Skip to content

fix(cli): display correct model for sub-agents in sessions list#18660

Merged
gumadeiras merged 9 commits intoopenclaw:mainfrom
robbyczgw-cla:fix/sessions-list-subagent-model-display
Feb 18, 2026
Merged

fix(cli): display correct model for sub-agents in sessions list#18660
gumadeiras merged 9 commits intoopenclaw:mainfrom
robbyczgw-cla:fix/sessions-list-subagent-model-display

Conversation

@robbyczgw-cla
Copy link
Copy Markdown
Contributor

@robbyczgw-cla robbyczgw-cla commented Feb 16, 2026

Fixes #18451

Problem

openclaw status and sessions list displayed the primary/default model (e.g. claude-sonnet-4-6) for sub-agent sessions, even when those sub-agents were actually running on a different model (e.g. synthetic/hf:moonshotai/Kimi-K2.5).

This made debugging and monitoring confusing — the displayed model did not match what was actually being used.

Root Cause

Two related issues:

  1. Display side (session-utils.ts): resolveSessionModelRef() fell back to the default primary model too early, ignoring entry.model (the runtime model recorded after the run).

  2. Patch validator side (sessions-patch.ts): When spawning a sub-agent, sessions.patch is called with the target agent's model. The patch validator builds its allowlist from agents.defaults.models. If the sub-agent's model is not in that global allowlist, the patch is rejected with "model not allowed" — silently treated as recoverable — and entry.model is never set. The session then falls back to the default in the display.

The root cause of the silent failure: a target agent's own configured model should always be permitted in its own session patch, regardless of the global allowlist.

Solution

Fix 1 — Display (session-utils.ts):
Prioritize entry.model (runtime model) over modelOverride and default fallback in resolveSessionModelRef.

Fix 2 — Patch validator (sessions-patch.ts):
When patching a sub-agent session, resolve the target agent's own configured model (agents.list[id].model.primary) and pass it as a hint to resolveAllowedModelRef — so it is always accepted even if absent from agents.defaults.models.

Fix 3 — Allowlist parsing (model-selection.ts):
buildAllowedModelSet now parses defaultModel via parseModelRef() instead of treating it as a plain model id string, correctly handling full refs like synthetic/hf:moonshotai/Kimi-K2.5.

Note: There is also a config-side workaround — adding the sub-agent's model to agents.defaults.models makes the patch validator accept it. However, a user who correctly configures agents.list[].model.primary should not need to duplicate that entry elsewhere. The silent failure (no warning when patch is rejected) is the core problem.

Changes

  • src/gateway/session-utils.ts: Prioritize runtime model in resolveSessionModelRef()
  • src/commands/status.summary.ts: Use corrected model resolution
  • src/commands/sessions.ts: Use corrected model resolution in sessions list
  • src/gateway/sessions-patch.ts: Pass target agent model as allowlist hint
  • src/agents/model-selection.ts: Parse defaultModel via parseModelRef()
  • src/gateway/session-utils.test.ts: Tests for runtime model priority
  • src/gateway/sessions-patch.test.ts: Regression test for allowlist fix (agent kimi with synthetic/hf:moonshotai/Kimi-K2.5, global allowlist only contains anthropic/claude-sonnet-4-6)

Testing

  • pnpm test -- src/gateway/sessions-patch.test.ts
  • pnpm test -- src/gateway/session-utils.test.ts
  • pnpm check (format + lint + typecheck) ✅

🤖 AI-assisted: Code changes by gpt-5.3-codex, PR description and verification by claude-sonnet-4-6

@openclaw-barnacle openclaw-barnacle bot added gateway Gateway runtime commands Command implementations size: S experienced-contributor labels Feb 16, 2026
@robbyczgw-cla robbyczgw-cla force-pushed the fix/sessions-list-subagent-model-display branch 3 times, most recently from ed974fb to 98f4cad Compare February 17, 2026 13:23
@gumadeiras
Copy link
Copy Markdown
Member

can you provide screenshots and steps to reproduce?

works fine here

image image

@robbyczgw-cla
Copy link
Copy Markdown
Contributor Author

Thanks for checking! After deeper investigation, I can confirm the bug is reproducible — but only under specific conditions.

Root cause (confirmed in subagent-spawn.ts lines 220–230):

When sessions.patch is called with the resolved model and the patch validator rejects it with "invalid model" or "model not allowed", the error is treated as recoverable — spawn continues, but modelApplied stays false. The session then falls back to the default primary model in the display.

Why the patch validator rejects the model:

resolveAllowedModelRef builds its allowlist from agents.defaults.models (line 313 in model-selection.ts). If allowAny = false (i.e. you have any entries in agents.defaults.models) and the sub-agent's model ref isn't in that allowlist, it returns "model not allowed".

Reproduction:

  1. Have entries in agents.defaults.models (any aliases/models configured)
  2. Configure a sub-agent whose model is not in that list
  3. Spawn it → sessions list shows default primary instead of the actual model

Why it works for you: Your test sub-agent's model (MiniMax-M2.5) is in your allowlist. If you spawn a sub-agent whose model isn't listed in agents.defaults.models, you should see the bug.

Our PR fixes the display side by prioritizing entry.model (runtime) over the default. The deeper fix would be in subagent-spawn.ts — not treating the model patch rejection as recoverable, or fixing the allowlist check to always permit the target agent's own configured model.

@robbyczgw-cla
Copy link
Copy Markdown
Contributor Author

robbyczgw-cla commented Feb 17, 2026

Addendum: To be fully transparent — there is also a config-side workaround: adding the sub-agent's model to agents.defaults.models will make the patch validator accept it and the bug disappears. So in that sense, it could be considered a config issue too.

However, I still think it's a bug because:

  1. The target agent already has its model correctly configured under agents.list[].model.primary — that should be sufficient
  2. The error is silently swallowed — spawn succeeds with no warning, no indication that the model patch failed. The user has no way to know something went wrong
  3. A target agent's own configured model should always be permitted in its own session patch

The config workaround exists, but the silent failure is the real problem.

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: M and removed size: S labels Feb 17, 2026
@robbyczgw-cla robbyczgw-cla force-pushed the fix/sessions-list-subagent-model-display branch from 86c3911 to 0fbebe0 Compare February 17, 2026 21:22
@robbyczgw-cla
Copy link
Copy Markdown
Contributor Author

Thanks for asking us to reproduce — it led us to find and fix a deeper root cause we would have missed otherwise. Really appreciate the thorough review 🙏

@robbyczgw-cla robbyczgw-cla force-pushed the fix/sessions-list-subagent-model-display branch from cc99eff to 6913320 Compare February 17, 2026 22:17
@gumadeiras gumadeiras force-pushed the fix/sessions-list-subagent-model-display branch 2 times, most recently from 3e66511 to d3870f7 Compare February 18, 2026 01:48
@gumadeiras gumadeiras force-pushed the fix/sessions-list-subagent-model-display branch from 53d61e5 to 8ec1150 Compare February 18, 2026 03:56
robbyczgw-cla and others added 5 commits February 17, 2026 23:57
- Prioritize runtime session model (entry.model) over default fallback
  in resolveSessionModelRef so sessions list shows the actual model used
- Fix patch validator to always permit the target agent's own configured
  model, even when absent from agents.defaults.models allowlist
- Add regression tests for both fixes

Fixes openclaw#18451
@gumadeiras gumadeiras force-pushed the fix/sessions-list-subagent-model-display branch from ce881ec to ba54c5a Compare February 18, 2026 04:58
@gumadeiras gumadeiras merged commit 5c69e62 into openclaw:main Feb 18, 2026
12 checks passed
@gumadeiras
Copy link
Copy Markdown
Member

Merged via squash.

Thanks @robbyczgw-cla!

rodrigogs pushed a commit to rodrigogs/openclaw that referenced this pull request Feb 18, 2026
…claw#18660)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: ba54c5a
Co-authored-by: robbyczgw-cla <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras
hongw pushed a commit to hongw/openclaw that referenced this pull request Feb 19, 2026
When user changes model via /model command, it sets modelOverride and
providerOverride fields. sessions.list was returning the original
model/modelProvider fields instead.

This is a minimal fix. Upstream fixed this properly in openclaw#18660 using
resolveSessionModelRef() which handles more edge cases.
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…claw#18660)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: ba54c5a
Co-authored-by: robbyczgw-cla <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations gateway Gateway runtime size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sessions list shows wrong model for sub-agents using non-default provider

2 participants