Skip to content

fix: preserve agent model fallbacks when switching models#1160

Merged
hazeone merged 1 commit into
ValueCell-ai:mainfrom
Grynder02:fix/preserve-agent-model-fallbacks
Jul 15, 2026
Merged

fix: preserve agent model fallbacks when switching models#1160
hazeone merged 1 commit into
ValueCell-ai:mainfrom
Grynder02:fix/preserve-agent-model-fallbacks

Conversation

@Grynder02

Copy link
Copy Markdown
Contributor

Fixes #1159.

Problem

updateAgentModel() in electron/utils/agent-config.ts replaced the agent's model block wholesale with { primary: modelRef } on every model switch (in-chat picker or Agents dialog). This has two destructive effects:

  1. Any hand-configured fallbacks array in that block is silently discarded.
  2. The resulting { primary }-only block disables the agent's entire fallback chain: the OpenClaw runtime's resolveSelectedModelFallbacksOverride() treats a per-agent model block that has primary but no fallbacks key as an explicit empty fallback override, which suppresses agents.defaults.model.fallbacks too. The gateway then reports fallbackConfigured: false, and a 429/rate-limit on the primary fails the turn with no fallback attempted.

Nothing in the UI indicates failover was turned off. Full analysis, logs, and reproduction in #1159.

Fix

  • Merge instead of replace: spread the existing model block and update primary, preserving fallbacks (and any other fields).
  • Inherit defaults into bare blocks: when the resulting block would still lack a fallbacks key (fresh block, or a pre-existing bare-primary block), copy agents.defaults.model.fallbacks into it, so a per-agent primary never silently disables failover.

The modelRef: null path (reset to default) is unchanged — deleting the block correctly falls back to the defaults chain.

Testing

  • tsc --noEmit -p tsconfig.node.json clean for this file (one pre-existing unrelated error about the generated _ext-bridge.generated module in a fresh checkout).
  • Direct invocation of updateAgentModel() against a real config, all three paths:
    • fresh block → { primary, fallbacks: [defaults chain] } inherited;
    • subsequent switch → primary updated, fallbacks preserved;
    • null → block deleted (unchanged behavior).
  • Verified from a real GUI click in a dev build: the in-chat picker switch wrote { "primary": "openrouter/qwen/qwen3.6-flash", "fallbacks": [ ...full defaults chain... ] } and gateway failover kept working.

An alternative design would be to keep per-agent blocks primary-only and change the empty-override semantics in the openclaw runtime instead — happy to rework if maintainers prefer that direction.

🤖 Generated with Claude Code

updateAgentModel() replaced the agent's model block wholesale with
{ primary }, silently discarding any configured fallbacks array. The
resulting block also suppressed agents.defaults.model.fallbacks, because
the OpenClaw runtime treats a per-agent model block without a fallbacks
key as an explicit empty fallback override. Net effect: any in-chat
model switch silently disabled all model failover for that agent.

Merge the new primary into the existing block instead, and inherit the
defaults fallback chain whenever the resulting block would lack one, so
switching models never turns off failover.

Fixes ValueCell-ai#1159

Co-Authored-By: Claude Fable 5 <[email protected]>
@hazeone

hazeone commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

LGTM

@hazeone
hazeone merged commit a9d9376 into ValueCell-ai:main Jul 15, 2026
5 checks passed
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.

[Bug]: In-chat model switch silently deletes per-agent fallbacks and disables all model failover

2 participants