Preserve conversation context and separate next actions in recaps (#45090)

## Why

The 900-byte recap prompt limit leaves little room for completed progress, unresolved caveats, and recent corrections. Recaps need this context to distinguish completed work from pending requests.

## What changed

- Introduce a shared `RecapPrompt` with a 32 KiB ceiling for instructions and history, using an 8,192-token estimate. Instruct summaries to retain the broader goal, completed outcomes, and unresolved availability or validation caveats.
- Select up to eight answered exchanges plus a pending request, preserving adjacent steering and progress messages. Drop older whole exchanges before excerpting both ends of oversized messages, while retaining the newest answer and pending correction.
- Require a `summary` and nullable `next_action`, bounded to 700 and 200 characters respectively. Reject malformed or oversized responses and display an optional, separately styled `Next:` line.

## Testing

Add coverage for UTF-8 prompt bounds, exchange selection, pending corrections, excerpt boundaries, strict response parsing, and next-action rendering. Extend the recap generation integration test to verify bounded history and the structured response schema.

GitOrigin-RevId: 6c6a84bc602a168418c1952feb1d286ec0cb9e28
This commit is contained in:
Felipe Coury
2026-09-12 18:04:18 +00:00
committed by copyberry
parent f16c2237a5
commit 8d3c6cc13d
9 changed files with 544 additions and 141 deletions

View File

@@ -73,7 +73,7 @@ pub fn approx_token_count(text: &str) -> usize {
len.saturating_add(APPROX_BYTES_PER_TOKEN.saturating_sub(1)) / APPROX_BYTES_PER_TOKEN
}
pub fn approx_bytes_for_tokens(tokens: usize) -> usize {
pub const fn approx_bytes_for_tokens(tokens: usize) -> usize {
tokens.saturating_mul(APPROX_BYTES_PER_TOKEN)
}