feat(delegate): run cursor_delegate as a navigable child session#70
Open
justin-carper wants to merge 2 commits into
Open
feat(delegate): run cursor_delegate as a navigable child session#70justin-carper wants to merge 2 commits into
justin-carper wants to merge 2 commits into
Conversation
cursor_delegate previously ran the Cursor SDK directly inside the tool and collapsed the turn into a single result block, so its tool calls, reasoning, and text were invisible in opencode. opencode exposes no API to inject externally-produced message parts into a session, so the only way to surface that activity is to let opencode drive the turn. The tool now creates a parent-linked child session (session.create with parentID = the calling session) and runs the delegated prompt through session.prompt against the cursor provider. opencode's existing provider pipeline streams the child turn, so Cursor's live activity renders in the navigable subagent UI and the child session persists for later inspection. - Forward per-turn controls (mode/thinking/sandbox/agentId/cwd) to only the matching child session via a session-keyed control map consumed by the chat.params hook; controls are cleared after the turn so siblings never inherit them. - Read per-turn sandbox and cwd from providerOptions.cursor so the child executes in the requested directory and sandbox (cwd now reaches acquireAgent, not just the session query). - Abort the in-flight child on tool abort and delete a child that finishes creation after abort won the race, so no empty orphan session lingers. - Remove the now-dead direct runDelegate runtime and its tests. 299 tests, typecheck, and build pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
opencode lets you navigate into and follow subagent calls from a parent session.
cursor_delegatedid not participate in that UI: it ran the Cursor SDK directly inside the tool and collapsed the whole turn into a single result block, so Cursor's tool calls, reasoning, and text were invisible.Why this approach
opencode's SDK has no API to inject externally-produced message parts into a session (
/global/eventis subscribe-only; there is no part-write endpoint). The only way to surface a live, navigable subagent is to let opencode itself drive the turn on a child session viasession.create({ parentID })+session.prompt(...).What changed
cursor_delegatenow (keeping its API-key check andcontext.askpermission gate up front):parentID = context.sessionID).session.promptagainst thecursorprovider.language-model.ts→stream-map.ts) streams the child turn, so Cursor's live activity renders in the navigable subagent UI; the child session persists for later inspection.{ childSessionID, model, status, usage }.Supporting changes:
mode/thinking/sandbox/agentId/cwdare forwarded to only the matching child session via a session-keyed map consumed by the existingchat.paramshook, then cleared after the turn (siblings never inherit).sandboxandcwdfromproviderOptions.cursor;cwdnow reachesacquireAgent(not just the session query).runDelegateruntime (src/provider/delegate.ts) and its tests.Testing
npm test— 299 passing (added child-session creation/prompt shape, control forwarding + sibling isolation, per-turncwd/sandbox, abort + orphan-delete, restored cloud-agent regressions).npm run typecheck— clean.npm run build— success.Reviews
Two
code-reviewerpasses. First surfaced acwd-propagation gap and an abort race (both fixed); second returned ready-to-merge with one Important item — abort-race child should bedeleted, notaborted (a no-op on an unprompted session) — now fixed and covered by a test.Notes
parentID/session.children; whether the parent's tool block is click-through depends on the opencode TUI version.childSessionIDis exposed in metadata to support click-through where available. No private TUI APIs used.