Skip to content

fix(agent-core): keep profile-routed subagent model on resume and retry - #28

Merged
elkaix merged 4 commits into
mainfrom
fix/subagent-model-routing-on-resume
Aug 5, 2026
Merged

fix(agent-core): keep profile-routed subagent model on resume and retry#28
elkaix merged 4 commits into
mainfrom
fix/subagent-model-routing-on-resume

Conversation

@elkaix

@elkaix elkaix commented Aug 5, 2026

Copy link
Copy Markdown
Member

Related Issue

No issue — problem described below.

Problem

An agent profile can route its subagents to a different model (a cheap
implementer under an expensive orchestrator, for example). That routing only
held on the initial spawn: resuming or retrying a subagent copied the parent
agent's model alias onto the child, so from the second turn on the subagent
silently ran on the orchestrator's model and the profile's effort setting was
dropped.

What changed

Resume and retry now re-resolve the child's model through the same precedence
as spawn — explicit run option, then profile, then parent — instead of copying
the parent's model. An alias the child's provider cannot resolve falls back to
the parent's model rather than failing at generate time. Added a regression
test covering resume with a profile-routed model and effort.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update. (internal behavior, no CLI docs surface)

Summary by CodeRabbit

  • Bug Fixes
    • Subagents now retain their assigned model and effort settings when resumed or retried.
    • Invalid or unavailable model aliases gracefully fall back to the parent agent’s model.
    • Profile configuration issues no longer prevent subagent resume or retry operations.

elkaix added 2 commits August 5, 2026 19:09
Resume and retry copied the parent's modelAlias onto the child, so a profile
that routes its subagents to another model reverted to the orchestrator's
model on the second turn. Both paths now re-resolve through the spawn
precedence (explicit option -> profile -> parent), falling back to the parent
when the child's provider cannot resolve the requested alias.
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 51 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e6f953f3-442d-42a4-8704-5a96a4ec942f

📥 Commits

Reviewing files that changed from the base of the PR and between ba48a91 and f6a2d58.

📒 Files selected for processing (1)
  • packages/agent-core/test/session/subagent-host.test.ts
📝 Walkthrough

Walkthrough

Subagent initialization, resume, and retry now use centralized configuration. Profile-selected model aliases and effort levels are preserved when aliases resolve, with fallback to the parent model when they do not.

Changes

Subagent model preservation

Layer / File(s) Summary
Model alias resolution
packages/agent-core/src/agent/config/index.ts
ConfigState exposes canResolveModel. Provider resolution now accepts an explicit model alias while preserving fallback behavior.
Centralized child configuration
packages/agent-core/src/session/subagent-host.ts, packages/agent-core/test/session/subagent-host.test.ts, .changeset/keep-subagent-routed-model.md
Initial setup, resume, and retry use shared configuration. Explicit options take priority, followed by profile settings and parent defaults. Tests verify preservation of the profile-routed model and effort.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SubagentHost
  participant ProfileResolver
  participant ConfigState
  participant ChildAgent
  SubagentHost->>ProfileResolver: Resolve profile settings
  ProfileResolver-->>SubagentHost: Return model and effort
  SubagentHost->>ConfigState: Validate model alias
  ConfigState-->>SubagentHost: Return resolution status
  SubagentHost->>ChildAgent: Apply model, effort, thinking level, and fast mode
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the fix prefix, stays within 72 characters, uses imperative mood, and clearly describes the subagent model-routing correction.
Description check ✅ Passed The description includes all required sections, explains the problem and solution, and confirms tests, changesets, documentation, and contribution checks.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 5, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@pythoughts/pythinker-code@f6a2d58
npx https://pkg.pr.new/@pythoughts/pythinker-code@f6a2d58

commit: f6a2d58

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
packages/agent-core/test/session/subagent-host.test.ts (1)

1375-1425: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover profile-routed configuration in retry.

The existing host.retry test covers rate-limit recovery but not profile-selected configuration. Add a Vitest case that retries a profile-routed child and asserts modelAlias and thinkingLevel retain the profile values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/agent-core/test/session/subagent-host.test.ts` around lines 1375 -
1425, Add a Vitest case for SessionSubagentHost.retry that configures a child
with a routed ResolvedAgentProfile, triggers a retry, and verifies the retry
preserves the profile’s modelAlias and thinkingLevel rather than the parent
configuration. Reuse the existing profile-routing setup and assertions from the
resume test while exercising retry-specific flow.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/agent-core/test/session/subagent-host.test.ts`:
- Around line 1375-1425: Add a Vitest case for SessionSubagentHost.retry that
configures a child with a routed ResolvedAgentProfile, triggers a retry, and
verifies the retry preserves the profile’s modelAlias and thinkingLevel rather
than the parent configuration. Reuse the existing profile-routing setup and
assertions from the resume test while exercising retry-specific flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c2af45df-3e70-4496-b19e-324a06fd32f0

📥 Commits

Reviewing files that changed from the base of the PR and between 251fb87 and ba48a91.

📒 Files selected for processing (4)
  • .changeset/keep-subagent-routed-model.md
  • packages/agent-core/src/agent/config/index.ts
  • packages/agent-core/src/session/subagent-host.ts
  • packages/agent-core/test/session/subagent-host.test.ts

@elkaix
elkaix merged commit cf5b6b1 into main Aug 5, 2026
11 checks passed
@elkaix
elkaix deleted the fix/subagent-model-routing-on-resume branch August 5, 2026 23:27
elkaix added a commit that referenced this pull request Aug 6, 2026
## Related Issue

No issue — problem described below.

## Problem

Every subagent in a Dynamic Workflow ran on whatever model the calling
agent
was using. A workflow that fans 128 children out over mechanical work —
reading
files, applying a mechanical edit, running a check — paid the
orchestrator's
model for all of it, and there was no way to say "plan here, implement
there"
without editing an agent profile up front.

The provider layer already supported this: a model alias resolves to its
own
provider per agent, and `configureChild` already honoured
`profile.model` /
`profile.effort` (kept across resume by #28). The routing decision just
had no
way to reach a single run.

## What changed

`DynamicWorkflow` accepts `model` and `effort`. Both apply to every
subagent in
the call and travel on `QueuedSubagentTask` through `SubagentBatch` into
`RunSubagentOptions`, where the existing option → profile → parent
precedence
resolves them, so the choice also survives resume and retry. An alias
the
provider cannot resolve falls back to the calling agent's model instead
of
failing at generate time.

`/workflow model <alias>` stores the choice for the session; `/workflow
model`
reports it and `/workflow model off` clears it. The alias reaches the
run as an
instruction on the task prompt rather than a hard override, so the agent
can
still pick something else when the work plainly calls for it — the same
shape
as the existing Dynamic Workflow mode reminders.

    /workflow model deepseek-v4
/workflow audit every route handler under src/routes/ for missing auth
→ orchestrator stays on the session model, all 128 children run on
deepseek-v4

## Checklist

- [x] I have read the CONTRIBUTING document.
- [x] I have linked a related issue, or explained the problem above.
- [x] I have added tests that prove my feature works.
- [x] Ran `gen-changesets` skill, or this PR needs no changeset.
- [x] Ran `gen-docs` skill, or this PR needs no doc update.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Configure a model and reasoning effort for all Dynamic Workflow
subagents.
* Use `/workflow model <alias>` to view, select, or clear the session’s
subagent model.
  * Added autocomplete support for the new workflow model command.

* **Documentation**
* Updated Dynamic Workflow and slash-command documentation with model
and effort configuration details.

* **Bug Fixes**
* Ensured selected model and reasoning settings apply consistently to
spawned and resumed workflow tasks.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
elkaix added a commit that referenced this pull request Aug 7, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @pythoughts/pythinker-code@0.10.0

### Minor Changes

- [#30](#30)
[`463b176`](463b176)
- Let a Dynamic Workflow run its subagents on a different model than the
agent orchestrating them. `DynamicWorkflow` accepts `model` and `effort`
for every subagent in the call, and `/workflow model <alias>` sets that
model for the session so an expensive orchestrator can hand mechanical
work to a cheaper or faster one.

### Patch Changes

- [#28](#28)
[`cf5b6b1`](cf5b6b1)
- Keep a subagent on the model and effort its profile assigns when the
subagent is resumed or retried, instead of reverting it to the main
agent's model.

- [#31](#31)
[`e5e9de4`](e5e9de4)
- Brighten the periwinkle accent in the VS Code extension's dark theme
so inline code in chat is easier to read.

- [#31](#31)
[`e5e9de4`](e5e9de4)
- Let `/yolo` and `/auto` be used in the VS Code extension before the
first message is sent — the request now applies to the session that chat
opens next instead of failing with "Could not change the permission
mode."

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: M Elkholy <melkholy@techmatrix.com>
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