MoonshotAI / MoonshotAI/kimi-code

ACP: subagent work is invisible — forward subagent lifecycle and streams over session updates

Open
#2,482 0 comments 0 reactions 0 assignees View on GitHub

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/failedpackages/protocol/src/events.ts) as ordinary tool_call / tool_call_update session updates, with the linkage in _meta.kimiCode.subagent:

  • spawnedtool_call with toolCallId: subagent:<subagentId> and _meta.kimiCode.subagent: {event, subagentId, subagentName, parentToolCallId, description?, swarmIndex?, runInBackground}.
  • started/suspended/completed/failedtool_call_update against that card; completion carries resultSummary/usage/contextTokens, suspension reason, failure error.
  • The subagent's own assistant.delta / thinking.delta / tool.call.* frames are forwarded (guard relaxed) with _meta.kimiCode.subagentId so 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.