Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/quality/file-size-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"_rebaseline_2026_06_16_3972_logs_autorefresh": "Issue #3972 own growth: RequestLoggerV2.tsx 1282->1287 (+5 = the auto-refresh interval now reads the live document.visibilityState each tick instead of a stale mount-time ref, plus a 3-line comment explaining the hidden-tab trap). Cohesive one-spot fix; structural shrink of this component tracked in #3501.",
"_rebaseline_2026_06_16_3976_llm7_byteplus_models": "Issue #3976 own growth: models/route.ts 2489->2494 (+5 = add llm7 + byteplus to NAMED_OPENAI_STYLE_PROVIDERS with an explanatory comment so the import route does a live <baseUrl>/models fetch instead of serving the stale hardcoded registry catalog). Structural shrink of this route tracked in #3789.",
"_rebaseline_2026_06_16_3954_cooldown_epoch": "Issue #3954 own growth: accountFallback.ts 1708->1727 (+19 = a shared cooldownUntilMs() normalizer + its use in isAccountUnavailable/getEarliestRateLimitedUntil/filterAvailableAccounts so a rate_limited_until persisted as a numeric-epoch string is honored, not parsed to NaN) and auth.ts 2216->2219 (+3 = parseFutureDateMs reuses cooldownUntilMs). Cohesive cooldown read-path hardening at the existing chokepoints; one helper, not extractable.",
"_rebaseline_2026_06_16_3960_engine_breakdown": "PR #3960 capture own growth: chatCore.ts 5851->5868 (+17 = persist result.stats.engineBreakdown into the new compression_engine_breakdown table after a stacked compression run, so getPerEngineAnalytics is accurate historically and not live-only). Cohesive analytics-persistence at the existing compression chokepoint; structural shrink of chatCore.ts tracked in #3501.",
"_rebaseline_2026_06_15_3938_perplexity_v218": "PR #3938 own growth: perplexity-web.ts 868->939 (+71 = rebuild buildPplxRequestBody to mirror the current www.perplexity.ai schematized request body — version 2.18, use_schematized_api + the full supported_block_use_cases list, dsl_query, shared requestId for frontend_uuid/client_search_results_cache_key, last_backend_uuid only on follow-ups — plus the x-perplexity-request-* / x-request-id headers replacing the stale X-App-ApiVersion pair that triggered HTTP 400). Cohesive upstream-schema sync in a single executor; not extractable.",
"cap": 800,
"frozen": {
Expand All @@ -36,7 +37,7 @@
"open-sse/executors/muse-spark-web.ts": 1284,
"open-sse/executors/perplexity-web.ts": 1013,
"open-sse/handlers/audioSpeech.ts": 965,
"open-sse/handlers/chatCore.ts": 5851,
"open-sse/handlers/chatCore.ts": 5868,
"open-sse/handlers/imageGeneration.ts": 3777,
"open-sse/handlers/responseSanitizer.ts": 1103,
"open-sse/handlers/search.ts": 1442,
Expand Down
19 changes: 18 additions & 1 deletion open-sse/handlers/chatCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2705,7 +2705,7 @@ export async function handleChatCore({
compressionAnalyticsRecorded = true;
compressionAnalyticsWritePromise = (async () => {
try {
const { insertCompressionAnalyticsRow } =
const { insertCompressionAnalyticsRow, insertCompressionEngineBreakdown } =
await import("../../src/lib/db/compressionAnalytics.ts");
const { calculateCost } = await import("../../src/lib/usage/costCalculator.ts");
const tokensSaved = Math.max(
Expand Down Expand Up @@ -2746,6 +2746,23 @@ export async function handleChatCore({
? rtkPointers.reduce((total, pointer) => total + pointer.bytes, 0)
: null,
});
// Persist the per-engine breakdown of a stacked run so per-engine
// analytics (getPerEngineAnalytics) is accurate historically, not just
// in the live `compression.completed` event.
const engineBreakdown = result.stats.engineBreakdown ?? [];
if (engineBreakdown.length > 0) {
insertCompressionEngineBreakdown(
engineBreakdown.map((b) => ({
timestamp: new Date().toISOString(),
request_id: skillRequestId,
engine: b.engine,
original_tokens: b.originalTokens,
compressed_tokens: b.compressedTokens,
tokens_saved: Math.max(0, b.originalTokens - b.compressedTokens),
duration_ms: b.durationMs ?? null,
}))
);
}
} catch (err) {
log?.debug?.(
"COMPRESSION",
Expand Down
27 changes: 25 additions & 2 deletions open-sse/services/compression/engines/cavemanAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,29 @@ function validateUltraConfig(config: Record<string, unknown>): EngineValidationR
return { valid: errors.length === 0, errors };
}

// Lite only honors `preserveSystemPrompt` (model/vision are runtime, not user config).
// Previously this engine wrongly exposed AGGRESSIVE_SCHEMA, surfacing irrelevant
// summarizer/threshold fields in the per-engine config UI.
const LITE_SCHEMA: EngineConfigField[] = [
{
key: "preserveSystemPrompt",
type: "boolean",
label: "Preserve system prompt",
defaultValue: true,
},
];

function validateLiteConfig(config: Record<string, unknown>): EngineValidationResult {
const errors: string[] = [];
if (
config.preserveSystemPrompt !== undefined &&
typeof config.preserveSystemPrompt !== "boolean"
) {
errors.push("preserveSystemPrompt must be a boolean");
}
return { valid: errors.length === 0, errors };
}

export const liteEngine: CompressionEngine = {
id: "lite",
name: "Lite",
Expand Down Expand Up @@ -240,10 +263,10 @@ export const liteEngine: CompressionEngine = {
return this.apply(body, { stepConfig: config });
},
getConfigSchema() {
return AGGRESSIVE_SCHEMA;
return LITE_SCHEMA;
},
validateConfig(config) {
return validateAggressiveConfig(config);
return validateLiteConfig(config);
},
};

Expand Down
103 changes: 97 additions & 6 deletions src/lib/db/compressionAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ export interface CompressionAnalyticsRow {
rtk_raw_output_total_bytes?: number | null;
}

/**
* One row per engine that ran inside a stacked compression pipeline. A stacked
* request writes a single aggregate `compression_analytics` row (engine = mode) plus
* N of these — so per-engine savings are queryable historically, not just live.
*/
export interface CompressionEngineBreakdownRow {
timestamp: string;
request_id?: string | null;
engine: string;
original_tokens: number;
compressed_tokens: number;
tokens_saved: number;
duration_ms?: number | null;
}

export interface CompressionAnalyticsSummary {
totalRequests: number;
totalTokensSaved: number;
Expand Down Expand Up @@ -139,6 +154,53 @@ export function insertCompressionAnalyticsRow(row: CompressionAnalyticsRow): voi
);
}

let breakdownTableEnsuredForDb: unknown = null;

function ensureCompressionEngineBreakdownTable(): void {
const db = getDbInstance();
if (breakdownTableEnsuredForDb === db) return;
db.exec(`
CREATE TABLE IF NOT EXISTS compression_engine_breakdown (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
request_id TEXT,
engine TEXT NOT NULL,
original_tokens INTEGER NOT NULL DEFAULT 0,
compressed_tokens INTEGER NOT NULL DEFAULT 0,
tokens_saved INTEGER NOT NULL DEFAULT 0,
duration_ms INTEGER
);
CREATE INDEX IF NOT EXISTS idx_ceb_engine_ts ON compression_engine_breakdown(engine, timestamp);
CREATE INDEX IF NOT EXISTS idx_ceb_request ON compression_engine_breakdown(request_id);
`);
breakdownTableEnsuredForDb = db;
}

export function insertCompressionEngineBreakdown(rows: CompressionEngineBreakdownRow[]): void {
if (!rows.length) return;
const db = getDbInstance();
ensureCompressionEngineBreakdownTable();
const stmt = db.prepare(
`INSERT INTO compression_engine_breakdown
(timestamp, request_id, engine, original_tokens, compressed_tokens, tokens_saved, duration_ms)
VALUES (?, ?, ?, ?, ?, ?, ?)`
);
const insertAll = db.transaction((items: CompressionEngineBreakdownRow[]) => {
for (const r of items) {
stmt.run(
r.timestamp,
r.request_id ?? null,
r.engine,
r.original_tokens,
r.compressed_tokens,
r.tokens_saved,
r.duration_ms ?? null
);
}
});
insertAll(rows);
}

export function attachCompressionUsageReceipt(
requestId: string | null | undefined,
usage: Record<string, unknown> | null | undefined,
Expand Down Expand Up @@ -205,24 +267,53 @@ function appendCondition(whereClause: string, condition: string): string {
return whereClause ? `${whereClause} AND ${condition}` : `WHERE ${condition}`;
}

type EngineAggRow = { runs: number; original: number; compressed: number; saved: number };

export function getPerEngineAnalytics(engineId: string, days = 7) {
const db = getDbInstance();
ensureCompressionAnalyticsColumns();
ensureCompressionEngineBreakdownTable();
const since = new Date(Date.now() - days * 86400_000).toISOString();
const row = db

// (1) Per-engine contributions from stacked runs (one breakdown row per engine).
const breakdown = db
.prepare(
`SELECT COUNT(*) AS runs,
COALESCE(SUM(original_tokens), 0) AS original,
COALESCE(SUM(compressed_tokens), 0) AS compressed,
COALESCE(SUM(tokens_saved), 0) AS saved
FROM compression_engine_breakdown
WHERE engine = ? AND timestamp >= ?`
)
.get(engineId, since) as EngineAggRow;

// (2) Legacy single-engine rows from compression_analytics, EXCLUDING any request
// that already has a per-engine breakdown — so a stacked run's aggregate row is not
// double-counted on top of its breakdown rows.
const legacy = db
.prepare(
`SELECT COUNT(*) AS runs,
COALESCE(SUM(original_tokens), 0) AS original,
COALESCE(SUM(compressed_tokens), 0) AS compressed,
COALESCE(SUM(tokens_saved), 0) AS saved
FROM compression_analytics
WHERE COALESCE(engine, mode) = ? AND timestamp >= ?`
WHERE COALESCE(engine, mode) = ? AND timestamp >= ?
AND (
request_id IS NULL
OR request_id NOT IN (
SELECT request_id FROM compression_engine_breakdown WHERE request_id IS NOT NULL
)
)`
)
.get(engineId, since) as { runs: number; original: number; compressed: number; saved: number };
const tokensSaved = Math.max(0, row.saved);
.get(engineId, since) as EngineAggRow;

const runs = breakdown.runs + legacy.runs;
const original = breakdown.original + legacy.original;
const compressed = breakdown.compressed + legacy.compressed;
const tokensSaved = Math.max(0, breakdown.saved + legacy.saved);
const avgSavingsPercent =
row.original > 0 ? Math.round(((row.original - row.compressed) / row.original) * 1000) / 10 : 0;
return { engineId, runs: row.runs, tokensSaved, avgSavingsPercent, days };
original > 0 ? Math.round(((original - compressed) / original) * 1000) / 10 : 0;
return { engineId, runs, tokensSaved, avgSavingsPercent, days };
}

export function getCompressionAnalyticsSummary(since?: string): CompressionAnalyticsSummary {
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/compression/engine-registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import assert from "node:assert/strict";
import {
aggressiveEngine,
cavemanEngine,
liteEngine,
ultraEngine,
} from "../../../open-sse/services/compression/engines/cavemanAdapter.ts";
import { rtkEngine as realRtkEngine } from "../../../open-sse/services/compression/engines/rtk/index.ts";
Expand Down Expand Up @@ -74,6 +75,15 @@ describe("compression engine registry contract", () => {
assert.ok(rtkSchema.some((field) => field.key === "applyToCodeBlocks"));
assert.ok(aggressiveSchema.some((field) => field.key === "maxTokensPerMessage"));
assert.ok(ultraSchema.some((field) => field.key === "compressionRate"));

// Lite exposes its OWN minimal schema (preserveSystemPrompt), NOT the aggressive
// summarizer/threshold fields it previously leaked.
const liteSchema = liteEngine.getConfigSchema();
assert.ok(liteSchema.some((field) => field.key === "preserveSystemPrompt"));
assert.ok(!liteSchema.some((field) => field.key === "maxTokensPerMessage"));
assert.ok(!liteSchema.some((field) => field.key === "summarizerEnabled"));
assert.equal(liteEngine.validateConfig({ preserveSystemPrompt: true }).valid, true);
assert.equal(liteEngine.validateConfig({ preserveSystemPrompt: "yes" }).valid, false);
assert.equal(cavemanEngine.validateConfig({ intensity: "full" }).valid, true);
assert.equal(cavemanEngine.validateConfig({ intensity: "bad" }).valid, false);
assert.equal(realRtkEngine.validateConfig({ maxLinesPerResult: 20 }).valid, true);
Expand Down
Loading