Files
OmniRoute/src/lib/db/compression.ts
oyi77 88dbefa141 feat(compression): reconcile Phase 2 with Phase 1 API surface
- Use 'standard' mode (not 'caveman') in CompressionMode type
- Align CompressionConfig with Phase 1 shape (enabled, defaultMode,
  autoTriggerTokens, cacheMinutes, preserveSystemPrompt, comboOverrides)
- Extend CompressionStats with techniquesUsed + rulesApplied + durationMs
- Make CompressionResult.stats nullable (Phase 1 compat)
- Add Phase 1 functions: estimateCompressionTokens, createCompressionStats,
  trackCompressionStats, selectCompressionStrategy, applyCompression,
  checkComboOverride, shouldAutoTrigger, getEffectiveMode
- Add lite.ts stub for Phase 1 'lite' compression mode
- Add index.ts barrel file for full module export
- Fix DB compression.ts to return Phase 1 CompressionConfig shape
- Fix chatCore.ts to use unified compression pipeline
  (selectCompressionStrategy + applyCompression)
- Add backwards-compatible estimateTokensForStats alias
- Renumber migration 028 → 030 (Phase 1 uses 028)
- Update all tests for reconciled API (67/67 pass)
2026-04-28 00:25:45 +07:00

99 lines
2.9 KiB
TypeScript

import { getDbInstance } from "./core.ts";
import { invalidateDbCache } from "./readCache.ts";
import {
DEFAULT_COMPRESSION_CONFIG,
DEFAULT_CAVEMAN_CONFIG,
} from "../../../open-sse/services/compression/types.ts";
import type {
CompressionConfig,
CavemanConfig,
CompressionMode,
} from "../../../open-sse/services/compression/types.ts";
const NAMESPACE = "compression";
type JsonRecord = Record<string, unknown>;
function toRecord(value: unknown): JsonRecord {
return value && typeof value === "object" ? (value as JsonRecord) : {};
}
function parseJsonSafe(raw: string | null): unknown {
if (!raw) return undefined;
try {
return JSON.parse(raw);
} catch {
return undefined;
}
}
export function getCompressionSettings(): CompressionConfig {
const db = getDbInstance();
const rows = db.prepare("SELECT key, value FROM key_value WHERE namespace = ?").all(NAMESPACE);
const config: CompressionConfig = {
...DEFAULT_COMPRESSION_CONFIG,
cavemanConfig: { ...DEFAULT_CAVEMAN_CONFIG },
};
for (const row of rows) {
const record = toRecord(row);
const key = typeof record.key === "string" ? record.key : null;
const rawValue = typeof record.value === "string" ? record.value : null;
if (!key || !rawValue) continue;
const parsed = parseJsonSafe(rawValue);
if (parsed === undefined) continue;
switch (key) {
case "enabled":
config.enabled = !!parsed;
break;
case "defaultMode":
if (["off", "lite", "standard", "aggressive", "ultra"].includes(parsed as string)) {
config.defaultMode = parsed as CompressionMode;
}
break;
case "autoTriggerTokens":
config.autoTriggerTokens = typeof parsed === "number" ? parsed : 0;
break;
case "cacheMinutes":
config.cacheMinutes = typeof parsed === "number" ? parsed : 5;
break;
case "preserveSystemPrompt":
config.preserveSystemPrompt = !!parsed;
break;
case "comboOverrides":
if (typeof parsed === "object" && parsed !== null) {
config.comboOverrides = parsed as Record<string, CompressionMode>;
}
break;
case "cavemanConfig":
if (typeof parsed === "object" && parsed !== null) {
config.cavemanConfig = {
...DEFAULT_CAVEMAN_CONFIG,
...(parsed as Partial<CavemanConfig>),
};
}
break;
}
}
return config;
}
export function updateCompressionSettings(settings: Record<string, unknown>): void {
const db = getDbInstance();
const upsert = db.prepare(
"INSERT INTO key_value (namespace, key, value) VALUES (?, ?, ?) ON CONFLICT(namespace, key) DO UPDATE SET value = excluded.value"
);
const transaction = db.transaction(() => {
for (const [key, value] of Object.entries(settings)) {
upsert.run(NAMESPACE, key, JSON.stringify(value));
}
});
transaction();
invalidateDbCache();
}