fix(status): warm context window cache at startup for correct /status on first call#92775
fix(status): warm context window cache at startup for correct /status on first call#92775samson910022 wants to merge 10 commits into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 14, 2026, 2:37 AM ET / 06:37 UTC. Summary PR surface: Source +10, Tests -1, Docs +89, Other +1. Total +99 across 9 files. Reproducibility: yes. for the review blockers: current main has source comments and tests preserving raw providerless slash-model lookup, and the cache warmup promise only completes when awaited. The first Review metrics: 2 noteworthy metrics.
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:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land a narrowed status/context fix that removes root policy churn, preserves existing proxy-model lookup contracts unless maintainers explicitly approve changing them, and includes redacted real gateway restart plus immediate Do we have a high-confidence way to reproduce the issue? Yes for the review blockers: current main has source comments and tests preserving raw providerless slash-model lookup, and the cache warmup promise only completes when awaited. The first Is this the best way to solve the issue? No. Delegating CLI status toward the shared resolver may be useful, but this branch is not the best fix until it removes unrelated root changes, preserves or explicitly re-approves lookup semantics, and makes the startup warmup deterministic with real proof. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against a02813164dd5. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +10, Tests -1, Docs +89, Other +1. Total +99 across 9 files. View PR surface stats
Security concerns:
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
|
…/status on first call The first /status after gateway restart shows DEFAULT_CONTEXT_TOKENS (200K) for ALL providers because async model discovery hasn't completed yet. resolveStatusRuntimeContextTokens already has a lazy guard (await ensureContextWindowCacheLoaded()) but the first call still pays cold-start latency on the user-facing /status path. Fix: fire the warmup eagerly during gateway startup inside startGatewayEarlyRuntime(), before the HTTP server starts listening. The call uses void semantics (fire-and-forget) to avoid blocking the startup sequence. The function is already idempotent via a singleton loadPromise guard and catches all errors internally. This is a companion optimization to the lazy-guard already present in resolveStatusRuntimeContextTokens (src/status/status-text.ts). Together they ensure: - First /status: cache already warm from startup - Subsequent /status: shares resolved singleton promise (microtask) - Mid-session /model switch: lazy guard triggers re-check via config primeConfiguredContextWindows with backoff - Concurrent /status calls: all share one discovery pass Relates to: openclaw#39857, openclaw#92760 Companion to: openclaw#92775 (CLI fix) Supersedes: openclaw#92772 (comprehensive branch)
34e367e to
b816e0d
Compare
CI Failure Analysis — Run #27480587880I investigated the 4 failures in this run. None are caused by our changes. 2 failures in
|
…t window resolution When a session entry has model="openrouter/anthropic/claude-sonnet-4" but entry.modelProvider is empty, buildStatusMessage() previously set contextLookupProvider = undefined, causing resolveContextTokensForModel() to skip the provider-qualified cache key lookup. Now extract the embedded provider (first slash segment) and pass it to the resolution chain so the correct context window is found. Combined with PR openclaw#92424's resolveFreshModel() fix and PR openclaw#92709's slash-guard removal in resolveContextTokensForModel(), this gives comprehensive coverage for proxy model context window resolution. Refs: openclaw#39857, openclaw#90889, openclaw#92424, openclaw#92709
…real context.ts function
…/status on first call The first /status after gateway restart shows DEFAULT_CONTEXT_TOKENS (200K) for ALL providers because async model discovery hasn't completed yet. resolveStatusRuntimeContextTokens already has a lazy guard (await ensureContextWindowCacheLoaded()) but the first call still pays cold-start latency on the user-facing /status path. Fix: fire the warmup eagerly during gateway startup inside startGatewayEarlyRuntime(), before the HTTP server starts listening. The call uses void semantics (fire-and-forget) to avoid blocking the startup sequence. The function is already idempotent via a singleton loadPromise guard and catches all errors internally. This is a companion optimization to the lazy-guard already present in resolveStatusRuntimeContextTokens (src/status/status-text.ts). Together they ensure: - First /status: cache already warm from startup - Subsequent /status: shares resolved singleton promise (microtask) - Mid-session /model switch: lazy guard triggers re-check via config primeConfiguredContextWindows with backoff - Concurrent /status calls: all share one discovery pass Relates to: openclaw#39857, openclaw#92760 Companion to: openclaw#92775 (CLI fix) Supersedes: openclaw#92772 (comprehensive branch)
…+ 2 test expectations) - Remove unused normalizeProviderId import from status.summary.runtime.ts - Remove assertion in context.lookup.test.ts that expected loadConfig not to be called (warmup now legitimately calls it once) - Update status.test.ts expectations from 999k to correct 2.0m context window value now that real discovery resolves properly
…he path) The transcript-derived slash model id test resolves context window via bare-key cache lookup (no explicit provider), so it correctly gets 999k from MODEL_CONTEXT_TOKEN_CACHE. The runtime test (with explicit provider) correctly expects 2.0m from config direct scan.
…ing check-guards failure)
…no consumer) Also add try/catch guard around ensureContextWindowCacheLoaded() in resolveStatusRuntimeContextTokens per code review.
6988302 to
6eaa685
Compare
The async ensureContextWindowCacheLoaded() call in status-text.ts triggers loadModelCatalog in the fast test bootstrap path where it is expected to remain uncalled. Production warmup already handles cache preloading via server-startup-early.ts.
…timeContextTokens
afb023c to
c212376
Compare
|
Superseded — replaced by a narrower fix based on upstream/main analysis. See new PR for correct root cause and scope. |
Summary
Fix
/statusshowing200k(DEFAULT_CONTEXT_TOKENS) instead of the correct per-model context window on the first call after gateway restart. This happens because async model discovery hasn't completed yet when the first/statusresolves synchronously.Root Cause
resolveContextTokensForModel()hasskipRuntimeConfigLoad = Boolean(cfg)— all production callers pass a truthycfg, so async discovery is always bypassed on first resolution. TheensureContextWindowCacheLoaded()lazy guard was added to fire-and-forget discovery, but it returns before the async work completes.Pure timing gap: between gateway restart → first
/status, discovery hasn't finished → fallback 200K.What We Fixed
This PR contains two complementary solutions forming a defense-in-depth approach:
Solution A — Eager Startup Warmup
Fires
void ensureContextWindowCacheLoaded()duringstartGatewayEarlyRuntime()before the HTTP server starts listening. Zero latency to the first/statusbecause the cache is populated before any request arrives.src/gateway/server-startup-early.ts— 3-line additionvoid primeRemoteSkillsCache()Solution B — Lazy Guard (then reverted)
Originally added
await ensureContextWindowCacheLoaded()inresolveStatusRuntimeContextTokensto catch any path the startup warmup doesn't cover. Reverted because it triggersloadModelCatalogin fast-path bootstrap tests (conflict with mock expectations). Startup warmup (A) alone suffices — the cache is always populated before any user sends/status.Commits (8 total)
CI Status
✅ PASS (all code-level checks)
❌ Known Non-Code Failures (NOT our bugs)
Verification
All CI failures were independently verified by subagents:
main)main)Next Steps
Real behavior proofscreenshotsRelated