Skip to content

fix(server): Claude subagents no longer show the parent's effort - #17042

Merged
juliusmarminge merged 6 commits into
pingdotgg:mainfrom
juansuaya17:fix/claude-subagent-effort-label
Nov 11, 2026
Merged

juliusmarminge merged 6 commits into
pingdotgg:mainfrom
juansuaya17:fix/claude-subagent-effort-label

Conversation

@juansuaya17

@juansuaya17 juansuaya17 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Claude custom agent definitions can override the parent or owner effort. Inheriting that value made a child thread display an effort it might never use. The adapter now records explicit launch effort and preserves it on subsequent updates; main's canonical model and effort validation remain intact.

The shared web/mobile native-subagent header also stops supplying catalog defaults or current values when the child has no selected or matching reported effort. Explicit and matching reported values, including the provider's Default sentinel, remain visible.

Rebuilt from @juansuaya17's #17042, preserving the contributor commits and merging main. The original model-copy helper was replaced with the current adapter's effort handling.

Verification

  • Existing Claude adapter and shared header tests were updated rather than adding another test file. Baseline: 286 adapter tests and 44 shared tests; revised regressions exposed 2 adapter and 5 shared failures before implementation. After: 332 passed across both full suites (286 adapter, 46 shared).
  • Scoped server and client-runtime typechecks passed. Changed-file lint and formatting passed, with one existing unused layer lint warning.
  • One independent adversarial round: Claude Opus 5.5 and Codex gpt-6-sol found no code blockers across the complete diff against main.
  • Live headless Linux web app, isolated SQLite fixtures: the same child with no effort displayed Medium using main's formatter and no effort using the head formatter; a separate child with explicit Low retained Low. These display fixtures do not launch a real Claude agent; SDK event tests cover parent/owner inheritance and later child updates.
  • Chromium's system fonts measured zero width; the preview tab loaded a local DejaVu font for both captures. No product font changes.
  • Not verified: a live Claude custom agent definition/account, macOS, Windows, iOS, Android, or Electron desktop. Mobile uses the shared formatter and was inspected, not launched.

Before — main formatter, unknown child effort:

Before: unknown Claude child effort incorrectly displays Medium

After — head formatter, same child and viewport:

After: unknown Claude child effort has no inferred label

After — explicit effort remains visible:

After: Claude child explicitly launched with Low still displays Low

Implementation: Codex gpt-6.1-sol; tests: Codex gpt-6-astra; reviews: Claude claude-opus-5-5 and Codex gpt-6-sol, through T3 Code delegated tasks. Maintainer integration: Codex gpt-6.1-sol in T3 Code.

When a Claude subagent ran on the parent's model, its child thread copied
the parent's whole model selection, effort included. A subagent's effort
comes from its agent definition or Agent call, which the SDK does not
report, so an agent defined with `effort: xhigh` was labelled with the
parent's `high`. The child selection now drops the effort option.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 8, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 8, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at cf65974

Macroscope's review found this PR approvable — Claude subagents will stop reporting their parent’s effort when their own effort is unknown. This is a narrow metadata correction that preserves explicit values without changing provider execution defaults.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

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

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

New subagents no longer inherit effort from their owner or the parent model selection. Existing subagents retain their recorded effort. Tests check explicit and unspecified effort values for nested subagents and their child threads.

Changes: Explicit model effort

Layer / File(s) Summary
Record explicit subagent effort
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts, apps/server/src/orchestration-v2/testkit/OrchestratorReplayRecovery.integration.test.ts
New subagents record effort only when the launch input supplies it. Tests check explicit and unspecified effort values for nested subagents and their child threads. The recovery test no longer asserts that the child thread has effort: high.

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

Change: Bug fix

Possibly related issues

  • pingdotgg/t3code#24143 — This issue describes parent effort appearing when a Claude subagent definition sets a different effort. This change removes the parent-effort fallback for new subagents.
  • pingdotgg/t3code#29200 — This issue describes child threads displaying parent effort. This change leaves effort unset when a new subagent does not explicitly specify it.

Possibly related PRs

Suggested labels: bugfix

Suggested reviewers: rakshithbhat03

Merge Risk: Minimal · up to cf659

Claude subagents will no longer show the parent's effort when none was set explicitly, and explicitly set values are still shown. No concrete merge-blocking risk was identified in the supplied change.

Architecture risk: Low · up to dd9ea

The change affects 2 systems.

Changed systems: apps/server, packages/client-runtime

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — apps/server (service) was modified; 2 changed files map to changed impact.
  • observed — packages/client-runtime (library) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: The opus subagent case now expects no recorded effort when the Agent call omits it, rather than "max".
  • observed — Modified behavior in apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: The nested-subagent test is renamed to cover only explicit effort, and its unspecified nested subagent gets a distinct identifier instead of being described as inheriting effort.
  • observed — Modified behavior in apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: The test launches an unspecified nested subagent and an explicitly "max" subagent; it no longer frames the first call as an inheritance case.
  • observed — Modified behavior in apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: Expected effort for the unspecified nested subagent and its child thread changes from "low" to undefined; the outer "low" and explicit nested "max" expectations remain.
Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: Claude subagents no longer inherit or display the parent effort.
Description check Passed The description explains the problem, implementation, affected shared UI behavior, verification results, limitations, and review context. It does not use separate Problem, Change, or Scope and approva…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the problem, implementation, affected shared UI behavior, verification results, limitations, and review context. It does not use separate Problem, Change, or Scope and approval headings, and it does not explicitly document maintainer approval, but the required information is mostly present.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between b66dfea and cf65974.

Files selected for processing: 1

  • apps/server/src/orchestration-v2/testkit/OrchestratorReplayRecovery.integration.test.ts
Files with no reviewable changes: 1

  • apps/server/src/orchestration-v2/testkit/OrchestratorReplayRecovery.integration.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 11, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 11, 2026 06:15

Dismissing prior approval to re-evaluate 9a12353

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 11, 2026
@juliusmarminge juliusmarminge self-assigned this Oct 19, 2026
@juliusmarminge

Copy link
Copy Markdown
Member

Taking over this one for batch claude-01. I’ll update the fix against current main while preserving explicit subagent effort handling, keep focused regression coverage, and verify it before publishing.

@macroscopeapp
macroscopeapp Bot dismissed their stale review October 19, 2026 06:38

Dismissing prior approval to re-evaluate dd9eaa6

@saphid

saphid commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Source review of dd9eaa6: an unsupported stored effort can still turn into a catalog-default label. In formatModelSelectionEffort, a saved { id: "effort", value: "old-level" } passes the new string-presence guard. However, getProviderOptionDescriptors has already normalized that obsolete choice through resolveDescriptorChoiceValue, which falls back to descriptor currentValue or the catalog default. getProviderOptionCurrentLabel then displays that fallback, e.g. Medium, although neither the child nor provider reported Medium.

Please add an obsolete stored-choice regression with a descriptor default/current value, and validate the raw stated choice against the offered options before displaying its label. Preserve the supported reported Default sentinel. A matching reported obsolete value follows a different raw-value path, so I am not asserting the same fallback for that case.

Exact-head source: header guard, descriptor normalization. This is independently checked source reasoning, not an executed test or real Claude reproduction. Exact-base/head custom-agent and client verification remain pending; the supplied display fixtures do not establish the provider's actual effort.

@smolpaw

smolpaw commented Oct 23, 2026

Copy link
Copy Markdown

#24143 has a live repro of this on 0.1.2 with a real Claude custom agent definition (effort: low, thread at xhigh). T3 stores xhigh, and Claude Code runs the subagent at low. The steps are runnable by an agent and check both sides: the T3 state database and the subagent's Claude Code transcript.

It also covers a second path: a PreToolUse hook that sets effort through updatedInput gets the same wrong label.

…ffort-label

# Conflicts:
#	apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
#	apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
#	packages/client-runtime/src/state/threadExecution.test.ts
#	packages/client-runtime/src/state/threadExecution.ts
AI-assisted; verified with the tests and tools listed above.
@github-actions github-actions Bot added size:XS 0-9 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Nov 11, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 11, 2026
AI-assisted; verified with the tests and tools listed above.
@macroscopeapp
macroscopeapp Bot dismissed their stale review November 11, 2026 07:09

Dismissing prior approval to re-evaluate cf65974

@juliusmarminge

Copy link
Copy Markdown
Member

Evidence

On both commits, configure the custom effort-probe agent with effort: low, start a fresh Claude parent at Extra High, and request a native Agent call with subagent_type: effort-probe, prompt Reply OK, and no effort parameter. Open the completed child. Both native child transcripts report low; base saves and displays Extra High, while head leaves effort absent.

Environment for both sides: real web client and server, isolated fresh databases, identical synthetic project, Chromium at 1280×800, light theme. Images crop the sidebar; black masks redact private model identifiers. Recordings show opening the completed child from its parent, with two seconds of final-frame hold added.

Before After
a03d9bce02 cf6597442f
Before: child incorrectly displays Extra High After: child has no effort label
Before recording After recording
Before saved selection and native transcript excerpt After saved selection and native transcript excerpt

Executed synthetic seed script · Read-only evidence extraction script

AI-assisted; verified with the tests and tools listed above. No tests were used as proof.

Not shown:

  • Explicitly supplied Agent effort, nested subagents, and resumed subagents were not exercised; this proof covers the reported custom-agent call with omitted effort.

@juliusmarminge
juliusmarminge merged commit 835e726 into pingdotgg:main Nov 11, 2026
35 checks passed
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Nov 11, 2026
**v0.1.10-nightly.20261111.4529** · 54 changes from 29 contributors

- **Find in browser.** Search pages in the desktop integrated browser with Cmd+F or Ctrl+F.
- **GitLab overview threads.** Resolve merge request overview threads from Summary and Timeline.
- **Faster worktree updates.** Checkpoint captures and status refreshes avoid rereading every file in newly created worktrees.
- **Imported session history.** Imported agent sessions now show their existing history instead of opening as empty threads.
- **SSH reconnect prompts.** Expired SSH verification prompts no longer stack up and force an app restart.
- **Large reasoning traces.** Opening a thread with a large collapsed reasoning trace no longer freezes the app.
- **Terminal scrollback.** Terminal history retains substantially more output instead of silently discarding older lines.

### Plus 45 more bug fixes and performance improvements.

<details>
<summary>Full changelog</summary>

## What's Changed
* fix(server): new worktrees refresh their index once, so captures and status stop re-hashing every file by @josephv123 in pingdotgg/t3code#21341
* fix(usage): Grok and Cursor usage limits show pace and the even-spend line by @wookiist in pingdotgg/t3code#21897
* fix(web): retain diff selection across navigation by @aleo113 in pingdotgg/t3code#22347
* fix(mobile): subscription widget no longer expires on a window that already reset by @juliusmarminge in pingdotgg/t3code#22993
* fix(opencode): verify CLI updates when loopback server is still running by @intrepid37 in pingdotgg/t3code#22839
* fix(usage): Claude subagent output is no longer undercounted by @rfrost-xyz in pingdotgg/t3code#20276
* fix(server): a remote update points the service unit at the runtime it committed by @Marve10s in pingdotgg/t3code#19652
* fix(server): a limited provider's queue stays held after another provider's turn succeeds by @Marve10s in pingdotgg/t3code#22425
* fix(shared): keep spreadsheet shorthand as inline code by @juliusmarminge in pingdotgg/t3code#23203
* fix(web): offer retry while an environment reconnects by @juliusmarminge in pingdotgg/t3code#23194
* fix(server): custom Codex providers no longer report native quota by @fixfon in pingdotgg/t3code#18622
* fix(desktop): Cmd+F now searches the page in the integrated browser by @armanarutiunov in pingdotgg/t3code#22960
* fix(desktop): an SSH password prompt that ended leaves the dialog instead of stacking by @Umais-Adeed in pingdotgg/t3code#34192
* fix(web): render Claude insight blocks as a callout by @macodev00 in pingdotgg/t3code#22239
* fix(scheduler): show short server timezone on fixed-time labels by @shawk08033 in pingdotgg/t3code#23111
* fix(web): focus the primary action when confirmation dialogs open by @rgrvlsk in pingdotgg/t3code#18187
* fix(web): Changes row matches the diff comparison by @whoisaldo in pingdotgg/t3code#19553
* fix(server): imported ACP sessions show their native history by @only21mil in pingdotgg/t3code#22155
* fix(preview): always return evaluated results by value by @juliusmarminge in pingdotgg/t3code#22948
* fix(provider-core): a model reply of "title" no longer replaces the thread title by @juliusmarminge in pingdotgg/t3code#25743
* fix(desktop,web): Open in runs locally for a background service sharing the desktop's T3 home by @KinanLak in pingdotgg/t3code#21661
* fix(web): question answers submit while normal sends are blocked by @t3dotgg in pingdotgg/t3code#22874
* fix(server): cancelling a background-only delegated task reports it interrupted by @only21mil in pingdotgg/t3code#21676
* fix(web): fall back to a readable server for shared repositories by @sanjaibalajee in pingdotgg/t3code#21530
* fix(web): composer follows an optionless thread instead of the settings default by @f4llenz in pingdotgg/t3code#16546
* fix(web): don't save retention age until committed by @macodev00 in pingdotgg/t3code#22208
* fix(server): one dropped probe no longer lists a live linked peer as unreachable by @juliusmarminge in pingdotgg/t3code#34208
* fix(server): preview automation reports ambiguous selectors instead of calling them invalid by @juliusmarminge in pingdotgg/t3code#34205
* fix(opencode): a context overflow that OpenCode compacts no longer fails the turn by @juliusmarminge in pingdotgg/t3code#26743
* fix(web): Ctrl + "+" zooms on keyboard layouts with a dedicated plus key by @juliusmarminge in pingdotgg/t3code#26408
* fix(ci): release version bump push retries when main moves by @t3dotgg in pingdotgg/t3code#34326
* fix(server): CLI commands no longer migrate the database of a running server by @juliusmarminge in pingdotgg/t3code#26763
* fix(web): keep saved default model when changing effort by @macodev00 in pingdotgg/t3code#22193
* fix(web): reveal expanded work rows hidden behind the composer by @ln-bodicherla in pingdotgg/t3code#21968
* fix(composer): steer instead of queueing during automatic compaction by @NikitaMGrimm in pingdotgg/t3code#24138
* feat(gitlab): resolve overview threads from Summary and Timeline by @TonybynMp4 in pingdotgg/t3code#30575
* fix(web): pull request search keeps partial-word matches after GitHub answers by @juliusmarminge in pingdotgg/t3code#26992
* fix(server): Claude subagents no longer show the parent's effort by @juansuaya17 in pingdotgg/t3code#17042
* fix(server): runs cancelled by a server restart say why in the thread by @juliusmarminge in pingdotgg/t3code#27192
* fix(client-runtime): server updates stop waiting 32 minutes when the host returns without this update's outcome by @juliusmarminge in pingdotgg/t3code#27275
* fix(web): Stop shows a pending state and repeat clicks no longer resume by @voida6 in pingdotgg/t3code#20809
* fix(web): collapsed reasoning previews no longer process the whole block by @juliusmarminge in pingdotgg/t3code#23001
* fix(server): storage cleanup skips stale worktree paths under a regular file by @juliusmarminge in pingdotgg/t3code#26594
* fix(terminal): use a byte budget for Ghostty scrollback by @zero-two-rafaeltab in pingdotgg/t3code#8766
* fix(server): storage cleanup keeps worktrees whose file listing exceeds the inspection limit by @juliusmarminge in pingdotgg/t3code#26593
* fix(server): delete temporary ACP health probe sessions by @juliusmarminge in pingdotgg/t3code#25397
* perf(client): streamed text no longer republishes thread queue and checkpoints by @juliusmarminge in pingdotgg/t3code#27425
* fix(web): convert composer list markers completed later by @juliusmarminge in pingdotgg/t3code#22997
* test: remove tests that repeat another case or restate the source by @shivamhwp in pingdotgg/t3code#34170
* fix(server): drop stale queued pull-request watch wakes by @Sinan53x in pingdotgg/t3code#21239
* fix(web): preview recordings stay decodable after a viewport resize by @MansTomb in pingdotgg/t3code#10495
* fix(server): only offer claude update for native Claude installs by @AI091 in pingdotgg/t3code#14170
* fix(server): tell outside agents which MCP tools need a thread and that t3_thread_list takes allProjects by @juliusmarminge in pingdotgg/t3code#26525

## New Contributors
* @wookiist made their first contribution in pingdotgg/t3code#21897
* @aleo113 made their first contribution in pingdotgg/t3code#22347
* @intrepid37 made their first contribution in pingdotgg/t3code#22839
* @rfrost-xyz made their first contribution in pingdotgg/t3code#20276
* @armanarutiunov made their first contribution in pingdotgg/t3code#22960
* @KinanLak made their first contribution in pingdotgg/t3code#21661
* @sanjaibalajee made their first contribution in pingdotgg/t3code#21530
* @ln-bodicherla made their first contribution in pingdotgg/t3code#21968
* @juansuaya17 made their first contribution in pingdotgg/t3code#17042
* @zero-two-rafaeltab made their first contribution in pingdotgg/t3code#8766
* @MansTomb made their first contribution in pingdotgg/t3code#10495
* @AI091 made their first contribution in pingdotgg/t3code#14170

**Full Changelog**: pingdotgg/t3code@v0.1.9-nightly.20261111.4515...v0.1.10-nightly.20261111.4529

</details>


Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.1.10-nightly.20261111.4529
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants