Skip to content

Fix subagent default model precedence#81783

Merged
joshavant merged 2 commits into
mainfrom
fix/subagent-default-model-precedence
May 14, 2026
Merged

Fix subagent default model precedence#81783
joshavant merged 2 commits into
mainfrom
fix/subagent-default-model-precedence

Conversation

@joshavant

@joshavant joshavant commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #81395.

agents.defaults.subagents.model now wins over a target agent's regular primary model when planning sessions_spawn, so documented subagent defaults are applied before runtime selection. This keeps model-scoped runtime policy, including agentRuntime: { id: "claude-cli" }, attached to the model selected for the child run instead of silently falling back to the target agent's primary model.

Real behavior proof

Behavior addressed: subagent model-default precedence and the runtime-policy bypass from #81395.
Real environment tested: Blacksmith Testbox via Crabbox on Linux, using the patched branch checkout.
Exact steps or command run after this patch: node --import tsx -e 'import { resolveSubagentModelAndThinkingPlan } from "./src/agents/subagent-spawn-plan.ts"; import { resolveAgentHarnessPolicy } from "./src/agents/harness/policy.ts"; /* resolve a config with agents.defaults.subagents.model, model-scoped claude-cli runtime, and a conflicting target agent primary model */'
Evidence after fix: Terminal output from Crabbox lease tbx_01krjzk0205rnj59p7th1qfpp5, GitHub Actions run https://github.com/openclaw/openclaw/actions/runs/25854477958:

{
  "selectedSubagentModel": "anthropic/claude-sonnet-4-6",
  "childInitialSessionModel": "anthropic/claude-sonnet-4-6",
  "modelOverrideSource": "auto",
  "targetAgentPrimaryModel": "anthropic/claude-opus-4-7",
  "runtime": {
    "runtime": "claude-cli",
    "runtimeSource": "model"
  }
}

Observed result after fix: the default subagent model was selected despite the target agent primary model, and the selected model's claude-cli runtime policy was preserved.
What was not tested: live Claude CLI OAuth billing behavior; no provider credentials were needed for this deterministic config/routing fix.

Verification

Behavior addressed: subagent model-default precedence and the runtime-policy bypass from #81395.
Real environment tested: Blacksmith Testbox via Crabbox on Linux.
Exact steps or command run after this patch: env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 node scripts/run-vitest.mjs src/agents/model-selection.test.ts src/agents/openclaw-tools.subagents.sessions-spawn.model.test.ts src/agents/harness/selection.test.ts src/agents/tools/agents-list-tool.test.ts
Evidence after fix: Crabbox lease tbx_01krjxvxwmtycxvs3djsnfnk77, GitHub Actions run https://github.com/openclaw/openclaw/actions/runs/25853218918.
Observed result after fix: 7 test files passed, 254 tests passed.
What was not tested: live Claude CLI OAuth billing behavior; the fix is deterministic config/routing precedence and was validated without provider credentials.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S maintainer Maintainer-authored PR labels May 14, 2026
@clawsweeper

clawsweeper Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The PR reorders subagent model selection so agents.defaults.subagents.model wins before a target agent primary model, adds regression coverage, and adds a changelog entry.

Reproducibility: yes. from source inspection: current main resolves a target agent primary model before agents.defaults.subagents.model, while the docs say the default subagent model should override inherited behavior. I did not run tests because this was a read-only review.

Real behavior proof
Needs real behavior proof before merge: The PR provides targeted tests/CI only; the contributor should add redacted terminal logs, live output, or a recording showing a real sessions_spawn child using the configured default model/runtime, then update the PR body for re-review or ask a maintainer for @clawsweeper re-review.

Next step before merge
The protected maintainer label and external real-behavior-proof gap make this a maintainer review/proof item, not a ClawSweeper repair job.

Security
Cleared: The diff only changes TypeScript resolver logic, focused tests, and the changelog; I found no concrete security or supply-chain concern.

Review details

Best possible solution:

Land this resolver and test change after maintainer review and acceptable real behavior proof, while keeping legacy whole-agent runtime inheritance out of scope unless maintainers explicitly change the runtime contract.

Do we have a high-confidence way to reproduce the issue?

Yes, from source inspection: current main resolves a target agent primary model before agents.defaults.subagents.model, while the docs say the default subagent model should override inherited behavior. I did not run tests because this was a read-only review.

Is this the best way to solve the issue?

Yes for the supported model-scoped runtime path: reordering the existing resolver is the narrowest fix and the added tests cover the precedence and runtime-policy attachment. It does not implement legacy agents.defaults.agentRuntime inheritance, which current docs say is ignored.

What I checked:

  • Current main resolver order: Current main still resolves per-agent subagents.model, then the target agent primary model, then agents.defaults.subagents.model, which is the precedence this PR changes. (src/agents/model-selection.ts:324, c8228245039b)
  • Documented behavior: The subagents docs say the child model inherits the caller unless agents.defaults.subagents.model or per-agent subagents.model is set; explicit sessions_spawn.model still wins. Public docs: docs/tools/subagents.md. (docs/tools/subagents.md:144, c8228245039b)
  • PR diff matches the narrow source fix: The PR moves agents.defaults.subagents.model ahead of agentConfig.model in resolveSubagentConfiguredModelSelection. (src/agents/model-selection.ts:325, dc4f36932bb2)
  • Regression coverage added: The PR flips the existing resolver expectation and adds coverage that model-scoped agentRuntime: { id: "claude-cli" } remains attached to the configured default subagent model. (src/agents/model-selection.test.ts:2189, dc4f36932bb2)
  • Related issue context: A related issue comment reports that agents.defaults.subagents.model is ignored on 2026.5.7 while per-agent subagents.model works, matching the resolver precedence bug fixed by this PR.
  • Runtime policy contract: Current docs say runtime policy belongs on providers or models, and whole-agent runtime keys such as agents.defaults.agentRuntime are legacy and ignored by runtime selection. Public docs: docs/gateway/config-agents.md. (docs/gateway/config-agents.md:401, c8228245039b)

Likely related people:

  • Vincent Koc: Local blame attributes the current subagent model resolver, spawn-plan helper, adjacent tests, and subagents docs to commit fe25ed2. (role: recent area contributor; confidence: medium; commits: fe25ed214ef5; files: src/agents/model-selection.ts, src/agents/subagent-spawn-plan.ts, src/agents/model-selection.test.ts)
  • Peter Steinberger: Recent runtime-policy migration work touched the agent runtime contract and docs that define model/provider-scoped agentRuntime behavior relevant to this PR's scope. (role: adjacent runtime-policy contributor; confidence: low; commits: a0f35574d047; files: docs/gateway/config-agents.md, docs/concepts/agent-runtimes.md, src/agents/model-runtime-aliases.ts)

Remaining risk / open question:

  • No real child-session proof shows sessions_spawn selecting agents.defaults.subagents.model and the associated model-scoped runtime outside targeted tests/CI.
  • The linked issue also discusses legacy agents.defaults.agentRuntime inheritance and a startup warning; current docs intentionally reject whole-agent runtime policy, so maintainers should confirm the issue-closing scope.

Codex review notes: model gpt-5.5, reasoning high; reviewed against c8228245039b.

@joshavant joshavant merged commit 2b04ced into main May 14, 2026
117 of 118 checks passed
@joshavant joshavant deleted the fix/subagent-default-model-precedence branch May 14, 2026 10:19
joshavant added a commit that referenced this pull request May 14, 2026
* fix subagent default model precedence

* docs changelog for subagent default fix
nighting0615 pushed a commit to nighting0615/openclaw that referenced this pull request May 19, 2026
* fix subagent default model precedence

* docs changelog for subagent default fix
martingarramon added a commit to martingarramon/openclaw that referenced this pull request May 20, 2026
…gentModelConfigSelectionResult

PR openclaw#58003 (e394262) introduced a regression in agent-scope.ts: agentConfig.model
(the agent's own model) was placed before cfg.agents.defaults.subagents.model (the
global subagent default) in the candidates array. This shadowed the global default
for any agent that has its own model configured — the common case.

openclaw#81783 fixed the same regression in model-selection.ts but the agent-scope.ts path
was missed. This path is used by the cron isolation runner and resolveSubagentModel-
FallbacksOverride.

Correct precedence:
  1. agentConfig.subagents.model (per-agent subagent config)
  2. cfg.agents.defaults.subagents.model (global subagent default)
  3. agentConfig.model (agent's own model — last resort only)

Closes openclaw#58822.
martingarramon added a commit to martingarramon/openclaw that referenced this pull request May 23, 2026
…gentModelConfigSelectionResult

PR openclaw#58003 (e394262) introduced a regression in agent-scope.ts: agentConfig.model
(the agent's own model) was placed before cfg.agents.defaults.subagents.model (the
global subagent default) in the candidates array. This shadowed the global default
for any agent that has its own model configured — the common case.

openclaw#81783 fixed the same regression in model-selection.ts but the agent-scope.ts path
was missed. This path is used by the cron isolation runner and resolveSubagentModel-
FallbacksOverride.

Correct precedence:
  1. agentConfig.subagents.model (per-agent subagent config)
  2. cfg.agents.defaults.subagents.model (global subagent default)
  3. agentConfig.model (agent's own model — last resort only)

Closes openclaw#58822.
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* fix subagent default model precedence

* docs changelog for subagent default fix
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
* fix subagent default model precedence

* docs changelog for subagent default fix
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
* fix subagent default model precedence

* docs changelog for subagent default fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling maintainer Maintainer-authored PR size: S

Projects

None yet

1 participant