Skip to content

fix(agent-core-v2): keep context size readings on the measured path - #1782

Merged
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:fix/context-size-measured-path
Jul 16, 2026
Merged

fix(agent-core-v2): keep context size readings on the measured path#1782
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:fix/context-size-measured-path

Conversation

@sailist

@sailist sailist commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is described below.

Problem

The context size reading (the TUI footer indicator and API consumers of the agent context token count) could under-report the model's actual context usage by orders of magnitude: after one "hi" on a fresh session, the provider-reported exchange totals ~29k tokens while the reading shows ~50.

Root cause: the step fold creates the assistant message in the context before the exchange finishes (a skeleton at step.begin, filled by content.part folds during streaming), and the input array handed to the context-size measurement is that same live array — it already includes the output. Computing the measured prefix length as input.length + output.length therefore counted the folded output twice and stored a prefix length one past the live context. The inflated length permanently failed the measured fast path in get(), silently falling back to per-message estimates.

What changed

  • Take the live context length as the measured prefix (input and context are identical under the identity guard), so the provider-reported token totals stay reachable through the measured path.
  • Clamp the measured prefix to the context length in get(), so a bad stored record can never knock reads off the measured path again.
  • Add regression tests that drive real turns and assert the stored model, get(), and the RPC context read against the exchange totals (3/4 fail without the fix).
  • Add a klient example that traces context/token readings of a fresh session after one "hi" against a real server (diff-polling getContext()/getUsage() plus agent events, with a final consistency check); used to verify the fix end-to-end.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

sailist added 3 commits July 16, 2026 18:31
The step fold creates the assistant message in the context before the
exchange finishes (a skeleton at step.begin, filled by content.part folds
during streaming), and the input array llmRequester passes to
contextSize.measured() is that same live array — it already includes the
output. Taking input.length + output.length therefore counted the folded
output twice, storing a measured prefix length one past the live context.
The inflated length permanently failed get()'s measured fast path, so
reads silently fell back to per-message estimates (e.g. ~50 tokens shown
for a ~29k-token "hi").

Take the live context length as the measured prefix instead (input and
context are identical under the identity guard), and clamp the measured
prefix to the context length in get() so a bad record can never knock
reads off the measured path again.

Add contextSize tests driving real turns that assert the wire model,
get(), and rpc getContext against the exchange totals.
Polls agent.getContext()/agent.getUsage() and streams agent events for a
new session after one "hi" against a real server, printing a timeline of
when the context/token readings move, plus a final consistency check
comparing the measured tokenCount to cumulative usage. Model seeding is
optional via KIMI_EXAMPLE_* env; the server token resolves from
<kimi-home>/server.token like the v2 e2e helpers.
@changeset-bot

changeset-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2090b65

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 16, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@2090b65
npx https://pkg.pr.new/@moonshot-ai/kimi-code@2090b65

commit: 2090b65

@sailist
sailist merged commit 072eed4 into MoonshotAI:main Jul 16, 2026
18 checks passed
This was referenced Jul 16, 2026
ywh114 pushed a commit to ywh114/kimi-code that referenced this pull request Jul 19, 2026
…oonshotAI#1782)

* fix(agent-core-v2): keep context size readings on the measured path

The step fold creates the assistant message in the context before the
exchange finishes (a skeleton at step.begin, filled by content.part folds
during streaming), and the input array llmRequester passes to
contextSize.measured() is that same live array — it already includes the
output. Taking input.length + output.length therefore counted the folded
output twice, storing a measured prefix length one past the live context.
The inflated length permanently failed get()'s measured fast path, so
reads silently fell back to per-message estimates (e.g. ~50 tokens shown
for a ~29k-token "hi").

Take the live context length as the measured prefix instead (input and
context are identical under the identity guard), and clamp the measured
prefix to the context length in get() so a bad record can never knock
reads off the measured path again.

Add contextSize tests driving real turns that assert the wire model,
get(), and rpc getContext against the exchange totals.

* feat(klient): add context-usage example tracing a fresh session

Polls agent.getContext()/agent.getUsage() and streams agent events for a
new session after one "hi" against a real server, printing a timeline of
when the context/token readings move, plus a final consistency check
comparing the measured tokenCount to cumulative usage. Model seeding is
optional via KIMI_EXAMPLE_* env; the server token resolves from
<kimi-home>/server.token like the v2 e2e helpers.

* chore: add changeset for the context size fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant