Fit requests to a token window and summarize older turns #5

Merged
jacensekai merged 1 commit from context-management into master 2026-10-13 19:09:18 -04:00
Owner

History was trimmed to a character budget that ignored the system
prompt and tool definitions, and old turns were simply dropped, so long
conversations lost context without notice and could still overflow the
model's window.

Requests are now fitted into context.windowTokens (system prompt, tool
definitions, history and room for the reply). Sizes are estimated in
characters with a chars-per-token ratio learned per model from the
usage the provider reports; streamChat() asks for usage and retries
without stream_options on endpoints that reject it.

Once a request passes compactAt of the window, everything but the most
recent keepRecent share is summarized by the model into a stored
summary message, cut at a user message and folding in the previous
summary. The summary goes into the system prompt in place of those
messages. If it still doesn't fit, older long tool results are replaced
by a note before whole turns are dropped. A failed summary falls back to
dropping turns and isn't retried within the run. Summaries can also be
made on request (POST /api/conversations/:id/compact), as a run.

The chat header shows a context meter with a breakdown and "Summarize
now", the timeline marks where a summary starts and dims what it
replaced, and Settings → Model gets the window and compaction settings.
A saved llm.contextChars is migrated to a token window unless it was
the old default.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

History was trimmed to a character budget that ignored the system prompt and tool definitions, and old turns were simply dropped, so long conversations lost context without notice and could still overflow the model's window. Requests are now fitted into context.windowTokens (system prompt, tool definitions, history and room for the reply). Sizes are estimated in characters with a chars-per-token ratio learned per model from the usage the provider reports; streamChat() asks for usage and retries without stream_options on endpoints that reject it. Once a request passes compactAt of the window, everything but the most recent keepRecent share is summarized by the model into a stored `summary` message, cut at a user message and folding in the previous summary. The summary goes into the system prompt in place of those messages. If it still doesn't fit, older long tool results are replaced by a note before whole turns are dropped. A failed summary falls back to dropping turns and isn't retried within the run. Summaries can also be made on request (POST /api/conversations/:id/compact), as a run. The chat header shows a context meter with a breakdown and "Summarize now", the timeline marks where a summary starts and dims what it replaced, and Settings → Model gets the window and compaction settings. A saved llm.contextChars is migrated to a token window unless it was the old default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fit requests to a token window and summarize older turns
Some checks failed
CI / Typecheck, build and test (pull_request) Successful in 16s
CI / End-to-end (Playwright) (pull_request) Successful in 55s
CI / Docker images and sandbox (pull_request) Failing after 11s
CI / Compose stack smoke test (pull_request) Failing after 6s
98ea273c14
History was trimmed to a character budget that ignored the system
prompt and tool definitions, and old turns were simply dropped, so long
conversations lost context without notice and could still overflow the
model's window.

Requests are now fitted into context.windowTokens (system prompt, tool
definitions, history and room for the reply). Sizes are estimated in
characters with a chars-per-token ratio learned per model from the
usage the provider reports; streamChat() asks for usage and retries
without stream_options on endpoints that reject it.

Once a request passes compactAt of the window, everything but the most
recent keepRecent share is summarized by the model into a stored
`summary` message, cut at a user message and folding in the previous
summary. The summary goes into the system prompt in place of those
messages. If it still doesn't fit, older long tool results are replaced
by a note before whole turns are dropped. A failed summary falls back to
dropping turns and isn't retried within the run. Summaries can also be
made on request (POST /api/conversations/:id/compact), as a run.

The chat header shows a context meter with a breakdown and "Summarize
now", the timeline marks where a summary starts and dims what it
replaced, and Settings → Model gets the window and compaction settings.
A saved llm.contextChars is migrated to a token window unless it was
the old default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jacensekai/lumina!5
No description provided.