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
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,11 @@ PROVIDER_LIMITS_SYNC_SPACING_MS=1500
# Used by: open-sse/services/compression/engines/rtk/filterLoader.ts. Default: 0.
#OMNIROUTE_RTK_TRUST_PROJECT_FILTERS=0

# Character cap for Lite proactive tool-result truncation when lite.maxToolLength
# is unset. Range 256-1000000. Dashboard setting wins over this env.
# Used by: open-sse/services/compression/lite.ts. Default: 2000.
#OMNIROUTE_LITE_MAX_TOOL_LENGTH=2000

# Maximum concurrent synchronous compression workers. Excess jobs wait FIFO.
# Used by: open-sse/services/compression/compressionWorkerPool.ts. Default: 2.
#OMNI_COMPRESSION_WORKERS=2
Expand Down
1 change: 1 addition & 0 deletions changelog.d/features/13915-lite-max-tool-length.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **feat(compression):** Lite tool-result truncation length is configurable (`lite.maxToolLength`, env `OMNIROUTE_LITE_MAX_TOOL_LENGTH`). Default stays 2000. An out-of-range step cap no longer hides a valid global cap; a toggle-only settings write keeps a stored cap; `maxToolLength: null` clears it. Dashboard copy no longer hard-codes 2,000 characters. ([#13915](https://github.com/diegosouzapw/OmniRoute/pull/13915) — refs [#13178](https://github.com/diegosouzapw/OmniRoute/issues/13178))
1 change: 1 addition & 0 deletions docs/reference/ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ detection above).
| `OMNIROUTE_CONFIG_HOT_RELOAD_MS` | `5000` | `src/lib/config/hotReload.ts` | Polling interval (ms) for config hot-reload. Lower than `1000` is rejected. |
| `OMNIROUTE_DISABLE_REDIS_AUTH_CACHE` | _(enabled)_ | `src/lib/db/apiKeys.ts` | Set `1` to bypass the Redis-backed API-key auth cache (forces DB reads). |
| `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | `0` | `open-sse/services/compression/engines/rtk/filterLoader.ts` | Trust user-managed RTK project filter rules without strict signature checks. |
| `OMNIROUTE_LITE_MAX_TOOL_LENGTH` | `2000` | `open-sse/services/compression/lite.ts` | Character cap for Lite proactive tool-result truncation when `lite.maxToolLength` is unset. Range 256–1000000. Dashboard setting wins over this env. |
| `OMNI_COMPRESSION_WORKERS` | `2` | `open-sse/services/compression/compressionWorkerPool.ts` | Maximum concurrent synchronous RTK/Caveman workers; excess jobs wait FIFO. |
| `OMNI_COMPRESSION_WORKER_TIMEOUT_MS` | `120000` | `open-sse/services/compression/compressionWorkerPool.ts` | Per-job timeout in milliseconds. Timed-out workers are terminated and the request fails open unchanged. |
| `OMNI_COMPRESSION_WORKER_IDLE_MS` | `60000` | `open-sse/services/compression/compressionWorkerPool.ts` | Idle lifetime in milliseconds before an unused compression worker is terminated. |
Expand Down
22 changes: 20 additions & 2 deletions open-sse/services/compression/engines/cavemanAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { applyLiteCompression } from "../lite.ts";
import { applyLiteCompression, isUsableLiteMaxToolLength } from "../lite.ts";
import { cavemanCompress } from "../caveman.ts";
import { compressAggressive } from "../aggressive.ts";
import { ultraCompressHeuristic } from "../ultra.ts";
Expand Down Expand Up @@ -226,9 +226,19 @@ const LITE_SCHEMA: EngineConfigField[] = [
type: "boolean",
label: "Proactively truncate long tool results",
description:
"Truncates tool results over 2,000 characters during Lite compression. Emergency overflow protection may still trim content when the context exceeds the model budget.",
"Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget.",
defaultValue: true,
},
{
key: "maxToolLength",
type: "number",
label: "Maximum tool-result length",
description:
"Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset.",
defaultValue: 2000,
min: 256,
max: 1_000_000,
},
];

function validateLiteConfig(config: Record<string, unknown>): EngineValidationResult {
Expand All @@ -240,6 +250,7 @@ function validateLiteConfig(config: Record<string, unknown>): EngineValidationRe
errors.push("preserveSystemPrompt must be a boolean");
}
validateBoolean(config, "compressToolResults", errors);
validateNumberRange(config, "maxToolLength", 256, 1_000_000, errors);
return { valid: errors.length === 0, errors };
}

Expand Down Expand Up @@ -267,6 +278,8 @@ export const liteEngine: CompressionEngine = {
// to global config.lite, then the default (keeps the type `boolean`, and a malformed
// step value can no longer leak through the `??` chain as `{}`).
const stepCompressToolResults = options?.stepConfig?.compressToolResults;
const stepMaxToolLength = options?.stepConfig?.maxToolLength;
const configMaxToolLength = options?.config?.lite?.maxToolLength;
const result = applyLiteCompression(adapter.body, {
...options,
preserveSystemPrompt: options?.config?.preserveSystemPrompt !== false,
Expand All @@ -277,6 +290,11 @@ export const liteEngine: CompressionEngine = {
typeof stepCompressToolResults === "boolean"
? stepCompressToolResults
: (options?.config?.lite?.compressToolResults ?? true),
maxToolLength: isUsableLiteMaxToolLength(stepMaxToolLength)
? Math.floor(stepMaxToolLength)
: isUsableLiteMaxToolLength(configMaxToolLength)
? Math.floor(configMaxToolLength)
: undefined,
});
return adapter.adapted ? { ...result, body: adapter.restore(result.body) } : result;
},
Expand Down
36 changes: 33 additions & 3 deletions open-sse/services/compression/lite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ interface LiteCompressionOptions {
supportsVision?: boolean | null;
preserveSystemPrompt?: boolean;
compressToolResults?: boolean;
maxToolLength?: number;
}

const DEFAULT_MAX_TOOL_LENGTH = 2000;
const MIN_MAX_TOOL_LENGTH = 256;
const MAX_MAX_TOOL_LENGTH = 1_000_000;

function envInt(name: string, fallback: number): number {
const raw = process.env[name];
if (raw === undefined || raw === null || raw === "") return fallback;
const parsed = Number(raw);
if (!Number.isFinite(parsed)) return fallback;
const n = Math.floor(parsed);
if (n < MIN_MAX_TOOL_LENGTH || n > MAX_MAX_TOOL_LENGTH) return fallback;
return n;
}

/** True when a value can be used as a Lite tool-result cap (not merely `typeof number`). */
export function isUsableLiteMaxToolLength(value: unknown): value is number {
if (typeof value !== "number" || !Number.isFinite(value)) return false;
const n = Math.floor(value);
return n >= MIN_MAX_TOOL_LENGTH && n <= MAX_MAX_TOOL_LENGTH;
}

export function resolveLiteMaxToolLength(maxToolLength?: number): number {
if (isUsableLiteMaxToolLength(maxToolLength)) return Math.floor(maxToolLength);
return envInt("OMNIROUTE_LITE_MAX_TOOL_LENGTH", DEFAULT_MAX_TOOL_LENGTH);
}

function normalizeMessageWhitespace(content: string): string {
Expand Down Expand Up @@ -118,12 +145,15 @@ function backOffToWordBoundary(content: string, cutIndex: number): number {
return cutIndex;
}

export function compressToolResults(body: ChatBody): {
export function compressToolResults(
body: ChatBody,
options: LiteCompressionOptions = {}
): {
body: ChatBody;
applied: boolean;
} {
if (!body.messages) return { body, applied: false };
const MAX_TOOL_LENGTH = 2000;
const MAX_TOOL_LENGTH = resolveLiteMaxToolLength(options.maxToolLength);
let applied = false;
const messages = body.messages.map((msg) => {
if (msg.role !== "tool" || typeof msg.content !== "string") return msg;
Expand Down Expand Up @@ -227,7 +257,7 @@ export function applyLiteCompression(
if (r2.applied) techniquesApplied.push("system-dedup");

if (options?.compressToolResults !== false) {
const r3 = compressToolResults(current);
const r3 = compressToolResults(current, options);
current = r3.body;
if (r3.applied) techniquesApplied.push("tool-compress");
}
Expand Down
4 changes: 3 additions & 1 deletion open-sse/services/compression/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ export interface OmniglyphConfig {

/** Lite detail settings for proactive request-time transformations. */
export interface LiteConfig {
/** Truncate tool-result strings over 2,000 characters before provider dispatch. */
/** Truncate tool-result strings over this many characters before provider dispatch. */
maxToolLength?: number;
/** When false, skip proactive tool-result truncation. */
compressToolResults: boolean;
}

Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/am.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "ረጅም የመሣሪያ ውጤቶችን አስቀድሞ ቀንስ",
"description": "በቀላል ጭመቃ ጊዜ ከ2,000 ቁምፊዎች በላይ የሆኑ የመሣሪያ ውጤቶችን ይቀንሳል። ዐውዱ ከሞዴሉ በጀት ሲያልፍ የአደጋ ጊዜ የመጠን ማለፍ መከላከያው አሁንም ይዘትን ሊቀንስ ይችላል።"
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "قم بقطع نتائج الأدوات الطويلة بشكل استباقي",
"description": "يقطع نتائج الأداة التي تتجاوز 2000 حرف أثناء ضغط Lite. قد تقوم حماية الفائض الطارئة بتقليص المحتوى عندما يتجاوز السياق ميزانية النموذج."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/az.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Uzun alət nəticələrini proaktiv şəkildə qısaldın",
"description": "Lite sıxma zamanı 2,000 simvoldan çox olan alət nəticələrini qısaldır. Fövqəladə daşma qorunması kontekst model büdcəsini aşdıqda hələ də məzmunu qısalda bilər."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Проактивно съкратете дългите резултати от инструменти",
"description": "Обрязва резултатите от инструмента над 2,000 знака по време на Lite компресия. Защитата от извънреден преливник все още може да отреже съдържание, когато контекстът надвишава бюджета на модела."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "সক্রিয়ভাবে দীর্ঘ টুলের ফলাফল কেটে ফেলুন",
"description": "লাইট সংকোচনের সময় ২,০০০ অক্ষরের বেশি টুলের ফলাফল কেটে ফেলা হয়। জরুরি ওভারফ্লো সুরক্ষা এখনও কনটেন্ট কেটে ফেলতে পারে যখন প্রসঙ্গ মডেল বাজেট অতিক্রম করে।"
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Proaktivně zkracujte dlouhé výsledky nástrojů",
"description": "Zkracuje výsledky nástroje na více než 2 000 znaků během Lite komprese. Ochrana proti přetečení v nouzi může stále oříznout obsah, když kontext překročí rozpočet modelu."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Proaktivt afkort lange værktøjsresultater",
"description": "Afkorter værktøjsresultater over 2.000 tegn under Lite-komprimering. Nødoverløbsbeskyttelse kan stadig trimme indhold, når konteksten overskrider modelbudgettet."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Proaktiv lange Tool-Ergebnisse kürzen",
"description": "Trimmt die Toolergebnisse über 2.000 Zeichen während der Lite-Kompression. Der Notüberlauf-Schutz kann den Inhalt weiterhin kürzen, wenn der Kontext das Modellbudget überschreitet."
"description": "Kürzt lange Tool-Ergebnisse während der Lite-Kompression. Die Obergrenze setzt das Feld „Maximale Tool-Ergebnis-Länge“ (oder OMNIROUTE_LITE_MAX_TOOL_LENGTH, wenn das Feld leer ist). Der Notüberlauf-Schutz kann den Inhalt weiter kürzen, wenn der Kontext das Modellbudget überschreitet."
},
"maxToolLength": {
"label": "Maximale Tool-Ergebnis-Länge",
"description": "Zeichenobergrenze für die vorausschauende Kürzung von Tool-Ergebnissen. Standard 2000. Überschreiben mit OMNIROUTE_LITE_MAX_TOOL_LENGTH, wenn das Feld leer ist."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Προληπτική περικοπή μακρών αποτελεσμάτων εργαλείων",
"description": "Περικόπτει αποτελέσματα εργαλείων άνω των 2.000 χαρακτήρων κατά τη συμπίεση Lite. Η έκτακτη προστασία υπερχείλισης ενδέχεται να περικόψει περαιτέρω περιεχόμενο όταν το πλαίσιο υπερβαίνει τον προϋπολογισμό του μοντέλου."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8593,7 +8593,11 @@
},
"compressToolResults": {
"label": "Proactively truncate long tool results",
"description": "Truncates tool results over 2,000 characters during Lite compression. Emergency overflow protection may still trim content when the context exceeds the model budget."
"description": "Truncates long tool results during Lite compression. The Maximum tool-result length field (or OMNIROUTE_LITE_MAX_TOOL_LENGTH when that field is unset) sets the cap. Emergency overflow protection may still trim content when the context exceeds the model budget."
},
"maxToolLength": {
"label": "Maximum tool-result length",
"description": "Character cap for proactive tool-result truncation. Default 2000. Override with OMNIROUTE_LITE_MAX_TOOL_LENGTH when this field is unset."
}
},
"engineFields": {
Expand Down
Loading
Loading