fix(agent-session): refresh this.model from store override in getContextUsage + branch summary (#92415 gaps #2 + #3)#95353
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 20, 2026, 11:18 AM ET / 15:18 UTC. Summary PR surface: Source +67, Tests +337, Other +278. Total +682 across 6 files. Reproducibility: yes. source-level. Current main persists providerOverride/modelOverride in the session store while getContextUsage and branch-summary code read the in-memory AgentSession model snapshot. Review metrics: 1 noteworthy metric.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Repair this branch or the canonical fix so AgentSession reads the canonical sessions.json selection through the real session-construction boundary, with direct getContextUsage and branch-summary coverage plus real model-switch proof. Do we have a high-confidence way to reproduce the issue? Yes, source-level. Current main persists providerOverride/modelOverride in the session store while getContextUsage and branch-summary code read the in-memory AgentSession model snapshot. Is this the best way to solve the issue? No. The helper is a plausible shape, but this PR leaves the real session construction paths without the canonical store path and proves the behavior only by mutating private fields in tests. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c5623e72f3d9. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +67, Tests +337, Other +278. Total +682 across 6 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
What Problem This Solves
Issue #92415 reports that
AgentSession.this.modelis a stale snapshot after/modelswitches. There are 8 call sites that readthis.model.{contextWindow,reasoning,thinkingLevelMap,provider}and produce wrong behavior between the/modelcommand and the next AgentSession restart.PR #93056 (open) covers
prompt()— but two gaps remain:getContextUsage()is called by TUI/status, status panels, and command status tools BETWEEN turns (after/model, before the nextprompt()). It reads stalethis.model.contextWindow.summarizeAndContinue's default branch-summarizer block callsgetRequiredRequestAuth(model)usingthis.modelat line 2934. Branch summary is an independent abortable async task; if/modelruns while summary is in flight, the summary uses the stale model.This PR closes both gaps with a single helper
syncModelFromStoreEntry()that intentionally complements #93056 (no name conflict, no behavior overlap — same helper signature).Changes
src/agents/sessions/agent-session.ts— new privatesyncModelFromStoreEntry()with 6 guards (storePath present, entry exists, override present, current matches, target in registry, auth configured). Call sites atgetContextUsage()entry (gap Login fails with 'WebSocket Error (socket hang up)' ECONNRESET #2) and at the default-summarizer block insidesummarizeAndContinue(gap WA business, groups & office hours #3).src/agents/sessions/sdk.ts— plumb new optionalstorePath+sessionKeythroughCreateAgentSessionOptions.src/agents/sessions/agent-session-services.ts— same pass-through onCreateAgentSessionFromServicesOptionsfor the services path.src/agents/sessions/agent-session.test.ts(new, 332 lines) — 8 unit tests covering both call sites and all 6 guards.scripts/repro/issue-92415-stale-model-context-usage.mts(new) — gap Login fails with 'WebSocket Error (socket hang up)' ECONNRESET #2 live proof.scripts/repro/issue-92415-stale-model-branch-summary.mts(new) — gap WA business, groups & office hours #3 live proof.Behavior rationale
The helper reads the JSON session store path (passed via
storePath), looks up the entry bysessionKey, and ifproviderOverride/modelOverrideare set to a model the registry knows with auth, swapsthis.model. The 6 guards ensure the helper is a no-op when no override is pending, when the entry is missing, when the target is unknown, or when no auth is configured — mirroringsetModel()'s safety. It does not callappendModelChangeorsetDefaultModelProvider(those side effects are owned bysetModel()for explicit user switches).Evidence
Live proof — gap #2 (
getContextUsage)Live proof — gap #3 (default-summarizer sync)
Unit + regression test results (run on current commit head
911fede3ab)node scripts/run-vitest.mjs src/agents/sessions/agent-session.test.ts→ 8 passednode scripts/run-vitest.mjs src/agents/sessions/sdk.test.ts→ 19 passed (no regression)node scripts/run-vitest.mjs src/agents/sessions/session-manager.test.ts→ 45 passed (no regression)node scripts/run-vitest.mjs src/agents/agent-command.live-model-switch.test.ts→ 65 passed (no regression)node scripts/run-tsgo.mjs→ exit 0pnpm build→ successWhat was not tested
prompt()entry-point sync (covered by fix(agents): sync stale this.model snapshot after /model switch #93056).storePath/sessionKeythrough the embedded runner — the runner creates a freshAgentSessionper run withparams.modelalready derived from the session entry atAttempt.ts, so the helper's call sites in this PR are only relevant for long-lived sessions created viacreateAgentSession/createAgentSessionFromServices.Risk
Low. The helper is a no-op when no override is in the store entry, when the registry lacks the target, or when no auth is configured. Existing callers in
getContextUsage()andsummarizeAndContinuesee the samethis.modelthey did before unless an override is pending.AI-assisted disclosure
This PR was prepared with AI assistance. Real behavior proof above was run on the current commit head (
911fede3ab) by hand against the local checkout, on top of the rebased upstreamopenclaw/main(947c21ee5a).🤖 Generated with Claude Code