Class: Insika::ToolOutputCompressor

Inherits:
Object
  • Object
show all
Defined in:
lib/insika/tool_output_compressor.rb

Overview

Mechanical (no-LLM) compression of tool output in the replayed transcript (A3/C3, hermes phase 1): identical tool results are stored ONCE — the first occurrence full — and every byte-identical repeat is replaced with a compact back-reference to it plus the original's first line. The cheap half of compaction: a search tool that returns the same catalog page over N turns currently pays for the full body N times, and that accumulation is what blows the budget first.

Deliberately crude on purpose: SHA-256 digest, so ONLY exact matches dedupe — a differing detail is kept, never "close enough" dropped. Deterministic per input (the same transcript compresses identically every turn, prompt-cache friendly). Never touches user/assistant content and never mutates the input (symbol or string keys are preserved per message).

Consumer: the history path of Context::Providers::Session, opt-in via AgentProfile#tool_output_compression. The LLM half of compaction (real summarization) remains F5 — decided with data, not by matrix.

Constant Summary collapse

MIN_LENGTH =

Below this a back-reference can never cost less than the body it replaces (an early bail; the REAL gate is the length check per repeat).

200
SUMMARY_LIMIT =

The mechanical "1-line summary": the original's first line, capped here (160 chars ≈ ~40 tokens — a bounded, informative stub).

160
BOILERPLATE =

The boilerplate deliberately carries NO positional pointer ("see above"): the budget cut evicts the OLDEST unit first, which is the original this back-reference points at — a "↑" that survives its target leaves a dangle in the model's context (C3). The summary is the content; it stands alone.

"[repeated tool output — byte-identical to an earlier result " \
"in this conversation; One-line summary: "

Class Method Summary collapse

Class Method Details

.compress_transcript(messages) ⇒ Object

[message, ...] with repeated tool results back-referenced. A non-tool message or a tool result that is not a String passes through untouched. A repeat is replaced ONLY when the back-reference is strictly shorter than the content it would replace (in the 200–~260-char band a back-reference is LONGER than the original — replacing there would GROW the transcript, C3).



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/insika/tool_output_compressor.rb', line 45

def compress_transcript(messages)
  seen = {}
  Array(messages).map do |m|
    content = text_of(m)
    next m unless content && content.length >= MIN_LENGTH

    digest = Digest::SHA256.hexdigest(content)
    if seen.key?(digest)
      replacement = back_reference(seen[digest][:summary])
      replacement.length < content.length ? replace_content(m, replacement) : m
    else
      seen[digest] = { summary: summarize(content) }
      m
    end
  end
end