Skip to content

feat(cascade): Bound conversation history sent to the llm and kept in memory - #74

Merged
austinchennn merged 1 commit into
mainfrom
GuanchengChen/nifty-kilby-c8926c
Oct 23, 2026
Merged

austinchennn merged 1 commit into
mainfrom
GuanchengChen/nifty-kilby-c8926c

Conversation

@austinchennn

Copy link
Copy Markdown
Collaborator

Description:

Fixes #xxx

No linked issue. Found while reviewing vRT's context management: CascadeSession.history only grew, so long voice sessions would eventually exceed the text LLM's context window and memory grew with session length.

Behaviours Completed

  • Requests to the llm send only a recent window of the history, bounded by message count (default 200) and an approximate token budget (default 32 000).
  • session.history itself is capped (default twice maxMessages), so memory no longer grows with session length.
  • Trimming keeps the conversation valid: a tool result is never kept without the assistant message that called it, the window never starts with a tool result, and it starts with a user message when one fits. Instructions are always sent.
  • history.process lets apps replace the default trim; trimHistory and estimateTokens are exported to build on.

Files Changed

  • packages/cascade/src/history.ts (new): HistoryLimits, estimateTokens, trimHistory.
  • packages/cascade/src/index.ts: CascadeOptions.history; all history writes go through #remember, requests through #window.
  • packages/cascade/test/cascade.test.ts: tests for the budget, tool call/result pairing, the stored cap, custom process, and unchanged behaviour for short sessions.

Brief Explanation

trimHistory marks every index that would orphan a tool result if the window started there, then walks back from the newest message accumulating the token estimate (about 4 characters per token) and picks the earliest valid start within budget, preferring a user message. If nothing fits, it falls back to the latest valid start. #remember applies the same function with the stored cap after each push.

Testing

npx vitest run packages: 551 tests pass across 34 files, including the new cascade tests. Typecheck in the worktree was not meaningful because it had no node_modules and resolved @vrealtime/* from an older checkout; relying on CI typecheck.

Unsure About

The token estimate is a character heuristic, not a real tokenizer, so the budget is approximate. Older history is dropped rather than summarized; summarization/compaction could be a follow-up.

@austinchennn
austinchennn merged commit bc1903c into main Oct 23, 2026
5 checks passed
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