Skip to content

fix(server): a resumed Claude subagent's thread shows the message that resumed it - #13668

Merged
juliusmarminge merged 1 commit into
t3code/codex-turn-mappingfrom
v2/claude-subagent-resume-prompt
Sep 25, 2026
Merged

juliusmarminge merged 1 commit into
t3code/codex-turn-mappingfrom
v2/claude-subagent-resume-prompt

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

When a Claude parent resumes a finished subagent with SendMessage, the CLI re-emits task_started for the same task_id. That frame carries the SendMessage call's tool_use_id and uses the sent text as prompt. The adapter only wrote a child-thread user message when a task first appeared, so the resumed run's reply showed up in the child thread with no message before it.

What changed

ActiveClaudeSubagent now records runToolUseId, the tool call that started the current run. A task_started for a known task under a different tool_use_id is a resume. It emits its own user message:

  • id derived from task:<id>:prompt:<toolUseId>
  • next child ordinal, so it sorts after the previous run's reply
  • same senderThreadId attribution ("Sent by another agent")

The launch prompt keeps its existing id (task:<id>:prompt, ordinal 100), so existing threads and fixtures are unchanged. A drain-replayed or duplicate task_started under the same tool call emits nothing new.

Verification

  • The recorded fixture claude_background_subagent_lifecycle already contains a SendMessage resume of Agent A. Its output assertion now checks the child thread in display order: user:A_FIRST prompt, assistant:A_FIRST, user:A_SECOND prompt, assistant:A_SECOND.
    • Before the fix it fails: the received list is [user:Reply with exactly: A_FIRST, assistant:A_FIRST, assistant:A_SECOND], with no resume prompt.
    • After the fix it passes.
  • vp test run src/orchestration-v2/testkit/OrchestratorReplayFixtures.integration.test.ts -t claude: 26 passed.
  • vp test run src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: 118 passed.
  • vp exec tsc --noEmit -p . in apps/server: no errors or warnings.
  • vp run knip:check: clean.
  • vp lint on the changed files: only a pre-existing unused layer warning at the end of ClaudeAdapterV2.ts, which this PR does not touch.
  • Not run: repo-wide checks, other providers' suites, a live Claude session.

Not covered here

In the live session that surfaced this, the original task text was replaced rather than missing. That happens on a different path. The server restarted between the launch and the SendMessage, so the adapter's in-memory subagent registry was empty. The resume task_started then looked like a brand-new task and rewrote the launch prompt's message id with the new text. This PR does not change that path. It needs its own fix and a recording with a session reopen between launch and resume.

Codex does not have this bug. It keys each child-thread user message on the native userMessage item id, and the subagent_continue fixture already asserts both prompts.

Model: Claude Opus 5.5 (Claude Code)

🤖 Generated with Claude Code


Devin Review

…t resumed it

SendMessage to a finished Claude subagent re-emits task_started for the
same task id under the SendMessage call's tool_use_id, with the sent text
as the prompt. The adapter only wrote a child-thread prompt for the launch,
so the resumed run's reply appeared with no user message before it.

Track the tool call that started the current run; a task_started under a
different one emits its own user message, keyed on that tool_use_id and
placed after the previous run. The launch prompt keeps its id.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Sep 25, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 75a160b

Macroscope's review found this PR approvable — This is a localized Claude adapter bug fix that adds the missing resume prompt to an existing subagent thread while preserving initial-launch and replay behavior. The targeted fixture verifies the expected prompt/reply ordering, with no schema, security, infrastructure, or default changes.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 4.9 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.4 KiB — 29.3 KiB ✅
Codex Live turn messages — 2 — 8 ✅
Claude Total thread wire — 4.9 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 20.8 KiB — 29.3 KiB ✅
Claude Live turn messages — 2 — 8 ✅

Baseline: unavailable · PR result: 75a160b · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 106.1 KiB
  • Claude decoded thread snapshot: 106.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@juliusmarminge
juliusmarminge merged commit a4cd403 into t3code/codex-turn-mapping Sep 25, 2026
24 of 25 checks passed
@juliusmarminge
juliusmarminge deleted the v2/claude-subagent-resume-prompt branch September 25, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant