Compare commits

..

2 Commits

Author SHA1 Message Date
Xiangzhe
9ced57bc08 refactor(sse): route executor lookup through ExecutorRegistry (R0.3)
Adds open-sse/executors/registry.ts (Map-based registry mirroring
translator/registry.ts): the built-in table in executors/index.ts stays
declarative, every entry is registered at module load, and
getExecutor()/hasSpecializedExecutor() resolve through the registry.
DefaultExecutor fallback, its memoization, and the cloud-agent (#6699) /
search-provider (#10274) guards are unchanged.

Also fixes a latent lookup leak: the old object-literal lookup treated
Object.prototype names (constructor, toString, ...) as specialized
executors; the Map registry resolves them to the DefaultExecutor
fallback like any unknown provider.

Parity proof: executor-map golden (137 entries, byte-identical
before/after), check:known-symbols green, 1018 tests across the 65
executor test files green. Docs: OPEN_SSE_ARCHITECTURE factory section
corrected (it claimed generation from providerRegistry).

Refs #3501
2026-08-18 00:36:21 -03:00
Xiangzhe
a459dfd221 test(sse): golden characterization of the executor map before the R0.3 registry refactor
Freezes the 137-entry provider-id → executor mapping (class, provider
identity, backing PROVIDERS config), the no-shared-instances invariant,
and the getExecutor() dispatch rules (memoized DefaultExecutor fallback,
cloud-agent guard #6699, search-provider guard #10274) as stable JSON
snapshots. The upcoming ExecutorRegistry must keep both snapshots
byte-identical.
2026-08-18 00:16:46 -03:00
37 changed files with 1110 additions and 1320 deletions

View File

@@ -853,7 +853,7 @@ Engines run in pipeline order; each is independently toggleable and configurable
<tr><td align="center" nowrap>9</td><td align="left" nowrap><b>Aggressive</b></td><td align="left">Summarization + progressive aging of old turns</td></tr>
<tr><td align="center" nowrap>10</td><td align="left" nowrap><b>LLMLingua-2</b></td><td align="left">ML semantic pruning via MobileBERT ONNX — code-safe, async</td></tr>
<tr><td align="center" nowrap>11</td><td align="left" nowrap><b>Ultra</b></td><td align="left">Heuristic token pruning with an optional small-model (SLM) tier</td></tr>
<tr><td align="center" nowrap>12</td><td align="left" nowrap><b>OmniGlyph</b></td><td align="left">Experimental context-as-image encoding for measured Claude Fable 5 on the direct Anthropic wire; GPT 5.6 transformers remain fail-closed pending provider receipts. Four compression profiles (aggressive default, balanced, coding-safe, passthrough) (most aggressive; opt-in)</td></tr>
<tr><td align="center" nowrap>12</td><td align="left" nowrap><b>OmniGlyph</b></td><td align="left">Experimental context-as-image encoding routed to Claude Fable 5 (most aggressive; opt-in)</td></tr>
</table>
Code blocks, URLs and structured data are **always preserved** byte-perfect. **One-click presets** combine the engines:

View File

@@ -19,36 +19,8 @@ OmniRoute compression is built around engine contracts. A mode can run one engin
| `aggressive` | Caveman + history/tool summarizers | Long chat sessions |
| `ultra` | Caveman + pruning helpers | Context-limit recovery |
| `rtk` | RTK | Terminal, shell, build, test, and git output |
| `omniglyph` | OmniGlyph | Context-as-image on the native provider wire |
| `stacked` | Pipeline, default `rtk -> caveman` | Mixed tool logs and prose, max savings |
### OmniGlyph compression profiles
The `omniglyph` engine (package `omniglyph`, 1.4.0+) accepts a named semantic profile, set
globally through `omniglyph.profile` in the compression settings or per step through the
stacked pipeline's step config:
| Profile | Boundary |
| -------------- | --------------------------------------------------------------------------- |
| `aggressive` | Default. The policy the published receipts measured — images system, tool docs and dense history |
| `balanced` | Keeps live state native, protects the last 8 turns, collapses older closed history |
| `coding-safe` | Keeps authority, tool schemas and live tool output native, protects the last 12 turns |
| `passthrough` | Routes without transforming; the engine is skipped |
The profile is a **ceiling, not a floor**: `mergeCompressionProfileOptions` in the package
refuses to let a caller override reopen a lossy lane the profile closed, so a per-step
`preserveSystemPrompt: false` cannot re-enable system compression under `coding-safe`.
Measured on this codebase: `coding-safe` and `balanced` raise `minCompressChars` to its
maximum and keep system, tool schemas and tool results native, so a session that has not
accumulated history yet stops at `below_min_chars` and the engine transforms nothing. That
is why the default is `aggressive` rather than the safest profile.
The package resolves its own model scope and profile from its environment configuration.
OmniRoute never delegates the decision: the adapter pins the model gate to the package's
most restrictive scope, so host environment settings can only narrow the allowlist, never
widen it past OmniRoute's measured receipts.
## Engine Registry
The registry lives in `open-sse/services/compression/engines/registry.ts`. Engines expose a shared

View File

@@ -368,7 +368,7 @@ const result = await executor.execute({
});
````
The factory is generated from `config/providerRegistry.ts` which lists all 338 providers and their executor class.
Resolution goes through the `ExecutorRegistry` (`executors/registry.ts`): every specialized executor is declared in the built-in table of `executors/index.ts` and registered via `registerExecutor(alias, instance)` at module load; `getExecutor()` consults the registry and falls back to a memoized `DefaultExecutor` for any provider without a specialized entry. The full alias → executor mapping is characterized by the golden test `tests/unit/executor-map-golden.test.ts`.
---

View File

@@ -1,4 +1,9 @@
import { SEARCH_PROVIDERS } from "../config/searchRegistry.ts";
import {
registerExecutor,
getRegisteredExecutor,
hasRegisteredExecutor,
} from "./registry.ts";
import { AntigravityExecutor } from "./antigravity.ts";
import { GithubExecutor } from "./github.ts";
import { GheCopilotExecutor } from "./ghe-copilot.ts";
@@ -78,6 +83,12 @@ import { XaiExecutor } from "./xai.ts";
import { PromptQlExecutor } from "./promptql.ts";
import { ConolWebExecutor } from "./conol-web.ts";
// R0.3 — declarative built-in table. The object literal stays as the single
// place built-ins are declared (compile-time duplicate-key safety; the
// check:known-symbols gate parses this literal from source), but lookup goes
// through the ExecutorRegistry (./registry.ts): every entry is registered at
// module load below, and getExecutor()/hasSpecializedExecutor() consult the
// registry — the literal is never read at request time.
const executors = {
antigravity: new AntigravityExecutor(),
agy: new AntigravityExecutor(),
@@ -221,6 +232,13 @@ const executors = {
cnl: new ConolWebExecutor(), // Alias
};
// Bootstrap: register every built-in in the ExecutorRegistry. registerExecutor
// throws on duplicates, so an alias collision fails at module load, exactly as
// loudly as a duplicate object key would have failed at lint time.
for (const [alias, executor] of Object.entries(executors)) {
registerExecutor(alias, executor);
}
const defaultCache = new Map();
// #6699 — providers that exist ONLY as Cloud Agent task-API entries
@@ -246,7 +264,8 @@ const CHAT_UNSUPPORTED_CLOUD_AGENT_PROVIDERS = new Set(["jules"]);
const CHAT_UNSUPPORTED_SEARCH_PROVIDERS = new Set(Object.keys(SEARCH_PROVIDERS));
export function getExecutor(provider) {
if (executors[provider]) return executors[provider];
const registered = getRegisteredExecutor(provider);
if (registered) return registered;
if (CHAT_UNSUPPORTED_CLOUD_AGENT_PROVIDERS.has(provider)) {
const err = new Error(
`Provider "${provider}" is a cloud-agent provider and does not support direct chat completions; use the Cloud Agents task API instead.`
@@ -266,9 +285,11 @@ export function getExecutor(provider) {
}
export function hasSpecializedExecutor(provider) {
return !!executors[provider];
return hasRegisteredExecutor(provider);
}
export { registerExecutor, listExecutorAliases } from "./registry.ts";
export { BaseExecutor } from "./base.ts";
export { AntigravityExecutor } from "./antigravity.ts";
export { GithubExecutor } from "./github.ts";

View File

@@ -0,0 +1,38 @@
import type { BaseExecutor } from "./base.ts";
// R0.3 — ExecutorRegistry: runtime registry for provider executors, mirroring
// open-sse/translator/registry.ts. Built-ins register at module load from
// executors/index.ts; getExecutor() resolves through this map instead of a
// hard-coded object literal. This is the seam the v4 plan (M1.6
// host.registerProvider) extends — today the surface is internal-only.
//
// The alias → executor mapping is characterized by
// tests/unit/executor-map-golden.test.ts (tests/snapshots/executors/): any
// change to keys, classes or instance sharing shows up as a golden diff.
const registry = new Map<string, BaseExecutor>();
/**
* Register an executor under an alias. Aliases are unique: registering the
* same alias twice throws, preserving the guarantee the old object literal
* gave at compile time (duplicate keys were impossible).
*/
export function registerExecutor(alias: string, executor: BaseExecutor): void {
if (registry.has(alias)) {
throw new Error(`executor alias already registered: "${alias}"`);
}
registry.set(alias, executor);
}
export function getRegisteredExecutor(alias: string): BaseExecutor | undefined {
return registry.get(alias);
}
export function hasRegisteredExecutor(alias: string): boolean {
return registry.has(alias);
}
/** All registered aliases, in registration order. */
export function listExecutorAliases(): string[] {
return [...registry.keys()];
}

View File

@@ -88,7 +88,6 @@ import { checkResourcePressureGuard } from "../utils/resourcePressure.ts";
import { normalizeHeaders } from "../utils/headers.ts";
import { resolveChatCoreRequestFormat } from "./chatCore/requestFormat.ts";
import { resolveChatCoreTargetFormat } from "./chatCore/targetFormat.ts";
import { resolveOmniGlyphTransport } from "../services/compression/imageTransportPolicy.ts";
import { stripStore, usesClaudeBridge } from "./chatCore/agentRouterProtocol.ts";
import { defaultClaudeToolType } from "./chatCore/claudeToolDefaults.ts";
import { injectSystemPrompt, injectCustomSystemPrompt } from "../services/systemPrompt.ts";
@@ -1549,13 +1548,16 @@ export async function handleChatCore({
// models, which is intentionally NOT `false` so the gate still preserves images.
supportsVision: getResolvedModelCapabilities({ provider, model: effectiveModel })
.supportsVision,
// OmniGlyph uses a measured provider/image-fidelity allowlist. Direct HTTP
// alone is not proof that a route preserves PNG bytes and dimensions.
...resolveOmniGlyphTransport(provider),
// Sem o provider, a contabilidade do OmniGlyph cai para `unknown` e
// recusa deduzir a semântica de cache (Anthropic usa buckets disjuntos,
// OpenAI reporta cached como subconjunto do input).
provider,
// Rotas diretas oficiais ('anthropic' API key e 'claude' OAuth) vs agregadores:
// o engine omniglyph exige 'direct' — agregadores redimensionam imagens
// (medido 2026-07-06). OAuth 'claude' é rota direta oficial (#7863).
providerTransport:
provider === "anthropic" ||
provider === "claude" ||
provider === "openai" ||
provider === "xai"
? ("direct" as const)
: ("aggregator" as const),
sourceFormat,
targetFormat,
compressionStage: "pre-translation" as const,

View File

@@ -9,7 +9,6 @@
* - modelo fora da allowlist medida → skip:model_not_approved
* - providerTransport !== 'direct' → skip:transport_not_direct
* (agregadores redimensionam imagens e destroem a legibilidade — medido)
* - imageTransportFidelity !== 'byte-preserving' → skip:transport_fidelity_unknown/resizes
* - wire não é Claude/OpenAI suportado → skip:target_format_not_supported
* - gate de rentabilidade interno do omniglyph decide o resto (patches 28px
* exatos; texto esparso/pequeno passa direto) → skip:not_profitable
@@ -21,65 +20,14 @@ import type { CompressionEngine, CompressionEngineApplyOptions } from "./types.t
import type { CompressionResult } from "../types.ts";
import { createCompressionStats } from "../stats.ts";
import {
buildOmniGlyphAccounting,
type OmniGlyphAccounting,
} from "../omniglyphTelemetry.ts";
import {
isOmniGlyphSupportedModelForScope,
mergeCompressionProfileOptions,
resolveCompressionProfile,
isOmniGlyphSupportedGptModel,
isOmniGlyphSupportedModel,
transformAnthropicMessages,
transformOpenAIChatCompletions,
transformOpenAIResponses,
type CompressionProfile,
type OmniGlyphSafetyScope,
} from "omniglyph";
import { isModelImageable } from "omniglyph/applicability";
/**
* Teto de modelos do OmniRoute — sempre o escopo mais restrito do pacote.
*
* `isOmniGlyphSupportedModel()` resolve o escopo lendo `OMNIGLYPH_PROFILE` do
* processo, e a lista base sai de `OMNIGLYPH_MODELS`. Duas variáveis do HOST
* decidiriam, em silêncio, o gate de todo request do OmniRoute: `passthrough`
* desligaria a engine inteira e `OMNIGLYPH_MODELS` ADMITIRIA modelos sem
* recibo medido — enquanto a UI continua prometendo "Claude Fable 5 na rota
* direta medida". Fixar o escopo mais restrito faz o gate só poder ESTREITAR
* pela env, nunca alargar, e mantém a decisão na configuração do OmniRoute.
*/
const MEASURED_MODEL_SCOPE: OmniGlyphSafetyScope = "coding-safe";
/**
* Perfil padrão do OmniRoute.
*
* `aggressive` é a política que os recibos publicados mediram. `coding-safe` e
* `balanced` fixam `minCompressChars` no máximo e só colapsam histórico antigo:
* medido nesta base, uma sessão sem histórico acumulado fica em
* `below_min_chars` e a engine não faz nada — o operador veria "ligado, 0% de
* ganho". Ficam disponíveis como escolha explícita, não como default.
*/
const DEFAULT_PROFILE: OmniGlyphSafetyScope = "aggressive";
/** Perfil do passo (mais específico) > perfil global > default do OmniRoute. */
function resolveProfileName(options?: CompressionEngineApplyOptions): string {
const step = options?.stepConfig?.profile;
if (typeof step === "string" && step.trim()) return step;
const global = (options?.config as { omniglyph?: { profile?: unknown } } | undefined)?.omniglyph
?.profile;
if (typeof global === "string" && global.trim()) return global;
return DEFAULT_PROFILE;
}
/**
* O modelo precisa passar no teto medido E no escopo em vigor. Os dois wires
* (Anthropic e GPT) compartilham a mesma allowlist no pacote desde 1.4.0, então
* uma única checagem cobre os dois.
*/
function isModelWithinScope(model: string, scope: OmniGlyphSafetyScope): boolean {
if (!isOmniGlyphSupportedModelForScope(model, MEASURED_MODEL_SCOPE)) return false;
return isOmniGlyphSupportedModelForScope(model, scope);
}
function skip(body: Record<string, unknown>, reason: string): CompressionResult {
try {
return {
@@ -132,36 +80,9 @@ async function applyOmniglyph(
const model = options?.model ?? (body as { model?: string }).model ?? "";
if (options?.supportsVision !== true) return skip(body, "no_vision");
if (options?.providerTransport !== "direct") return skip(body, "transport_not_direct");
// Keep the old direct-call contract usable for standalone callers, but let
// production callers override it explicitly. The chat pipeline supplies
// `unknown` for every provider without a byte-preservation receipt.
if (
options?.imageTransportFidelity !== undefined &&
options.imageTransportFidelity !== "byte-preserving"
) {
return skip(
body,
options.imageTransportFidelity === "resizes"
? "transport_resizes_images"
: "transport_fidelity_unknown"
);
}
const stage = options?.compressionStage ?? "pre-translation";
const wireFormat = resolveWireFormat(body, options);
// A source/target format mismatch means the body is still on the wrong wire,
// even when the source itself is native Claude. Defer the engine until the
// translated provider body so Claude→OpenAI cannot be imaged once before
// translation and then considered again on the target wire.
const sourceWireFormat = options?.sourceFormat ?? wireFormat;
if (
stage === "pre-translation" &&
options?.targetFormat &&
sourceWireFormat &&
options.targetFormat !== sourceWireFormat
) {
return skip(body, "requires_post_translation");
}
// The pre-translation lane is retained for the existing native Claude
// passthrough. OpenAI requests must wait until translation has produced the
// exact provider wire, otherwise Responses input[] would be flattened by the
@@ -183,98 +104,53 @@ async function applyOmniglyph(
) {
return skip(body, "source_format_not_openai_responses");
}
let profile: CompressionProfile;
try {
profile = resolveCompressionProfile(resolveProfileName(options));
} catch {
// `resolveCompressionProfile` lança em nome desconhecido. Um perfil que o
// pacote não entende não pode virar "roda com a política padrão".
return skip(body, "invalid_profile");
}
if (profile.name === "passthrough") return skip(body, "profile_passthrough");
if (!isModelWithinScope(model, profile.name)) {
return skip(body, "model_not_approved");
}
const preserveSystemPrompt =
(typeof options?.stepConfig?.preserveSystemPrompt === "boolean"
? options.stepConfig.preserveSystemPrompt
: options?.config?.preserveSystemPrompt) === true;
// `compressSystem` só existe no transform Anthropic. Os wires OpenAI honram
// apenas compressTools/gptHistory/minCompressChars/reflow e sempre trocam a
// instrução por um ponteiro para a imagem. Imagear o system quando o OmniRoute
// decidiu preservá-lo queimaria o prefixo quente que a política cache-aware
// está protegendo — e nada no corpo devolvido denunciaria isso. Sem como
// honrar a política nesse wire, a engine pula.
if (preserveSystemPrompt && wireFormat !== "claude") {
return skip(body, "system_preservation_unsupported_on_wire");
}
const supportedModel =
wireFormat === "claude"
? isOmniGlyphSupportedModel(model)
: isOmniGlyphSupportedGptModel(model);
if (!supportedModel) return skip(body, "model_not_approved");
// OmniGlyph 1.3.x deliberately keeps unverified families (currently Grok)
// text-only until the operator acknowledges them via its own env gate.
if (!isModelImageable(model)) return skip(body, "model_not_imageable");
const started = Date.now();
let outBody: Record<string, unknown>;
let accounting: OmniGlyphAccounting | undefined;
try {
// The upstream OpenAI transformer resolves its billing/render profile from
// body.model. Keep the provider body byte-compatible on output, but use the
// already-resolved engine model for that internal gate when a translator
// omitted the model or left an alias in place.
const transformBody =
wireFormat !== "claude" && model && body.model !== model ? { ...body, model } : body;
const encoded = new TextEncoder().encode(JSON.stringify(transformBody));
const overrides = preserveSystemPrompt ? { compressSystem: false } : {};
// Só `transformAnthropicMessages` resolve o perfil por conta própria; os
// transformadores OpenAI recebem TransformOptions cru e ignorariam o campo.
const openAIOptions = mergeCompressionProfileOptions(profile, overrides);
const encoded = new TextEncoder().encode(JSON.stringify(body));
const result =
wireFormat === "claude"
? await transformAnthropicMessages({
body: encoded,
model,
options: { ...overrides, profile: profile.name },
})
? await transformAnthropicMessages({ body: encoded, model })
: wireFormat === "openai"
? await transformOpenAIChatCompletions(encoded, openAIOptions)
: await transformOpenAIResponses(encoded, openAIOptions);
const applied = "applied" in result ? result.applied : result.info.compressed;
? await transformOpenAIChatCompletions(encoded)
: await transformOpenAIResponses(encoded);
const applied = wireFormat === "claude" ? result.applied : result.info.compressed;
if (!applied) return skip(body, result.info?.reason ?? "not_profitable");
outBody = JSON.parse(new TextDecoder().decode(result.body)) as Record<string, unknown>;
if (transformBody !== body && body.model !== undefined) outBody.model = body.model;
accounting = buildOmniGlyphAccounting({
provider: options?.provider,
model,
originalBytes: encoded.byteLength,
transformedBytes: result.body.byteLength,
info: result.info,
durationMs: Date.now() - started,
});
} catch {
// Fail-open: qualquer erro no encode/transform/decode (ex.: corpo não serializável,
// render PNG estourando, JSON decodificado malformado) vira skip, nunca propaga.
return skip(body, "transform_error");
}
const stats = createCompressionStats(
body,
outBody,
"stacked",
["omniglyph:context-as-image"],
undefined,
Date.now() - started
);
// A contabilidade só acompanha uma conversão que realmente aconteceu: um skip
// não tem economia para reportar, e inventar zeros ali viraria "0% de ganho"
// indistinguível de "a engine nem rodou".
if (accounting) stats.omniglyph = accounting;
return { body: outBody, compressed: true, stats };
return {
body: outBody,
compressed: true,
stats: createCompressionStats(
body,
outBody,
"stacked",
["omniglyph:context-as-image"],
undefined,
Date.now() - started
),
};
}
export const omniglyphEngine: CompressionEngine = {
id: "omniglyph",
name: "OmniGlyph",
description:
"Contexto-como-imagem para Claude Fable 5 na rota direta medida; wires GPT nativos ficam disponíveis apenas após recibo de fidelidade do provedor.",
"Contexto-como-imagem (Anthropic Fable 5, rota direta): system prompt, tool docs e histórico viram páginas PNG densas — ~10× menos tokens no bloco convertido.",
icon: "image",
targets: ["messages", "tool_results"],
stackable: true,
@@ -284,7 +160,7 @@ export const omniglyphEngine: CompressionEngine = {
id: "omniglyph",
name: "OmniGlyph",
description:
"Contexto-como-imagem para Claude Fable 5 na rota direta medida; transformadores GPT nativos permanecem fail-closed até validação do provedor.",
"Contexto-como-imagem para Claude Fable 5 e GPT 5.6 via wires nativos Anthropic/OpenAI em rota direta.",
inputScope: "mixed",
targetLatencyMs: 250, // render+encode PNG de páginas grandes
supportsPreview: true,

View File

@@ -7,9 +7,6 @@ export type CompressionWireFormat = "claude" | "openai" | "openai-responses" | s
export type CompressionStage = "pre-translation" | "post-translation";
/** Whether an upstream route preserves OmniGlyph PNG bytes and dimensions. */
export type ImageTransportFidelity = "byte-preserving" | "resizes" | "unknown";
export interface EngineConfigField {
key: string;
type: "boolean" | "number" | "string" | "select" | "multiselect";
@@ -45,11 +42,8 @@ export interface CompressionEngineApplyOptions {
/** Como o request chega ao provider: rota direta oficial ('direct') vs
* agregador que pode reprocessar imagens ('aggregator'). O engine omniglyph
* exige 'direct' — medição 2026-07-06: agregadores redimensionam as páginas
* e destroem a legibilidade. A política de produção também informa
* imageTransportFidelity; chamadas legadas sem esse campo mantêm o gate direct. */
* e destroem a legibilidade. undefined = desconhecido = skip (fail-closed). */
providerTransport?: "direct" | "aggregator";
/** Independent image-fidelity gate; direct HTTP does not imply byte preservation. */
imageTransportFidelity?: ImageTransportFidelity;
/** Protocol shape before the current compression stage. */
sourceFormat?: CompressionWireFormat;
/** Protocol shape expected by the upstream provider. */
@@ -61,10 +55,6 @@ export interface CompressionEngineApplyOptions {
stepConfig?: Record<string, unknown>;
/** Authenticated principal (API key id) making the request. Used by CCR to scope its store. */
principalId?: string;
/** Provider resolvido do alvo. A contabilidade do omniglyph depende dele:
* Anthropic reporta input/cache em buckets disjuntos, OpenAI/xAI reportam
* cached como subconjunto do input. Ausente => `unknown` (falha fechado). */
provider?: string;
}
export interface CompressionEngine {

View File

@@ -1,33 +0,0 @@
/**
* Provider-level image transport policy for loss-sensitive compression engines.
*
* `supportsVision` only says that a model can read images. OmniGlyph also needs
* the PNG bytes and dimensions to survive the provider route unchanged. The
* allowlist below contains only paths with an existing OmniRoute receipt;
* everything else is deliberately classified as unknown and skipped.
*/
import type { ImageTransportFidelity } from "./engines/types.ts";
export type OmniGlyphTransportPolicy = {
providerTransport: "direct" | "aggregator";
imageTransportFidelity: ImageTransportFidelity;
};
const BYTE_PRESERVING_PROVIDERS = new Set(["anthropic", "claude"]);
export function resolveOmniGlyphTransport(
provider: string | null | undefined
): OmniGlyphTransportPolicy {
const normalized = typeof provider === "string" ? provider.trim().toLowerCase() : "";
if (BYTE_PRESERVING_PROVIDERS.has(normalized)) {
return {
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
};
}
return {
providerTransport: "aggregator",
imageTransportFidelity: "unknown",
};
}

View File

@@ -1,156 +0,0 @@
/**
* Ponte de telemetria do OmniGlyph — allowlist positiva.
*
* `TransformInfo` mistura contadores inofensivos com material que NUNCA pode
* ser persistido: bytes PNG, `imageSourceText(s)`, `recoverable[].text`, os
* sha8 de system/CLAUDE.md/primeira mensagem, os nomes de tags observadas e o
* bloco `env` (cwd, branch, versões). Copiar o objeto inteiro seria transformar
* a telemetria de compressão num vazamento do prompt.
*
* Este módulo não filtra por denylist — ele MONTA um objeto novo, campo a
* campo, só com número e enum. Um campo novo no upstream não entra sozinho.
*
* `normalizeAccounting()` (OmniGlyph 1.4.0) faz a parte difícil: classifica o
* grau de evidência da economia e resolve a semântica de cache por provider —
* Anthropic reporta input/cache-create/cache-read em buckets DISJUNTOS,
* enquanto OpenAI e xAI reportam `cached` como SUBCONJUNTO do input. Somar à
* mão dá double-count silencioso.
*/
import {
normalizeAccounting,
type AccountingProvider,
type OmniGlyphTransformInfo,
type SavingsEvidence,
} from "omniglyph";
/** Contabilidade segura de uma execução do OmniGlyph. Só número e enum. */
export interface OmniGlyphAccounting {
provider: AccountingProvider;
model?: string;
bytes: {
original?: number;
transformed?: number;
reduced?: number;
compressionRatio?: number;
};
tokens: {
estimatedOriginalInput?: number;
estimatedActualInput?: number;
estimatedReduced?: number;
image?: number;
};
savings: {
/** De onde saiu o número: contagem do provider, estimativa ou só bytes. */
evidence: SavingsEvidence;
inputTokensReduced?: number;
inputReductionRatio?: number;
};
images: {
count: number;
bytes: number;
pixels?: number;
};
/** Chars de origem imageados vs. mantidos como texto por turno. */
chars: {
original?: number;
imaged?: number;
static?: number;
dynamic?: number;
outgoingText?: number;
};
dynamicBlockCount?: number;
latencyMs?: number;
}
/**
* A semântica de cache de `normalizeAccounting` depende da família do provider,
* não do nome comercial da rota. Rota desconhecida vira `unknown`, que faz o
* upstream falhar fechado em vez de adivinhar buckets de cache.
*/
export function toAccountingProvider(provider: string | null | undefined): AccountingProvider {
const normalized = typeof provider === "string" ? provider.trim().toLowerCase() : "";
if (normalized === "anthropic" || normalized === "claude") return "anthropic";
if (normalized === "openai" || normalized === "codex" || normalized === "chatgpt") {
return "openai";
}
if (normalized === "xai" || normalized === "grok") return "xai";
return "unknown";
}
function count(value: unknown): number | undefined {
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
}
export function buildOmniGlyphAccounting(params: {
provider: string | null | undefined;
model?: string;
originalBytes: number;
transformedBytes: number;
info?: OmniGlyphTransformInfo | null;
durationMs?: number;
}): OmniGlyphAccounting {
const { info } = params;
const provider = toAccountingProvider(params.provider);
// `baselineImagedTokens` é o custo em tokens de texto do que foi imageado (o
// "teria pago assim"); `imageTokens` é o que as imagens custam de fato. Os
// dois só existem no wire GPT — no Anthropic a evidência honesta cai para
// bytes, e é isso que o campo `evidence` passa a dizer em vez de exibir um
// número sem procedência.
const normalized = normalizeAccounting({
provider,
...(params.model ? { model: params.model } : {}),
originalBytes: params.originalBytes,
transformedBytes: params.transformedBytes,
...(count(info?.baselineImagedTokens) !== undefined
? { estimatedOriginalInputTokens: info!.baselineImagedTokens }
: {}),
...(count(info?.imageTokens) !== undefined
? { estimatedTransformedInputTokens: info!.imageTokens }
: {}),
...(count(info?.imageTokens) !== undefined ? { imageTokens: info!.imageTokens } : {}),
...(params.durationMs !== undefined ? { proxyAddedLatencyMs: params.durationMs } : {}),
});
const chars = {
...(count(info?.origChars) !== undefined ? { original: info!.origChars } : {}),
...(count(info?.compressedChars) !== undefined ? { imaged: info!.compressedChars } : {}),
...(count(info?.staticChars) !== undefined ? { static: info!.staticChars } : {}),
...(count(info?.dynamicChars) !== undefined ? { dynamic: info!.dynamicChars } : {}),
...(count(info?.outgoingTextChars) !== undefined
? { outgoingText: info!.outgoingTextChars }
: {}),
};
return {
provider: normalized.provider,
...(normalized.model ? { model: normalized.model } : {}),
bytes: normalized.bytes,
tokens: {
...(normalized.tokens.estimatedOriginalInput !== undefined
? { estimatedOriginalInput: normalized.tokens.estimatedOriginalInput }
: {}),
...(normalized.tokens.estimatedActualInput !== undefined
? { estimatedActualInput: normalized.tokens.estimatedActualInput }
: {}),
...(normalized.tokens.estimatedReduced !== undefined
? { estimatedReduced: normalized.tokens.estimatedReduced }
: {}),
...(normalized.tokens.image !== undefined ? { image: normalized.tokens.image } : {}),
},
savings: normalized.savings,
images: {
count: count(info?.imageCount) ?? 0,
bytes: count(info?.imageBytes) ?? 0,
...(count(info?.imagePixels) !== undefined ? { pixels: info!.imagePixels } : {}),
},
chars,
...(count(info?.dynamicBlockCount) !== undefined
? { dynamicBlockCount: info!.dynamicBlockCount }
: {}),
...(normalized.latency.proxyAddedMs !== undefined
? { latencyMs: normalized.latency.proxyAddedMs }
: {}),
};
}

View File

@@ -110,8 +110,5 @@ export function mergeStackStep(
techniquesUsed: result.stats.techniquesUsed,
...(result.stats.rulesApplied ? { rulesApplied: result.stats.rulesApplied } : {}),
...(result.stats.durationMs !== undefined ? { durationMs: result.stats.durationMs } : {}),
// O agregado do pipeline soma tokens de todas as engines; a contabilidade
// física do omniglyph só faz sentido no passo que a produziu.
...(result.stats.omniglyph ? { omniglyph: result.stats.omniglyph } : {}),
});
}

View File

@@ -77,7 +77,7 @@ function isOpenAIResponsesPngImagePart(value: unknown): value is OpenAIResponses
}
function pngDimensionsFromDataUrl(value: string): { width: number; height: number } | null {
const marker = ";base64,";
const marker = ",base64,";
const markerIndex = value.indexOf(marker);
if (markerIndex < 0) return null;
return decodePngDimensions(value.slice(markerIndex + marker.length));

View File

@@ -11,7 +11,6 @@ import type {
CompressionEngineApplyOptions,
CompressionStage,
CompressionWireFormat,
ImageTransportFidelity,
} from "./engines/types.ts";
import { applyLiteCompression } from "./lite.ts";
import { cavemanCompress } from "./caveman.ts";
@@ -267,7 +266,6 @@ export function applyCompression(
options?: {
model?: string;
supportsVision?: boolean | null;
imageTransportFidelity?: ImageTransportFidelity;
sourceFormat?: CompressionWireFormat;
targetFormat?: CompressionWireFormat;
compressionStage?: CompressionStage;
@@ -294,7 +292,6 @@ function runCompression(
options?: {
model?: string;
supportsVision?: boolean | null;
imageTransportFidelity?: ImageTransportFidelity;
sourceFormat?: CompressionWireFormat;
targetFormat?: CompressionWireFormat;
compressionStage?: CompressionStage;
@@ -482,9 +479,6 @@ export async function applyCompressionAsync(
supportsVision?: boolean | null;
/** Direct-to-provider vs. aggregator transport (gates transport-sensitive engines like omniglyph). */
providerTransport?: "direct" | "aggregator";
/** Provider resolvido — a contabilidade do omniglyph depende dele. */
provider?: string;
imageTransportFidelity?: ImageTransportFidelity;
sourceFormat?: CompressionWireFormat;
targetFormat?: CompressionWireFormat;
compressionStage?: CompressionStage;
@@ -507,9 +501,6 @@ async function runCompressionAsync(
supportsVision?: boolean | null;
/** Direct-to-provider vs. aggregator transport (gates transport-sensitive engines like omniglyph). */
providerTransport?: "direct" | "aggregator";
/** Provider resolvido — a contabilidade do omniglyph depende dele. */
provider?: string;
imageTransportFidelity?: ImageTransportFidelity;
sourceFormat?: CompressionWireFormat;
targetFormat?: CompressionWireFormat;
compressionStage?: CompressionStage;
@@ -702,9 +693,6 @@ interface StackOptions {
supportsVision?: boolean | null;
/** Direct-to-provider vs. aggregator transport (gates transport-sensitive engines like omniglyph). */
providerTransport?: "direct" | "aggregator";
/** Provider resolvido — a contabilidade do omniglyph depende dele. */
provider?: string;
imageTransportFidelity?: ImageTransportFidelity;
sourceFormat?: CompressionWireFormat;
targetFormat?: CompressionWireFormat;
compressionStage?: CompressionStage;

View File

@@ -16,7 +16,6 @@ import type { RiskGateConfig } from "./riskGate/riskGate.ts";
import type { PipelineCircuitBreakerConfig } from "./pipelineEngineBreaker.ts";
import type { RiskGateStats } from "./riskGate/riskGateStep.ts";
import type { QuantumLockConfig, QuantumLockStats } from "./quantumLock/quantumPatterns.ts";
import type { OmniGlyphAccounting } from "./omniglyphTelemetry.ts";
// Re-export so consumers that already import from this module (e.g. src/lib/db/compression.ts)
// can get ENGINE_IDS without a second bare `@omniroute/open-sse/...engineCatalog.ts` specifier.
@@ -158,22 +157,6 @@ export interface LiveZoneConfig {
enabled: boolean;
}
/** Perfil semântico do OmniGlyph (pacote 1.4.0+). */
export type OmniglyphProfile = "coding-safe" | "balanced" | "aggressive" | "passthrough";
/**
* Política do OmniGlyph escolhida pelo operador.
*
* O perfil é um TETO: `mergeCompressionProfileOptions` do pacote não deixa um
* override reabrir uma lane que o perfil fechou. Trocar de `aggressive` para
* `coding-safe` mantém system, schemas de tools e tool results nativos, ao custo
* medido de a engine não fazer nada até a sessão acumular histórico
* (`minCompressChars` vai ao máximo). Por isso o default é `aggressive`.
*/
export interface OmniglyphConfig {
profile: OmniglyphProfile;
}
/** Lite detail settings for proactive request-time transformations. */
export interface LiteConfig {
/** Truncate tool-result strings over 2,000 characters before provider dispatch. */
@@ -223,8 +206,6 @@ export interface CompressionConfig {
comboOverrides: Record<string, CompressionMode>;
compressionComboId?: string | null;
stackedPipeline?: CompressionPipelineStep[];
/** Política do engine OmniGlyph (perfil semântico). */
omniglyph?: OmniglyphConfig;
/** Opt-in QuantumLock cache-prefix stabilization (default off). */
quantumLock?: QuantumLockConfig;
/** Opt-in per-step fidelity gate (default disabled). */
@@ -322,12 +303,6 @@ export interface CompressionStats {
validationWarnings?: string[];
validationErrors?: string[];
fallbackApplied?: boolean;
/**
* Contabilidade física do OmniGlyph, normalizada pelo próprio pacote
* (`normalizeAccounting`). Só número e enum — ver `omniglyphTelemetry.ts`
* para a allowlist e o que nunca pode entrar aqui.
*/
omniglyph?: OmniGlyphAccounting;
riskGate?: RiskGateStats;
/**
* Phase 4 (B): which `ultra` tier actually ran for this request.
@@ -366,8 +341,6 @@ export interface CompressionStats {
durationMs?: number;
rejected?: boolean;
rejectReason?: string;
/** Contabilidade física — presente só no passo omniglyph que comprimiu. */
omniglyph?: OmniGlyphAccounting;
}>;
/** Present only when QuantumLock stabilized ≥1 fragment this run. */
quantumLock?: QuantumLockStats;
@@ -487,16 +460,6 @@ export const DEFAULT_COMPRESSION_LANGUAGE_CONFIG: CompressionLanguageConfig = {
enabledPacks: ["en"],
};
/**
* `aggressive` é a política que os recibos publicados mediram. Medido nesta
* base: com `coding-safe`/`balanced`, uma sessão sem histórico acumulado para em
* `below_min_chars` e a engine não faz nada — como o OmniGlyph é opt-in, esse
* default entregaria "ligado, 0% de ganho".
*/
export const DEFAULT_OMNIGLYPH_CONFIG: OmniglyphConfig = {
profile: "aggressive",
};
export const DEFAULT_CONTEXT_EDITING_CONFIG: ContextEditingConfig = {
enabled: false,
};

8
package-lock.json generated
View File

@@ -60,7 +60,7 @@
"next-intl": "^4.13.6",
"next-themes": "^0.4.6",
"node-machine-id": "^1.1.12",
"omniglyph": "^1.4.0",
"omniglyph": "^1.0.2",
"onnxruntime-node": "~1.24.3",
"open": "^11.0.0",
"ora": "^9.4.1",
@@ -28871,9 +28871,9 @@
"license": "MIT"
},
"node_modules/omniglyph": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/omniglyph/-/omniglyph-1.4.0.tgz",
"integrity": "sha512-4zAqDW9pBb2i+fiGOVLIKbdecZeo55UmKQoLku1apxo3TSA4gfqcMo2MqQpal1VicckUwTbexFLasW7qngXUHA==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/omniglyph/-/omniglyph-1.3.1.tgz",
"integrity": "sha512-6QnZCoXYczjsPN2x+XpbimimjO6kCoSZUzsdSvoKjtw28U1U724VgLICBNaLX4FFs5jd7SrYNNs9Aee2iIkcoA==",
"license": "MIT",
"dependencies": {
"gpt-tokenizer": "^3.4.0"

View File

@@ -304,7 +304,7 @@
"next-intl": "^4.13.6",
"next-themes": "^0.4.6",
"node-machine-id": "^1.1.12",
"omniglyph": "^1.4.0",
"omniglyph": "^1.0.2",
"open": "^11.0.0",
"ora": "^9.4.1",
"parse5": "^8.0.1",

View File

@@ -17,22 +17,10 @@ import { SAMPLE_BEFORE_TEXT, SAMPLE_PAGE_PNG_DATA_URI, SAMPLE_METRICS } from "./
interface CompressionConfigLite {
engines?: Record<string, { enabled: boolean; level?: string }>;
omniglyph?: { profile?: string };
}
type EngineMap = Record<string, { enabled: boolean; level?: string }>;
/** Perfis do pacote, na ordem do mais permissivo ao mais restrito. O primeiro é
* o default: a política que os recibos publicados mediram. */
const PROFILES = [
{ id: "aggressive", key: "aggressive" },
{ id: "balanced", key: "balanced" },
{ id: "coding-safe", key: "codingSafe" },
{ id: "passthrough", key: "passthrough" },
] as const;
type ProfileId = (typeof PROFILES)[number]["id"];
/** The measured fail-closed gate chain, in evaluation order. Every no-op is telemetered
* as `skip:<reason>`; the engine only fires when all pass. */
const GATES = [
@@ -169,40 +157,6 @@ function GatesCard() {
);
}
function ProfileCard(props: {
profile: ProfileId;
disabled: boolean;
onChange: (next: ProfileId) => void;
}) {
const t = useTranslations("omniglyph");
const selected = PROFILES.find((p) => p.id === props.profile) ?? PROFILES[0];
return (
<Card className="p-6">
<div className="flex flex-col gap-3">
<h2 className="text-lg font-semibold">{t("profileTitle")}</h2>
<p className="max-w-xl text-sm text-text-muted">{t("profileDescription")}</p>
<select
className="w-full max-w-sm rounded-md border border-border bg-surface px-3 py-2 text-sm"
value={props.profile}
disabled={props.disabled}
aria-label={t("profileAria")}
data-testid="omniglyph-profile-select"
onChange={(e) => props.onChange(e.target.value as ProfileId)}
>
{PROFILES.map((p) => (
<option key={p.id} value={p.id}>
{t(`profiles.${p.key}.label`)}
</option>
))}
</select>
<span className="max-w-xl text-xs text-text-muted">
{t(`profiles.${selected.key}.description`)}
</span>
</div>
</Card>
);
}
function EnableCard(props: {
enabled: boolean;
disabled: boolean;
@@ -245,7 +199,6 @@ function EnableCard(props: {
export default function OmniglyphContextPageClient() {
const [engines, setEngines] = useState<EngineMap>({});
const [enabled, setEnabled] = useState(false);
const [profile, setProfile] = useState<ProfileId>("aggressive");
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [status, setStatus] = useState<"" | "saved" | "error">("");
@@ -257,8 +210,6 @@ export default function OmniglyphContextPageClient() {
const e = data?.engines ?? {};
setEngines(e);
setEnabled(e.omniglyph?.enabled === true);
const stored = data?.omniglyph?.profile;
if (PROFILES.some((p) => p.id === stored)) setProfile(stored as ProfileId);
})
.catch(() => {})
.finally(() => setLoading(false));
@@ -294,41 +245,12 @@ export default function OmniglyphContextPageClient() {
}
};
// O perfil vive na config do engine (não no mapa `engines`), então é um PATCH
// próprio — misturá-lo no payload do toggle reescreveria o mapa inteiro.
const changeProfile = async (next: ProfileId) => {
const previous = profile;
setProfile(next);
setSaving(true);
setStatus("");
try {
const res = await fetch("/api/settings/compression", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ omniglyph: { profile: next } }),
});
if (res.ok) {
setStatus("saved");
setTimeout(() => setStatus(""), 2000);
} else {
setProfile(previous);
setStatus("error");
}
} catch {
setProfile(previous);
setStatus("error");
} finally {
setSaving(false);
}
};
return (
<div className="mx-auto flex max-w-4xl flex-col gap-6 p-6" data-testid="omniglyph-page">
<PageHeader />
<EconomicsCard />
<BeforeAfterCard />
<GatesCard />
<ProfileCard profile={profile} disabled={loading || saving} onChange={changeProfile} />
<EnableCard
enabled={enabled}
disabled={loading || saving}

View File

@@ -20,7 +20,6 @@
import { logger } from "@omniroute/open-sse/utils/logger.ts";
import { estimateTokens } from "@omniroute/open-sse/services/contextManager.ts";
import { adaptBodyForCompression } from "@omniroute/open-sse/services/compression/bodyAdapter.ts";
import { resolveOmniGlyphTransport } from "@omniroute/open-sse/services/compression/imageTransportPolicy.ts";
import type {
CompressionConfig,
CompressionResult,
@@ -56,16 +55,13 @@ export async function applyResponsesWsCompression(
if (!enabled || !settings) return responseBody;
const adapter = adaptBodyForCompression(responseBody);
if (
!adapter.adapted ||
!Array.isArray(adapter.body.messages) ||
adapter.body.messages.length === 0
) {
if (!adapter.adapted || !Array.isArray(adapter.body.messages) || adapter.body.messages.length === 0) {
return responseBody;
}
const { selectCompressionStrategy, applyCompressionAsync } =
await import("@omniroute/open-sse/services/compression/strategySelector.ts");
const { selectCompressionStrategy, applyCompressionAsync } = await import(
"@omniroute/open-sse/services/compression/strategySelector.ts"
);
const estimatedTokens = estimateTokens(adapter.body.messages);
const cachingContext = {
@@ -87,8 +83,8 @@ export async function applyResponsesWsCompression(
const result = await applyCompressionAsync(adapter.body, mode, {
model: ctx.model,
...resolveOmniGlyphTransport(ctx.provider),
provider: ctx.provider,
providerTransport:
ctx.provider === "anthropic" || ctx.provider === "claude" ? "direct" : "aggregator",
config: settings as CompressionConfig,
cachingContext,
});

View File

@@ -8534,13 +8534,13 @@
},
"omniglyph": {
"preview": "Preview",
"description": "Context-as-image compression. Renders the system prompt, tool documentation, and dense history as compact PNG pages for the measured Claude Fable 5 path. The published OmniGlyph package also exposes native GPT 5.6 transformers, but OmniRoute keeps those routes fail-closed until provider fidelity and reading receipts exist.",
"description": "Context-as-image compression. Renders the system prompt, tool documentation, and dense history as compact PNG pages that Claude Fable 5 reads instead of text. Image tokens are billed by dimensions rather than characters, so the converted block costs about 10× less. Direct Anthropic route only.",
"economicsTitle": "The economics",
"economics": {
"fewerTokens": "fewer tokens on the converted block",
"savings": "end-to-end savings (measured)",
"imageTokens": "image tokens for a 1568×728 page (about 28k characters)",
"accuracy": "scoped Fable 5 reading receipt"
"accuracy": "reading accuracy on Fable 5 (n=30)"
},
"beforeAfterTitle": "Before → after",
"blockSavings": "{percent}% tokens on this block",
@@ -8553,18 +8553,18 @@
"gates": {
"model": {
"label": "Model",
"pass": "claude-fable-5 (measured); gpt-5.6 (HOLD)",
"why": "Only the measured Fable 5 path is enabled in OmniRoute. GPT 5.6 is structurally supported by the package but remains blocked until its provider receipt; unverified families such as Grok stay text-only."
"pass": "claude-fable-5",
"why": "Only Fable 5 reads dense pages at 100% accuracy (measured, n=30). GPT-5.5 and Gemini 2.5 Flash are blocked."
},
"transport": {
"label": "Transport",
"pass": "direct provider",
"why": "Aggregators may resample images and destroy legibility — only a direct provider route is authoritative."
"pass": "direct Anthropic",
"why": "Aggregators resample images and destroy legibility — only the direct route is authoritative."
},
"format": {
"label": "Format",
"pass": "native Claude/OpenAI",
"why": "The body must match the provider wire: Claude Messages, OpenAI Chat Completions, or native OpenAI Responses input[]."
"pass": "native Claude",
"why": "The body must use Claude format and must never put a system role inside messages."
},
"profitable": {
"label": "Profitable",
@@ -8573,28 +8573,7 @@
}
},
"enableTitle": "Enable the engine",
"enableDescription": "Runs last in the stack after text engines clean the request, using the native provider wire; OpenAI Chat/Responses requests are compressed after translation so their shape is preserved. It also runs standalone through <code>omniglyph</code> mode. This is a preview and remains off by default until end-to-end validation is complete.",
"profileTitle": "Compression profile",
"profileDescription": "The profile is a ceiling, not a floor: a stricter profile cannot be reopened by a per-step override. Measured on this codebase: with coding-safe or balanced, a session that has not accumulated history yet compresses nothing, because both raise the minimum-characters threshold and keep the system prompt, tool schemas and tool results native.",
"profiles": {
"aggressive": {
"label": "Aggressive (default)",
"description": "The policy the published receipts measured. Images the system prompt, tool documentation and dense history."
},
"balanced": {
"label": "Balanced",
"description": "Keeps live state native and protects the last 8 turns; only collapses older closed history."
},
"codingSafe": {
"label": "Coding-safe",
"description": "Keeps authority, tool schemas and live tool output native, protecting the last 12 turns. Compresses nothing until the session accumulates history."
},
"passthrough": {
"label": "Passthrough",
"description": "Routes without transforming. The engine is skipped and the request is forwarded untouched."
}
},
"profileAria": "Select the OmniGlyph compression profile",
"enableDescription": "Runs last in the stack (after RTK/Caveman cleans the text, OmniGlyph converts the remainder to images) and also runs standalone through <code>omniglyph</code> mode. This is a preview and remains off by default until end-to-end validation is complete.",
"saved": "Saved.",
"saveFailed": "Could not save.",
"enableAria": "Enable the OmniGlyph engine",

View File

@@ -8534,13 +8534,13 @@
},
"omniglyph": {
"preview": "Visualização",
"description": "Compressão de contexto como imagem. Renderiza o prompt de sistema, a documentação de ferramentas e o histórico denso como páginas PNG compactas para a rota medida do Claude Fable 5. O pacote OmniGlyph também expõe transformadores nativos para GPT 5.6, mas o OmniRoute mantém essas rotas fail-closed até existirem recibos de fidelidade do provedor e de leitura.",
"description": "Compressão de contexto como imagem. Renderiza o prompt de sistema, a documentação de ferramentas e o histórico denso como páginas PNG compactas que o Claude Fable 5 lê em vez de texto. Os tokens de imagem são cobrados por dimensões em vez de caracteres, então o bloco convertido custa cerca de 10× menos. Somente na rota direta da Anthropic.",
"economicsTitle": "A economia",
"economics": {
"fewerTokens": "menos tokens no bloco convertido",
"savings": "economia de ponta a ponta (medida)",
"imageTokens": "tokens de imagem para uma página de 1568×728 (cerca de 28 mil caracteres)",
"accuracy": "recibo de leitura do Fable 5 (escopo medido)"
"accuracy": "precio de leitura no Fable 5 (n=30)"
},
"beforeAfterTitle": "Antes → depois",
"blockSavings": "{percent}% de tokens neste bloco",
@@ -8553,18 +8553,18 @@
"gates": {
"model": {
"label": "Modelo",
"pass": "claude-fable-5 (medido); gpt-5.6 (HOLD)",
"why": "Somente a rota medida do Fable 5 está habilitada no OmniRoute. O GPT 5.6 tem suporte estrutural no pacote, mas continua bloqueado até seu recibo do provedor; famílias não verificadas, como Grok, permanecem em texto."
"pass": "claude-fable-5",
"why": "Somente o Fable 5 lê páginas densas com 100% de precisão (medido, n=30). GPT-5.5 e Gemini 2.5 Flash são bloqueados."
},
"transport": {
"label": "Transporte",
"pass": "provedor direto",
"why": "Agregadores podem reamostrar imagens e destruir a legibilidade — apenas uma rota direta do provedor é confiável."
"pass": "direto Anthropic",
"why": "Agregadores reamostram imagens e destroem a legibilidade — apenas a rota direta é confiável."
},
"format": {
"label": "Formato",
"pass": "Claude/OpenAI nativo",
"why": "O corpo precisa corresponder ao wire do provedor: Claude Messages, OpenAI Chat Completions ou input[] nativo do OpenAI Responses."
"pass": "Claude nativo",
"why": "O corpo deve usar o formato Claude e nunca colocar um papel system dentro de messages."
},
"profitable": {
"label": "Rentável",
@@ -8573,28 +8573,7 @@
}
},
"enableTitle": "Ativar a engine",
"enableDescription": "Executa por último na pilha, depois que os engines de texto limpam a solicitação, usando o wire nativo do provedor; solicitações OpenAI Chat/Responses são comprimidas depois da tradução para preservar seu formato. Também roda de forma independente pelo modo <code>omniglyph</code>. Este é um preview e permanece desativado por padrão até que a validação de ponta a ponta seja concluída.",
"profileTitle": "Perfil de compressão",
"profileDescription": "O perfil é um teto, não um piso: um perfil mais restrito não pode ser reaberto por um override de passo. Medido nesta base: com coding-safe ou balanced, uma sessão que ainda não acumulou histórico não comprime nada, porque os dois elevam o mínimo de caracteres e mantêm o system prompt, os schemas de tools e os tool results nativos.",
"profiles": {
"aggressive": {
"label": "Agressivo (padrão)",
"description": "A política que os recibos publicados mediram. Imageia o system prompt, a documentação de tools e o histórico denso."
},
"balanced": {
"label": "Equilibrado",
"description": "Mantém o estado vivo nativo e protege os últimos 8 turnos; só colapsa histórico antigo já fechado."
},
"codingSafe": {
"label": "Seguro para código",
"description": "Mantém autoridade, schemas de tools e saída de ferramenta nativos, protegendo os últimos 12 turnos. Não comprime nada até a sessão acumular histórico."
},
"passthrough": {
"label": "Sem transformação",
"description": "Só roteia. A engine é pulada e o request segue intacto."
}
},
"profileAria": "Selecionar o perfil de compressão do OmniGlyph",
"enableDescription": "Executa por último na pilha (depois que RTK/Caveman limpa o texto, o OmniGlyph converte o restante em imagens) e também roda de forma independente pelo modo <code>omniglyph</code>. Este é um preview e permanece desativado por padrão até que a validação de ponta a ponta seja concluída.",
"saved": "Salvo.",
"saveFailed": "Não foi possível salvar.",
"enableAria": "Ativar a engine OmniGlyph",

View File

@@ -8574,27 +8574,6 @@
},
"enableTitle": "Bật bộ máy",
"enableDescription": "Chạy cuối cùng trong ngăn xếp (sau khi RTK/Caveman làm sạch văn bản, OmniGlyph chuyển phần còn lại thành hình ảnh) và cũng có thể chạy độc lập qua chế độ <code>omniglyph</code>. Đây là bản xem trước và mặc định vẫn tắt cho đến khi hoàn tất kiểm thử đầu cuối.",
"profileTitle": "Hồ sơ nén",
"profileDescription": "Hồ sơ là giới hạn trên, không phải giới hạn dưới: một hồ sơ chặt chẽ hơn không thể bị mở lại bằng ghi đè ở từng bước. Đo trên chính mã nguồn này: với coding-safe hoặc balanced, một phiên chưa tích lũy lịch sử sẽ không nén gì cả, vì cả hai đều nâng ngưỡng số ký tự tối thiểu và giữ nguyên system prompt, lược đồ công cụ và kết quả công cụ.",
"profiles": {
"aggressive": {
"label": "Tích cực (mặc định)",
"description": "Chính sách mà các biên nhận đã công bố đo được. Kết xuất system prompt, tài liệu công cụ và lịch sử dày đặc thành ảnh."
},
"balanced": {
"label": "Cân bằng",
"description": "Giữ nguyên trạng thái đang hoạt động và bảo vệ 8 lượt gần nhất; chỉ gộp lịch sử cũ đã khép lại."
},
"codingSafe": {
"label": "An toàn cho lập trình",
"description": "Giữ nguyên thẩm quyền, lược đồ công cụ và đầu ra công cụ đang hoạt động, bảo vệ 12 lượt gần nhất. Không nén gì cho đến khi phiên tích lũy lịch sử."
},
"passthrough": {
"label": "Không biến đổi",
"description": "Chỉ định tuyến. Engine bị bỏ qua và yêu cầu được chuyển tiếp nguyên vẹn."
}
},
"profileAria": "Chọn hồ sơ nén của OmniGlyph",
"saved": "Đã lưu.",
"saveFailed": "Không thể lưu.",
"enableAria": "Bật bộ máy OmniGlyph",

View File

@@ -26,8 +26,6 @@ import {
DEFAULT_CODEX_RESPONSES_CONFIG,
type CodexResponsesConfig,
type ContextEditingConfig,
DEFAULT_OMNIGLYPH_CONFIG,
type OmniglyphConfig,
type EngineToggle,
type HeadroomConfig,
type McpAccessibilityConfig,
@@ -306,19 +304,6 @@ function normalizeLanguageConfig(value: unknown): CompressionLanguageConfig {
};
}
function normalizeOmniglyphConfig(value: unknown): OmniglyphConfig {
const record = toRecord(value);
const profile = record.profile;
// Um perfil desconhecido não pode virar "roda com a política padrão": cai para
// o default explícito, e o adapter ainda falha fechado se algo passar por aqui.
return {
profile:
profile === "coding-safe" || profile === "balanced" || profile === "passthrough"
? profile
: DEFAULT_OMNIGLYPH_CONFIG.profile,
};
}
function normalizeContextEditingConfig(value: unknown): ContextEditingConfig {
const record = toRecord(value);
return {
@@ -636,7 +621,6 @@ export async function getCompressionSettings(): Promise<CompressionConfig> {
...buildDetailConfigDefaults(),
contextBudget: normalizeContextBudgetConfig(undefined),
contextEditing: { ...DEFAULT_CONTEXT_EDITING_CONFIG },
omniglyph: { ...DEFAULT_OMNIGLYPH_CONFIG },
liveZone: { enabled: false },
engines: {},
activeComboId: null,
@@ -760,9 +744,6 @@ export async function getCompressionSettings(): Promise<CompressionConfig> {
case "contextEditing":
config.contextEditing = normalizeContextEditingConfig(parsed);
break;
case "omniglyph":
config.omniglyph = normalizeOmniglyphConfig(parsed);
break;
case "liveZone":
config.liveZone = { enabled: toRecord(parsed).enabled === true };
break;

View File

@@ -346,19 +346,6 @@ export const contextBudgetConfigSchema = z
})
.strict();
/**
* Perfil semântico do OmniGlyph. O perfil é um TETO: o pacote não deixa um
* override reabrir uma lane que o perfil fechou. `aggressive` é o default e a
* política que os recibos publicados mediram; `coding-safe`/`balanced` mantêm
* system, schemas de tools e tool results nativos, e não comprimem nada até a
* sessão acumular histórico.
*/
export const omniglyphConfigSchema = z
.object({
profile: z.enum(["coding-safe", "balanced", "aggressive", "passthrough"]),
})
.strict();
export const compressionSettingsUpdateSchema = z
.object({
enabled: z.boolean().optional(),
@@ -386,7 +373,6 @@ export const compressionSettingsUpdateSchema = z
ccr: ccrConfigSchema.optional(),
contextBudget: contextBudgetConfigSchema.optional(),
contextEditing: contextEditingConfigSchema.optional(),
omniglyph: omniglyphConfigSchema.optional(),
liveZone: z.object({ enabled: z.boolean() }).strict().optional(),
engines: z.record(z.string(), engineToggleSchema).optional(),
enginesExplicit: z.boolean().optional(),

View File

@@ -0,0 +1,86 @@
{
"cloudAgentGuard": {
"jules": {
"message": "Provider \"jules\" is a cloud-agent provider and does not support direct chat completions; use the Cloud Agents task API instead.",
"status": 400,
"throws": true
}
},
"fallback": {
"className": "DefaultExecutor",
"configSource": "openai",
"provider": "golden-test-unknown-provider"
},
"searchGuard": {
"brave-search": {
"message": "Provider \"brave-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"duckduckgo-free": {
"message": "Provider \"duckduckgo-free\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"exa-search": {
"message": "Provider \"exa-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"firecrawl": {
"message": "Provider \"firecrawl\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"google-pse-search": {
"message": "Provider \"google-pse-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"linkup-search": {
"message": "Provider \"linkup-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"ollama-search": {
"message": "Provider \"ollama-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"perplexity-search": {
"message": "Provider \"perplexity-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"searchapi-search": {
"message": "Provider \"searchapi-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"searxng-search": {
"message": "Provider \"searxng-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"serper-search": {
"message": "Provider \"serper-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"tavily-search": {
"message": "Provider \"tavily-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"youcom-search": {
"message": "Provider \"youcom-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
},
"zai-search": {
"message": "Provider \"zai-search\" is a search provider and does not support chat completions; use the /v1/search endpoint instead.",
"status": 400,
"throws": true
}
}
}

View File

@@ -0,0 +1,691 @@
{
"entries": {
"9router": {
"className": "NineRouterExecutor",
"configSource": "<custom-config>",
"provider": "9router"
},
"adapta-web": {
"className": "AdaptaWebExecutor",
"configSource": "<custom-config>",
"provider": "adapta-web"
},
"adobe-firefly": {
"className": "AdobeFireflyExecutor",
"configSource": "<custom-config>",
"provider": "adobe-firefly"
},
"adp-web": {
"className": "AdaptaWebExecutor",
"configSource": "<custom-config>",
"provider": "adapta-web"
},
"agy": {
"className": "AntigravityExecutor",
"configSource": "antigravity",
"provider": "antigravity"
},
"amazon-q": {
"className": "KiroExecutor",
"configSource": "kiro",
"provider": "amazon-q"
},
"antigravity": {
"className": "AntigravityExecutor",
"configSource": "antigravity",
"provider": "antigravity"
},
"auggie": {
"className": "AuggieExecutor",
"configSource": "<custom-config>",
"provider": "auggie"
},
"azure-ai": {
"className": "AzureAiExecutor",
"configSource": "openai",
"provider": "azure-ai"
},
"azure-openai": {
"className": "AzureOpenAIExecutor",
"configSource": "openai",
"provider": "azure-openai"
},
"bb-web": {
"className": "BlackboxWebExecutor",
"configSource": "<custom-config>",
"provider": "blackbox-web"
},
"bedrock": {
"className": "BedrockExecutor",
"configSource": "bedrock",
"provider": "bedrock"
},
"blackbox-web": {
"className": "BlackboxWebExecutor",
"configSource": "<custom-config>",
"provider": "blackbox-web"
},
"cbcn": {
"className": "CodeBuddyCnExecutor",
"configSource": "codebuddy-cn",
"provider": "codebuddy-cn"
},
"cf": {
"className": "CloudflareAIExecutor",
"configSource": "cloudflare-ai",
"provider": "cloudflare-ai"
},
"cgpt-codex": {
"className": "ChatGptWebCodexExecutor",
"configSource": "<custom-config>",
"provider": "chatgpt-web-codex"
},
"cgpt-web": {
"className": "ChatGptWebExecutor",
"configSource": "<custom-config>",
"provider": "chatgpt-web"
},
"chatgpt-web": {
"className": "ChatGptWebExecutor",
"configSource": "<custom-config>",
"provider": "chatgpt-web"
},
"chatgpt-web-codex": {
"className": "ChatGptWebCodexExecutor",
"configSource": "<custom-config>",
"provider": "chatgpt-web-codex"
},
"cheaperinference": {
"className": "CheaperInferenceExecutor",
"configSource": "cheaperinference",
"provider": "cheaperinference"
},
"chipotle": {
"className": "ChipotleExecutor",
"configSource": "<custom-config>",
"provider": "chipotle"
},
"cinf": {
"className": "CheaperInferenceExecutor",
"configSource": "cheaperinference",
"provider": "cheaperinference"
},
"claude-web": {
"className": "ClaudeWebExecutor",
"configSource": "<custom-config>",
"provider": "claude-web"
},
"cliproxyapi": {
"className": "CliproxyapiExecutor",
"configSource": "<custom-config>",
"provider": "cliproxyapi"
},
"cloudflare-ai": {
"className": "CloudflareAIExecutor",
"configSource": "cloudflare-ai",
"provider": "cloudflare-ai"
},
"cmd": {
"className": "CommandCodeExecutor",
"configSource": "<custom-config>",
"provider": "command-code"
},
"cnl": {
"className": "ConolWebExecutor",
"configSource": "<custom-config>",
"provider": "conol-web"
},
"codebuddy-cn": {
"className": "CodeBuddyCnExecutor",
"configSource": "codebuddy-cn",
"provider": "codebuddy-cn"
},
"codex": {
"className": "CodexExecutor",
"configSource": "codex",
"provider": "codex"
},
"command-code": {
"className": "CommandCodeExecutor",
"configSource": "<custom-config>",
"provider": "command-code"
},
"conol-web": {
"className": "ConolWebExecutor",
"configSource": "<custom-config>",
"provider": "conol-web"
},
"copilot": {
"className": "CopilotWebExecutor",
"configSource": "<custom-config>",
"provider": "copilot-web"
},
"copilot-m365-web": {
"className": "CopilotM365WebExecutor",
"configSource": "<custom-config>",
"provider": "copilot-m365-web"
},
"copilot-web": {
"className": "CopilotWebExecutor",
"configSource": "<custom-config>",
"provider": "copilot-web"
},
"cpa": {
"className": "CliproxyapiExecutor",
"configSource": "<custom-config>",
"provider": "cliproxyapi"
},
"cu": {
"className": "CursorExecutor",
"configSource": "cursor",
"provider": "cursor"
},
"cursor": {
"className": "CursorExecutor",
"configSource": "cursor",
"provider": "cursor"
},
"cw-web": {
"className": "ClaudeWebExecutor",
"configSource": "<custom-config>",
"provider": "claude-web"
},
"dario": {
"className": "DarioExecutor",
"configSource": "<custom-config>",
"provider": "dario"
},
"db": {
"className": "DoubaoWebExecutor",
"configSource": "<custom-config>",
"provider": "doubao-web"
},
"ddgw": {
"className": "DuckDuckGoWebExecutor",
"configSource": "<custom-config>",
"provider": "duckduckgo-web"
},
"deepseek-web": {
"className": "DeepSeekWebWithAutoRefreshExecutor",
"configSource": "<custom-config>",
"provider": "deepseek-web"
},
"devin": {
"className": "DevinCliExecutor",
"configSource": "<custom-config>",
"provider": "devin-cli"
},
"devin-cli": {
"className": "DevinCliExecutor",
"configSource": "<custom-config>",
"provider": "devin-cli"
},
"devin-cli-agentic": {
"className": "DevinCliAgenticExecutor",
"configSource": "<custom-config>",
"provider": "devin-cli-agentic"
},
"devin-desktop": {
"className": "DevinDesktopExecutor",
"configSource": "devin-desktop",
"provider": "devin-desktop"
},
"doubao-web": {
"className": "DoubaoWebExecutor",
"configSource": "<custom-config>",
"provider": "doubao-web"
},
"dr": {
"className": "DarioExecutor",
"configSource": "<custom-config>",
"provider": "dario"
},
"ds-web": {
"className": "DeepSeekWebWithAutoRefreshExecutor",
"configSource": "<custom-config>",
"provider": "deepseek-web"
},
"duckduckgo-web": {
"className": "DuckDuckGoWebExecutor",
"configSource": "<custom-config>",
"provider": "duckduckgo-web"
},
"felo": {
"className": "FeloWebExecutor",
"configSource": "<custom-config>",
"provider": "felo-web"
},
"felo-web": {
"className": "FeloWebExecutor",
"configSource": "<custom-config>",
"provider": "felo-web"
},
"firefly": {
"className": "AdobeFireflyExecutor",
"configSource": "<custom-config>",
"provider": "adobe-firefly"
},
"gc": {
"className": "GrokCliExecutor",
"configSource": "grok-cli",
"provider": "grok-cli"
},
"gembiz": {
"className": "GeminiBusinessExecutor",
"configSource": "<custom-config>",
"provider": "gemini-business"
},
"gemini-business": {
"className": "GeminiBusinessExecutor",
"configSource": "<custom-config>",
"provider": "gemini-business"
},
"gemini-web": {
"className": "GeminiWebExecutor",
"configSource": "<custom-config>",
"provider": "gemini-web"
},
"ghe-copilot": {
"className": "GheCopilotExecutor",
"configSource": "<custom-config>",
"provider": "ghe-copilot"
},
"github": {
"className": "GithubExecutor",
"configSource": "github",
"provider": "github"
},
"gitlab": {
"className": "GitlabExecutor",
"configSource": "<custom-config>",
"provider": "gitlab"
},
"gitlab-duo": {
"className": "GitlabExecutor",
"configSource": "<custom-config>",
"provider": "gitlab-duo"
},
"glm": {
"className": "GlmExecutor",
"configSource": "glm",
"provider": "glm"
},
"glm-cn": {
"className": "GlmExecutor",
"configSource": "glm-cn",
"provider": "glm-cn"
},
"glmt": {
"className": "GlmExecutor",
"configSource": "glmt",
"provider": "glmt"
},
"grok-cli": {
"className": "GrokCliExecutor",
"configSource": "grok-cli",
"provider": "grok-cli"
},
"grok-web": {
"className": "GrokWebExecutor",
"configSource": "<custom-config>",
"provider": "grok-web"
},
"gweb": {
"className": "GeminiWebExecutor",
"configSource": "<custom-config>",
"provider": "gemini-web"
},
"ha": {
"className": "HyperAgentExecutor",
"configSource": "<custom-config>",
"provider": "hyperagent"
},
"hailuo-web": {
"className": "HailuoWebExecutor",
"configSource": "<custom-config>",
"provider": "hailuo-web"
},
"hc": {
"className": "HuggingChatExecutor",
"configSource": "<custom-config>",
"provider": "huggingchat"
},
"huggingchat": {
"className": "HuggingChatExecutor",
"configSource": "<custom-config>",
"provider": "huggingchat"
},
"hyperagent": {
"className": "HyperAgentExecutor",
"configSource": "<custom-config>",
"provider": "hyperagent"
},
"in-ai": {
"className": "InnerAiExecutor",
"configSource": "<custom-config>",
"provider": "inner-ai"
},
"inner-ai": {
"className": "InnerAiExecutor",
"configSource": "<custom-config>",
"provider": "inner-ai"
},
"kimi": {
"className": "MoonshotExecutor",
"configSource": "kimi",
"provider": "kimi"
},
"kimi-coding": {
"className": "KimiExecutor",
"configSource": "kimi-coding",
"provider": "kimi-coding"
},
"kimi-coding-apikey": {
"className": "KimiExecutor",
"configSource": "kimi-coding-apikey",
"provider": "kimi-coding-apikey"
},
"kimi-web": {
"className": "KimiWebExecutor",
"configSource": "<custom-config>",
"provider": "kimi-web"
},
"kiro": {
"className": "KiroExecutor",
"configSource": "kiro",
"provider": "kiro"
},
"lma": {
"className": "LMArenaExecutor",
"configSource": "<custom-config>",
"provider": "lmarena"
},
"lmarena": {
"className": "LMArenaExecutor",
"configSource": "<custom-config>",
"provider": "lmarena"
},
"mcode": {
"className": "MimocodeExecutor",
"configSource": "<custom-config>",
"provider": "mimocode"
},
"microsoft-designer-web": {
"className": "MicrosoftDesignerWebExecutor",
"configSource": "<custom-config>",
"provider": "microsoft-designer-web"
},
"mimocode": {
"className": "MimocodeExecutor",
"configSource": "<custom-config>",
"provider": "mimocode"
},
"moonshot": {
"className": "MoonshotExecutor",
"configSource": "moonshot",
"provider": "moonshot"
},
"ms-web": {
"className": "MuseSparkWebExecutor",
"configSource": "<custom-config>",
"provider": "muse-spark-web"
},
"msdesigner": {
"className": "MicrosoftDesignerWebExecutor",
"configSource": "<custom-config>",
"provider": "microsoft-designer-web"
},
"muse-spark-web": {
"className": "MuseSparkWebExecutor",
"configSource": "<custom-config>",
"provider": "muse-spark-web"
},
"nlpcloud": {
"className": "NlpCloudExecutor",
"configSource": "nlpcloud",
"provider": "nlpcloud"
},
"notion-web": {
"className": "NotionWebExecutor",
"configSource": "<custom-config>",
"provider": "notion-web"
},
"nr": {
"className": "NineRouterExecutor",
"configSource": "<custom-config>",
"provider": "9router"
},
"nw": {
"className": "NotionWebExecutor",
"configSource": "<custom-config>",
"provider": "notion-web"
},
"opencode": {
"className": "OpencodeExecutor",
"configSource": "opencode-zen",
"provider": "opencode-zen"
},
"opencode-go": {
"className": "OpencodeExecutor",
"configSource": "opencode-go",
"provider": "opencode-go"
},
"opencode-zen": {
"className": "OpencodeExecutor",
"configSource": "opencode-zen",
"provider": "opencode-zen"
},
"pepper": {
"className": "ChipotleExecutor",
"configSource": "<custom-config>",
"provider": "chipotle"
},
"perplexity-web": {
"className": "PerplexityWebExecutor",
"configSource": "<custom-config>",
"provider": "perplexity-web"
},
"poe-web": {
"className": "PoeWebExecutor",
"configSource": "<custom-config>",
"provider": "poe-web"
},
"pol": {
"className": "PollinationsExecutor",
"configSource": "pollinations",
"provider": "pollinations"
},
"pollinations": {
"className": "PollinationsExecutor",
"configSource": "pollinations",
"provider": "pollinations"
},
"pplx-web": {
"className": "PerplexityWebExecutor",
"configSource": "<custom-config>",
"provider": "perplexity-web"
},
"pql": {
"className": "PromptQlExecutor",
"configSource": "<custom-config>",
"provider": "promptql"
},
"promptql": {
"className": "PromptQlExecutor",
"configSource": "<custom-config>",
"provider": "promptql"
},
"qoder": {
"className": "QoderExecutor",
"configSource": "qoder",
"provider": "qoder"
},
"qw": {
"className": "QwenWebExecutor",
"configSource": "<custom-config>",
"provider": "qwen-web"
},
"qwen-web": {
"className": "QwenWebExecutor",
"configSource": "<custom-config>",
"provider": "qwen-web"
},
"raycast": {
"className": "RaycastExecutor",
"configSource": "raycast",
"provider": "raycast"
},
"rc": {
"className": "RaycastExecutor",
"configSource": "raycast",
"provider": "raycast"
},
"t3-web": {
"className": "T3ChatWebExecutor",
"configSource": "<custom-config>",
"provider": "t3-web"
},
"t3chat": {
"className": "T3ChatWebExecutor",
"configSource": "<custom-config>",
"provider": "t3-web"
},
"tasw": {
"className": "TencentAIStudioWebExecutor",
"configSource": "<custom-config>",
"provider": "tencent-aistudio-web"
},
"tcw": {
"className": "TinyCmsExecutor",
"configSource": "<custom-config>",
"provider": "tinycms-web"
},
"tencent-aistudio-web": {
"className": "TencentAIStudioWebExecutor",
"configSource": "<custom-config>",
"provider": "tencent-aistudio-web"
},
"theoldllm": {
"className": "TheOldLlmExecutor",
"configSource": "<custom-config>",
"provider": "theoldllm"
},
"tinycms-web": {
"className": "TinyCmsExecutor",
"configSource": "<custom-config>",
"provider": "tinycms-web"
},
"tllm": {
"className": "TheOldLlmExecutor",
"configSource": "<custom-config>",
"provider": "theoldllm"
},
"trae": {
"className": "TraeExecutor",
"configSource": "trae",
"provider": "trae"
},
"v0": {
"className": "V0VercelWebExecutor",
"configSource": "<custom-config>",
"provider": "v0-vercel-web"
},
"v0-vercel-web": {
"className": "V0VercelWebExecutor",
"configSource": "<custom-config>",
"provider": "v0-vercel-web"
},
"ven": {
"className": "VeniceWebExecutor",
"configSource": "<custom-config>",
"provider": "venice-web"
},
"venice-web": {
"className": "VeniceWebExecutor",
"configSource": "<custom-config>",
"provider": "venice-web"
},
"veo-free": {
"className": "VeoAIFreeWebExecutor",
"configSource": "<custom-config>",
"provider": "veoaifree-web"
},
"veoaifree-web": {
"className": "VeoAIFreeWebExecutor",
"configSource": "<custom-config>",
"provider": "veoaifree-web"
},
"vertex": {
"className": "VertexExecutor",
"configSource": "vertex",
"provider": "vertex"
},
"vertex-partner": {
"className": "VertexExecutor",
"configSource": "vertex",
"provider": "vertex"
},
"xai": {
"className": "XaiExecutor",
"configSource": "xai",
"provider": "xai"
},
"xai-oauth": {
"className": "XaiExecutor",
"configSource": "xai-oauth",
"provider": "xai-oauth"
},
"xao": {
"className": "XaiExecutor",
"configSource": "xai-oauth",
"provider": "xai-oauth"
},
"ybw": {
"className": "YuanbaoWebExecutor",
"configSource": "<custom-config>",
"provider": "yuanbao-web"
},
"yuanbao-web": {
"className": "YuanbaoWebExecutor",
"configSource": "<custom-config>",
"provider": "yuanbao-web"
},
"zai-web": {
"className": "ZaiWebExecutor",
"configSource": "<custom-config>",
"provider": "zai-web"
},
"zc": {
"className": "ZcodeExecutor",
"configSource": "<custom-config>",
"provider": "zcode"
},
"zcode": {
"className": "ZcodeExecutor",
"configSource": "<custom-config>",
"provider": "zcode"
},
"zed-hosted": {
"className": "ZedHostedExecutor",
"configSource": "zed-hosted",
"provider": "zed-hosted"
},
"zenmux-free": {
"className": "ZenmuxFreeExecutor",
"configSource": "<custom-config>",
"provider": "zenmux-free"
},
"zmf": {
"className": "ZenmuxFreeExecutor",
"configSource": "<custom-config>",
"provider": "zenmux-free"
},
"zw": {
"className": "ZaiWebExecutor",
"configSource": "<custom-config>",
"provider": "zai-web"
}
},
"keyCount": 137,
"sharedInstances": []
}

View File

@@ -1,7 +1,7 @@
import { test } from "node:test";
import assert from "node:assert";
import { estimateCompressionTokens } from "../../../open-sse/services/compression/stats.ts";
import { transformAnthropicMessages, transformOpenAIChatCompletions } from "omniglyph";
import { transformAnthropicMessages } from "omniglyph";
const CHARS_PER_TOKEN = 4;
@@ -67,33 +67,3 @@ test("regressão: corpo sem imagem estima o MESMO valor de antes (char-count pur
const expected = Math.ceil(JSON.stringify(plainBody).length / CHARS_PER_TOKEN);
assert.equal(estimateCompressionTokens(plainBody), expected);
});
test("estimateCompressionTokens contabiliza image_url PNG no wire OpenAI", async () => {
const originalBody = {
model: "gpt-5.6",
messages: [
{ role: "system", content: DENSE },
{ role: "user", content: "oi" },
],
};
const encoded = new TextEncoder().encode(JSON.stringify(originalBody));
const result = await transformOpenAIChatCompletions(encoded);
assert.equal(result.info.compressed, true);
const compressedBody = JSON.parse(new TextDecoder().decode(result.body)) as Record<
string,
unknown
>;
assert.ok(JSON.stringify(compressedBody).includes('"type":"image_url"'));
const originalEstimate = estimateCompressionTokens(originalBody);
const compressedEstimate = estimateCompressionTokens(compressedBody);
const naiveEstimate = Math.ceil(JSON.stringify(compressedBody).length / CHARS_PER_TOKEN);
assert.ok(
compressedEstimate < naiveEstimate,
`expected image-aware (${compressedEstimate}) < base64 char estimate (${naiveEstimate})`
);
assert.ok(
compressedEstimate < originalEstimate,
`expected OpenAI image compression (${compressedEstimate}) < original (${originalEstimate})`
);
});

View File

@@ -18,17 +18,11 @@ function claudeBody(): Record<string, unknown> {
messages: [{ role: "user", content: [{ type: "text", text: "oi" }] }],
};
}
const OK = {
model: "claude-fable-5",
supportsVision: true,
providerTransport: "direct" as const,
imageTransportFidelity: "byte-preserving" as const,
};
const OK = { model: "claude-fable-5", supportsVision: true, providerTransport: "direct" as const };
const GPT_OK = {
model: "gpt-5.6",
supportsVision: true,
providerTransport: "direct" as const,
imageTransportFidelity: "byte-preserving" as const,
sourceFormat: "openai" as const,
targetFormat: "openai" as const,
compressionStage: "post-translation" as const,
@@ -88,15 +82,6 @@ test("skip fail-closed: sem supportsVision / transporte agregador / undefined",
}
});
test("skip fail-closed: rota direta sem recibo de fidelidade de imagem", async () => {
const r = await omniglyphEngine.applyAsync!(claudeBody(), {
...OK,
imageTransportFidelity: "unknown",
});
assert.equal(r.compressed, false);
assert.ok(r.stats?.techniquesUsed.includes("skip:transport_fidelity_unknown"));
});
test("skip: modelo fora da allowlist medida", async () => {
const body = { ...claudeBody(), model: "gpt-5.5" };
const r = await omniglyphEngine.applyAsync!(body, { ...OK, model: "gpt-5.5" });
@@ -125,31 +110,6 @@ test("cache_control do cliente sobrevive byte a byte", async () => {
assert.ok(JSON.stringify(r.body).includes('"cache_control"'));
});
test("preserveSystemPrompt mantém o sistema nativo e ainda pode comprimir tool_result", async () => {
const body = {
...claudeBody(),
messages: [
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "call_1",
content: DENSE,
},
],
},
],
};
const r = await omniglyphEngine.applyAsync!(body, {
...OK,
config: { preserveSystemPrompt: true } as never,
});
assert.equal(r.compressed, true);
assert.equal((r.body as { system?: unknown }).system, DENSE);
assert.ok(JSON.stringify(r.body).includes('"type":"image"'));
});
test("apply síncrono é pass-through seguro (engine async-only)", () => {
const body = claudeBody();
const r = omniglyphEngine.apply(body, OK);
@@ -187,139 +147,3 @@ test("OpenAI não roda no estágio pré-tradução", async () => {
assert.equal(r.compressed, false);
assert.ok(r.stats?.techniquesUsed.includes("skip:requires_post_translation"));
});
// OmniGlyph 1.4.0 introduziu escopos de segurança (`coding-safe`/`balanced`/
// `aggressive`/`passthrough`) e passou a resolvê-los, dentro de
// `isOmniGlyphSupportedModel()`, lendo `process.env.OMNIGLYPH_PROFILE`. Isso
// transforma uma variável de ambiente do HOST num gate silencioso de TODO
// request do OmniRoute: um `OMNIGLYPH_PROFILE=passthrough` exportado no shell
// do processo desligaria a engine sem que nenhuma configuração do OmniRoute
// tivesse mudado — e sem nenhum sinal na UI. A política é do OmniRoute; o
// adapter tem de passar o escopo explicitamente.
async function withEnv<T>(key: string, value: string, fn: () => Promise<T>): Promise<T> {
const had = Object.prototype.hasOwnProperty.call(process.env, key);
const previous = process.env[key];
process.env[key] = value;
try {
return await fn();
} finally {
if (had) process.env[key] = previous;
else delete process.env[key];
}
}
test("OMNIGLYPH_PROFILE do host não decide o gate de modelo do OmniRoute", async () => {
const r = await withEnv("OMNIGLYPH_PROFILE", "passthrough", () =>
omniglyphEngine.applyAsync!(claudeBody(), OK)
);
assert.equal(
r.compressed,
true,
"env do processo não pode desligar a engine: o escopo vem da config do OmniRoute"
);
});
test("OMNIGLYPH_PROFILE do host não amplia a allowlist de modelos do OmniRoute", async () => {
const body = { ...claudeBody(), model: "claude-sonnet-5" };
const r = await withEnv("OMNIGLYPH_PROFILE", "aggressive", () =>
withEnv("OMNIGLYPH_MODELS", "claude-fable-5,claude-sonnet-5", () =>
omniglyphEngine.applyAsync!(body, { ...OK, model: "claude-sonnet-5" })
)
);
assert.equal(r.compressed, false, "modelo sem recibo medido não pode entrar via env do host");
assert.ok(r.stats?.techniquesUsed.includes("skip:model_not_approved"));
});
// ---------------------------------------------------------------------------
// Perfis semânticos (OmniGlyph 1.4.0)
//
// `transformAnthropicMessages()` resolve e mescla o perfil sozinho, mas os
// transformadores OpenAI recebem `TransformOptions` cru e NÃO conhecem
// `profile`. Sem o merge explícito do host, um perfil escolhido pelo operador
// valeria no wire Claude e seria silenciosamente ignorado no wire OpenAI.
// ---------------------------------------------------------------------------
/** Histórico longo o bastante para o colapso valer mesmo com o system nativo. */
function claudeBodyWithHistory(): Record<string, unknown> {
const messages: Array<Record<string, unknown>> = [];
for (let i = 0; i < 40; i++) {
messages.push({ role: "user", content: [{ type: "text", text: `pergunta ${i}: ${DENSE}` }] });
messages.push({
role: "assistant",
content: [{ type: "text", text: `resposta ${i}: ${DENSE}` }],
});
}
messages.push({ role: "user", content: [{ type: "text", text: "oi" }] });
return { model: "claude-fable-5", max_tokens: 128, system: DENSE, messages };
}
test("perfil coding-safe chega ao wire OpenAI (não só ao wrapper Anthropic)", async () => {
const aggressive = await omniglyphEngine.applyAsync!(openaiChatBody(), {
...GPT_OK,
stepConfig: { profile: "aggressive" } as never,
});
assert.equal(aggressive.compressed, true, "aggressive é a política medida atual");
const codingSafe = await omniglyphEngine.applyAsync!(openaiChatBody(), {
...GPT_OK,
stepConfig: { profile: "coding-safe" } as never,
});
assert.equal(
codingSafe.compressed,
false,
"coding-safe mantém system e schemas de tools nativos no wire OpenAI"
);
assert.ok(
codingSafe.stats?.techniquesUsed.some((t) => t.startsWith("skip:below_min_chars")),
`esperado skip por minCompressChars, veio ${JSON.stringify(codingSafe.stats?.techniquesUsed)}`
);
});
test("perfil é TETO, não piso: coding-safe mantém o system nativo mesmo sem preserveSystemPrompt", async () => {
const body = claudeBodyWithHistory();
const r = await omniglyphEngine.applyAsync!(body, {
...OK,
stepConfig: { profile: "coding-safe", preserveSystemPrompt: false } as never,
});
assert.equal(r.compressed, true, "o histórico antigo ainda colapsa");
assert.equal(
(r.body as { system?: unknown }).system,
DENSE,
"coding-safe não deixa um override do chamador reabrir a compressão do system"
);
});
test("perfil passthrough desliga a engine sem tocar no corpo", async () => {
const body = claudeBodyWithHistory();
const r = await omniglyphEngine.applyAsync!(body, {
...OK,
stepConfig: { profile: "passthrough" } as never,
});
assert.equal(r.compressed, false);
assert.ok(r.stats?.techniquesUsed.includes("skip:profile_passthrough"));
assert.deepEqual(r.body, body);
});
test("perfil inválido falha fechado, não propaga exceção", async () => {
const r = await omniglyphEngine.applyAsync!(claudeBody(), {
...OK,
stepConfig: { profile: "turbo-max" } as never,
});
assert.equal(r.compressed, false);
assert.ok(r.stats?.techniquesUsed.includes("skip:invalid_profile"));
});
test("preserveSystemPrompt: wire OpenAI pula, porque o pacote não sabe preservar system lá", async () => {
// O transform OpenAI do OmniGlyph 1.4.0 honra apenas compressTools, gptHistory,
// minCompressChars e reflow — não existe compressSystem nesse wire, e a
// instrução vira sempre um ponteiro para a imagem. Imagear assim queimaria o
// prefixo quente que a decisão cache-aware do OmniRoute mandou preservar, e o
// OmniRoute não teria como saber. Sem opção de honrar a política, pula.
const r = await omniglyphEngine.applyAsync!(openaiChatBody(), {
...GPT_OK,
config: { preserveSystemPrompt: true } as never,
});
assert.equal(r.compressed, false);
assert.ok(r.stats?.techniquesUsed.includes("skip:system_preservation_unsupported_on_wire"));
assert.deepEqual(r.body, openaiChatBody());
});

View File

@@ -1,27 +1,12 @@
import { readFileSync } from "node:fs";
import assert from "node:assert/strict";
import { test } from "node:test";
import { resolveOmniGlyphTransport } from "../../../open-sse/services/compression/imageTransportPolicy.ts";
test("chatCore uses the measured Anthropic byte-preserving transport policy", () => {
test("chatCore treats both Anthropic providers as direct OmniGlyph transports", () => {
const chatCore = readFileSync("open-sse/handlers/chatCore.ts", "utf8");
assert.match(chatCore, /resolveOmniGlyphTransport\(provider\)/);
const translationIndex = chatCore.indexOf("translatedBody = translateRequest(");
const postCompressionIndex = chatCore.indexOf("if (runPostTranslationCompression");
assert.ok(translationIndex >= 0, "chatCore deve manter a tradução explícita");
assert.ok(postCompressionIndex > translationIndex, "OmniGlyph target-wire roda após tradução");
assert.match(chatCore, /compressionStage: "post-translation"/);
assert.deepEqual(resolveOmniGlyphTransport("anthropic"), {
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
});
assert.deepEqual(resolveOmniGlyphTransport("claude"), {
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
});
assert.deepEqual(resolveOmniGlyphTransport("openai"), {
providerTransport: "aggregator",
imageTransportFidelity: "unknown",
});
assert.match(
chatCore,
/providerTransport:\s*provider === "anthropic" \|\| provider === "claude"[\s\S]{0,80}?"direct"/
);
});

View File

@@ -6,7 +6,6 @@ test("pacote omniglyph exporta a API que o adapter consome", async () => {
assert.equal(typeof mod.transformAnthropicMessages, "function");
assert.equal(typeof mod.transformOpenAIChatCompletions, "function");
assert.equal(typeof mod.transformOpenAIResponses, "function");
assert.equal(typeof mod.transformRequest, "function");
assert.equal(typeof mod.isOmniGlyphSupportedModel, "function");
assert.equal(typeof mod.isOmniGlyphSupportedGptModel, "function");
assert.equal(mod.isOmniGlyphSupportedModel("claude-fable-5"), true);
@@ -15,30 +14,3 @@ test("pacote omniglyph exporta a API que o adapter consome", async () => {
const applicability = await import("omniglyph/applicability");
assert.equal(typeof applicability.isModelImageable, "function");
});
// Superfícies introduzidas no 1.4.0. Sem esta asserção, uma remoção upstream só
// apareceria em runtime — o adapter importa esses símbolos diretamente.
test("omniglyph 1.4.0 exporta escopo de segurança, perfis e accounting", async () => {
const mod = await import("omniglyph");
// Gate de modelo por escopo explícito (não pela env do processo).
assert.equal(typeof mod.isOmniGlyphSupportedModelForScope, "function");
assert.equal(mod.isOmniGlyphSupportedModelForScope("claude-fable-5", "coding-safe"), true);
assert.equal(mod.isOmniGlyphSupportedModelForScope("claude-sonnet-5", "coding-safe"), false);
assert.equal(
mod.isOmniGlyphSupportedModelForScope("claude-fable-5", "passthrough"),
false,
"passthrough não habilita modelo nenhum"
);
// Perfis semânticos.
assert.equal(typeof mod.resolveCompressionProfile, "function");
assert.equal(typeof mod.mergeCompressionProfileOptions, "function");
assert.equal(typeof mod.shouldKeepToolResultSharp, "function");
assert.equal(mod.resolveCompressionProfile("coding-safe").name, "coding-safe");
assert.throws(() => mod.resolveCompressionProfile("nao-existe"));
// Contabilidade física normalizada.
assert.equal(typeof mod.normalizeAccounting, "function");
assert.equal(typeof mod.providerActualInputTokens, "function");
});

View File

@@ -18,20 +18,6 @@ const body = () => ({
messages: [{ role: "user", content: [{ type: "text", text: "oi" }] }],
});
const openaiBody = () => ({
model: "gpt-5.6",
messages: [
{ role: "system", content: DENSE },
{ role: "user", content: "oi" },
],
});
const responsesBody = () => ({
model: "gpt-5.6",
instructions: DENSE,
input: [{ type: "message", role: "user", content: [{ type: "input_text", text: "oi" }] }],
});
// Agora que `estimateCompressionTokens` (stats.ts) é image-aware (Task 6), o guard
// honesto de inflação agregada do stacked (`guardPipelineInflation` em
// pipelineGuards.ts) não reverte mais a saída imageada do omniglyph: o estimador
@@ -44,7 +30,6 @@ test("stacked com step omniglyph recebe providerTransport (engine roda, não é
model: "claude-fable-5",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
config: { stackedPipeline: [{ engine: "rtk" }, { engine: "omniglyph" }] } as never,
});
const omniglyphStep = r.stats?.engineBreakdown?.find((e) => e.engine === "omniglyph");
@@ -74,122 +59,3 @@ test("stacked sem providerTransport 'direct' pula omniglyph (transport_not_direc
assert.ok(omniglyphStep, "omniglyph step deveria aparecer no engineBreakdown mesmo pulado");
assert.ok(omniglyphStep!.techniquesUsed.includes("skip:transport_not_direct"));
});
test("stacked pós-tradução preserva o wire OpenAI Chat e executa OmniGlyph nativo", async () => {
registerBuiltinCompressionEngines();
const r = await applyCompressionAsync(openaiBody(), "stacked", {
model: "gpt-5.6",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
sourceFormat: "openai",
targetFormat: "openai",
compressionStage: "post-translation",
config: { stackedPipeline: [{ engine: "rtk" }, { engine: "omniglyph" }] } as never,
});
const omniglyphStep = r.stats?.engineBreakdown?.find((e) => e.engine === "omniglyph");
assert.ok(omniglyphStep);
assert.ok(omniglyphStep!.techniquesUsed.includes("omniglyph:context-as-image"));
assert.equal(r.compressed, true);
assert.ok(JSON.stringify(r.body).includes('"type":"image_url"'));
assert.ok(
r.stats?.validationWarnings?.some((warning) => warning.includes("rtk: skipped (stage")),
"engines sem suporte ao estágio devem ser explicitamente pulados"
);
});
test("stacked pós-tradução não adapta input[] Responses para messages[] antes do OmniGlyph", async () => {
registerBuiltinCompressionEngines();
const r = await applyCompressionAsync(responsesBody(), "stacked", {
model: "gpt-5.6",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
sourceFormat: "openai-responses",
targetFormat: "openai-responses",
compressionStage: "post-translation",
config: { stackedPipeline: [{ engine: "omniglyph" }] } as never,
});
assert.equal(r.compressed, true);
assert.ok(JSON.stringify(r.body).includes('"type":"input_image"'));
assert.ok(Array.isArray((r.body as { input?: unknown }).input));
});
test("OpenAI→Claude usa o wire traduzido sem uma segunda tradução", async () => {
registerBuiltinCompressionEngines();
const translatedClaudeBody = body();
const r = await applyCompressionAsync(translatedClaudeBody, "omniglyph", {
model: "claude-fable-5",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
sourceFormat: "openai",
targetFormat: "claude",
compressionStage: "post-translation",
});
assert.equal(r.compressed, true);
assert.ok(JSON.stringify(r.body).includes('"type":"image"'));
assert.ok(!JSON.stringify(r.body).includes('"type":"image_url"'));
});
test("Claude→OpenAI aguarda o wire alvo e não imageia o corpo fonte", async () => {
registerBuiltinCompressionEngines();
const pre = await applyCompressionAsync(body(), "omniglyph", {
model: "claude-fable-5",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
sourceFormat: "claude",
targetFormat: "openai",
compressionStage: "pre-translation",
});
assert.equal(pre.compressed, false);
assert.ok(pre.stats?.techniquesUsed.includes("skip:requires_post_translation"));
const post = await applyCompressionAsync(
{
model: "gpt-5.6",
messages: [
{ role: "system", content: DENSE },
{ role: "user", content: "oi" },
],
},
"omniglyph",
{
model: "gpt-5.6",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
sourceFormat: "claude",
targetFormat: "openai",
compressionStage: "post-translation",
}
);
assert.equal(post.compressed, true);
assert.ok(JSON.stringify(post.body).includes('"type":"image_url"'));
});
// O `provider` é threaded explicitamente por cada camada do selector (não é um
// spread cego), então uma camada nova pode derrubá-lo em silêncio: a
// contabilidade cairia para `unknown` e passaria a recusar a semântica de cache
// sem nenhum erro aparecer.
test("provider chega do selector até a contabilidade da engine", async () => {
registerBuiltinCompressionEngines();
const r = await applyCompressionAsync(body(), "stacked", {
model: "claude-fable-5",
provider: "anthropic",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
config: { stackedPipeline: [{ engine: "omniglyph" }] } as never,
});
assert.equal(r.compressed, true);
const omniglyphStep = r.stats?.engineBreakdown?.find((e) => e.engine === "omniglyph");
assert.ok(omniglyphStep, "omniglyph step deveria aparecer no engineBreakdown");
assert.equal(
omniglyphStep!.omniglyph?.provider,
"anthropic",
"sem o provider a contabilidade cai para unknown e recusa a semântica de cache"
);
assert.equal(omniglyphStep!.omniglyph?.savings.evidence, "bytes-only");
});

View File

@@ -1,83 +0,0 @@
/**
* Perfil semântico do OmniGlyph (pacote 1.4.0) — persistência ponta a ponta.
*
* Cobre:
* 1. compressionSettingsUpdateSchema aceita omniglyph:{profile} e RECUSA nome inválido
* 2. updateCompressionSettings / getCompressionSettings fazem round-trip do perfil
* 3. o default persistido é `aggressive` (a política que os recibos mediram)
* 4. um perfil desconhecido vindo do storage cai para o default, não vaza adiante
*/
import { describe, it, beforeEach, afterEach, after } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { compressionSettingsUpdateSchema } from "../../../src/shared/validation/compressionConfigSchemas.ts";
import { DEFAULT_OMNIGLYPH_CONFIG } from "../../../open-sse/services/compression/types.ts";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-omniglyph-profile-"));
const ORIGINAL_DATA_DIR = process.env.DATA_DIR;
process.env.DATA_DIR = TEST_DATA_DIR;
const core = await import("../../../src/lib/db/core.ts");
const { getCompressionSettings, updateCompressionSettings } = await import(
"../../../src/lib/db/compression.ts"
);
beforeEach(() => {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
});
afterEach(() => {
core.resetDbInstance();
});
after(() => {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
if (ORIGINAL_DATA_DIR === undefined) delete process.env.DATA_DIR;
else process.env.DATA_DIR = ORIGINAL_DATA_DIR;
});
describe("omniglyph profile config", () => {
it("o schema aceita os quatro perfis e recusa qualquer outro nome", () => {
for (const profile of ["coding-safe", "balanced", "aggressive", "passthrough"]) {
const parsed = compressionSettingsUpdateSchema.safeParse({ omniglyph: { profile } });
assert.equal(parsed.success, true, `perfil válido recusado: ${profile}`);
}
// Um nome inválido tem de morrer no schema. Se passar, o adapter ainda falha
// fechado (skip:invalid_profile), mas o operador veria a engine desligada
// sem nenhum erro na tela de configuração.
assert.equal(
compressionSettingsUpdateSchema.safeParse({ omniglyph: { profile: "turbo-max" } }).success,
false
);
assert.equal(
compressionSettingsUpdateSchema.safeParse({ omniglyph: { profile: "" } }).success,
false
);
});
it("o default é aggressive — a política que os recibos publicados mediram", async () => {
assert.equal(DEFAULT_OMNIGLYPH_CONFIG.profile, "aggressive");
assert.equal((await getCompressionSettings()).omniglyph?.profile, "aggressive");
});
it("round-trip do perfil escolhido pelo operador", async () => {
await updateCompressionSettings({ omniglyph: { profile: "coding-safe" } });
assert.equal((await getCompressionSettings()).omniglyph?.profile, "coding-safe");
await updateCompressionSettings({ omniglyph: { profile: "passthrough" } });
assert.equal((await getCompressionSettings()).omniglyph?.profile, "passthrough");
});
it("perfil desconhecido no storage cai para o default em vez de vazar adiante", async () => {
await updateCompressionSettings({ omniglyph: { profile: "coding-safe" } });
// Simula uma linha gravada por uma versão futura/adulterada, contornando o schema.
await updateCompressionSettings({ omniglyph: { profile: "turbo-max" } } as never);
assert.equal((await getCompressionSettings()).omniglyph?.profile, "aggressive");
});
});

View File

@@ -3,13 +3,8 @@ import assert from "node:assert";
import { applyCompressionAsync } from "../../../open-sse/services/compression/strategySelector.ts";
import { registerBuiltinCompressionEngines } from "../../../open-sse/services/compression/engines/index.ts";
const DENSE =
"X".repeat(500) +
"\n" +
Array.from(
{ length: 400 },
(_, i) => `const row_${i} = compute(${i * 17}, "${"v".repeat(80)}");`
).join("\n");
const DENSE = "X".repeat(500) + "\n" +
Array.from({ length: 400 }, (_, i) => `const row_${i} = compute(${i * 17}, "${"v".repeat(80)}");`).join("\n");
const body = () => ({
model: "claude-fable-5",
max_tokens: 128,
@@ -23,7 +18,6 @@ test("modo omniglyph sozinho comprime (selecionar o modo é o enable)", async ()
model: "claude-fable-5",
supportsVision: true,
providerTransport: "direct",
imageTransportFidelity: "byte-preserving",
});
assert.equal(r.compressed, true);
assert.ok(JSON.stringify(r.body).includes('"type":"image"'));

View File

@@ -1,121 +0,0 @@
import { test } from "node:test";
import assert from "node:assert";
import { omniglyphEngine } from "../../../open-sse/services/compression/engines/omniglyphAdapter.ts";
// O OmniGlyph 1.4.0 expõe `normalizeAccounting()`, que classifica o GRAU DE
// EVIDÊNCIA da economia (provider-reported / estimated / bytes-only /
// unavailable) e resolve a semântica de cache por provider — Anthropic usa
// buckets disjuntos, OpenAI/xAI reportam cached como subconjunto do input.
// Somar à mão dá double-count. Antes disso o adapter descartava tudo e a UI
// exibia um número sem dizer de onde ele veio.
const SEGREDO = "sk-ant-api03-SEGREDO-QUE-NAO-PODE-VAZAR-NA-TELEMETRIA";
const DENSE =
"X".repeat(500) +
"\n" +
Array.from(
{ length: 400 },
(_, i) => `const row_${i} = compute(${i * 17}, "${"v".repeat(80)}");`
).join("\n");
function claudeBody(): Record<string, unknown> {
return {
model: "claude-fable-5",
max_tokens: 128,
system: `${DENSE}\nAPI_KEY=${SEGREDO}\ncwd=/home/operador/projeto-secreto`,
messages: [{ role: "user", content: [{ type: "text", text: "oi" }] }],
};
}
const OK = {
model: "claude-fable-5",
provider: "anthropic",
supportsVision: true,
providerTransport: "direct" as const,
imageTransportFidelity: "byte-preserving" as const,
};
test("stats do omniglyph carregam a contabilidade normalizada com grau de evidência", async () => {
const r = await omniglyphEngine.applyAsync!(claudeBody(), OK as never);
assert.equal(r.compressed, true);
const accounting = r.stats?.omniglyph;
assert.ok(accounting, "compressão aplicada deve registrar a contabilidade");
assert.equal(accounting.provider, "anthropic");
assert.ok(
["provider-reported", "estimated", "bytes-only", "unavailable"].includes(
accounting.savings.evidence
),
`evidência inesperada: ${accounting.savings.evidence}`
);
// Sem contadores do provider nesta etapa, a base honesta é o tamanho do corpo.
assert.equal(accounting.savings.evidence, "bytes-only");
assert.ok(typeof accounting.bytes.original === "number" && accounting.bytes.original > 0);
assert.ok(typeof accounting.bytes.transformed === "number");
assert.ok(typeof accounting.images.count === "number" && accounting.images.count > 0);
assert.ok(typeof accounting.images.bytes === "number" && accounting.images.bytes > 0);
});
test("telemetria não carrega conteúdo: nem base64, nem prompt, nem segredo, nem ambiente", async () => {
const r = await omniglyphEngine.applyAsync!(claudeBody(), OK as never);
assert.equal(r.compressed, true);
const serialized = JSON.stringify(r.stats);
// Valores do request.
assert.ok(!serialized.includes(SEGREDO), "segredo do system vazou na telemetria");
assert.ok(!serialized.includes("projeto-secreto"), "caminho do operador vazou");
assert.ok(!serialized.includes("const row_0 = compute"), "texto do system vazou");
assert.ok(!serialized.includes("data:image/png;base64"), "data URL de imagem vazou");
assert.ok(!serialized.includes("iVBORw0KGgo"), "cabeçalho PNG em base64 vazou");
// Chaves do TransformInfo que carregam conteúdo, hash de conteúdo ou ambiente.
for (const proibida of [
"imageSourceText",
"imageSourceTexts",
"recoverable",
"systemSha8",
"claudeMdSha8",
"firstUserSha8",
"unknownStaticTags",
"churningStaticTags",
'"env"',
]) {
assert.ok(!serialized.includes(proibida), `campo proibido na telemetria: ${proibida}`);
}
// A allowlist é positiva: todo valor da contabilidade é número, string de enum
// conhecida, ou objeto desses. Nada de texto livre vindo do request.
const accounting = r.stats?.omniglyph;
assert.ok(accounting);
const enums = new Set([
"anthropic",
"openai",
"xai",
"unknown",
"provider-reported",
"estimated",
"bytes-only",
"unavailable",
"claude-fable-5",
]);
const walk = (value: unknown, path: string): void => {
if (value === undefined || value === null || typeof value === "number") return;
if (typeof value === "string") {
assert.ok(enums.has(value), `string fora da allowlist em ${path}: ${value}`);
return;
}
assert.equal(typeof value, "object", `tipo inesperado em ${path}`);
for (const [k, v] of Object.entries(value as Record<string, unknown>)) walk(v, `${path}.${k}`);
};
walk(accounting, "omniglyph");
});
test("skip não inventa contabilidade", async () => {
const r = await omniglyphEngine.applyAsync!(claudeBody(), {
...OK,
imageTransportFidelity: "unknown",
} as never);
assert.equal(r.compressed, false);
assert.equal(r.stats?.omniglyph, undefined);
});

View File

@@ -0,0 +1,134 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
// R0.3 GOLDEN LOCK (characterization BEFORE the ExecutorRegistry refactor):
// freeze the full provider-id → executor mapping of open-sse/executors/index.ts —
// every specialized key with its executor class, effective provider identity and
// which PROVIDERS config entry backs it — plus the getExecutor() dispatch rules
// (specialized hit, DefaultExecutor fallback + cache, cloud-agent guard #6699,
// search-provider guard #10274). The registry refactor must keep this snapshot
// byte-identical: any drift in keys, classes, provider identity or guard behavior
// is a golden diff, not a silent routing change.
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-executor-golden-"));
process.env.DATA_DIR = TEST_DATA_DIR;
// Dynamic imports AFTER DATA_DIR is set so db/core.ts picks up the temp path.
const { getExecutor, hasSpecializedExecutor, DefaultExecutor } = await import(
"../../open-sse/executors/index.ts"
);
const { PROVIDERS } = await import("../../open-sse/config/constants.ts");
const { SEARCH_PROVIDERS } = await import("../../open-sse/config/searchRegistry.ts");
const { goldenSnapshot } = await import("../helpers/goldenSnapshot.ts");
test.after(() => {
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
});
// The specialized keys are not exported; enumerate them through the public
// surface by probing every plausible id source AND the literal keys read from
// the module source. Reading the source keeps the golden honest: a key added
// to (or removed from) the hard-coded map cannot hide from the snapshot.
function readSpecializedKeys(): string[] {
const src = fs.readFileSync(
path.resolve(path.dirname(new URL(import.meta.url).pathname), "../../open-sse/executors/index.ts"),
"utf8"
);
const mapMatch = src.match(/const executors = \{([\s\S]*?)\n\};/);
assert.ok(mapMatch, "executors map literal not found in open-sse/executors/index.ts");
const keys: string[] = [];
for (const line of mapMatch[1].split("\n")) {
const m = line.match(/^\s*(?:"([^"]+)"|([A-Za-z0-9_$-]+)):\s*new /);
if (m) keys.push(m[1] ?? m[2]);
}
return keys;
}
// Map a ProviderConfig object back to its PROVIDERS key by identity, so the
// snapshot records WHICH config backs each executor without freezing the whole
// (huge, frequently-edited) config content.
const providerConfigKeyByRef = new Map<object, string>();
for (const [key, cfg] of Object.entries(PROVIDERS)) {
if (cfg && typeof cfg === "object" && !providerConfigKeyByRef.has(cfg)) {
providerConfigKeyByRef.set(cfg, key);
}
}
function describeExecutor(instance: unknown): {
className: string;
provider: string | null;
configSource: string | null;
} {
const inst = instance as { constructor: { name: string }; provider?: string; config?: object };
const cfg = inst.config;
return {
className: inst.constructor.name,
provider: typeof inst.provider === "string" ? inst.provider : null,
configSource:
cfg == null ? null : (providerConfigKeyByRef.get(cfg) ?? "<custom-config>"),
};
}
const specializedKeys = readSpecializedKeys();
test("golden: specialized executor map — key → class + provider identity + config source", () => {
assert.ok(specializedKeys.length >= 100, `suspiciously few keys: ${specializedKeys.length}`);
const entries: Record<
string,
{ className: string; provider: string | null; configSource: string | null }
> = {};
const byInstance = new Map<unknown, string[]>();
for (const key of [...specializedKeys].sort()) {
assert.equal(hasSpecializedExecutor(key), true, `hasSpecializedExecutor(${key})`);
const instance = getExecutor(key);
entries[key] = describeExecutor(instance);
const group = byInstance.get(instance) ?? [];
group.push(key);
byInstance.set(instance, group);
}
// Keys sharing the SAME instance share per-instance state (session pools,
// rotation cooldowns); today every map entry is its own `new X()`. Freeze that.
const sharedInstances = [...byInstance.values()]
.filter((keys) => keys.length > 1)
.map((keys) => keys.sort())
.sort((a, b) => a[0].localeCompare(b[0]));
goldenSnapshot("executors/executor-map", {
keyCount: specializedKeys.length,
entries,
sharedInstances,
});
});
test("golden: getExecutor dispatch rules — fallback, cache and 400-guards", () => {
// 1. Unknown provider → DefaultExecutor for that provider, memoized.
const unknown = "golden-test-unknown-provider";
assert.equal(hasSpecializedExecutor(unknown), false);
const fallback = getExecutor(unknown);
assert.ok(fallback instanceof DefaultExecutor, "fallback must be DefaultExecutor");
assert.equal(getExecutor(unknown), fallback, "DefaultExecutor fallback must be cached");
// 2. Cloud-agent guard (#6699) and search guard (#10274) → status-400 throw.
const guardOutcome = (provider: string) => {
try {
getExecutor(provider);
return { throws: false as const };
} catch (err) {
const e = err as Error & { status?: number };
return { throws: true as const, status: e.status ?? null, message: e.message };
}
};
const searchProviders = Object.keys(SEARCH_PROVIDERS).sort();
goldenSnapshot("executors/dispatch-rules", {
fallback: describeExecutor(fallback),
cloudAgentGuard: { jules: guardOutcome("jules") },
searchGuard: Object.fromEntries(searchProviders.map((p) => [p, guardOutcome(p)])),
});
});

View File

@@ -0,0 +1,57 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
// R0.3 — unit tests for the ExecutorRegistry seam itself (registration
// semantics + wiring of the built-ins). Behavior parity of the full map is
// covered separately by tests/unit/executor-map-golden.test.ts.
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-executor-registry-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const { registerExecutor, getRegisteredExecutor, hasRegisteredExecutor, listExecutorAliases } =
await import("../../open-sse/executors/registry.ts");
const { getExecutor, hasSpecializedExecutor, BaseExecutor, DefaultExecutor } = await import(
"../../open-sse/executors/index.ts"
);
test.after(() => {
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
});
test("built-ins are registered at module load and resolve through the registry", () => {
const aliases = listExecutorAliases();
assert.ok(aliases.length >= 100, `expected the built-in table, got ${aliases.length} aliases`);
for (const alias of ["antigravity", "kiro", "glm", "9router", "conol-web"]) {
assert.ok(hasRegisteredExecutor(alias), `missing built-in: ${alias}`);
assert.equal(getExecutor(alias), getRegisteredExecutor(alias));
assert.ok(getExecutor(alias) instanceof BaseExecutor);
}
});
test("registerExecutor throws on duplicate alias", () => {
assert.throws(() => registerExecutor("kiro", getRegisteredExecutor("kiro")!), {
message: /already registered: "kiro"/,
});
});
test("registering a new alias makes it resolvable via getExecutor and hasSpecializedExecutor", () => {
const alias = "registry-test-provider";
assert.equal(hasSpecializedExecutor(alias), false);
const instance = new DefaultExecutor(alias);
registerExecutor(alias, instance);
assert.equal(hasSpecializedExecutor(alias), true);
assert.equal(getExecutor(alias), instance);
});
test("registry lookup is exact — Object.prototype names are not executors", () => {
// The old object-literal lookup (`executors[provider]`) leaked prototype
// members: getExecutor("constructor") returned Object's constructor. The Map
// registry must treat these as unknown providers (DefaultExecutor fallback).
for (const name of ["constructor", "toString", "hasOwnProperty", "__proto__"]) {
assert.equal(hasSpecializedExecutor(name), false, name);
assert.ok(getExecutor(name) instanceof DefaultExecutor, name);
}
});

View File

@@ -108,11 +108,7 @@ describe("OmniglyphContextPage", () => {
expect(img!.getAttribute("src")).toMatch(/^data:image\/png;base64,/);
// Gates
expect(text).toContain("claude-fable-5");
// A cópia do gate deixou de dizer "direct Anthropic" quando os wires OpenAI
// nativos entraram: transporte direto é condição de TODO provider, e o que
// restringe a rota ao Anthropic é o recibo de fidelidade de bytes, não o
// rótulo do transporte.
expect(text).toContain("direct provider");
expect(text).toContain("direct Anthropic");
// Config control
expect(container.querySelector('[data-testid="omniglyph-enable-toggle"]')).toBeTruthy();
});
@@ -142,66 +138,4 @@ describe("OmniglyphContextPage", () => {
expect(engines.rtk?.enabled).toBe(true);
expect(engines.caveman?.enabled).toBe(false);
});
it("carrega o perfil salvo e faz PATCH só do perfil, sem reescrever o mapa de engines", async () => {
const puts: CapturedPut[] = [];
const json = (body: unknown, status = 200) =>
new Response(JSON.stringify(body), {
status,
headers: { "Content-Type": "application/json" },
});
const stored = {
enabled: true,
engines: { rtk: { enabled: true, level: "standard" } },
omniglyph: { profile: "coding-safe" },
};
vi.spyOn(globalThis, "fetch").mockImplementation(
async (input: RequestInfo | URL, init?: RequestInit) => {
const url = input.toString();
const method = (init?.method ?? "GET").toUpperCase();
if (url.includes("/api/settings/compression")) {
if (method === "PUT") {
puts.push({ url, body: JSON.parse(String(init?.body ?? "{}")) });
return json(stored);
}
return json(stored);
}
return json({}, 404);
}
);
const { default: Page } = await import(
"../../../src/app/(dashboard)/dashboard/context/omniglyph/OmniglyphContextPageClient"
);
let container!: HTMLElement;
await act(async () => {
container = mount(<Page />);
});
await flush();
const select = container.querySelector(
'[data-testid="omniglyph-profile-select"]'
) as HTMLSelectElement | null;
expect(select, "o seletor de perfil deve existir").toBeTruthy();
expect(select!.value, "o perfil salvo tem de vir selecionado").toBe("coding-safe");
// Os quatro perfis do pacote, com aggressive como primeiro (default).
expect(Array.from(select!.options).map((o) => o.value)).toEqual([
"aggressive",
"balanced",
"coding-safe",
"passthrough",
]);
await act(async () => {
select!.value = "passthrough";
select!.dispatchEvent(new Event("change", { bubbles: true }));
});
await flush();
expect(puts.length).toBe(1);
expect(puts[0]!.body).toEqual({ omniglyph: { profile: "passthrough" } });
// O perfil vive fora do mapa `engines`: mandá-lo junto reescreveria o mapa inteiro.
expect(puts[0]!.body.engines).toBeUndefined();
});
});

View File

@@ -88,6 +88,7 @@ export default defineConfig({
"src/app/(dashboard)/dashboard/endpoint/__tests__/ApiEndpointsTab.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed
"tests/unit/ui/compression-combos-routing-mode-6760.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed
"tests/unit/ui/use-local-storage-pool-migration.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed
"tests/unit/ui/omniglyphContextPage.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed
"tests/unit/ui/waterfallInspector.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed
"tests/unit/ui/playground-compare-column.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed
"tests/unit/ui/playground-chat-tab.test.tsx", // #8618 — pre-existing failure; remove this exclusion when fixed