Skip to content

fix: avoid stale dashboard child context budgets#97332

Merged
galiniliev merged 2 commits into
openclaw:mainfrom
galiniliev:bug-050-dashboard-contexttokens
Jun 28, 2026
Merged

fix: avoid stale dashboard child context budgets#97332
galiniliev merged 2 commits into
openclaw:mainfrom
galiniliev:bug-050-dashboard-contexttokens

Conversation

@galiniliev

@galiniliev galiniliev commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Closes #97331

What Problem This Solves

Fixes an issue where users opening a new Control UI dashboard chat could see and use a stale inherited context budget when the parent dashboard session had cached context metadata from an older model/config state.

Why This Change Was Made

Dashboard child sessions still inherit the parent runtime selection that represents user intent, including provider/model/auth profile and run settings. They no longer inherit cached context or usage metadata, so the new session can derive the current budget from the active model/config/catalog.

User Impact

New Control UI dashboard chats no longer get pinned to a stale smaller context window from their parent session. For the observed github-copilot/claude-opus-4.8 case, a child session can derive the current 1M budget instead of carrying forward the parent's cached 128k budget.

Evidence

Before evidence:

Sanitized BUG-folder log excerpt:

# Active config proves the expected model/context budget is 1M:
[redacted config path]:102 "primary": "github-copilot/claude-opus-4.8"
[redacted config path]:127 "contextTokens": 1000000
[redacted config path]:360 "id": "claude-opus-4.8"
[redacted config path]:367 "contextWindow": 1000000
[redacted config path]:368 "contextTokens": 1000000

# Fresh user-reported Control UI session URL, session key redacted:
[redacted local Control UI URL]?session=agent%3A[redacted-agent]%3Adashboard%3A[redacted-dashboard-session]

# Stale inherited parent chain before local cleanup:
[redacted session store backup]:10173 "agent:[redacted-agent]:dashboard:[redacted-parent-dashboard-session]": {
[redacted session store backup]:10177 "modelProvider": "github-copilot",
[redacted session store backup]:10178 "model": "claude-opus-4.8",
[redacted session store backup]:10179 "contextTokens": 128000,
[redacted session store backup]:12942 "agent:[redacted-agent]:dashboard:[redacted-child-dashboard-session]": {
[redacted session store backup]:12943 "sessionId": "[redacted session id]",
[redacted session store backup]:12946 "modelProvider": "github-copilot",
[redacted session store backup]:12947 "model": "claude-opus-4.8",
[redacted session store backup]:12948 "contextTokens": 128000,
[redacted session store backup]:12951 "parentSessionKey": "agent:[redacted-agent]:dashboard:[redacted-parent-dashboard-session]",

# Runtime transcript shows the fresh child session was already reporting the stale 128k context:
[redacted transcript path]:1 {"type":"session","version":3,"id":"[redacted session id]","timestamp":"2026-06-27T22:02:07.602Z",...}
[redacted transcript path]:2 {"type":"model_change","timestamp":"2026-06-27T22:02:42.971Z","provider":"github-copilot","modelId":"claude-opus-4.8"}
[redacted transcript path]:4 {"type":"custom","customType":"model-snapshot","data":{"timestamp":1782597763025,"provider":"github-copilot","modelApi":"anthropic-messages","modelId":"claude-opus-4.8"},...}
[redacted transcript path]:7 Context: 16k/128k (13%)
[redacted transcript path]:7 Session: agent:[redacted-agent]:dashboard:[redacted-child-dashboard-session]
[redacted transcript path]:9 "parentSessionKey":"agent:[redacted-agent]:dashboard:[redacted-parent-dashboard-session]","sessionId":"[redacted session id]","model":"claude-opus-4.8","contextTokens":128000,"status":"running"

# Post-cleanup verification from the same evidence folder proves the row can derive 1M from current config/model metadata once stale cached metadata is gone:
$ pnpm openclaw sessions list --all-agents --json
{"key":"agent:[redacted-agent]:dashboard:[redacted-child-dashboard-session]","sessionId":"[redacted session id]","modelProvider":"github-copilot","model":"claude-opus-4.8","contextTokens":1000000,"totalTokens":null}

Redaction note: exact agent names, session keys, session IDs, local state paths, and local backup filenames are redacted. Provider/model names, timestamps, field names, context values, and line numbers are retained because they are behavior-relevant.

After-fix local proof:

$ node scripts/run-vitest.mjs src/gateway/server.sessions.create.test.ts --reporter=verbose
[test] starting test/vitest/vitest.gateway.config.ts
 ✓ |gateway-server| ../../src/gateway/server.sessions.create.test.ts > sessions.create inherits parent runtime model selection without stale context metadata 34ms
 ✓ |gateway-methods| ../../src/gateway/server.sessions.create.test.ts > sessions.create inherits parent runtime model selection without stale context metadata 26ms

 Test Files  2 passed (2)
      Tests  26 passed (26)
   Duration  84.99s (transform 74.69s, setup 2.11s, import 18.97s, tests 63.20s, environment 1ms)

[test] passed 1 Vitest shard in 105.95s

$ git diff --check
# no output

$ .agents/skills/autoreview/scripts/autoreview --mode local
autoreview clean: no accepted/actionable findings reported
overall: patch is correct (0.86)

Real behavior proof

Behavior addressed: Newly created dashboard child sessions no longer inherit stale parent contextTokens, inputTokens, outputTokens, totalTokens, totalTokensFresh, or contextBudgetStatus metadata while still inheriting runtime model selection.

Real environment tested: Local source checkout worktree on upstream/main at 36722014ef, branch bug-050-dashboard-contexttokens, Node v26.3.0, pnpm 11.2.2 after corepack pnpm install.

Exact steps or command run after this patch: node scripts/run-vitest.mjs src/gateway/server.sessions.create.test.ts --reporter=verbose; git diff --check; .agents/skills/autoreview/scripts/autoreview --mode local.

Evidence after fix:

$ node scripts/run-vitest.mjs src/gateway/server.sessions.create.test.ts --reporter=verbose
[test] starting test/vitest/vitest.gateway.config.ts
 ✓ |gateway-server| ../../src/gateway/server.sessions.create.test.ts > sessions.create inherits parent runtime model selection without stale context metadata 34ms
 ✓ |gateway-methods| ../../src/gateway/server.sessions.create.test.ts > sessions.create inherits parent runtime model selection without stale context metadata 26ms

 Test Files  2 passed (2)
      Tests  26 passed (26)
   Duration  84.99s (transform 74.69s, setup 2.11s, import 18.97s, tests 63.20s, environment 1ms)

[test] passed 1 Vitest shard in 105.95s

Observed result after fix: The regression test creates a parent entry with stale context and usage metadata, then verifies the child session keeps the intended runtime provider/model/auth settings while all stale context/usage metadata fields are absent so current model metadata can be resolved normally.

What was not tested: I did not rerun a live Control UI browser session against the private affected dashboard chain after the code patch; the reproducible seam is covered at sessions.create, which is where the stale metadata was copied.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XS maintainer Maintainer-authored PR labels Jun 27, 2026
@clawsweeper

clawsweeper Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 28, 2026, 12:23 AM ET / 04:23 UTC.

Summary
The PR removes inherited contextTokens from dashboard child session creation and adds a regression test, while also carrying broad changes to chat history pagination, media handling, doctor checks, plugin catalog snapshots, docs, QA scenarios, and generated protocol/schema files.

PR surface: Source +1802, Tests +2446, Docs -78, Generated +26, Other +167. Total +4363 across 74 files.

Reproducibility: yes. at source level: current main copies parentEntry.contextTokens during sessions.create, session rows prefer the stored value, and the Control UI consumes that row budget. I did not run a live Control UI reproduction in this read-only review.

Review metrics: 3 noteworthy metrics.

  • Scope beyond stated fix: 2 stated-fix files, 72 additional files. The branch is not a narrow dashboard child-session fix, so maintainers need to review unrelated behavior and storage surfaces before merge.
  • Persistent state schema: 1 shared-state table added. A new SQLite table for hosted plugin catalog snapshots changes persisted state and upgrade review scope.
  • Protocol/tool API surface: 1 optional offset parameter added. Adding ChatHistoryParams.offset changes Gateway/agent tool API behavior outside the linked session-state bug.

Stored data model
Persistent data-model change detected: database schema: src/gateway/server.sessions.create.test.ts, database schema: src/state/openclaw-state-schema.generated.ts, database schema: src/state/openclaw-state-schema.sql, migration/backfill/repair: docs/platforms/mac/bundled-gateway.md, migration/backfill/repair: qa/scenarios/config/cli-channel-picker.yaml, migration/backfill/repair: src/flows/doctor-core-checks.runtime.test.ts, and 32 more. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #97331
Summary: This PR is the direct candidate fix for the linked stale dashboard child context-budget issue; older context display issues are adjacent, and the open model-inheritance issue overlaps only in child-session state semantics.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦪 silver shellfish
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Split or rebase the branch so the PR contains only the dashboard child-session metadata fix and focused regression test.
  • [P1] Add redacted after-fix Control UI or real gateway output showing a newly created dashboard child derives the current context budget.
  • Move the hosted catalog, schema, protocol, media, docs, and QA changes into separate PRs with their own proof and owner review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: After-fix proof is limited to Vitest, git diff --check, and autoreview output; add redacted live Control UI or real gateway output, redact private details, then update the PR body or ask a maintainer to comment @clawsweeper re-review if needed.

Mantis proof suggestion
A short real Control UI or gateway-visible proof would materially verify the user-facing context-budget behavior after child-session creation. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify a new Control UI dashboard child session derives the current context budget while preserving parent provider/model selection.

Risk before merge

  • [P1] The branch is much broader than the linked session bug: 72 additional files change protocol, media, doctor, plugin catalog, schema, docs, QA, generated Swift, and snapshots beyond the two stated session-fix files.
  • [P1] Merging changes the dashboard child-session state boundary by preserving provider/model/auth/runtime intent while dropping cached parent context-budget metadata; that is the desired fix, but it needs maintainer acceptance and real behavior proof.
  • [P1] The unrelated hosted plugin catalog fetch/cache and shared-state schema changes are plugin distribution and storage surfaces, so they need separate security, upgrade, and owner review before they ride along with this session-state fix.

Maintainer options:

  1. Narrow before merge (recommended)
    Rebase or split this branch so the PR contains only the sessions.create metadata inheritance change and regression proof, with catalog/protocol/media/docs/schema changes moved to separate reviewed PRs.
  2. Accept the broad branch intentionally
    Maintainers can choose to merge the full branch only if they explicitly review and own the unrelated plugin distribution, state schema, API, media, docs, and QA changes together.
  3. Require real dashboard or gateway proof
    Before landing the narrowed fix, require redacted after-fix Control UI or real gateway output showing a new dashboard child derives the current context budget while preserving provider/model/auth selection.

Next step before merge

  • [P1] Human maintainer review is needed because the protected maintainer label, missing real behavior proof, and broad unrelated security/storage/API surfaces make this unsafe for automated repair or cleanup close.

Security
Needs attention: Needs attention: the PR includes unrelated hosted plugin catalog network/cache and state-schema changes in a session-state bugfix branch.

Review findings

  • [P1] Split the hosted catalog surface out of this session fix — src/plugins/official-external-plugin-catalog.ts:749-765
Review details

Best possible solution:

Land a narrowed PR containing only the session inheritance fix and focused regression test, or explicitly split and approve the additional plugin/catalog/protocol/media/schema work with its own proof.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level: current main copies parentEntry.contextTokens during sessions.create, session rows prefer the stored value, and the Control UI consumes that row budget. I did not run a live Control UI reproduction in this read-only review.

Is this the best way to solve the issue?

No, not as submitted. Removing cached context-budget inheritance at the gateway session creation boundary is the right narrow fix, but bundling unrelated plugin catalog, schema, protocol, media, docs, and QA changes is not the best merge shape.

Full review comments:

  • [P1] Split the hosted catalog surface out of this session fix — src/plugins/official-external-plugin-catalog.ts:749-765
    This dashboard session bugfix branch also adds hosted official external plugin catalog fetching/caching, source profiles, and a new state table. That is a plugin distribution and supply-chain/storage surface unrelated to stale dashboard child contextTokens, so it should be removed from this PR or explicitly re-scoped with maintainer approval and separate proof before merge.
    Confidence: 0.82

Overall correctness: patch is incorrect
Overall confidence: 0.78

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 07b934901a32.

Label changes

Label changes:

  • add merge-risk: 🚨 compatibility: The branch adds protocol/tool parameters, generated Swift model fields, and a shared-state table that can affect API and upgrade behavior beyond the stated fix.
  • add merge-risk: 🚨 security-boundary: The branch also changes hosted plugin catalog fetching/caching and inbound media handling, which are supply-chain and security-boundary surfaces that green CI alone does not settle.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority dashboard/gateway session-state bugfix PR with limited blast radius, plus merge-readiness concerns, but no confirmed outage, data loss, or security exploit.
  • merge-risk: 🚨 compatibility: The branch adds protocol/tool parameters, generated Swift model fields, and a shared-state table that can affect API and upgrade behavior beyond the stated fix.
  • merge-risk: 🚨 session-state: The intended fix changes which parent session metadata is inherited by newly created dashboard child sessions.
  • merge-risk: 🚨 security-boundary: The branch also changes hosted plugin catalog fetching/caching and inbound media handling, which are supply-chain and security-boundary surfaces that green CI alone does not settle.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: After-fix proof is limited to Vitest, git diff --check, and autoreview output; add redacted live Control UI or real gateway output, redact private details, then update the PR body or ask a maintainer to comment @clawsweeper re-review if needed.
Evidence reviewed

PR surface:

Source +1802, Tests +2446, Docs -78, Generated +26, Other +167. Total +4363 across 74 files.

View PR surface stats
Area Files Added Removed Net
Source 28 2059 257 +1802
Tests 23 2498 52 +2446
Docs 11 142 220 -78
Config 0 0 0 0
Generated 2 26 0 +26
Other 10 169 2 +167
Total 74 4894 531 +4363

Security concerns:

  • [medium] Unrelated plugin distribution surface — src/plugins/official-external-plugin-catalog.ts:749
    The branch adds a hosted official external plugin catalog loader and snapshot-backed fallback path, plus a shared-state table for cached feed bodies; because plugin catalogs influence package/plugin distribution, this needs separate security and upgrade review instead of riding along with the dashboard session fix.
    Confidence: 0.82

What I checked:

  • Repository policy read and applied: Root AGENTS.md and scoped gateway, gateway/server-methods, agents, agents/tools, plugins, docs, scripts, extensions, and test guides were read; the relevant policy treats session state, provider/model routing, plugin distribution, state schema, and security-sensitive surfaces as compatibility-sensitive review areas. (AGENTS.md:31, 07b934901a32)
  • Current main copies stale context budget: Current main's inheritSessionRuntimeSelection() copies parentEntry.contextTokens into child session entries, which is the reported stale-budget path. (src/gateway/server-methods/sessions.ts:187, 07b934901a32)
  • Current main applies inherited parent state on session create: sessions.create overlays inheritSessionRuntimeSelection(parentSessionEntry) when no explicit model is provided, so the stale copied field reaches the new child entry. (src/gateway/server-methods/sessions.ts:1434, 07b934901a32)
  • Session rows prefer stored context budget: Gateway session row projection resolves entry.contextTokens before model-derived context tokens, so a copied stale value can control the row budget. (src/gateway/session-utils.ts:2078, 07b934901a32)
  • Control UI consumes the row context budget: The chat view uses activeSession.contextTokens as the thread context window, matching the visible stale dashboard budget path. (ui/src/ui/views/chat.ts:2120, 07b934901a32)
  • PR head removes the stale field copy: At PR head, inheritSessionRuntimeSelection() preserves provider/model/auth/runtime settings but no longer copies contextTokens. (src/gateway/server-methods/sessions.ts:187, b209ee011767)

Likely related people:

  • jalehman: Recent GitHub history shows multiple commits in src/gateway/server-methods/sessions.ts and src/gateway/session-utils.ts adding session lifecycle, transcript reader, and alias mutation seams around the affected session path. (role: recent session-method contributor; confidence: high; commits: cf64a9c51799, d216f7c876dd, e442b575b986; files: src/gateway/server-methods/sessions.ts, src/gateway/session-utils.ts)
  • vincentkoc: Recent history in src/gateway/session-utils.ts includes session-row and numeric/context helper refactors adjacent to the row budget resolution used by the Control UI. (role: adjacent session row contributor; confidence: medium; commits: 0a338147a52f, 2b75806197ab, 7217477553f6; files: src/gateway/session-utils.ts)
  • joshavant: Local blame attributes the current inheritSessionRuntimeSelection() helper lines, including contextTokens inheritance, to commit fbfadbd806; the local history boundary makes this a weaker routing signal than the GitHub file history. (role: line-level current implementation carrier; confidence: low; commits: fbfadbd806; files: src/gateway/server-methods/sessions.ts)
  • giodl73-repo: The broad PR delta includes hosted official external plugin catalog and snapshot-store changes; recent GitHub history shows this person carrying the same catalog feed, snapshot, and source-profile files. (role: recent plugin-catalog surface contributor; confidence: high; commits: 1b0766080a30, d1b917120a47, 12685ee6b752; files: src/plugins/official-external-plugin-catalog.ts, src/plugins/official-external-plugin-catalog-snapshot-store.ts, src/state/openclaw-state-schema.sql)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jun 27, 2026
@galiniliev galiniliev self-assigned this Jun 28, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: macos App: macos app: web-ui App: web-ui scripts Repository scripts agents Agent runtime and tooling extensions: qa-lab extensions: codex size: XL and removed size: XS labels Jun 28, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 28, 2026
@galiniliev
galiniliev merged commit c6ade83 into openclaw:main Jun 28, 2026
200 of 209 checks passed
@galiniliev

Copy link
Copy Markdown
Contributor Author

Merged via squash.

@galiniliev
galiniliev deleted the bug-050-dashboard-contexttokens branch June 28, 2026 04:31
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 28, 2026
* fix(gateway): avoid stale child session context tokens

* fix(gateway): avoid stale child session context tokens

---------

Co-authored-by: Galin Iliev <[email protected]>
QiuYuang pushed a commit to QiuYuang/openclaw that referenced this pull request Jul 1, 2026
* fix(gateway): avoid stale child session context tokens

* fix(gateway): avoid stale child session context tokens

---------

Co-authored-by: Galin Iliev <[email protected]>
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 1, 2026
* fix(gateway): avoid stale child session context tokens

* fix(gateway): avoid stale child session context tokens

---------

Co-authored-by: Galin Iliev <[email protected]>
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
* fix(gateway): avoid stale child session context tokens

* fix(gateway): avoid stale child session context tokens

---------

Co-authored-by: Galin Iliev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: macos App: macos app: web-ui App: web-ui docs Improvements or additions to documentation extensions: codex extensions: qa-lab gateway Gateway runtime maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. scripts Repository scripts size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Dashboard child sessions inherit stale parent context token budget

1 participant