Skip to content

fix(runtime): bound text history summarizer inputs #3013

Description

@M4n5ter

Problem

HistoryCompactSummaryInput carries an inputBudget so a compactor can avoid dispatching a request that is already estimated to exceed the selected model's capacity. The provider-native Codex compactor consumes that budget, but buildLlmHistorySummarizer() currently ignores it and materializes every newly folded RuntimeEvent into the generateText() request unchanged.

A large historical Tool Result can therefore make the text-summarization request itself exceed the context window before the model has a chance to summarize it. The resulting provider failure safely fails open, but it spends a request on a projection Runtime already estimated cannot fit and reports a generic provider failure instead of the precise local cause.

This text-summarizer behavior predates #2993. PR #2993 exposes the common input-budget contract while adding Codex provider-native compaction, but changing the existing text path is not part of that PR and should not block it.

Desired behavior

Make the text history summarizer honor HistoryCompactSummaryInput.inputBudget before provider dispatch.

The solution should:

  • keep the RuntimeEvent ledger unchanged;
  • preserve complete Tool Call / Tool Result pairing in the summarizer projection;
  • preferentially bound or omit older Tool Result payloads while retaining later grounded conversation context;
  • preserve rolling-summary behavior (previousCheckpoint plus newly folded events);
  • throw the typed input_too_large summarizer failure before dispatch when the remaining non-tool projection still cannot fit;
  • continue using the existing fail-open and diagnostic paths.

The implementation may share deterministic request-fitting logic with provider-native compaction if that reduces total complexity, but this issue does not require a new provider registry or compactor framework.

Non-goals

  • Changing which compactor is selected for Codex subscription connections.
  • Adding native-to-text fallback behavior.
  • Making checkpoint formats interchangeable.
  • Claiming tokenizer-exact capacity measurement; the existing context-budget estimate remains the policy input.

Acceptance criteria

  • An oversized text-summarizer Tool Result is bounded before generateText() without producing an orphan call or result.
  • A projection that still exceeds inputBudget after eligible Tool Result omission fails locally with input_too_large and does not dispatch.
  • Ordinary and rolling text compaction remain behaviorally unchanged when the projection already fits.
  • Tests verify the deterministic outgoing projection and failure boundary rather than treating a mocked provider response as proof that the request fits.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions