MoonshotAI / MoonshotAI/kimi-code
ACP: subagent work is invisible — forward subagent lifecycle and streams over session updates
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Problem
Over ACP, subagent work is invisible: the adapter drops every non-main-agent event at the isFromMainAgent guard in packages/acp-adapter/src/session.ts (runTurnBody). An ACP client sees the parent Agent tool call and then nothing until it completes — no spawn signal, no per-tool progress, no completion summary. In the TUI the same information is rendered live from subagent.* events (src/tui/controllers/subagent-event-handler.ts).
Related: #2131 (subagents as first-class observable sessions), #2163 (agent-initiated turns never emit session/update).
Proposal
Forward the existing internal events (subagent.spawned/started/suspended/completed/failed — packages/protocol/src/events.ts) as ordinary tool_call / tool_call_update session updates, with the linkage in _meta.kimiCode.subagent:
spawned→tool_callwithtoolCallId: subagent:<subagentId>and_meta.kimiCode.subagent: {event, subagentId, subagentName, parentToolCallId, description?, swarmIndex?, runInBackground}.started/suspended/completed/failed→tool_call_updateagainst that card; completion carriesresultSummary/usage/contextTokens, suspensionreason, failureerror.- The subagent's own
assistant.delta/thinking.delta/tool.call.*frames are forwarded (guard relaxed) with_meta.kimiCode.subagentIdso clients can nest them under the subagent's card. - Capability advertised as
agentCapabilities._meta.kimiCode.subagentEvents.
Why standard frames + _meta instead of a custom sessionUpdate kind: v1 SDKs parse SessionUpdate as a closed union and silently drop unknown kinds, and the v2 enum-extension draft reserves non-underscore discriminator values for ACP. This is the same pattern claude-agent-acp uses for subagent progress (namespaced _meta on tool calls), and it stays compatible with every existing client — they see a flat but complete tool stream.
The shape also lines up with the direction of the open subagent RFD in the spec repo (agentclientprotocol/agent-client-protocol#855: tool calls with subagent linkage metadata), so a future migration to whatever that RFD stabilizes is a mapping change, not a redesign.
I have this implemented and tested in my fork (happy to open a PR immediately): ~350 lines with tests, additive-only diff.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/acp-adapter/src/session.ts at runTurnBody, then read the subagent event definitions in packages/protocol/src/events.ts and the live rendering flow in src/tui/controllers/subagent-event-handler.ts. Done means forwarding the specified subagent lifecycle and nested stream updates with the described _meta linkage, advertising the capability, and covering the behavior with tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100