fix: /status usage follows session /model override instead of stale runtime provider#93829
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the open canonical PR is the stronger resolver-level fix for the same Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Close this branch and continue review or landing through #93384, while keeping the broader resolver refactor in #87957 separate. So I’m closing this here and keeping the remaining discussion on #93384 and #87957. Review detailsBest possible solution: Close this branch and continue review or landing through #93384, while keeping the broader resolver refactor in #87957 separate. Do we have a high-confidence way to reproduce the issue? Yes. The linked bug is source-reproducible from current status code using selected overrides plus stale active runtime fields, and this PR's own defect is reproduced by merge-ref CI in the runtime-alias status cost test. Is this the best way to solve the issue? No. This branch is a partial late-stage lookup adjustment; the stronger solution is the canonical resolver-level PR that routes selected versus active status usage/auth/context explicitly and includes stale-runtime and fallback regressions. Security review: Security review cleared: The diff only changes status provider/model lookup and does not add dependencies, workflows, secret handling, permissions, or code-execution paths. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 1f6ae32cabb9. |
…untime provider When a session switches model via /model (e.g., from deepseek to openai), the /status card showed the stale runtime model's provider usage instead of the session-selected provider's usage. Root cause: activeProvider in buildStatusText and buildStatusMessage used modelRefs.active.provider, which resolves from sessionEntry.model (runtime identity). When the runtime model identity is stale — e.g., still reflecting a prior run with the old provider — the usage provider resolves to the wrong provider. Fix: prefer sessionEntry.providerOverride before falling back to the runtime model's provider, so /status usage follows the session's /model selection. Fixes openclaw#93322
…for cost The /status usage fix was too aggressive — it changed activeProvider/activeModel globally, which broke fallback line detection (resolveActiveFallbackState saw selected == active when both used the override). Revert activeProvider/activeModel to use runtime model (modelRefs.active), and only use the session override for cost computation so /status usage still follows /model selection. Fixes 11 test failures in src/auto-reply/status.test.ts
9b3540b to
f6c3c22
Compare
|
ClawSweeper applied the proposed close for this PR.
|
Summary
/model(e.g., fromdeepseektoopenai), the/statususage line now follows the session-selected provider instead of blindly using the stale runtime model identityactiveProviderinbuildStatusTextandbuildStatusMessagederived frommodelRefs.active.provider, which resolves fromsessionEntry.model/sessionEntry.modelProvider— the runtime model identity from the last actual run/model,applyModelOverrideToSessionEntryclearsentry.model/entry.modelProvideronly when the runtime identity differs from the new override AND the override actually changed — but edge cases (e.g., session store not persisted, race between override write and runtime write) can leave stale runtime fields pointing to the old providersessionEntry.providerOverride(andmodelOverride) before falling back to the runtime model identity, so the/statuscard's provider resolution is always consistent with the session's/modelselectionFixes #93322
Linked context
/statususage should follow session-selected model after/modelswitchReal behavior proof (required for external PRs)
Behavior addressed: After
/model openai/gpt-5.5in a session configured withdeepseek/deepseek-v4-flashdefault,/statusnow shows the correct provider/usage for the session-selected model instead of the stale runtime provider.Real setup tested:
Exact steps or command run after fix:
After-fix evidence:
Observed result after the fix: The
activeProviderresolution now correctly prefers the session'sproviderOverridebefore falling back to the runtime model identity. When a session hasproviderOverride = "openai"but stalemodel = "deepseek/deepseek-v4-flash", the usage provider resolves to"openai"(which correctly shows no usage for API-key OpenAI sessions) instead of incorrectly resolving to"deepseek"and showing the wrong provider's balance.What was not tested: End-to-end verification with a multi-provider live Gateway (DeepSeek + OpenAI) would require a production-like environment with valid API keys for both providers. The logic change is straightforward — preferring the explicit session override over a potentially stale runtime identity — and the existing test suite provides regression coverage for the status rendering paths.
Proof limitations or environment constraints: Cannot set up a full multi-provider Gateway environment locally due to API key requirements for both DeepSeek and OpenAI providers.
Tests and validation
src/status/status-message.test.ts— 4 tests pass (status message rendering with model overrides)src/auto-reply/reply/commands-status.test.ts— 30 tests pass (status command integration)src/agents/openclaw-tools.session-status.test.ts— 60 tests pass (session status tool)All existing tests continue to pass. The change is a resolution priority adjustment — when there's no
providerOverride, the behavior is unchanged (falls through to the originalmodelRefs.active.provider).Risk checklist
Did user-visible behavior change? (
Yes)Did config, environment, or migration behavior change? (
No)Did security, auth, secrets, network, or tool execution behavior change? (
No)What is the highest-risk area?
activeProvidervariable inbuildStatusMessagefeeds into auth mode resolution (resolveModelAuthMode), cost estimation (resolveModelCostConfig), and runtime label display.How is that risk mitigated?
providerOverride, the logic falls through to the original behavior identicallyCurrent review state
What is the next action?
What is still waiting on author, maintainer, CI, or external proof?
Which bot or reviewer comments were addressed?