feat(compression): per-model/endpoint compression exclusion filter (#8034) (#8064)

* feat(compression): per-model/endpoint compression exclusion filter (#8034)

* chore(quality): rebaseline compression.ts own-growth 845->850 (#8034 exclusions persistence)

---------

Co-authored-by: Probe Test <probe@example.com>
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-22 16:15:57 -03:00
committed by GitHub
parent f23d7770ec
commit dbdc7daade
17 changed files with 593 additions and 3 deletions

View File

@@ -0,0 +1 @@
- Add a per-model/endpoint compression exclusion filter: name model ids or `provider/model` patterns (`*` wildcard) that must never be compressed, checked before any engine runs so the request passes through byte-identical; configurable from a new Dashboard → Compression → Exclusions tab (#8034)

View File

@@ -183,7 +183,8 @@
"open-sse/handlers/sseParser.ts": 830,
"open-sse/handlers/videoGeneration.ts": 1275,
"_rebaseline_2026_07_22_8010_codex_responses_engine": "PR #8010 (@JxnLexn) own growth: open-sse/mcp-server/schemas/tools.ts 1497->1505 (+8 = threading the new \"codex-responses\" literal into the compressionConfigureInput strategy/autoTriggerMode Zod enums and setCompressionEngineInput engine enum, mirroring the existing rtk/omniglyph enum entries; no new tool). open-sse/services/compression/strategySelector.ts 1043->1054 (+11 = one new `if (mode === \"codex-responses\")` dispatch branch in runCompression that delegates 100% to the new codexResponsesEngine.apply, mirroring the existing rtk single-mode dispatch, plus threading config.codexResponsesConfig.preserveToolNames into the shared adaptBodyForCompression call at the 3 existing call sites). src/lib/db/compression.ts (untracked, new-file cap 800) 794->845 (+51 = normalizeCodexResponsesConfig, mirroring the existing normalizeRtkConfig normalizer, plus registering \"codex-responses\" in the COMPRESSION_MODES/STACKED_PIPELINE_ENGINE_IDS/SINGLE_MODE_ENGINE sets and the getCompressionSettings load/save switch) — added to the baseline at its current size. All three are cohesive dispatch/normalizer wiring at existing chokepoints (mirroring the prior compression-mode rebaselines #6534/#6556), not extractable without hiding the mode-dispatch boundary. Covered by tests/unit/compression/codex-responses.test.ts (6) + omniglyph-registries.test.ts/types.test.ts (22, updated for the new mode).",
"src/lib/db/compression.ts": 845,
"_rebaseline_2026_07_22_8034_compression_exclusions_persistence": "#8034 (compression exclusions) own growth: src/lib/db/compression.ts 845->850 (+5 = threading the new compressionExclusions field through the existing getCompressionSettings/saveCompressionSettings load/save switch over the shared key_value compression namespace — no new table, no raw SQL). Mirrors the prior compression-field rebaselines (#8010 codex-responses normalizer at the same chokepoint); the load/save switch is a single dispatch boundary, not extractable without hiding it. Covered by the PR's 8 node:test + 3 vitest cases.",
"src/lib/db/compression.ts": 850,
"open-sse/mcp-server/schemas/tools.ts": 1505,
"open-sse/mcp-server/server.ts": 1555,
"open-sse/mcp-server/tools/advancedTools.ts": 1120,
@@ -310,7 +311,9 @@
"_rebaseline_2026_07_19_7787_ic2_localdb_reexports": "PR #7787 (IC2 raw connections cache + lazy-decrypt) own growth: localDb.ts 805->807 (gate units, +2). localDb.ts is the re-export-only layer (hard rule #2 — no logic); the PR adds 4 new db/readCache re-exports (touchConnectionLastUsed, getCachedRawProviderConnections, getCachedProviderConnectionById, getCachedProviderNodes) required by existing barrel importers. Irreducible for a re-export list; frozen so it can only shrink.",
"_rebaseline_2026_07_20_7819_autocandidateoverrides_reexport": "PR for #7819 (Level 1+2: read-only auto/* candidate transparency + per-API-key exclusions) own growth: localDb.ts 807->808 (+1). Adds a single `export * from \"./db/autoCandidateOverrides\"` barrel re-export (hard rule #2 — no logic) for the new DB module backing per-apiKey candidate exclusions. Irreducible for a re-export list; frozen so it can only shrink.",
"src/lib/localDb.ts": 808,
"_rebaseline_2026_07_12_v3847_mergeprs_tail": "v3.8.47 /merge-prs tail (owner-approved): src/lib/localDb.ts NEW>800 (799->805, +6 re-exports countFreeProxies + recordFreeProxySyncErrors/clearFreeProxySyncErrors/getFreeProxySyncErrors + FreeProxySyncErrors type for #6909 free-pool relay-repair; re-export-only per Hard Rule #2, not extractable)."
"_rebaseline_2026_07_12_v3847_mergeprs_tail": "v3.8.47 /merge-prs tail (owner-approved): src/lib/localDb.ts NEW>800 (799->805, +6 re-exports countFreeProxies + recordFreeProxySyncErrors/clearFreeProxySyncErrors/getFreeProxySyncErrors + FreeProxySyncErrors type for #6909 free-pool relay-repair; re-export-only per Hard Rule #2, not extractable).",
"_rebaseline_2026_07_21_8034_compression_exclusions_sidebar": "#8034 (compression exclusions dashboard tab) own growth: sections.ts 796->806 (+10, one new COMPRESSION_CONTEXT_GROUP sidebar item linking /dashboard/compression/exclusions). The file was already 796/800 before this PR (organic growth from prior sidebar entries), so a single new nav item pushed it 6 lines over cap. Freezing at 806 (cannot grow further); the sidebar item array is data, not extractable logic.",
"src/shared/constants/sidebarVisibility/sections.ts": 806
},
"testCap": 800,
"testFrozen": {

View File

@@ -313,6 +313,38 @@ Compression exposes five MCP tools:
| `omniroute_list_compression_combos` | `read:compression` | List compression combos |
| `omniroute_compression_combo_stats` | `read:compression` | Read combo/engine analytics |
## Scope & exclusions
**Embeddings are never compressed.** `open-sse/handlers/embeddings.ts` never calls any
compression engine — the request/response bodies pass straight to the executor untouched.
This is structural today (embeddings and chat completions are disjoint handlers), not a
runtime check, but it means the vector-distortion concern in #8034 has no exposure surface
in the embeddings path.
**Per-model/endpoint exclusion filter (#8034).** For chat completions, an operator can name
model ids / `provider/model` targets that must never be compressed — a guardrail useful if
compression is ever wired closer to an embeddings-adjacent path later, and generally useful
for any model whose exact byte-for-byte prompt matters (deterministic evals, cache-sensitive
prefixes, etc.).
- Settings field: `exclusions?: string[]` on the global compression config
(`GET`/`PUT /api/settings/compression`), persisted via the existing `key_value` compression
namespace (`src/lib/db/compression.ts`) — no new table.
- Dashboard tab: **Dashboard → Compression → Exclusions**
(`/dashboard/compression/exclusions`).
- Pattern syntax: `*` is the only wildcard. Every other regex metacharacter in a pattern is
escaped before matching, so `gpt-5.6` matches the literal string only, never `gpt-5x6`
(ReDoS-safe, bounded, no nested quantifiers). Patterns match case-insensitively against
both the bare model id and the `provider/model` composite — `gpt-5-6`, `openai/gpt-5-6`,
and `openai/*` all work, and `*` alone excludes every model.
- Matching: `isCompressionExcluded()` / `normalizeCompressionExclusions()` in
`open-sse/services/compression/exclusions.ts`. `chatCore.ts` checks the excluded target
right after resolving compression settings, **before any engine runs**, and treats a match
exactly like compression being globally disabled — the request body is provably
byte-identical. The skip is recorded via `writeCompressionSkip(..., "excluded")` for
analytics visibility.
- Default (empty/absent list): identical to pre-#8034 behavior — nothing is excluded.
## Known limitations
- **LLMLingua-2 (SLM) requires co-located optional deps.** The worker only runs in a

View File

@@ -206,6 +206,7 @@ import {
mergeResponseToolNameMap,
} from "./chatCore/passthroughToolNames.ts";
import { resolveCompressionSettings } from "./chatCore/compressionSettings.ts";
import { isCompressionExcluded } from "../services/compression/exclusions.ts";
import {
isBuiltinStackedPipeline,
isStackedCompressionCombo,
@@ -1069,8 +1070,39 @@ export async function handleChatCore({
let estimatedTokens = estimateTokens(allMessages);
const compressionSettingsResult = await resolveCompressionSettings(log);
const compressionSettings: CompressionConfig | null = compressionSettingsResult.settings;
const promptCompressionEnabled = compressionSettingsResult.enabled;
// #8034 — operator-named model/endpoint exclusions bypass the whole pipeline, exactly
// like compression being globally disabled, so the body is provably byte-identical.
const compressionExcluded = isCompressionExcluded(
{ provider, model: effectiveModel },
compressionSettings?.exclusions
);
let promptCompressionEnabled = compressionSettingsResult.enabled && !compressionExcluded;
contextEditingEnabled = compressionSettingsResult.contextEditingEnabled;
if (compressionExcluded) {
void writeCompressionSkip(
{
stats: {
originalTokens: estimatedTokens,
compressedTokens: estimatedTokens,
savingsPercent: 0,
techniquesUsed: [],
mode: "off",
timestamp: Date.now(),
},
provider,
effectiveModel,
effectiveServiceTier,
comboName,
mode: "off",
compressionComboId: null,
skillRequestId,
cavemanOutputModeApplied: false,
cavemanOutputModeIntensity: null,
log,
},
"excluded"
);
}
// --- Modular Compression Pipeline (Phase 1 Lite + Phase 2 Standard/Caveman + Phase 3 Aggressive) ---
// Runs BEFORE the existing reactive compressContext() to proactively reduce tokens.
@@ -1095,6 +1127,7 @@ export async function handleChatCore({
preserveSystemPrompt: true,
comboOverrides: {},
};
if (compressionExcluded) config = { ...config, enabled: false };
if (!promptCompressionEnabled || !compressionSettings) {
log?.debug?.("COMPRESSION", "Prompt compression disabled or unavailable");
}

View File

@@ -0,0 +1,73 @@
/**
* Compression Exclusions (#8034) — per-model/endpoint exclusion filter.
*
* Lets an operator name model ids / `provider/model` targets that must NEVER be
* compressed. Matching targets bypass the whole compression pipeline and pass
* through byte-identical (see `chatCore.ts` — the check runs before any engine
* executes). Default (empty/absent list) preserves pre-existing behavior exactly.
*
* Pattern syntax: `*` is the only wildcard. Every other regex metacharacter is
* escaped before the pattern is compiled, so a pattern like `gpt-5.6` matches the
* literal string only (not `gpt-5x6`) — never build a regex from raw operator
* input without escaping (ReDoS convention, see CLAUDE.md).
*/
const MAX_EXCLUSIONS = 200;
export type CompressionExclusions = string[];
/** Escape every regex metacharacter except `*`, which the caller re-inserts as `.*`. */
function escapeExceptWildcard(pattern: string): string {
return pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
}
/** Compile a single normalized (already lowercased/trimmed) pattern into a bounded regex. */
function compilePattern(pattern: string): RegExp {
return new RegExp(`^${escapeExceptWildcard(pattern)}$`);
}
/**
* Normalizes a raw settings value into a bounded list of lowercase, trimmed, deduped
* patterns. Drops non-strings and blanks. Caps length so a pathological settings value
* cannot make the per-request check expensive.
*/
export function normalizeCompressionExclusions(raw: unknown): CompressionExclusions {
if (!Array.isArray(raw)) return [];
const seen = new Set<string>();
const result: CompressionExclusions = [];
for (const entry of raw) {
if (typeof entry !== "string") continue;
const trimmed = entry.trim().toLowerCase();
if (!trimmed || seen.has(trimmed)) continue;
seen.add(trimmed);
result.push(trimmed);
if (result.length >= MAX_EXCLUSIONS) break;
}
return result;
}
/**
* True when the given target matches any configured exclusion pattern. Matches
* case-insensitively against both the bare model id and the `provider/model`
* composite, so `gpt-5-6`, `openai/gpt-5-6` and `openai/*` all work.
*/
export function isCompressionExcluded(
target: { provider?: string | null; model?: string | null },
exclusions: CompressionExclusions | undefined
): boolean {
if (!exclusions || exclusions.length === 0) return false;
const model = (target.model ?? "").trim().toLowerCase();
const provider = (target.provider ?? "").trim().toLowerCase();
if (!model && !provider) return false;
const composite = provider && model ? `${provider}/${model}` : "";
for (const pattern of exclusions) {
if (!pattern) continue;
const regex = compilePattern(pattern);
if (model && regex.test(model)) return true;
if (composite && regex.test(composite)) return true;
}
return false;
}

View File

@@ -266,6 +266,13 @@ export interface CompressionConfig {
ultraSlmPrewarm?: boolean;
/** Opt-in result memoization for deterministic engines only (default off). */
memoizeCompressionResults?: boolean;
/**
* #8034 — per-model/endpoint compression exclusion filter. Patterns are matched
* case-insensitively against both the bare model id and the `provider/model`
* composite (`*` is the only wildcard). Absent/empty → no exclusions, default
* behavior unchanged. See `open-sse/services/compression/exclusions.ts`.
*/
exclusions?: string[];
}
export interface CompressionStats {

View File

@@ -0,0 +1,105 @@
"use client";
// ExclusionsPanel (#8034) — per-model/endpoint compression exclusion filter.
//
// Lets the operator name model ids / `provider/model` patterns that must never be
// compressed (`*` is the only wildcard). Persisted via the existing
// GET/PUT /api/settings/compression endpoint (`exclusions` field), read/normalized by
// `normalizeCompressionExclusions` (open-sse/services/compression/exclusions.ts).
// Default (empty list) preserves pre-existing behavior exactly.
import { useEffect, useState } from "react";
import { useTranslations } from "next-intl";
import Card from "@/shared/components/Card";
import Button from "@/shared/components/Button";
import Textarea from "@/shared/components/Textarea";
function parsePatterns(raw: string): string[] {
return raw
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0);
}
export default function ExclusionsPanel() {
const t = useTranslations("settings");
const [raw, setRaw] = useState("");
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [status, setStatus] = useState<"" | "saved" | "error">("");
useEffect(() => {
fetch("/api/settings/compression")
.then((r) => (r.ok ? r.json() : null))
.then((data: { exclusions?: string[] } | null) => {
if (data && Array.isArray(data.exclusions)) {
setRaw(data.exclusions.join("\n"));
}
})
.catch(() => {})
.finally(() => setLoading(false));
}, []);
const patterns = parsePatterns(raw);
const save = async () => {
setSaving(true);
setStatus("");
try {
const res = await fetch("/api/settings/compression", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ exclusions: patterns }),
});
setStatus(res.ok ? "saved" : "error");
if (res.ok) setTimeout(() => setStatus(""), 2000);
} catch {
setStatus("error");
} finally {
setSaving(false);
}
};
return (
<Card
title={t("compressionExclusionsTitle")}
subtitle={t("compressionExclusionsDesc")}
data-testid="compression-exclusions-panel"
>
<div className="flex flex-col gap-3">
<Textarea
rows={8}
value={raw}
disabled={loading || saving}
placeholder={t("compressionExclusionsPlaceholder")}
onChange={(e) => setRaw(e.target.value)}
data-testid="compression-exclusions-textarea"
/>
<div className="flex items-center justify-between gap-3">
<span className="text-xs text-text-muted" data-testid="compression-exclusions-count">
{patterns.length === 0
? t("compressionExclusionsEmpty")
: t("compressionExclusionsCount", { count: patterns.length })}
</span>
<div className="flex items-center gap-2">
{status === "saved" && (
<span className="text-xs text-emerald-600 dark:text-emerald-400">
{t("compressionExclusionsSaved")}
</span>
)}
<Button
size="sm"
variant="primary"
loading={saving}
disabled={loading || saving}
onClick={save}
data-testid="compression-exclusions-save"
>
{t("compressionExclusionsSave")}
</Button>
</div>
</div>
</div>
</Card>
);
}

View File

@@ -0,0 +1,11 @@
"use client";
import ExclusionsPanel from "./ExclusionsPanel";
export default function CompressionExclusionsPage() {
return (
<div className="flex flex-col gap-4 p-4">
<ExclusionsPanel />
</div>
);
}

View File

@@ -1050,6 +1050,7 @@
"combosLive": "Combo Studio",
"combosLiveSubtitle": "Live routing cascade",
"compressionStudio": "Compression Studio",
"compressionExclusions": "Exclusions",
"contextSettingsSubtitle": "Global defaults",
"contextHeadroomSubtitle": "Tabular compaction",
"contextSessionDedupSubtitle": "Cross-turn deduplication",
@@ -1060,6 +1061,7 @@
"contextUltraSubtitle": "Heuristic pruning",
"contextOmniglyphSubtitle": "Context as images",
"compressionStudioSubtitle": "Live engine cascade",
"compressionExclusionsSubtitle": "Per-model/endpoint bypass",
"chaosConfigSubtitle": "Multi-model parallel execution",
"routingSection": "Routing",
"protocolsSection": "Protocols",
@@ -6876,6 +6878,13 @@
"compressionPreserveSystemNever": "Never",
"compressionLiveZoneTitle": "Cache-aligned Live Zone",
"compressionLiveZoneDesc": "Keep the compressed conversation prefix stable and process only newly appended items.",
"compressionExclusionsTitle": "Compression Exclusions",
"compressionExclusionsDesc": "Model ids or provider/model patterns that must never be compressed. `*` is the only wildcard (e.g. `openai/*`, `*embedding*`). A matching request passes through byte-identical — no compression engine runs.",
"compressionExclusionsPlaceholder": "One pattern per line, e.g.\nopenai/text-embedding-3-large\nanthropic/*",
"compressionExclusionsSave": "Save",
"compressionExclusionsSaved": "Saved",
"compressionExclusionsCount": "{count, plural, one {# exclusion} other {# exclusions}} configured",
"compressionExclusionsEmpty": "No exclusions configured — every model/endpoint is eligible for compression (default behavior).",
"compressionCavemanConfig": "Caveman Engine Configuration",
"compressionCavemanConfigDesc": "Fine-tune the rule-based compression engine",
"compressionCavemanPanelHint": "Its on/off and level are set in the panel:",

View File

@@ -1050,6 +1050,8 @@
"combosLive": "Combo Studio",
"combosLiveSubtitle": "Cascata de roteamento em tempo real",
"compressionStudio": "Compression Studio",
"compressionExclusions": "Exclusões",
"compressionExclusionsSubtitle": "Bypass por modelo/endpoint",
"contextSettingsSubtitle": "Padrões globais",
"contextHeadroomSubtitle": "Compactação tabular",
"contextSessionDedupSubtitle": "Deduplicação entre turnos",
@@ -6874,6 +6876,13 @@
"compressionPreserveSystemNever": "Nunca",
"compressionLiveZoneTitle": "Zona ativa alinhada ao cache",
"compressionLiveZoneDesc": "Mantém estável o prefixo comprimido da conversa e processa apenas os itens recém-adicionados.",
"compressionExclusionsTitle": "Exclusões de Compressão",
"compressionExclusionsDesc": "Ids de modelo ou padrões provider/model que nunca devem ser comprimidos. `*` é o único curinga (ex.: `openai/*`, `*embedding*`). Uma requisição correspondente passa byte-a-byte idêntica — nenhum engine de compressão é executado.",
"compressionExclusionsPlaceholder": "Um padrão por linha, ex.:\nopenai/text-embedding-3-large\nanthropic/*",
"compressionExclusionsSave": "Salvar",
"compressionExclusionsSaved": "Salvo",
"compressionExclusionsCount": "{count, plural, one {# exclusão configurada} other {# exclusões configuradas}}",
"compressionExclusionsEmpty": "Nenhuma exclusão configurada — todo modelo/endpoint é elegível para compressão (comportamento padrão).",
"compressionCavemanConfig": "Caveman Engine Configuration",
"compressionCavemanConfigDesc": "Fine-tune the rule-based compression engine",
"compressionCavemanPanelHint": "Ativado/desativado e o nível são definidos no painel:",

View File

@@ -1050,6 +1050,7 @@
"combosLive": "Combo Studio",
"combosLiveSubtitle": "Chuỗi định tuyến trực tiếp",
"compressionStudio": "Compression Studio",
"compressionExclusions": "Loại trừ",
"contextSettingsSubtitle": "Mặc định toàn cục",
"contextHeadroomSubtitle": "Nén dạng bảng",
"contextSessionDedupSubtitle": "Khử trùng lặp giữa các lượt",
@@ -1060,6 +1061,7 @@
"contextUltraSubtitle": "Lược bỏ theo kinh nghiệm",
"contextOmniglyphSubtitle": "Ngữ cảnh dưới dạng hình ảnh",
"compressionStudioSubtitle": "Chuỗi bộ máy trực tiếp",
"compressionExclusionsSubtitle": "Bỏ qua theo từng model/endpoint",
"chaosConfigSubtitle": "Thực thi song song nhiều mô hình",
"routingSection": "Định tuyến",
"protocolsSection": "Giao thức",
@@ -6866,6 +6868,13 @@
"compressionPreserveSystemNever": "Không bao giờ",
"compressionLiveZoneTitle": "Vùng hoạt động theo bộ nhớ đệm",
"compressionLiveZoneDesc": "Giữ ổn định tiền tố hội thoại đã nén và chỉ xử lý các mục mới được thêm vào.",
"compressionExclusionsTitle": "Loại trừ khỏi Nén",
"compressionExclusionsDesc": "Id model hoặc mẫu provider/model không bao giờ được nén. `*` là ký tự đại diện duy nhất (vd. `openai/*`, `*embedding*`). Yêu cầu khớp mẫu sẽ đi qua nguyên vẹn từng byte — không engine nén nào chạy.",
"compressionExclusionsPlaceholder": "Mỗi dòng một mẫu, vd.:\nopenai/text-embedding-3-large\nanthropic/*",
"compressionExclusionsSave": "Lưu",
"compressionExclusionsSaved": "Đã lưu",
"compressionExclusionsCount": "{count, plural, one {# loại trừ} other {# loại trừ}} đã cấu hình",
"compressionExclusionsEmpty": "Chưa cấu hình loại trừ nào — mọi model/endpoint đều đủ điều kiện để nén (hành vi mặc định).",
"compressionCavemanConfig": "Cấu hình động cơ Caveman",
"compressionCavemanConfigDesc": "Tinh chỉnh động cơ nén dựa trên quy tắc",
"compressionCavemanPanelHint": "Trạng thái bật/tắt và cấp độ của nó được thiết lập trong bảng điều khiển:",

View File

@@ -30,6 +30,7 @@ import {
type RtkConfig,
type UltraConfig,
} from "@omniroute/open-sse/services/compression/types.ts";
import { normalizeCompressionExclusions } from "@omniroute/open-sse/services/compression/exclusions.ts";
import { DEFAULT_CONTEXT_BUDGET } from "@omniroute/open-sse/services/compression/adaptiveCompression/types.ts";
import { normalizeContextBudgetConfig } from "./compressionContextBudget";
import {
@@ -604,6 +605,7 @@ export async function getCompressionSettings(): Promise<CompressionConfig> {
liveZone: { enabled: false },
engines: {},
activeComboId: null,
exclusions: [],
};
// Tracks whether a usable stored `engines` row was found. When absent (pre-migration-102 install)
@@ -729,6 +731,9 @@ export async function getCompressionSettings(): Promise<CompressionConfig> {
case "ultraSlmPrewarm":
config.ultraSlmPrewarm = parsed === true;
break;
case "exclusions":
config.exclusions = normalizeCompressionExclusions(parsed);
break;
}
}

View File

@@ -197,6 +197,15 @@ export const COMPRESSION_CONTEXT_GROUP: SidebarItemGroup = {
subtitleFallback: "Live engine cascade",
icon: "monitoring",
},
{
id: "compression-exclusions",
href: "/dashboard/compression/exclusions",
i18nKey: "compressionExclusions",
labelFallback: "Exclusions",
subtitleKey: "compressionExclusionsSubtitle",
subtitleFallback: "Per-model/endpoint bypass",
icon: "block",
},
],
};

View File

@@ -23,6 +23,7 @@ export const HIDEABLE_SIDEBAR_ITEM_IDS = [
"context-ultra",
"context-omniglyph",
"compression-studio",
"compression-exclusions",
// OmniProxy > Tools
"cli-code",
"cli-agents",

View File

@@ -343,6 +343,10 @@ export const compressionSettingsUpdateSchema = z
activeComboId: z.string().nullable().optional(),
ultraEngine: z.enum(["heuristic", "slm"]).optional(),
ultraSlmPrewarm: z.boolean().optional(),
// #8034 — per-model/endpoint compression exclusion patterns. Bounded length/size so a
// pathological PUT body can't blow up the per-request matcher; normalizeCompressionExclusions
// (open-sse/services/compression/exclusions.ts) is the authoritative post-read normalizer.
exclusions: z.array(z.string().max(200)).max(200).optional(),
})
.strict();

View File

@@ -0,0 +1,126 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
isCompressionExcluded,
normalizeCompressionExclusions,
} from "../../open-sse/services/compression/exclusions.ts";
import { applyStackedCompression } from "../../open-sse/services/compression/strategySelector.ts";
import type { CompressionPipelineStep } from "../../open-sse/services/compression/types.ts";
// #8034 — per-model/endpoint compression exclusion filter.
test("isCompressionExcluded: excluded model is true, non-excluded is false", () => {
const exclusions = normalizeCompressionExclusions(["text-embedding-3-large"]);
assert.equal(isCompressionExcluded({ model: "text-embedding-3-large" }, exclusions), true);
assert.equal(isCompressionExcluded({ model: "gpt-5-6" }, exclusions), false);
});
test("isCompressionExcluded: provider/model composite and bare-model patterns both match", () => {
const composite = normalizeCompressionExclusions(["openai/text-embedding-3-large"]);
assert.equal(
isCompressionExcluded({ provider: "openai", model: "text-embedding-3-large" }, composite),
true
);
// Bare model alone (no provider given) does not match a provider-qualified pattern.
assert.equal(isCompressionExcluded({ model: "text-embedding-3-large" }, composite), false);
const bare = normalizeCompressionExclusions(["text-embedding-3-large"]);
assert.equal(
isCompressionExcluded({ provider: "openai", model: "text-embedding-3-large" }, bare),
true
);
});
test("isCompressionExcluded: provider/* wildcard matches every model of that provider; * excludes everything", () => {
const providerWildcard = normalizeCompressionExclusions(["openai/*"]);
assert.equal(
isCompressionExcluded({ provider: "openai", model: "gpt-5-6" }, providerWildcard),
true
);
assert.equal(
isCompressionExcluded({ provider: "anthropic", model: "claude-opus" }, providerWildcard),
false
);
const everything = normalizeCompressionExclusions(["*"]);
assert.equal(isCompressionExcluded({ provider: "anthropic", model: "claude-opus" }, everything), true);
assert.equal(isCompressionExcluded({ model: "anything" }, everything), true);
});
test("isCompressionExcluded: case-insensitive match", () => {
const exclusions = normalizeCompressionExclusions(["OpenAI/GPT-5-6"]);
assert.equal(
isCompressionExcluded({ provider: "openai", model: "gpt-5-6" }, exclusions),
true
);
assert.equal(
isCompressionExcluded({ provider: "OPENAI", model: "GPT-5-6" }, exclusions),
true
);
});
test("isCompressionExcluded: empty / absent / malformed exclusions => false (default unchanged)", () => {
assert.equal(isCompressionExcluded({ model: "gpt-5-6" }, undefined), false);
assert.equal(isCompressionExcluded({ model: "gpt-5-6" }, []), false);
// Malformed raw input normalizes to an empty list.
assert.equal(
isCompressionExcluded({ model: "gpt-5-6" }, normalizeCompressionExclusions("not-an-array")),
false
);
assert.equal(
isCompressionExcluded({ model: "gpt-5-6" }, normalizeCompressionExclusions(null)),
false
);
});
test("isCompressionExcluded: regex metacharacters in a pattern are escaped", () => {
const exclusions = normalizeCompressionExclusions(["gpt-5.6"]);
assert.equal(isCompressionExcluded({ model: "gpt-5.6" }, exclusions), true);
// A literal `.` must not behave as "any character" — gpt-5x6 must NOT match.
assert.equal(isCompressionExcluded({ model: "gpt-5x6" }, exclusions), false);
});
test("normalizeCompressionExclusions: drops non-strings and dedupes", () => {
const result = normalizeCompressionExclusions([
"gpt-5-6",
"GPT-5-6",
" gpt-5-6 ",
42,
null,
undefined,
{ not: "a string" },
"claude-opus",
]);
assert.deepEqual(result, ["gpt-5-6", "claude-opus"]);
});
test("behavior: excluded target passes through byte-identical; non-excluded still compresses", () => {
const pipeline: CompressionPipelineStep[] = [{ engine: "caveman", intensity: "full" }];
const body = {
messages: [
{
role: "user",
content:
"I would like to please politely and kindly ask you a question if that is okay with you.",
},
],
};
const exclusions = normalizeCompressionExclusions(["openai/text-embedding-3-large"]);
// Excluded target: the caller must skip the whole pipeline before calling into it — this
// assertion proves the gate condition itself, not applyStackedCompression's own no-op path.
const excludedTarget = { provider: "openai", model: "text-embedding-3-large" };
assert.equal(isCompressionExcluded(excludedTarget, exclusions), true);
const passthroughBody = JSON.parse(JSON.stringify(body));
assert.deepEqual(passthroughBody, body);
// Non-excluded target: the pipeline is not gated and still compresses (savings observed).
const nonExcludedTarget = { provider: "openai", model: "gpt-5-6" };
assert.equal(isCompressionExcluded(nonExcludedTarget, exclusions), false);
const result = applyStackedCompression(JSON.parse(JSON.stringify(body)), pipeline, {
preserveSystemPrompt: false,
});
assert.equal(result.compressed, true);
assert.notEqual(JSON.stringify(result.body), JSON.stringify(body));
});

View File

@@ -0,0 +1,153 @@
// @vitest-environment jsdom
import React, { act } from "react";
import { createRoot } from "react-dom/client";
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
// #8034 — dashboard tab for the per-model/endpoint compression exclusion filter.
vi.mock("next-intl", () => ({
useTranslations: () => (key: string) => key,
useLocale: () => "en",
}));
const containers: HTMLElement[] = [];
const roots: Array<{ unmount: () => void }> = [];
function mountInContainer(ui: React.ReactElement): HTMLElement {
const container = document.createElement("div");
document.body.appendChild(container);
containers.push(container);
const root = createRoot(container);
roots.push(root);
act(() => {
root.render(ui);
});
return container;
}
beforeEach(() => {
(
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
});
afterEach(async () => {
vi.restoreAllMocks();
await act(async () => {
while (roots.length > 0) {
roots.pop()?.unmount();
}
});
for (let i = 0; i < 10; i++) {
await Promise.resolve();
}
while (containers.length > 0) {
containers.pop()?.remove();
}
document.body.innerHTML = "";
});
function setupFetchMock(exclusions: string[] = []) {
vi.spyOn(globalThis, "fetch").mockImplementation(async (input: RequestInfo | URL, init) => {
const url = input.toString();
if (url.includes("/api/settings/compression")) {
if (init?.method === "PUT") {
return new Response(JSON.stringify({ exclusions }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
return new Response(JSON.stringify({ exclusions }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
return new Response(JSON.stringify({}), { status: 404 });
});
}
describe("CompressionExclusionsPage", () => {
it("mounts, loads existing exclusions, and renders the panel", async () => {
setupFetchMock(["openai/text-embedding-3-large"]);
const { default: CompressionExclusionsPage } = await import(
"../../../src/app/(dashboard)/dashboard/compression/exclusions/page"
);
let container!: HTMLElement;
await act(async () => {
container = mountInContainer(<CompressionExclusionsPage />);
});
await act(async () => {
await Promise.resolve();
});
expect(container).toBeTruthy();
const textarea = container.querySelector(
'[data-testid="compression-exclusions-textarea"]'
) as HTMLTextAreaElement | null;
expect(textarea).toBeTruthy();
expect(textarea?.value).toContain("openai/text-embedding-3-large");
});
it("saves edited patterns via PUT /api/settings/compression", async () => {
setupFetchMock([]);
const { default: CompressionExclusionsPage } = await import(
"../../../src/app/(dashboard)/dashboard/compression/exclusions/page"
);
let container!: HTMLElement;
await act(async () => {
container = mountInContainer(<CompressionExclusionsPage />);
});
await act(async () => {
await Promise.resolve();
});
const textarea = container.querySelector(
'[data-testid="compression-exclusions-textarea"]'
) as HTMLTextAreaElement;
const nativeSetter = Object.getOwnPropertyDescriptor(
window.HTMLTextAreaElement.prototype,
"value"
)?.set;
await act(async () => {
nativeSetter?.call(textarea, "anthropic/*\ngpt-5-6");
textarea.dispatchEvent(new Event("input", { bubbles: true }));
});
const saveButton = container.querySelector(
'[data-testid="compression-exclusions-save"]'
) as HTMLButtonElement;
await act(async () => {
saveButton.click();
await Promise.resolve();
await Promise.resolve();
});
const putCall = (globalThis.fetch as unknown as { mock: { calls: unknown[][] } }).mock.calls.find(
(call) => (call[1] as RequestInit | undefined)?.method === "PUT"
);
expect(putCall).toBeTruthy();
const body = JSON.parse((putCall?.[1] as RequestInit).body as string);
expect(body.exclusions).toEqual(["anthropic/*", "gpt-5-6"]);
});
it("does not crash when fetch fails (fail-soft)", async () => {
vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("Network error"));
const { default: CompressionExclusionsPage } = await import(
"../../../src/app/(dashboard)/dashboard/compression/exclusions/page"
);
let container!: HTMLElement;
await act(async () => {
container = mountInContainer(<CompressionExclusionsPage />);
});
await act(async () => {
await Promise.resolve();
});
expect(container).toBeTruthy();
expect(container.parentNode).toBeTruthy();
});
});