Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions devlog/2026-07-09_more-compression-candidates/REQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# REQ: Increase max tool compression candidates from 5 to 15

## Background

The context breakdown (shown when usage crosses the threshold) and the
tool-output reminder nudge both surface a list of "largest ranges" to the
model as compression candidates.

Before this change:

- `estimateContextComposition()` returned at most 10 message ranges and 5
tool-output ranges.
- `injectCompressNudges()` sliced the top 5 from `largestRanges` when
building the tool-output reminder.

Observation: the model was compressing too narrowly — frequently one
message per `compress` call — because only a handful of candidates were
visible at once. The compression philosophy in the system prompt asks the
model to cover "the largest range you can in a single call (aim for 20+
messages)", but the candidate list did not back that up.

## Requirement

Surface more compression candidates so the model can pick larger ranges:

1. `estimateContextComposition()`:
- `largestRanges`: 10 → **15**
- `largestToolRanges`: 5 → **15**
2. `injectCompressNudges()` tool-output reminder:
- `topRanges`: 5 → **15**

Code and plain-text candidate lists (`largestCodeRanges`,
`largestMessageRanges`) stay at 5 — they are informational, not the
primary compression target.

## Scope

- `lib/messages/inject/utils.ts` (2 lines)
- `lib/messages/inject/inject.ts` (1 line)

No config, no persisted-state, no prompt-template changes.

## Why split from PR #80

This change was originally bundled into the `2026-07-09_summary-role-assistant`
branch (Bug 39: compression summary role). PR #80 is pending review and
cannot merge immediately, which blocks this independent improvement from
shipping. Splitting it into its own PR lets both move forward independently.

issue #13
32 changes: 32 additions & 0 deletions devlog/2026-07-09_more-compression-candidates/WORKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# WORKLOG: more-compression-candidates

## 2026-07-09

### Implementation

Cherry-picked commit `ea7db98` from `2026-07-09_summary-role-assistant`
onto a fresh branch `2026-07-09_more-compression-candidates` based on
`master` (`b8fba7a`).

Changes (3 lines across 2 files):

- `lib/messages/inject/utils.ts:652` — `perMessage.slice(0, 10)` →
`slice(0, 15)` (`largestRanges`)
- `lib/messages/inject/utils.ts:653` — `perTool.slice(0, 5)` →
`slice(0, 15)` (`largestToolRanges`)
- `lib/messages/inject/inject.ts:214` —
`composition.largestRanges.slice(0, 5)` → `slice(0, 15)`
(`toolOutputReminder` top ranges)

### Verification

- `npm run typecheck` — clean
- `npm run build` — clean
- Tests — green on the source branch (no test changes in this slice)

### Files

- `lib/messages/inject/utils.ts`
- `lib/messages/inject/inject.ts`
- `devlog/2026-07-09_more-compression-candidates/REQ.md`
- `devlog/2026-07-09_more-compression-candidates/WORKLOG.md`
2 changes: 1 addition & 1 deletion lib/messages/inject/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export const injectCompressNudges = (
const toolGrowth = composition.toolTokens - state.nudges.lastToolOutputNudgeTokens
if (toolGrowth >= toolOutputThreshold) {
const fmt = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}K` : String(n))
const topRanges = composition.largestRanges.slice(0, 5).map((r) => `${r.ref} (${fmt(r.tokens)})`).join(", ")
const topRanges = composition.largestRanges.slice(0, 15).map((r) => `${r.ref} (${fmt(r.tokens)})`).join(", ")
toolOutputReminder = `\n\n⚠️ ${fmt(toolGrowth)} new tool outputs accumulated (${fmt(composition.toolTokens)} total). Largest: ${topRanges}. Use compress tool to compress these ranges now.`
state.nudges.lastToolOutputNudgeTokens = composition.toolTokens
anchorsChanged = true
Expand Down
4 changes: 2 additions & 2 deletions lib/messages/inject/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,8 @@ export function estimateContextComposition(
messageTokens,
textTokens: Math.max(0, messageTokens - codeTokens),
total: toolTokens + summaryTokens + messageTokens,
largestRanges: perMessage.slice(0, 10),
largestToolRanges: perTool.slice(0, 5),
largestRanges: perMessage.slice(0, 15),
largestToolRanges: perTool.slice(0, 15),
largestCodeRanges: perCode.slice(0, 5),
largestMessageRanges: perText.slice(0, 5),
}
Expand Down
Loading