Repository navigation
Per-turn context window and what fills it - #318
Merged
Merged
Conversation
A session's turns only carried their measured usage. The desktop app
wants to show how full a turn's context window was and what was
occupying it, so:
- `TurnView` gains `context_window`: the window of the model that
answered the turn, resolved now through the one spec resolution
core already has (`tw_config::model_specs`: the upstream's manual
spec first, then the price table), looked up by the model name the
upstream actually received (`sent_model`, now carried by `TurnRow`).
- New endpoint `GET /sessions/{id}/turns/{turn}/context` answering
`TurnContext`: the stored request body decoded with the client's
dialect and estimated in one pass as four parts (system prompt,
tool definitions, every message before the last user message, the
last user message with the tool results it carries) by the same
estimator `count_tokens` answers with, next to the measured input
and cache-read tokens from the history row. A body that was never
kept, has expired, was truncated or cannot be decoded answers
`kept: false` with `parts: null`. An unknown session is
`control.session_not_found`; a turn that is not in that session is
`control.request_not_found`.
- `tw_engine::estimate_parts` is the per-part twin of
`estimate_tokens`; each part rounds on its own, so the sum differs
from the whole-body estimate by at most a few tokens.
- Protocol version 45. tw-control now depends on tw-dialect directly
to decode stored bodies.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A session's turns only carried their measured usage. The desktop app wants to show how full a turn's context window was and what was occupying it.
TurnViewgainscontext_window: number | null: the window of the model that answered the turn, resolved now through the one spec resolution core already has (tw_config::model_specs: the upstream's manualmodel_specsfirst, then the price table), looked up by the model name the upstream actually received (sent_model, now carried byTurnRow).GET /sessions/{id}/turns/{turn}/contextansweringTurnContext:parts: the stored request body decoded with the client's dialect (Anthropicsystem+ messages; Chat system/developer messages; Responsesinstructions+ input items; GeminisystemInstruction+ contents) and estimated in one pass assystem,tools(tool definitions),history(every message before the last user message),last_user(the last user message with the tool results it carries) andtotal, by the same estimatorcount_tokensanswers with (tw_engine::estimate_parts, the per-part twin ofestimate_tokens; each part rounds on its own, so the sum can differ from the whole-body estimate by a few tokens).window,input_tokens,cache_read_tokensfrom the spec and the history row.kept: falsewithparts: nullwhen the body was never kept, has expired, was truncated or cannot be decoded.control.session_not_foundfor an unknown session; 404control.request_not_foundfor a turn that is not in that session.CONTROL_API_VERSION44 → 45, with the version notes above it; the new types are in the TypeScript export (not kept in-tree; CI regenerates it).tw-controlnow depends ontw-dialectdirectly to decode stored bodies (one line inCargo.lock).New messages
None. The endpoint reuses
control.session_not_foundandcontrol.request_not_found.Verified
cargo fmt --all --checkcargo clippy -p tw-api -p tw-engine -p tw-store -p tw-control -p twcore --all-targets -- -D warningscargo test --workspacewith the local proxy unset: all greencargo run -p tw-api --features ts --example export_ts: exportsTurnContext,ContextParts,TurnView.context_windowcrates/tw-control/tests/turn_context.rs(Anthropic, Chat, Responses and Gemini bodies split into four parts; body gone; manual spec vs price table vs unknown model; the two 404s),tw_engine::facts::tests::parts_split_the_body_at_the_last_user_message, and ats.rstest pinning the exported shape.🤖 Generated with Claude Code