Skip to content

fix(sessions): provider-qualified context limits (#62472)#62493

Merged
obviyus merged 4 commits into
openclaw:mainfrom
neeravmakwana:fix/context-tokens-provider-62472
Apr 9, 2026
Merged

fix(sessions): provider-qualified context limits (#62472)#62493
obviyus merged 4 commits into
openclaw:mainfrom
neeravmakwana:fix/context-tokens-provider-62472

Conversation

@neeravmakwana

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Session usage persistence, inline directive handling, and memory-flush / preflight compaction sizing used bare model ids (lookupContextTokens / lookupCachedContextTokens) for context limits. When several providers expose the same model id with different configured context windows, the wrong limit could be written to sessionEntry.contextTokens and affect /status, compaction, and flush behavior ([Bug]: Context token / context window can be persisted incorrectly when multiple providers share the same model id, causing wrong /status values and potentially premature compaction #62472).
  • Why it matters: Persisted contextTokens drives usage display, compaction thresholds, and related safeguards; a stale or collided value can make the runtime overly conservative or inconsistent with the active provider.
  • What changed: Use resolveContextTokensForModel({ cfg, provider, model, allowAsyncLoad: false }) in the auto-reply agent and follow-up runners, in persistInlineDirectives return value, and in resolveMemoryFlushContextWindowTokens (threading cfg + provider from the follow-up run). Follow-up runs now resolve providerUsed from agent meta when present, matching the main reply path.
  • What did NOT change: CLI updateSessionStoreAfterAgentRun already used provider-qualified resolution; gateway session row building and status logic were left as-is. The global context cache structure is unchanged; resolution goes through the existing resolveContextTokensForModel contract.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: Mixed strategies: resolveContextTokensForModel correctly scans cfg.models.providers per provider, but several hot paths still used bare-model cache lookups or cached tokens keyed only by model id, so duplicate ids across providers could leak the wrong window into persisted session metadata.
  • Missing detection / guardrail: Unit coverage did not assert provider-qualified resolution for resolveMemoryFlushContextWindowTokens when two providers list the same model id with different limits.
  • Contributing context (if known): N/A

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/auto-reply/reply/reply-state.test.ts
  • Scenario the test should lock in: Two providers in config share one model id with different contextWindow values; resolveMemoryFlushContextWindowTokens returns the limit for the requested provider.
  • Why this is the smallest reliable guardrail: Exercises the same resolveContextTokensForModel path used by reply usage persistence and memory sizing without standing up a full channel run.
  • Existing test that already covers this (if any): Partial — resolveContextTokensForModel tests in src/agents/context.lookup.test.ts; this adds coverage at the memory-flush entry point.
  • If no new test is added, why not: N/A — test added.

User-visible / Behavior Changes

  • Session contextTokens and related usage / flush thresholds should match the active provider’s configured window when multiple providers reuse the same model id.

Diagram (if applicable)

N/A

Security Impact (required)

  • New permissions/capabilities? No
  • New network endpoints or trust boundaries? No

Testing

  • pnpm exec oxlint --type-aware on touched src/auto-reply/reply/*.ts files
  • pnpm test src/auto-reply/reply/reply-state.test.ts -t resolveMemoryFlushContextWindowTokens

@greptile-apps

greptile-apps Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes provider-qualified context window resolution across the memory-flush and preflight-compaction gates, inline-directive persist, and followup runners. Previously these paths used bare model-id lookups that could collide when multiple providers share a model id, writing the wrong contextTokens into session metadata and skewing compaction thresholds.

Confidence Score: 5/5

Safe to merge; the fix correctly threads provider context through all affected paths and adds targeted regression coverage.

All remaining findings are P2. The priority inversion for agentCfgContextTokens in the flush gate is a minor inconsistency that only affects rare deployments with explicit per-agent contextTokens overrides; the primary bug fix is correct and well-tested.

src/auto-reply/reply/memory-flush.ts — minor agentCfgContextTokens priority ordering

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/auto-reply/reply/memory-flush.ts
Line: 13-22

Comment:
**`agentCfgContextTokens` priority inconsistency with main run path**

In `agent-runner.ts` and `followup-runner.ts`, `agentCfgContextTokens` takes the highest priority (`agentCfgContextTokens ?? resolveContextTokensForModel(...)`), and in `directive-handling.persist.ts` it is passed as `contextTokensOverride` so it wins there too. Here the order is reversed — `resolveContextTokensForModel` wins, and `agentCfgContextTokens` only fires when no model is found in config. If an agent has an explicit `contextTokens` override smaller than the provider's configured window, the flush/compaction gate will use the larger model value and may not trigger when it should. Threading it as `contextTokensOverride` would restore consistency:

```suggestion
  return (
    resolveContextTokensForModel({
      cfg: params.cfg,
      provider: params.provider,
      model: params.modelId,
      contextTokensOverride: params.agentCfgContextTokens,
      allowAsyncLoad: false,
    }) ??
    DEFAULT_CONTEXT_TOKENS
  );
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(sessions): provider-qualified contex..." | Re-trigger Greptile

Comment thread src/auto-reply/reply/memory-flush.ts
@neeravmakwana

Copy link
Copy Markdown
Contributor Author

Review follow-up (commit c248c9d)

Greptile (inline on memory-flush.ts) — addressed
resolveMemoryFlushContextWindowTokens now passes agentCfgContextTokens into resolveContextTokensForModel as contextTokensOverride, matching agent-runner / followup-runner (leading agentCfgContextTokens ?? …) and directive-handling.persist (override inside resolveContextTokensForModel). The memory-flush / preflight-compaction gate therefore uses the same precedence: explicit per-agent contextTokens wins over provider/model config when both are set.

Regression test
Added prefers agent contextTokens override over the provider configured window in reply-state.test.ts (512k provider window vs 100k agent override → 100k).

Aisle Security (PR comment) — partial

  • Agent cap vs model window: The change above aligns flush gating with the agent cap; no separate “model wins over agent” path remains in this helper.
  • Non-finite / unbounded contextTokens: Sanitizing or clamping overrides and config-sourced limits inside resolveContextTokensForModel would be a broader contract change affecting many callers; it was not introduced by this PR. If we want a global clamp, that should be a dedicated follow-up with a shared constant and call-site audit.

All automated review items above are either implemented (Greptile + Aisle cap ordering) or explicitly scoped out (finite/clamp in core resolver) to avoid an unrelated refactor in this bugfix.

@obviyus obviyus force-pushed the fix/context-tokens-provider-62472 branch from c248c9d to 8b5bba5 Compare April 9, 2026 11:16

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b5bba51c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/auto-reply/reply/followup-runner.ts
@obviyus obviyus self-assigned this Apr 9, 2026
@obviyus obviyus force-pushed the fix/context-tokens-provider-62472 branch from 8b5bba5 to 6b8859c Compare April 9, 2026 11:50
@obviyus obviyus force-pushed the fix/context-tokens-provider-62472 branch from fcc533d to 6e84928 Compare April 9, 2026 11:54

@obviyus obviyus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed latest changes; landing now.

@obviyus obviyus merged commit 2645ed1 into openclaw:main Apr 9, 2026
23 of 26 checks passed
@obviyus

obviyus commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Landed on main.

Thanks @neeravmakwana.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e84928f1a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

sessionEntry?.contextTokens ??
DEFAULT_CONTEXT_TOKENS;
resolveContextTokensForModel({
cfg: queued.run.config,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve follow-up context window from runtime config

This lookup uses queued.run.config even though the follow-up run itself is executed and persisted with runtimeConfig right below. If the runtime snapshot differs (for example after a hot config reload), contextTokensUsed can be derived from stale provider/model limits and then written into session usage, which skews /status reporting and memory-flush/compaction thresholds for that turn. Use the same runtimeConfig object here so context sizing matches the config actually used for the run.

Useful? React with 👍 / 👎.

steipete pushed a commit that referenced this pull request Apr 10, 2026
…avmakwana)

* fix(sessions): provider-qualified context limits (#62472)

* fix(sessions): honor agent context cap in memory-flush gate

* refactor(sessions): unify context token resolution

* fix: keep followup snapshot freshness on the active provider (#62493) (thanks @neeravmakwana)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
@neeravmakwana)

* fix(sessions): provider-qualified context limits (openclaw#62472)

* fix(sessions): honor agent context cap in memory-flush gate

* refactor(sessions): unify context token resolution

* fix: keep followup snapshot freshness on the active provider (openclaw#62493) (thanks @neeravmakwana)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
@neeravmakwana)

* fix(sessions): provider-qualified context limits (openclaw#62472)

* fix(sessions): honor agent context cap in memory-flush gate

* refactor(sessions): unify context token resolution

* fix: keep followup snapshot freshness on the active provider (openclaw#62493) (thanks @neeravmakwana)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
@neeravmakwana)

* fix(sessions): provider-qualified context limits (openclaw#62472)

* fix(sessions): honor agent context cap in memory-flush gate

* refactor(sessions): unify context token resolution

* fix: keep followup snapshot freshness on the active provider (openclaw#62493) (thanks @neeravmakwana)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
@neeravmakwana)

* fix(sessions): provider-qualified context limits (openclaw#62472)

* fix(sessions): honor agent context cap in memory-flush gate

* refactor(sessions): unify context token resolution

* fix: keep followup snapshot freshness on the active provider (openclaw#62493) (thanks @neeravmakwana)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
@neeravmakwana)

* fix(sessions): provider-qualified context limits (openclaw#62472)

* fix(sessions): honor agent context cap in memory-flush gate

* refactor(sessions): unify context token resolution

* fix: keep followup snapshot freshness on the active provider (openclaw#62493) (thanks @neeravmakwana)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

2 participants