tamaratran/fast-jev-compaction
Claude Code plugin that replaces the compaction summary with Jev decisions: every tool call and result is scored in one fast request, stale ones are dropped or truncated, everything kept stays verbatim.
fast‑jev‑compaction – a Claude Code plug‑in & npm library
What it does
- When you work with Claude Code, the session history can become huge because every tool use (e.g.,
Read,Write) and its result is stored verbatim. - The built‑in “compaction” feature normally asks the LLM to summarise old turns, which can lose important details like file paths or exact error messages.
fast-jev-compactionreplaces that summary with a selective pruning process: it asks the Jev model (a Typesafe LLM) whether each tool call and each tool result is still needed. Anything judged unnecessary is dropped; everything else is kept exactly as it was.
How it works
- Pair every
tool_usewith itstool_resultviatool_use_id. The first message and the newest N messages (configurable) are “pinned” and never touched. - Build a state that contains the whole conversation (oldest first) but replaces each result with a short placeholder like
ok, 4213 chars (omitted). No summarisation of text messages. - Fit the state into a token budget (
maxStateTokens, default 25 k) by progressively truncating tool inputs, abbreviating long texts, collapsing old messages, etc. - For each non‑pinned tool call, send Jev two yes/no questions: keep the call? and keep the result verbatim?.
- Batch the questions into as many requests as needed while staying under
maxRequestTokens(default 30 k). Requests run concurrently; answers are merged. - Apply a threshold (
keepThreshold, default 0.5):- If the result‑keep probability ≥ threshold → keep both call and result.
- Else if the call‑keep probability ≥ threshold → keep the call, truncate the result to
truncateHeadChars(default 300) plus a note. - Otherwise drop both.
- Re‑assemble the message list, removing any message that ends up empty. The output never contains a result without its call.
Installation
npm install fast-jev-compaction
export TYPESAFE_API_KEY=… # your Typesafe (Jev) key
Basic usage (TypeScript)
import { compactMessages, reductionRatio, type Message } from 'fast-jev-compaction';
const transcript: Message[] = [
{ role: 'user', text: 'Fix the failing test. Never edit src/generated.', toolUses: [] },
{
role: 'assistant',
text: '',
toolUses: [{ tool_use_id: 'toolu_1', tool: 'Read', input: { file_path: 'src/a.ts' } }],
},
{ role: 'user', text: '', toolUses: [], toolResults: [{ tool_use_id: 'toolu_1', text: '…file…' }] },
];
const result = await compactMessages(transcript, { preserveRecentMessages: 4 });
console.log(result.messages, result.decisions, result.stats);
if (reductionRatio(result) < 0.25) {
// not enough compression – fall back to a normal summary
}
compactMessagesreturns the pruned message list, the per‑call decisions, and statistics.- Advanced use: implement your own
JevAsker(provides anask(state, questions)method) and call the lower‑levelcompact(messages, asker, options).
Configuration options (defaults shown)
| Option | Default | Meaning |
|---|---|---|
apiKey |
process.env.TYPESAFE_API_KEY |
Your Typesafe (Jev) API key |
model |
jev-latest |
Which Jev model to query |
baseUrl |
https://api.typesafe.ai/v1/systemone |
API endpoint |
goal |
last 3 user prompts | Task description included in the state |
keepThreshold |
0.5 |
Probability cut‑off for keeping calls/results |
preserveRecentMessages |
6 |
Newest messages never pruned (first message always kept) |
maxStateTokens |
25000 |
Token budget for the state sent to Jev |
maxRequestTokens |
30000 |
Token budget for each request (state + questions) |
truncateHeadChars |
300 |
How many characters of a dropped result are retained |
Limitations
- Only tool calls/results are ever removed; plain user/assistant text is never shortened in the final output.
- Token counts are rough estimates derived from character length, not a true tokenizer.
- The model’s probability scores are not guarantees; the assistant can always re‑run a dropped tool.
- The full state is resent with every batch request, so very long histories may generate many API calls.
Claude Code plug‑in
- The repo includes a plug‑in (
hooks/fast-jev.ts) that automatically runs this compaction on Claude Code sessions. - Install via Claude Code’s marketplace:
claude plugin marketplace add tamaratran/fast-jev-compaction claude plugin install fast-jev-compaction@fast-jev-compaction - After installation, the
/compactcommand (and auto‑compaction) will use Jev; a toast will indicate whether pruning succeeded or fell back to the built‑in summary.
Development & demo
npm testruns unit tests with a fake Jev client (no network).demo/JevDemois a small SwiftUI macOS app that visualises the pruning flow; it does not call the real API and is meant for screen‑recording.
Bottom line
fast-jev-compaction gives developers a way to keep every important tool interaction intact while discarding truly unnecessary history, avoiding the lossy summarisation that Claude Code normally performs. It can be used as a plain npm package or as a first‑class Claude Code plug‑in.
Related
- Project
- Project
- Project
- Project