Skip to content

🤖 feat: expose sub-agent model and thinking level in task schedule and report - #3789

Merged
ibetitsmike merged 8 commits into
mainfrom
mike/task-model-thinking-exposure
Aug 4, 2026
Merged

🤖 feat: expose sub-agent model and thinking level in task schedule and report#3789
ibetitsmike merged 8 commits into
mainfrom
mike/task-model-thinking-exposure

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Task tool results and the sub-agent report envelope now carry the child's resolved model and thinking level, and the UI renders them: the TaskToolCall card shows <model> · thinking: <level> per task row, and SubagentReportMessageContent shows the same meta line on in-progress and completed report messages.

Background

When a parent spawns sub-agents, the resolved model/thinking settings were invisible unless you opened the child workspace. Model and thinking overrides (task({ model, thinking })) made this worse: there was no way to confirm from the parent transcript which settings a child actually ran with.

Implementation

  • taskService records the child's resolved modelString/thinkingLevel on spawn and threads them into spawned-task rows and completed-report entries of task tool results (toolDefinitions.ts schemas extended with optional fields).

  • The sub-agent report envelope (subagentReportEnvelope.ts) carries optional model/thinkingLevel; parsing tolerates absent or malformed values so a bad producer cannot invalidate an otherwise well-formed report.

  • TaskToolCall prefers live child-workspace metadata whenever the workspace exists (a plan child's auto-handoff to exec rewrites settings after launch, so result snapshots can go stale) and falls back to result-carried settings after cleanup; rendering reuses ModelDisplay plus the existing thinking badge styling.

  • Report-time settings (from review): completed task results read the child's settings at report time (threaded through waitForAgentReport and the report cache/artifact), not the launch snapshot, so a plan child that auto-handoffs to exec is labeled with the exec phase's model and thinking level.

  • Downgrade hardening (from review): getTaskToolPartialState() now extracts referenced task IDs from persisted partial task outputs with a tolerant reader instead of the strict result schema, so future optional result fields cannot break interrupted-stream recovery bookkeeping when downgrading to this release.

  • task_await propagation (from review): completed task_await results carry the report-time modelString/thinkingLevel, and taskReportLinking feeds them back to the original task card (precedence: live metadata, then linked report, then spawn snapshot), covering actively awaited background tasks whose synthetic report is suppressed.

  • Narrow-card overflow (from review): the task card's AI settings row constrains long custom model IDs (min-w-0 at both flex levels plus break-words) so unbroken tokens wrap instead of overflowing the right edge; guarded by a 320px story with an overflow play contract.

Validation

UAT in an isolated dev-server sandbox with real sub-agent spawns (foreground, background, and workspace-turn paths): verified the badge on running and completed task rows, both report surfaces, envelope contents on disk, and mobile (375px) wrapping with no right-edge overflow.

Recovery hardening is covered by a red-green regression test: a persisted task output carrying unknown future fields must not cause a duplicate fallback report; the test fails under the previous strict-parse behavior.

Risks

Low. All new schema fields are optional, so old persisted tool results and envelopes without the fields render exactly as before. Downgrading to the previous release keeps a narrow known window: a partial persisted mid-stream by this release is skipped by the old strict recovery parse, which can at worst duplicate a fallback report (same class as earlier optional additions like groupKind/label).


Generated with mux • Model: anthropic:claude-fable-5 • Thinking: xhigh

…d report

Task tool results (spawned rows, completed reports) and the sub-agent report
envelope now carry the child's resolved modelString/thinkingLevel, and the
TaskToolCall card plus SubagentReportMessageContent render them.

---

_Generated with `mux` • Model: `anthropic:claude-fable-5` • Thinking: `xhigh`_

<!-- mux-attribution: model=anthropic:claude-fable-5 thinking=xhigh -->
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b5aafc991

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/common/utils/tools/toolDefinitions.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e9d56e5961

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/tools/task.ts Outdated
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ffb83dfb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Tools/TaskToolCall.tsx Outdated
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c42b2fa70

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/Tools/TaskToolCall.tsx Outdated
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a1e21c0d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/taskService.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: f0f3b54230

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike merged commit d8e92cb into main Aug 4, 2026
21 of 22 checks passed
@ibetitsmike
ibetitsmike deleted the mike/task-model-thinking-exposure branch August 4, 2026 07:32
@mux-bot mux-bot Bot mentioned this pull request Aug 4, 2026
mux-bot Bot added a commit that referenced this pull request Aug 4, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 5, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 6, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 6, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 7, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 7, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 7, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
mux-bot Bot added a commit that referenced this pull request Aug 8, 2026
The module reads every field out of persisted tool args/results typed as
`unknown`, and #3789/#3793 grew that from four to seven copies of the same
"is a string, is not blank, use the trimmed form" check. Collapse those seven
into a single coerceNonBlankString helper.

The two task_await result reads are deliberately left alone: they validate a
field is non-blank but then store the raw, untrimmed value, so routing them
through the helper would change what gets persisted.
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.

1 participant