Skip to content

Fix/replay persisted subagents - #1020

Open
euri10 wants to merge 2 commits into
agentclientprotocol:mainfrom
euri10:fix/replay-persisted-subagents
Open

Fix/replay persisted subagents#1020
euri10 wants to merge 2 commits into
agentclientprotocol:mainfrom
euri10:fix/replay-persisted-subagents

Conversation

@euri10

@euri10 euri10 commented Aug 21, 2026

Copy link
Copy Markdown

Summary

Fix session/load replay losing tool calls made inside persisted Claude
subagents.

Problem

The ACP session/load contract
requires the agent to replay the entire conversation through session/update
notifications. Tool executions are represented by
tool_call updates.

Claude stores subagent messages separately from the main session transcript:

  • getSessionMessages() returns the main transcript.
  • listSubagents() discovers persisted subagents.
  • getSubagentMessages() returns each subagent transcript.

replaySessionHistory() only loaded the main transcript. As a result, a nested
tool call appeared during the original live turn but silently disappeared when
the same session was loaded. The parent Agent/Task result remained visible,
making the replay look complete while omitting the subagent's actual work.

This affected the adapter's
nested subagent transcript behavior.
The client capability controls whether nested updates are rendered or flattened;
it does not transfer session-history recovery to the client.

Fix

  • Discover persisted subagents with listSubagents().
  • Load their histories with getSubagentMessages().
  • Recursively interleave each subagent history after its launching Agent/Task
    tool call.
  • Reuse the existing replay conversion so capability filtering and
    parentToolUseId attribution remain unchanged.

Regression test

The commits intentionally preserve red/green ordering:

  1. fece865 adds a split-storage regression fixture matching the Claude SDK's
    persisted-session layout.

  2. Before the implementation, the test fails:

    Expected: ["parent-agent-call", "child-tool"]
    Received: ["parent-agent-call"]
    
  3. e8f2df4 adds the implementation and makes the same test pass.

Real-session ACP evidence

The original live session emitted the nested call with its parent relationship:

{
  "method": "session/update",
  "params": {
    "sessionId": "<redacted>",
    "update": {
      "sessionUpdate": "tool_call",
      "toolCallId": "toolu_01AB1x1SdnkvcFoPF6EcmTqr",
      "rawInput": {
        "command": "ls -d <project>/*/ | xargs -n1 basename | paste -sd, -"
      },
      "_meta": {
        "claudeCode": {
          "parentToolUseId": "toolu_018NnXLu4qGQc7e4bei8C52a"
        }
      }
    }
  }
}

Before this fix, loading the same session emitted no corresponding child
tool_call update. After this fix, the child update is replayed with its
parent attribution and appears in the exported transcript in the expected
parent → child → assistant order.

Full logs are not included because they contain session content and local
environment details. The deterministic regression test provides reproducible
coverage; this excerpt documents the real ACP behavior that motivated it.

Verification

  • Focused regression test: passed
  • Full Vitest suite: 811 passed, 20 skipped
  • ESLint: passed
  • Prettier: passed
  • TypeScript build: passed
  • Manual session/load verification against a real persisted Claude session:
    nested child tool call restored with the correct parent ID

Copilot AI lite review requested due to automatic review settings August 21, 2026 02:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes session/load replay so it includes tool calls performed inside persisted Claude subagent transcripts, by loading subagent histories and interleaving them into the main session history before emitting session/update replays (preserving existing capability filtering and parentToolUseId attribution).

Changes:

  • Load persisted subagent IDs via listSubagents() and fetch their transcripts via getSubagentMessages().
  • Interleave subagent transcripts immediately after the launching Agent/Task tool call (recursively), then replay the combined history.
  • Add a regression test ensuring a child tool call from a persisted subagent is replayed and correctly attributed to its parent tool call.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/acp-agent.ts Loads persisted subagent transcripts and interleaves them into replay history so nested tool calls are replayed during session/load.
src/tests/acp-agent.test.ts Adds a regression test covering split-storage replay (main transcript + persisted subagent transcript) to ensure child tool calls are restored with correct parentToolUseId.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants