Skip to content

feat(session): spawn subagent sessions and wait for their answer - #62036

Open
kitlangton wants to merge 7 commits into
pool-subagents-backgroundfrom
pool-subagents-spawn
Open

kitlangton wants to merge 7 commits into
pool-subagents-backgroundfrom
pool-subagents-spawn

Conversation

@kitlangton

Copy link
Copy Markdown
Contributor

Clients can now start a subagent session with one call and wait for its answer.
A new experimental spawn endpoint creates a child of a session, records whether the parent wants a report, and can send the child's first prompt. session.wait now returns how the child's last run ended and its final answer, instead of nothing.

Stacked on #62035 (background by default), which is stacked on #61833. Part 3 of 3.

💡 Why
Today a client that wants a subagent has to create a session with parentID, prompt it, wait, then read its messages to find the answer. Plugins and the SDK kept re-implementing that, and none of them could say "don't report back to the parent".

🆕 Now you can

  • POST /api/experimental/session/:id/spawn with { id?, notify?, agent?, model?, title?, prompt? } and get the child's id back. Pass your own id to make a retry safe: the same id returns the same child instead of a second one.
  • POST /api/experimental/session/:id/wait returns { outcome, text }: the last run's outcome and the newest completed, error-free assistant answer, paging back through the whole history rather than only the newest 20 messages.
  • In core, Session.spawn({ parent: { id, notify }, … }) does the same.

🚦 How it ships: both endpoints stay under /api/experimental. Creating a child with parentID on create still works but is marked deprecated in favor of spawn.

- create({ parentID }) -> prompt(child) -> wait(child): void -> read messages -> find answer
+ spawn({ parent: { id, notify }, prompt }) -> wait(child): { outcome, text }

📊 Proof

Check Result
core session-wait, session-create, subagent-lifetime 90 pass, 2 fail (see below)
server session-create 7 pass
client effect, promise 50 pass

The new tests cover spawn inheriting location, metadata and permissions from the parent, the retry with a caller-chosen id, notify reaching the child, and wait finding an answer older than the newest 20 messages. The two local failures are the existing session.shell tests in session-create, which time out on my machine on the bottom PR too, where session.ts is unchanged from dev; CI is the judge for those.

↩️ Undo: session.wait changed from an empty 204 to a JSON body. A client generated before this PR rejects the new response, and a new client rejects an old server's 204, so revert the regenerated clients together with the server. The endpoint is under /api/experimental, and the CLI and TUI ship with the server, so only third-party callers of the experimental route see the change.

👀 Read: packages/core/src/session.ts, the extracted createChild, which both create-with-parent and spawn now use; check that inheritance and the existing-ID path match the old branch. And Session.wait in session/session.ts, which re-reads the session after idle so it doesn't return the previous run's outcome. The rest is routine.

From a team design discussion · no user reports · reviewed before push

Checks run
  • bun test test/session-wait.test.ts test/session-create.test.ts test/subagent-lifetime.test.ts (packages/core): 90 pass, 2 session.shell timeouts
  • bun test test/session-create.test.ts test/session-wait.test.ts (packages/server): 7 pass
  • bun test test/effect.test.ts test/promise.test.ts (packages/client): 50 pass

@kitlangton
kitlangton force-pushed the pool-subagents-background branch from c9b3b28 to d690980 Compare November 5, 2026 10:03
@kitlangton
kitlangton force-pushed the pool-subagents-spawn branch from 3d9759c to f23941d Compare November 5, 2026 10:03

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant