Files
OmniRoute/open-sse/services/compression/adaptiveCompression/ladder.ts
Diego Rodrigues de Sa e Souza fd7e4c10e5 feat(compression): omniglyph engine (context-as-image, Fable 5 direct) — stack + single mode (#6556)
* feat(compression): dependência omniglyph (file:) + smoke de import

* feat(compression): engine omniglyph — contexto-como-imagem com gates fail-closed

* fix(compression): omniglyph adapter fail-open no transform (try/catch)

* feat(compression): registra omniglyph no registry e catálogo (single mode, stackPriority 90)

* feat(compression): modo único omniglyph (async), selecionar o modo é o enable

* feat(compression): plumbing supportsVision + providerTransport até os engines

* feat(compression): estimador de tokens image-aware — modo stacked mantém a saída do omniglyph

* docs(compression): corrige comentário do prefixo base64 no decode PNG (64 chars)

* feat(compression): registra omniglyph nas listas de modo/engine (db, combo, deriveDefaultPlan, mcp)

* feat(dashboard): dedicated OmniGlyph engine screen (context-as-image)

Adds a per-engine detail page at /dashboard/context/omniglyph, alongside the
other compression engines in the sidebar. Four sections: the economics (measured
savings), a REAL before→after (dense text vs the rendered PNG page, not a mockup),
the fail-closed gate flow, and the enable control wired to /api/settings/compression
(preview engine, off by default). Sidebar entry + i18n label across all locales.

* chore(compression): consume published omniglyph@^1.0.0 from the npm registry

Replaces the local file: dependency used during the preview phase — npm ci
now resolves omniglyph from the registry with integrity, unblocking CI.

* fix(compression): satisfy v3.8.47 quality gates for the omniglyph engine

- dependency-allowlist: approve omniglyph (own package, published from
  diegosouzapw/OmniGlyph; supply-chain review done by the maintainer)
- ladder maps (#6533 guard): rank omniglyph 80 (stackPriority 90, runs after
  every text engine) with expectedReductionFactor 0.35 (measured 0.23-0.33)
- drop the two explicit any casts in omniglyph tests (no-explicit-any is
  error-level in tests since #6218)

* chore(compression): rebaseline strategySelector for the omniglyph mode dispatch

+18 lines of cohesive dispatch/type wiring at the existing mode chokepoints
(sync no-op + async single-mode branch + providerTransport on the options
types) — not extractable without hiding the dispatch boundary, mirroring the
prior compression rebaselines. Also drops an unused eslint-disable directive
in image-aware-tokens.test.ts (warning-level red under --max-warnings 0).

* chore(quality): register inherited base tests in stryker tap.testFiles

masked-200-exhaustion-fallback-6427 and headroom-codex-quota-snapshot-6379
arrived via the base merge without their stryker registration —
check:mutation-test-coverage --strict requires covering tests to be listed.

* refactor(compression): keep omniglyph wiring under the complexity gate

- extract the async single-mode resolution to engines/omniglyphSingleMode.ts
  (runCompressionAsync was at complexity 17 after the mode branch; back <=15)
- split OmniglyphContextPageClient into section components (was 161 lines in
  one function; every function now under the 80-line cap)
- complexity baseline 2052->2053: the +1 is inherited base drift (the ratchet
  does not run on fast-path merges — same pattern as the v3.8.44/46
  rebaselines); this PR's own code is measured complexity-net-zero

* chore(quality): register 3 more inherited base tests in stryker tap.testFiles

route-guard-middleware-local-only, combo-diagnostics-trace and
idempotency-fusion-collision arrived via the latest base merge without their
stryker registration (fast-path merges skip check:mutation-test-coverage).

* chore(quality): cognitive-complexity baseline 883->884 (inherited base drift)

check:cognitive-complexity measures 884 identically on the pristine
origin/release/v3.8.47 tip and on this HEAD — the PR itself is
cognitive-net-zero (single-mode resolution extracted to its own module,
page client split into section components). Same inherited-drift pattern
as the v3.8.4x release rebaselines.

---------

Co-authored-by: diegosouzapw <diegosouzapw@devbox.local>
2026-07-08 07:56:44 -03:00

84 lines
4.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { LadderStage } from "./types.ts";
/**
* Default escalation ladder (design D-C2): cheapest/most-lossless → most aggressive.
* Ordered by the engine catalog's stackPriority. `ccr` and `llmlingua` are intentionally
* excluded from the AUTOMATIC ladder (ccr = retrieval markers, llmlingua = optional ONNX
* SLM tier wired through `ultra`); an operator can still add them via ladderOverride.
*/
export const DEFAULT_LADDER: LadderStage[] = [
{ engine: "session-dedup" }, // lossless cross-turn dedup (catalog pri 3)
{ engine: "rtk", intensity: "standard" }, // command-output filtering (pri 10)
{ engine: "headroom" }, // tabular JSON compaction (pri 15)
{ engine: "lite" }, // whitespace/format cleanup (pri 5, but cheap prose pass)
{ engine: "caveman", intensity: "full" }, // rule-based prose (pri 20)
{ engine: "aggressive" }, // summarize + age old turns (pri 30)
{ engine: "ultra" }, // heuristic token pruning + optional SLM (pri 40)
];
/**
* Aggressiveness rank used to know where a base plan sits so `floor` mode escalates
* BEYOND it (design §4.2). Keyed by engine id AND by the equivalent CompressionMode name
* ("standard" === caveman) so a base plan's `mode` string maps cleanly.
*
* Rescaled ×10 vs the original 7-entry scale (#6533) to make room for the novel catalog
* engines that ship in `open-sse/services/compression/engines/index.ts` but are not part
* of DEFAULT_LADDER: `ccr` and `llmlingua` are intentionally excluded from the AUTOMATIC
* ladder (see DEFAULT_LADDER doc comment) yet must still rank correctly when an operator
* adds them via `ladderOverride` — same for `ionizer`, `relevance`, `llm`, and
* `read-lifecycle`. Placement follows each engine's documented `stackPriority` in
* `engineCatalog.ts` / its own module header, interpolated onto the existing 7-tier scale
* (the `lite` exception — ranked after `headroom` despite a lower stackPriority — is a
* pre-existing, deliberate design call and is left untouched).
*/
const AGGRESSIVENESS: Record<string, number> = {
off: 0,
"session-dedup": 10, // stackPriority 3 — lossless cross-turn dedup
ccr: 15, // stackPriority 4 — reversible retrieval marker, only if it shrinks
rtk: 20, // stackPriority 10 — command-output filtering
ionizer: 25, // stackPriority 13 — tabular row sampling (lighter than headroom)
headroom: 30, // stackPriority 15 — tabular JSON compaction
lite: 40, // pri 5, but cheap prose pass (pre-existing reorder, kept as-is)
"read-lifecycle": 42, // stackPriority 5 (ties lite) — narrow-scope, opt-in, fully lossy
relevance: 45, // stackPriority 18 — extractive sentence scoring, opt-in
caveman: 50,
standard: 50, // mode-name alias for caveman
stacked: 50, // a derived/stacked base plan sits at the prose tier; floor escalates past it
aggressive: 60,
llmlingua: 65, // stackPriority 35 — semantic pruning (ONNX), after aggressive, before ultra/llm
llm: 68, // stackPriority 38 — full LLM-tier compressor, opt-in default-off
ultra: 70,
omniglyph: 80, // stackPriority 90 — context-as-image (lossy render), runs after every text engine
};
export function aggressivenessOf(engineOrMode: string): number {
return AGGRESSIVENESS[engineOrMode] ?? 0;
}
/**
* Cheap per-engine EXPECTED reduction factor (output/input). Used by the default injected
* estimator to model "apply this stage" WITHOUT a dry-run (design §9: no per-stage dry-run
* in the hot path). Conservative, monotonic with aggressiveness; never 0 (content preserved).
*/
const REDUCTION_FACTOR: Record<string, number> = {
"session-dedup": 0.95,
ccr: 0.9, // conservative: only replaces a block when the marker is shorter than it
rtk: 0.85,
ionizer: 0.83, // row sampling, lighter than headroom's full tabular compaction
headroom: 0.8,
lite: 0.92,
"read-lifecycle": 0.88, // scope-limited to stale/superseded Read tool-results
relevance: 0.75, // extractive sentence dropping
caveman: 0.7,
standard: 0.7,
aggressive: 0.55,
llmlingua: 0.5, // semantic pruning (ONNX)
llm: 0.45, // full LLM-tier compressor, stronger than llmlingua
ultra: 0.4,
omniglyph: 0.35, // measured 0.23-0.33 on converted blocks (254->84 tokens); 0.35 stays conservative
};
export function expectedReductionFactor(engine: string): number {
return REDUCTION_FACTOR[engine] ?? 0.9;
}