fix(server): Claude subagent threads show the subagent's thinking#27211

open2
main
fix/issue-27178
opened8d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 8d ago

Problem

A Claude subagent started with the Agent tool shows its tool calls in its child thread but never its thinking. Reproduced on main dd14848153 in the web dev server with Claude Opus 5.5 and a foreground subagent told to think, run echo done, and think again. The child thread listed only the Bash call. The subagent's transcript (subagents/agent-<id>.jsonl) held two non-empty thinking blocks.

Change

By default the Claude Agent SDK forwards only a subagent's tool_use/tool_result blocks. Its forwardSubagentText option also forwards the subagent's thinking and text blocks as assistant messages tagged with parent_tool_use_id. In non-interactive sessions the CLI otherwise sets subagent thinking display to "omitted". makeClaudeQueryOptions now sets forwardSubagentText: true, and the option appears in the logged query options. The adapter already routes these frames into the child thread (emitSubagentThinking, emitSubagentConversationMessage). It already skips the final result when it matches the last forwarded text, so the reply still appears once. Child threads now also show the subagent's own narration text between tool calls, as parent threads already do.

Scope and approval

Fixes pingdotgg/t3code#27178

Triaged via the automated issue flow.

Verification

  • ClaudeAdapterV2 runtime query policy > asks Claude to forward subagent thinking and text, not just tool calls: fails on main (expected undefined to be true) and passes on this branch.

  • shows forwarded subagent thinking in the child thread only: feeds forwarded subagent thinking frames through the adapter. It checks that reasoning lands in the child thread only and that the reply appears once.

  • vp test run apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: 256/256 pass. vp run check:changed: format, lint, knip, typecheck and tests pass.

  • SDK 0.3.276 probe with the same subagent prompt:

    Claude CodeSubagent frames, option offSubagent frames, option on
    2.1.304tool_use onlythinking (1035 chars), tool_use, thinking (180), text
    2.1.312 (reporter's version)tool_use onlythinking (254), tool_use ×2, thinking (633), text
  • The web dev server (T3CODE_DEV_SEED=0 vp run dev) ran a fresh database, Claude Opus 5.5 and Claude Code 2.1.304, with a 1280×800 viewport and the light theme:

    CaseBefore (dd14848153)After (84751082ee)
    Foreground subagent, child threadOnly the Bash call, no thinkingTwo Thinking rows around the Bash call, reply once
    Foreground subagent, parent threadn/aOnly the parent's own thinking plus the subagent card; no subagent thinking leaks
    Background subagent (run_in_background: true), child threadn/aThinking row, narration, Bash call, reply once, no extra status line

    Captures, in table order:

  • A real two-member Workflow run with the option on forwarded no member frames with parent_tool_use_id (reviewer check), so transcript-tailed member projection is unaffected.

  • Not checked: Claude Code versions older than 2.1.304. The SDK sends the option in its initialize request, not as a CLI flag, so an older CLI that does not know it should ignore it. Desktop and mobile were not run; this is a server-only change and they render the same reasoning items as web.

Model and harness: Claude Opus 5.5 (Claude Code) as lead, red test and implementation; GPT-6.1-Sol (Codex) and Claude Opus 5.5 as reviewers.

🤖 Generated with Claude Code

Checks

22 successful · 11 skipped · 1 neutral
All checks passed
8475108

Added 2 commits

  • test(server): reproduce #27178, Claude subagent thinking is never requested31ee331
  • fix(server): Claude subagent threads show the subagent's thinking8475108
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — Claude queries now enable subagent text forwarding by default so subagent threads can show their thinking. Human confirmation is required for this change to default content visibility.

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

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.3 KiB1.3 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded21.6 KiB21.6 KiB0 B (0.0%)24.4 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.1 KiB+6 B (+0.1%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.3 KiB1.3 KiB+6 B (+0.5%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.9 KiB21.9 KiB0 B (0.0%)24.4 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: dd14848 · PR result: 8475108 · 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: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

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

Synced from GitHub

Review in Change Stack →

Walkthrough

Claude queries now enable forwardSubagentText, and protocol logging records the option when enabled. Tests verify the option and check that forwarded subagent thinking appears only in the child thread.

Changes: Claude subagent forwarding

Layer / File(s)Summary
Forwarding option and thread routing
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
Claude query options enable and log forwardSubagentText. Tests check the option and verify that subagent thinking appears in the child thread while assistant text remains routed to the child and root threads.

Priority: External image Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related PRs

  • pingdotgg/t3code#24410: Updates Claude assistant-text projection and reconciliation, which is part of the projection path used for forwarded subagent text.

Suggested labels: bugfix, size:S

Suggested reviewers: t3dotgg

Merge Risk: External image Minimal · up to 84751

No merge-blocking risk was established for the forwarding change.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title "fix(server): Claude subagent threads show the subagent's thinking" names the main change. The diff sets forwardSubagentText: true in Claude query options so the SDK forwards subagent thinki…
Description checkPassedThe description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section gives the expected and observed behavior and a reproduction environment…
Linked Issues checkPassedRequirement [#27178]: native Claude Agent subagent child threads must show the subagent's thinking, during the run and after it finishes. The diff at ClaudeAdapterV2.ts adds `forwardSubagentText: true…
Out of Scope Changes checkPassedAll changes connect to #27178. The adapter diff adds the forwardSubagentText: true option in makeClaudeQueryOptions. It adds the matching optional-true field to ClaudeAgentSdkLoggedQueryOptions …
Full details: Title check

Explanation

The title "fix(server): Claude subagent threads show the subagent's thinking" names the main change. The diff sets forwardSubagentText: true in Claude query options so the SDK forwards subagent thinking and text, and the adapter routes those frames into the child thread. The title is specific, uses a conventional commit prefix, and fits the linked issue #27178.

Full details: Description check

Explanation

The description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section gives the expected and observed behavior and a reproduction environment. The Change section explains the option and the adapter routing. Scope links issue #27178 and says it was triaged through the automated issue flow. Verification lists specific tests, the model and Claude Code versions, before and after captures, and what was not checked. One gap: the Scope section does not give a maintainer approval comment or explain the exemption for a small fix. The template asks for one of these, so a reviewer may need to confirm the scope approval.

Full details: Linked Issues check

Explanation

Requirement [#27178]: native Claude Agent subagent child threads must show the subagent's thinking, during the run and after it finishes. The diff at ClaudeAdapterV2.ts adds forwardSubagentText: true to makeClaudeQueryOptions. The SDK then forwards subagent thinking and text blocks as assistant frames with parent_tool_use_id. The existing adapter path (emitSubagentThinking, emitSubagentConversationMessage) projects those frames into the child thread. The new test shows forwarded subagent thinking in the child thread only checks that reasoning ['Check the diffs.'] lands in the child thread, that the parent thread gets no reasoning, and that the reply appears once. The new test asks Claude to forward subagent thinking and text, not just tool calls checks the option. The ^0.3.276 SDK dependency in apps/server/package.json matches the probe the author reports. The PR description reports a live probe on Claude Code 2.1.304 and 2.1.312 with the option on, which shows thinking frames. Screenshots show the child thread after the change. I did not run the tests. The adapter-side projection was confirmed through the test code, not by reading emitSubagentThinking directly. The issue leaves the fix method to the implementer, and the option-based fix meets the stated behavior. Workflow member projection is unaffected per the reviewer check described in the PR.

Full details: Out of Scope Changes check

Explanation

All changes connect to #27178. The adapter diff adds the forwardSubagentText: true option in makeClaudeQueryOptions. It adds the matching optional-true field to ClaudeAgentSdkLoggedQueryOptions and logs the option in loggedClaudeQueryOptions, which records the option in the query options log. The test diff adds one option-policy test and one child-thread routing test that covers this behavior. No unrelated files are in the reviewed diff summary. The PR description states that the adapter routing and the final-reply deduplication already existed. The diff does not change those paths, so they are not out of scope.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.