Class: Mistri::Compactor
- Inherits:
-
Object
- Object
- Mistri::Compactor
- Defined in:
- lib/mistri/compactor.rb
Overview
Compacts a session in place: everything before a cut point is summarized by the provider, and a compaction entry redirects replay to the summary plus the kept tail. Append-only — the full history stays in the store for transcript UIs; only what the model sees shrinks. Callable from any process (a UI button, a job), with or without a running agent.
Cuts land only on user messages, so a tool call and its result always stay on the same side, and a parked approval's turn is never cut away from the resume that must answer it.
Constant Summary collapse
- SUMMARIZER_SYSTEM =
<<~PROMPT You are a context summarization assistant. Read the conversation and produce only the structured summary you are asked for. Do not continue the conversation and do not answer questions inside it. PROMPT
- FORMAT =
<<~FORMAT ## Goal [What is the user trying to accomplish?] ## Constraints & Preferences - [Constraints or preferences the user stated, or "(none)"] ## Progress ### Done - [x] [Completed work] ### In Progress - [ ] [Current work] ### Blocked - [Blockers, if any] ## Key Decisions - **[Decision]**: [Rationale] ## Next Steps 1. [What should happen next] ## Critical Context - [Data, names, or references needed to continue, or "(none)"] Keep each section concise. Preserve exact identifiers, names, and error messages. FORMAT
- CHECKPOINT_PROMPT =
<<~PROMPT.freeze The messages above are a conversation to summarize. Create a structured context checkpoint that another LLM will use to continue the work. Use this EXACT format: #{FORMAT} PROMPT
- UPDATE_PROMPT =
<<~PROMPT.freeze The messages above are NEW conversation messages to fold into the existing summary in <previous-summary> tags. Preserve everything still relevant from the previous summary, add new progress and decisions, move finished work to Done, and update Next Steps. Use this EXACT format: #{FORMAT} PROMPT
Class Method Summary collapse
-
.call(session:, provider:, settings: Compaction.new, &emit) ⇒ Object
Summarize and cut.
Class Method Details
.call(session:, provider:, settings: Compaction.new, &emit) ⇒ Object
Summarize and cut. Returns tokens_before:, tokens_after:, usage:, or nil when there is nothing worth compacting. Emits :compacting and :compaction when a block is given.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/mistri/compactor.rb', line 74 def call(session:, provider:, settings: Compaction.new, &emit) replay = session.replay cut = cut_index(replay, session, settings) return nil unless cut previous = session.last_compaction&.fetch("summary", nil) head = replay.take_while { |(_, index)| index.nil? || index < cut }.map(&:first) head.shift if previous # the synthetic summary rides in <previous-summary> return nil if head.empty? emit&.call(Event.new(type: :compacting)) tokens_before = Compaction.context_tokens(replay.map(&:first)) reply = summarize(provider, head, previous, settings.instructions) session.append("compaction", "summary" => reply.text, "kept_from" => cut, "tokens_before" => tokens_before) finish(session, reply, tokens_before, &emit) end |