Skip to content

feat(cli, config, conversation): Implement conversation compaction#544

Open
JeanMertz wants to merge 3 commits intomainfrom
prr111
Open

feat(cli, config, conversation): Implement conversation compaction#544
JeanMertz wants to merge 3 commits intomainfrom
prr111

Conversation

@JeanMertz
Copy link
Copy Markdown
Collaborator

Add jp conversation compact command and --compact / -k flag across query, fork, and compact commands, implementing RFD 064 (non-destructive conversation compaction).

The core idea is that compaction is additive: a Compaction overlay event is appended to the conversation stream rather than modifying or deleting any existing events. The projection layer applies overlays at request-build time (Thread::into_parts()), so the LLM sees a reduced view while the full raw history is preserved on disk.

What users can do now:

# Compact with workspace defaults (strip reasoning + tools)
jp conversation compact

# Strip reasoning, keep last 5 turns
jp conversation compact --reasoning --keep-last 5

# Preview without applying
jp conversation compact --dry-run

# Remove all compaction events (undo)
jp conversation compact --reset

# Compact before querying (inline DSL, summarize all but last 3 turns)
jp query -k s:..-3 -- "Continue the task"

# Fork and compact in one step
jp conversation fork --compact

DSL (--compact=SPEC) supports r (reasoning), t (tools), s (summarize) as policy letters, combined with +, and an optional range after :. Examples: s:..-3, r+t, s:5..-3. Bare --compact applies config rules; --compact=SPEC applies inline rules; both forms compose.

Summarization calls the configured LLM and stores the result in the Compaction event as a SummaryPolicy. At projection time the covered turns are replaced with a synthetic request/response pair containing the summary text. Summary range auto-extension prevents partial overlaps with existing summary compactions.

Configuration is under conversation.compaction.rules — a MergedVec<CompactionRuleConfig> where each rule produces one compaction event. The built-in default (strip reasoning + tools) uses discard_when_merged: true so it is replaced the moment any user rule is present. Alternative compaction configurations can be expressed as individual configuration files loaded with --cfg, consistent with JP's existing config layering.

jp conversation print --compacted shows the projected (assistant) view of the conversation, making it easy to verify the effect of compaction.

The IntoPartialAppConfig trait gains a handles parameter so commands can access resolved conversation targets when building their config overrides.

Ref: #57

@JeanMertz JeanMertz marked this pull request as ready for review April 14, 2026 13:36
@JeanMertz JeanMertz force-pushed the prr111 branch 3 times, most recently from 83b5bfe to c596f41 Compare April 16, 2026 15:15
Add `jp conversation compact` command and `--compact` / `-k` flag across
`query`, `fork`, and `compact` commands, implementing RFD 064
(non-destructive conversation compaction).

The core idea is that compaction is additive: a `Compaction` overlay
event is appended to the conversation stream rather than modifying or
deleting any existing events. The projection layer applies overlays at
request-build time (`Thread::into_parts()`), so the LLM sees a reduced
view while the full raw history is preserved on disk.

**What users can do now:**

```sh
# Compact with workspace defaults (strip reasoning + tools)
jp conversation compact

# Strip reasoning, keep last 5 turns
jp conversation compact --reasoning --keep-last 5

# Preview without applying
jp conversation compact --dry-run

# Remove all compaction events (undo)
jp conversation compact --reset

# Compact before querying (inline DSL, summarize all but last 3 turns)
jp query -k s:..-3 -- "Continue the task"

# Fork and compact in one step
jp conversation fork --compact
```

**DSL (`--compact=SPEC`)** supports `r` (reasoning), `t` (tools), `s`
(summarize) as policy letters, combined with `+`, and an optional range after
`:`. Examples: `s:..-3`, `r+t`, `s:5..-3`. Bare `--compact` applies config
rules; `--compact=SPEC` applies inline rules; both forms compose.

**Summarization** calls the configured LLM and stores the result in the
`Compaction` event as a `SummaryPolicy`. At projection time the covered turns
are replaced with a synthetic request/response pair containing the summary text.
Summary range auto-extension prevents partial overlaps with existing summary
compactions.

**Configuration** is under `conversation.compaction.rules` — a
`MergedVec<CompactionRuleConfig>` where each rule produces one compaction event.
The built-in default (strip reasoning + tools) uses `discard_when_merged: true`
so it is replaced the moment any user rule is present. Alternative compaction
configurations can be expressed as individual configuration files loaded with
`--cfg`, consistent with JP's existing config layering.

**`jp conversation print --compacted`** shows the projected (assistant) view of
the conversation, making it easy to verify the effect of compaction.

The `IntoPartialAppConfig` trait gains a `handles` parameter so commands can
access resolved conversation targets when building their config overrides.

Ref: #57
Signed-off-by: Jean Mertz <git@jeanmertz.com>
JeanMertz added 2 commits May 2, 2026 21:34
…tion

Signed-off-by: Jean Mertz <git@jeanmertz.com>
…tion

Signed-off-by: Jean Mertz <git@jeanmertz.com>
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