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
78 changes: 61 additions & 17 deletions open-sse/handlers/chatCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1120,29 +1120,44 @@ export async function handleChatCore({
);
}
}
if (config.enabled && config.cavemanOutputMode?.enabled) {
// Phase 4A: unified output styles (supersedes cavemanOutputMode via the back-compat shim).
let outputStyleResult: import("../services/compression/outputStyles/apply.ts").OutputStylesResult | null =
null;
if (config.enabled) {
try {
const { applyCavemanOutputMode } = await import("../services/compression/outputMode.ts");
const outputModeLanguage =
config.languageConfig?.enabled === true ? config.languageConfig.defaultLanguage : "en";
const outputMode = applyCavemanOutputMode(
body as Parameters<typeof applyCavemanOutputMode>[0],
config.cavemanOutputMode,
outputModeLanguage
const { resolveOutputStyleSelection } = await import(
"../services/compression/outputStyles/backCompat.ts"
);
if (outputMode.applied) {
body = outputMode.body as typeof body;
cavemanOutputModeApplied = true;
cavemanOutputModeIntensity = config.cavemanOutputMode.intensity;
estimatedTokens = estimateTokens(body?.messages ?? body?.input ?? []);
log?.debug?.("COMPRESSION", "Caveman output mode instruction applied");
} else if (outputMode.skippedReason && outputMode.skippedReason !== "disabled") {
log?.debug?.("COMPRESSION", `Caveman output mode skipped: ${outputMode.skippedReason}`);
const selection = resolveOutputStyleSelection(config);
if (selection.length > 0) {
const { applyOutputStyles } = await import(
"../services/compression/outputStyles/apply.ts"
);
const outputStyleLanguage =
config.languageConfig?.enabled === true ? config.languageConfig.defaultLanguage : "en";
outputStyleResult = applyOutputStyles(
body as Parameters<typeof applyOutputStyles>[0],
selection,
outputStyleLanguage
);
if (outputStyleResult.applied) {
body = outputStyleResult.body as typeof body;
cavemanOutputModeApplied = true;
cavemanOutputModeIntensity =
outputStyleResult.appliedStyles?.map((s) => `${s.id}:${s.level}`).join(",") ?? null;
estimatedTokens = estimateTokens(body?.messages ?? body?.input ?? []);
log?.debug?.("COMPRESSION", "Output styles applied");
} else if (
outputStyleResult.skippedReason &&
outputStyleResult.skippedReason !== "no_styles"
) {
log?.debug?.("COMPRESSION", `Output styles skipped: ${outputStyleResult.skippedReason}`);
}
}
} catch (err) {
log?.debug?.(
"COMPRESSION",
"Caveman output mode skipped: " + (err instanceof Error ? err.message : String(err))
"Output styles skipped: " + (err instanceof Error ? err.message : String(err))
);
}
}
Expand Down Expand Up @@ -1396,6 +1411,35 @@ export async function handleChatCore({
}
})();
}
if (outputStyleResult) {
void (async () => {
try {
const { buildOutputStyleTelemetry } = await import(
"../services/compression/outputStyles/telemetry.ts"
);
const { insertCompressionRunTelemetryRow } = await import(
"../../src/lib/db/compressionRunTelemetry.ts"
);
const record = buildOutputStyleTelemetry({
requestId: skillRequestId ?? traceId ?? "",
model: effectiveModel ?? "",
provider: provider ?? "",
source: config.compressionComboId ? "active-profile" : "default",
tokensBefore: estimatedTokens,
tokensAfter: estimatedTokens,
applied: outputStyleResult.applied,
appliedStyles: outputStyleResult.appliedStyles,
skippedReason: outputStyleResult.skippedReason,
});
insertCompressionRunTelemetryRow(record);
} catch (err) {
log?.debug?.(
"COMPRESSION",
"Run-telemetry emit skipped: " + (err instanceof Error ? err.message : String(err))
);
}
})();
}
} catch (err) {
log?.warn?.(
"COMPRESSION",
Expand Down
2 changes: 1 addition & 1 deletion open-sse/services/compression/outputMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface CavemanOutputModeResult {
export const SHARED_BOUNDARIES =
"Code blocks, file paths, commands, errors, URLs: keep exact. Security warnings, irreversible action confirmations, multi-step ordered sequences: write normal. Resume terse style after. Active every response until user asks for normal mode.";

const CAVEMAN_INSTRUCTION_BY_LANGUAGE = {
export const CAVEMAN_INSTRUCTION_BY_LANGUAGE = {
en: {
lite: `Respond concise. Drop filler, pleasantries, hedging. Keep full sentences, technical terms, code, errors, URLs, and identifiers exact. ${SHARED_BOUNDARIES}`,
full: `Respond terse like smart caveman. Drop articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, hedging. Fragments OK. Short synonyms (big not extensive, fix not implement). Keep all technical substance, code, errors, URLs, identifiers exact. ${SHARED_BOUNDARIES}`,
Expand Down
135 changes: 135 additions & 0 deletions open-sse/services/compression/outputStyles/apply.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { SHARED_BOUNDARIES, shouldBypassCavemanOutputMode } from "../outputMode.ts";
import { OUTPUT_STYLE_IDS, outputStyleMeta } from "./catalog.ts";

export type OutputStyleLevel = "lite" | "full" | "ultra";

export interface OutputStyleSelectionEntry {
id: string;
level: OutputStyleLevel;
}

interface ChatMessage {
role: string;
content?: string | unknown[];
[key: string]: unknown;
}

interface ChatRequestBody {
messages?: ChatMessage[];
instructions?: string;
input?: unknown;
[key: string]: unknown;
}

export interface OutputStylesResult {
body: ChatRequestBody;
applied: boolean;
skippedReason?: string;
/** The styles actually injected (after unknown/locale filtering), in catalog order. */
appliedStyles?: OutputStyleSelectionEntry[];
}

/** Single idempotency marker guarding the unified injection (D-A: one marker for all styles). */
export const OUTPUT_STYLE_MARKER = "[OmniRoute Output Styles]";

/**
* Resolve the selection into the ordered, locale-gated, known styles in catalog order.
* Pure: drops unknown ids and locale-mismatched styles; never throws (D-A6 forward-compat).
*/
function resolveStyles(
selection: OutputStyleSelectionEntry[],
language: string
): OutputStyleSelectionEntry[] {
const byId = new Map(selection.map((entry) => [entry.id, entry]));
const resolved: OutputStyleSelectionEntry[] = [];
for (const id of OUTPUT_STYLE_IDS) {
const entry = byId.get(id);
if (!entry) continue;
const meta = outputStyleMeta(id);
if (!meta) continue;
if (meta.locale && meta.locale !== language) continue;
resolved.push({ id, level: entry.level });
}
return resolved;
}

/** Build the combined instruction body (no marker, no trailing boundary). Pure / deterministic. */
function buildStyleInstructions(
resolved: OutputStyleSelectionEntry[],
language: string
): string {
const parts: string[] = [];
for (const { id, level } of resolved) {
const meta = outputStyleMeta(id);
const localized = meta.i18n?.[language];
const levels = localized ?? meta.levels;
// Strip the per-style boundary so SHARED_BOUNDARIES is appended exactly once below.
parts.push(levels[level].replace(SHARED_BOUNDARIES, "").trim());
}
return parts.join("\n");
}

/**
* Inject one or more output styles deterministically and front-loaded into the system prompt.
* - Selection resolved in catalog order; unknown/locale-mismatched styles dropped.
* - SHARED_BOUNDARIES applied once at the end (not per style).
* - Single idempotency marker; re-applying is a no-op.
* - Content bypass runs once across the whole turn (all-or-nothing); reason recorded.
*/
export function applyOutputStyles(
body: ChatRequestBody,
selection: OutputStyleSelectionEntry[],
language = "en"
): OutputStylesResult {
const resolved = resolveStyles(selection ?? [], language);
if (resolved.length === 0) {
return { body, applied: false, skippedReason: "no_styles" };
}

// Single space before the shared boundary so a legacy single-style (terse-prose)
// injection stays byte-identical to the old caveman output mode (D-A5 back-compat).
const combined = `${buildStyleInstructions(resolved, language)} ${SHARED_BOUNDARIES}`;
const instruction = `${OUTPUT_STYLE_MARKER}\n${combined}`;

const messages = Array.isArray(body.messages) ? body.messages : null;
if (!messages || messages.length === 0) {
if (typeof body.instructions === "string") {
if (body.instructions.includes(OUTPUT_STYLE_MARKER)) {
return { body, applied: false, skippedReason: "already_applied" };
}
return {
body: { ...body, instructions: `${body.instructions.trim()}\n\n${instruction}` },
applied: true,
appliedStyles: resolved,
};
}
if (typeof body.input === "string" || Array.isArray(body.input)) {
return { body: { ...body, instructions: instruction }, applied: true, appliedStyles: resolved };
}
return { body, applied: false, skippedReason: "no_messages" };
}

// Idempotency before bypass so an already-injected marker (which contains
// SHARED_BOUNDARIES keywords) cannot trigger a false-positive bypass.
const alreadyApplied = messages.some(
(message) =>
message.role === "system" &&
typeof message.content === "string" &&
message.content.includes(OUTPUT_STYLE_MARKER)
);
if (alreadyApplied) return { body, applied: false, skippedReason: "already_applied" };

// Content bypass (all-or-nothing for the turn): reuse the existing rules verbatim.
const bypass = shouldBypassCavemanOutputMode(messages);
if (bypass) return { body, applied: false, skippedReason: bypass };

const nextMessages = [...messages];
const first = nextMessages[0];
if (first?.role === "system" && typeof first.content === "string") {
nextMessages[0] = { ...first, content: `${first.content.trim()}\n\n${instruction}` };
} else {
nextMessages.unshift({ role: "system", content: instruction });
}

return { body: { ...body, messages: nextMessages }, applied: true, appliedStyles: resolved };
}
29 changes: 29 additions & 0 deletions open-sse/services/compression/outputStyles/backCompat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { OutputStyleSelectionEntry } from "./apply.ts";

interface LegacyOutputModeConfig {
enabled?: boolean;
intensity?: "lite" | "full" | "ultra";
}

interface ConfigSlice {
outputStyles?: OutputStyleSelectionEntry[];
cavemanOutputMode?: LegacyOutputModeConfig;
}

/**
* Resolve the effective output-style selection (D-A5 back-compat).
* Precedence: an explicit non-empty `outputStyles` wins; otherwise a stored
* `cavemanOutputMode` (when enabled) maps to `[{ terse-prose, <intensity> }]`,
* keeping existing installs byte-identical until they opt into other styles.
* Pure; never throws.
*/
export function resolveOutputStyleSelection(config: ConfigSlice): OutputStyleSelectionEntry[] {
if (Array.isArray(config.outputStyles) && config.outputStyles.length > 0) {
return config.outputStyles;
}
const legacy = config.cavemanOutputMode;
if (legacy?.enabled) {
return [{ id: "terse-prose", level: legacy.intensity ?? "full" }];
}
return [];
}
76 changes: 76 additions & 0 deletions open-sse/services/compression/outputStyles/catalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { SHARED_BOUNDARIES, CAVEMAN_INSTRUCTION_BY_LANGUAGE } from "../outputMode.ts";

/**
* A single output-steering style. Instruction text MUST be static per
* `(id, level, language)` — no timestamps, no per-request interpolation — so the
* injected system prefix stays prompt-cache-stable (D-A4). The registry contract
* forbids non-deterministic instruction text.
*/
export interface OutputStyle {
/** Stable id, e.g. "terse-prose" | "less-code" | "terse-cjk". */
id: string;
/** Human label for the settings panel. */
label: string;
/** Short panel description (i18n-independent English). */
description?: string;
/** Instruction text per intensity. Static / deterministic. */
levels: { lite: string; full: string; ultra: string };
/** Optional per-style boundary clause; when absent the SHARED_BOUNDARIES is used. */
boundaries?: string;
/** Locale gate: when set, the style is only offered/honored under this language code. */
locale?: string;
/** Optional localized `levels`, keyed by language code. */
i18n?: Record<string, { lite: string; full: string; ultra: string }>;
}

/**
* The Output Style registry. Adding a style = one entry here; the injector and the
* settings panel both enumerate this object, so no other file needs to change (D-A1).
* Declaration order is the deterministic concatenation order used by the injector.
*/
export const OUTPUT_STYLE_CATALOG: Record<string, OutputStyle> = {
"terse-prose": {
id: "terse-prose",
label: "Terse prose",
description: "Drop filler/articles/hedging; keep technical substance exact.",
// Migrated verbatim from the caveman output mode (outputMode.ts) — referenced (not
// re-typed) so the back-compat injection stays byte-identical across ALL languages,
// not just English (the legacy mode localized to en/pt-BR/ja/id).
levels: CAVEMAN_INSTRUCTION_BY_LANGUAGE.en,
i18n: {
"pt-BR": CAVEMAN_INSTRUCTION_BY_LANGUAGE["pt-BR"],
ja: CAVEMAN_INSTRUCTION_BY_LANGUAGE.ja,
id: CAVEMAN_INSTRUCTION_BY_LANGUAGE.id,
},
},
"less-code": {
id: "less-code",
label: "Less code",
description: "YAGNI ladder: smallest working change, no unrequested abstractions.",
// Ported from 9router ponytail (ponytailPrompt.js); attribution preserved.
levels: {
lite: `Write the smallest change that satisfies the request. Skip speculative abstractions. ${SHARED_BOUNDARIES}`,
full: `Act like a lazy senior dev applying YAGNI. Smallest working change only. No unrequested abstractions, no premature generalization, no extra layers, no defensive scaffolding the request did not ask for. Reuse existing code over adding new code. ${SHARED_BOUNDARIES}`,
ultra: `Minimal diff discipline. Touch the fewest lines that make it work. Zero new files, classes, or config unless strictly required. Inline over abstract. No "while we're here" extras. ${SHARED_BOUNDARIES}`,
},
},
"terse-cjk": {
id: "terse-cjk",
label: "Terse CJK (文言)",
description: "Classical-Chinese ultra-terse style (locale-gated to zh).",
// Ported from 9router wenyan (cavemanPrompts.js); the worked extensibility example.
locale: "zh",
levels: {
lite: `回答从简,去虚词、寒暄、修饰。代码、路径、命令、错误、URL、标识符一律照原样保留。${SHARED_BOUNDARIES}`,
full: `以文言简体回答,惜字如金,去赘语虚词。代码、路径、命令、错误、URL、标识符照原样保留,不得改写。${SHARED_BOUNDARIES}`,
ultra: `以极简文言回答,字字千金。仅留要义。代码、API名、错误串、URL、标识符照原样保留,绝不省略或改写。${SHARED_BOUNDARIES}`,
},
},
};

/** Catalog ids in declaration order (the deterministic concat order). */
export const OUTPUT_STYLE_IDS: string[] = Object.keys(OUTPUT_STYLE_CATALOG);

export function outputStyleMeta(id: string): OutputStyle {
return OUTPUT_STYLE_CATALOG[id];
}
Loading
Loading