Skip to content

feat(engine): unify compaction under one Compactor abstraction; add summarizer + truncation; comprehensive stats - #2

Merged
OsherElhadad merged 1 commit into
mainfrom
feat/compactor-abstraction-summarize-truncate
Jun 25, 2026
Merged

feat(engine): unify compaction under one Compactor abstraction; add summarizer + truncation; comprehensive stats#2
OsherElhadad merged 1 commit into
mainfrom
feat/compactor-abstraction-summarize-truncate

Conversation

@OsherElhadad

@OsherElhadad OsherElhadad commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Unifies the pipeline under a single Compactor abstraction and adds two new compaction approaches, uniform model/credential handling, a self-caching-client lever, and comprehensive metrics — plus a real 10-task SWE-bench run.

Every compaction approach now implements one interface — engine.Compactor (conversation in → conversation out), name-registered and selected via compactors:. reduce, extract, summarize, truncate, cache are all Compactors; a new approach plugs in the same way (implement → Register → list by name).

What's included

  • Summarizer (internal/summarize): ReSum-style prompts ported from CE-Manager; replaces older turns with one <summary>, keeps the last keep_last verbatim, dropped span recoverable. Opt-in.
  • Truncation: naive keep-last-N baseline (no model), recoverable. Opt-in.
  • Extract fully decoupled from the reduce candidate flow — does its own large-output detection (reduce.SelectLLMCandidates) and runs before reduce.
  • Uniform model + credentials for every LLM compactor (config.ModelTransport + engine.ModelSpec): provider/model/auth/base, inline api_key or key_env, and source: config|incoming (reuse the proxied request's own model + credentials).
  • --reduce-cached-prefix: run the deterministic reducers + extractor on a self-caching client's cached prefix (e.g. Claude Code) instead of deferring to its cache.
  • Comprehensive /stats: per-session breakdown, a recent-per-call ring, and full latency distribution (p50/p95/p99/max/mean) at global + session scope; the per-call slog event carries the same metrics.
  • Naming purge: the upstream prototype name is gone from the runtime surface — markers («labcx:…», labcx_expand), /labcx/expand, x-labcx-bypass, LABCX_* env, the eval compose service; provenance comments reworded (only the ../winnow path reference to the prototype dir remains).
  • Docs: README / RUNNING / RESULTS + the swe-bench integration doc updated for the new abstraction, flags, stats, and the run below.

Validation

  • make fmt lint test build clean; new tests for the Compactor registry, summarize/truncate, model-spec incoming, modelBase prefixing, and the enriched aggregator.
  • Live: offline reducers up to −98%; Haiku extractor −57…−80% on structured fixtures; summarize + truncate live on Haiku.
  • SWE-bench (10 real tasks, Claude Code → lab-cx → gateway): −35.5% aggregate input tokens (4,405,821 → 2,840,296; 1,565,525 saved over 263 requests; −10.4…−51.8% per task), from the deterministic reducers (1,598 blocks) on the cached prefix. Caveat: arm64 Epoch bases (native Apple-Silicon runs) are best-effort for grading, so resolve status may understate accuracy; token reduction is architecture-independent.

Assisted-By: Claude Opus 4.8

…ummarizer + truncation; comprehensive stats

Every compaction approach now implements one interface, engine.Compactor
(conversation in -> conversation out), name-registered and selected via
`compactors:` config. reduce, extract, summarize, truncate and cache are all
Compactors; a new approach plugs in the same way (implement + Register + list).

- Summarizer (internal/summarize): ReSum-style prompts ported from CE-Manager;
  replaces older turns with one <summary>, keeps the last keep_last verbatim,
  dropped span recoverable. Opt-in.
- Truncation: naive keep-last-N baseline (no model), recoverable. Opt-in.
- Extract fully decoupled from the reduce candidate flow: it does its own
  large-output detection (reduce.SelectLLMCandidates) and runs before reduce.
- Uniform model + credentials for every LLM compactor (config.ModelTransport +
  engine.ModelSpec): provider/model/auth/base, inline api_key or key_env, and
  source=config|incoming (reuse the proxied request's own model + credentials).
- --reduce-cached-prefix: run the deterministic reducers + extractor on a
  self-caching client's cached prefix (e.g. Claude Code) instead of deferring.
- Observability: /stats now exposes per-session breakdown, a recent-per-call
  ring, and full latency distribution (p50/p95/p99/max/mean) at global + session
  scope; the per-call slog event carries the same metrics.
- Naming: purge the upstream prototype name from the runtime surface — markers
  («labcx:..», labcx_expand), /labcx/expand, x-labcx-bypass, LABCX_* env, the
  eval compose service; provenance comments reworded.
- Docs: README/RUNNING/RESULTS + swe-bench integration updated with the new
  abstraction, flags, stats, and a real 10-task SWE-bench run (-35.5% aggregate
  input tokens via the deterministic reducers on Claude Code's cached prefix).

Assisted-By: Claude Opus 4.8
Signed-off-by: Osher-Elhadad <Osher.Elhadad@ibm.com>
@OsherElhadad
OsherElhadad merged commit 0919622 into main Jun 25, 2026
3 of 4 checks passed
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