llm-cli-gateway 2.15.0 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +50 -1
  2. package/dist/acp/process-manager.js +2 -1
  3. package/dist/acp/provider-registry.js +8 -8
  4. package/dist/async-job-manager.d.ts +4 -1
  5. package/dist/async-job-manager.js +15 -6
  6. package/dist/compressor/estimate.d.ts +5 -0
  7. package/dist/compressor/estimate.js +21 -0
  8. package/dist/compressor/index.d.ts +23 -0
  9. package/dist/compressor/index.js +77 -0
  10. package/dist/compressor/router.d.ts +2 -0
  11. package/dist/compressor/router.js +57 -0
  12. package/dist/compressor/transforms/ansi.d.ts +3 -0
  13. package/dist/compressor/transforms/ansi.js +89 -0
  14. package/dist/compressor/transforms/json.d.ts +1 -0
  15. package/dist/compressor/transforms/json.js +156 -0
  16. package/dist/compressor/transforms/log.d.ts +12 -0
  17. package/dist/compressor/transforms/log.js +55 -0
  18. package/dist/compressor/transforms/whitespace.d.ts +8 -0
  19. package/dist/compressor/transforms/whitespace.js +79 -0
  20. package/dist/config.d.ts +8 -0
  21. package/dist/config.js +25 -0
  22. package/dist/executor.d.ts +1 -0
  23. package/dist/executor.js +5 -2
  24. package/dist/flight-recorder.d.ts +9 -0
  25. package/dist/flight-recorder.js +42 -0
  26. package/dist/index.d.ts +18 -2
  27. package/dist/index.js +273 -66
  28. package/dist/job-store.d.ts +4 -0
  29. package/dist/job-store.js +16 -0
  30. package/dist/provider-definitions.d.ts +1 -0
  31. package/dist/provider-definitions.js +28 -10
  32. package/dist/provider-tool-capabilities.js +3 -3
  33. package/dist/request-helpers.js +1 -1
  34. package/dist/spawn-env-isolation.d.ts +10 -0
  35. package/dist/spawn-env-isolation.js +55 -0
  36. package/dist/upstream-contracts.js +47 -27
  37. package/npm-shrinkwrap.json +2 -2
  38. package/package.json +7 -3
@@ -0,0 +1,156 @@
1
+ const WS = new Set([" ", "\t", "\n", "\r"]);
2
+ function skipWs(c) {
3
+ while (c.pos < c.text.length && WS.has(c.text[c.pos]))
4
+ c.pos += 1;
5
+ }
6
+ function fail() {
7
+ throw new SyntaxError("json-minify: not valid JSON");
8
+ }
9
+ const SIMPLE_ESCAPES = new Set(['"', "\\", "/", "b", "f", "n", "r", "t"]);
10
+ const HEX = /^[0-9a-fA-F]{4}$/;
11
+ function copyString(c) {
12
+ const start = c.pos;
13
+ if (c.text[c.pos] !== '"')
14
+ fail();
15
+ c.pos += 1;
16
+ while (c.pos < c.text.length) {
17
+ const ch = c.text[c.pos];
18
+ if (ch === "\\") {
19
+ const esc = c.text[c.pos + 1];
20
+ if (esc === undefined)
21
+ fail();
22
+ if (esc === "u") {
23
+ if (!HEX.test(c.text.slice(c.pos + 2, c.pos + 6)))
24
+ fail();
25
+ c.pos += 6;
26
+ continue;
27
+ }
28
+ if (!SIMPLE_ESCAPES.has(esc))
29
+ fail();
30
+ c.pos += 2;
31
+ continue;
32
+ }
33
+ if (ch === '"') {
34
+ c.pos += 1;
35
+ c.out.push(c.text.slice(start, c.pos));
36
+ return;
37
+ }
38
+ if (ch.charCodeAt(0) < 0x20)
39
+ fail();
40
+ c.pos += 1;
41
+ }
42
+ fail();
43
+ }
44
+ const NUMBER = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/;
45
+ function copyNumber(c) {
46
+ const match = NUMBER.exec(c.text.slice(c.pos));
47
+ if (!match || match[0].length === 0)
48
+ fail();
49
+ c.out.push(match[0]);
50
+ c.pos += match[0].length;
51
+ }
52
+ function copyLiteral(c, word) {
53
+ if (c.text.startsWith(word, c.pos)) {
54
+ c.out.push(word);
55
+ c.pos += word.length;
56
+ return;
57
+ }
58
+ fail();
59
+ }
60
+ function copyValue(c) {
61
+ skipWs(c);
62
+ const ch = c.text[c.pos];
63
+ if (ch === undefined)
64
+ fail();
65
+ if (ch === "{") {
66
+ c.out.push("{");
67
+ c.pos += 1;
68
+ skipWs(c);
69
+ if (c.text[c.pos] === "}") {
70
+ c.out.push("}");
71
+ c.pos += 1;
72
+ return;
73
+ }
74
+ for (;;) {
75
+ skipWs(c);
76
+ copyString(c);
77
+ skipWs(c);
78
+ if (c.text[c.pos] !== ":")
79
+ fail();
80
+ c.out.push(":");
81
+ c.pos += 1;
82
+ copyValue(c);
83
+ skipWs(c);
84
+ if (c.text[c.pos] === ",") {
85
+ c.out.push(",");
86
+ c.pos += 1;
87
+ continue;
88
+ }
89
+ if (c.text[c.pos] === "}") {
90
+ c.out.push("}");
91
+ c.pos += 1;
92
+ return;
93
+ }
94
+ fail();
95
+ }
96
+ }
97
+ if (ch === "[") {
98
+ c.out.push("[");
99
+ c.pos += 1;
100
+ skipWs(c);
101
+ if (c.text[c.pos] === "]") {
102
+ c.out.push("]");
103
+ c.pos += 1;
104
+ return;
105
+ }
106
+ for (;;) {
107
+ copyValue(c);
108
+ skipWs(c);
109
+ if (c.text[c.pos] === ",") {
110
+ c.out.push(",");
111
+ c.pos += 1;
112
+ continue;
113
+ }
114
+ if (c.text[c.pos] === "]") {
115
+ c.out.push("]");
116
+ c.pos += 1;
117
+ return;
118
+ }
119
+ fail();
120
+ }
121
+ }
122
+ if (ch === '"') {
123
+ copyString(c);
124
+ return;
125
+ }
126
+ if (ch === "t") {
127
+ copyLiteral(c, "true");
128
+ return;
129
+ }
130
+ if (ch === "f") {
131
+ copyLiteral(c, "false");
132
+ return;
133
+ }
134
+ if (ch === "n") {
135
+ copyLiteral(c, "null");
136
+ return;
137
+ }
138
+ if (ch === "-" || (ch >= "0" && ch <= "9")) {
139
+ copyNumber(c);
140
+ return;
141
+ }
142
+ fail();
143
+ }
144
+ export function minifyJson(text) {
145
+ const c = { text, pos: 0, out: [] };
146
+ try {
147
+ copyValue(c);
148
+ skipWs(c);
149
+ if (c.pos !== text.length)
150
+ return null;
151
+ return c.out.join("");
152
+ }
153
+ catch {
154
+ return null;
155
+ }
156
+ }
@@ -0,0 +1,12 @@
1
+ export declare const SENTINEL_PREFIX = "[[gateway-";
2
+ export declare const LIT_MARKER = "[[gateway-lit:v1]] ";
3
+ export declare function repeatMarker(lines: number, count: number): string;
4
+ export declare function crMarker(frames: number): string;
5
+ export declare function noteLine(folded: number, escaped: number): string;
6
+ export interface MarkerCounts {
7
+ folded: number;
8
+ escaped: number;
9
+ }
10
+ export declare function escapeSentinelLikeLines(text: string, counts: MarkerCounts): string;
11
+ export declare const MIN_RUN = 3;
12
+ export declare function dedupAdjacentLines(text: string, counts: MarkerCounts): string;
@@ -0,0 +1,55 @@
1
+ import { mapUnfenced } from "./whitespace.js";
2
+ export const SENTINEL_PREFIX = "[[gateway-";
3
+ export const LIT_MARKER = "[[gateway-lit:v1]] ";
4
+ export function repeatMarker(lines, count) {
5
+ return `[[gateway-repeat:v1 lines=${lines} count=${count}]]`;
6
+ }
7
+ export function crMarker(frames) {
8
+ return `[[gateway-cr:v1 frames=${frames}]]`;
9
+ }
10
+ export function noteLine(folded, escaped) {
11
+ return (`[[gateway-note:v1 folded=${folded} escaped=${escaped}]] ` +
12
+ "Gateway compressor markers follow: [[gateway-repeat:v1 ...]] folds byte-identical repeated lines (count included), " +
13
+ "[[gateway-cr:v1 ...]] keeps the final frame of carriage-return-rewritten lines, " +
14
+ "and lines opening with [[gateway-lit:v1]] are verbatim input with that prefix added.");
15
+ }
16
+ export function escapeSentinelLikeLines(text, counts) {
17
+ return mapUnfenced(text, segment => segment
18
+ .split("\n")
19
+ .map(line => {
20
+ if (line.trimStart().startsWith(SENTINEL_PREFIX)) {
21
+ counts.escaped += 1;
22
+ return LIT_MARKER + line;
23
+ }
24
+ return line;
25
+ })
26
+ .join("\n"));
27
+ }
28
+ export const MIN_RUN = 3;
29
+ export function dedupAdjacentLines(text, counts) {
30
+ return mapUnfenced(text, segment => {
31
+ const lines = segment.split("\n");
32
+ const out = [];
33
+ let i = 0;
34
+ while (i < lines.length) {
35
+ const line = lines[i];
36
+ let runEnd = i + 1;
37
+ if (line.trim() !== "") {
38
+ while (runEnd < lines.length && lines[runEnd] === line)
39
+ runEnd += 1;
40
+ }
41
+ const runLength = runEnd - i;
42
+ if (runLength >= MIN_RUN) {
43
+ out.push(line);
44
+ out.push(repeatMarker(1, runLength));
45
+ counts.folded += 1;
46
+ }
47
+ else {
48
+ for (let j = i; j < runEnd; j += 1)
49
+ out.push(lines[j]);
50
+ }
51
+ i = runEnd;
52
+ }
53
+ return out.join("\n");
54
+ });
55
+ }
@@ -0,0 +1,8 @@
1
+ export interface FenceSegment {
2
+ text: string;
3
+ fenced: boolean;
4
+ }
5
+ export declare function splitFences(text: string): FenceSegment[];
6
+ export declare function joinFences(segments: FenceSegment[]): string;
7
+ export declare function mapUnfenced(text: string, op: (segment: string) => string): string;
8
+ export declare function normalizeWhitespace(text: string): string;
@@ -0,0 +1,79 @@
1
+ const FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})/;
2
+ export function splitFences(text) {
3
+ const segments = [];
4
+ const lines = text.split("\n");
5
+ let current = [];
6
+ let fenced = false;
7
+ let fenceMarker = "";
8
+ const flush = (nextFenced) => {
9
+ if (current.length > 0) {
10
+ segments.push({ text: current.join("\n"), fenced });
11
+ current = [];
12
+ }
13
+ fenced = nextFenced;
14
+ };
15
+ for (const line of lines) {
16
+ if (!fenced) {
17
+ const open = FENCE_OPEN.exec(line);
18
+ if (open) {
19
+ flush(true);
20
+ fenceMarker = open[1];
21
+ current.push(line);
22
+ continue;
23
+ }
24
+ current.push(line);
25
+ }
26
+ else {
27
+ current.push(line);
28
+ const marker = FENCE_OPEN.exec(line);
29
+ if (marker &&
30
+ marker[1][0] === fenceMarker[0] &&
31
+ marker[1].length >= fenceMarker.length &&
32
+ line.trim() === marker[1]) {
33
+ flush(false);
34
+ }
35
+ }
36
+ }
37
+ flush(false);
38
+ return segments;
39
+ }
40
+ export function joinFences(segments) {
41
+ return segments.map(s => s.text).join("\n");
42
+ }
43
+ export function mapUnfenced(text, op) {
44
+ const segments = splitFences(text);
45
+ return joinFences(segments.map(s => (s.fenced ? s : { ...s, text: op(s.text) })));
46
+ }
47
+ export function normalizeWhitespace(text) {
48
+ return mapUnfenced(text, segment => {
49
+ const lines = segment.split("\n").map(line => {
50
+ if (line.includes("`"))
51
+ return line;
52
+ const crlf = line.endsWith("\r");
53
+ const body = crlf ? line.slice(0, -1) : line;
54
+ const stripped = body.replace(/[ \t]+$/, "");
55
+ return crlf ? `${stripped}\r` : stripped;
56
+ });
57
+ const out = [];
58
+ let blankRun = 0;
59
+ const collapse = () => {
60
+ if (blankRun < 3)
61
+ return;
62
+ const keep = out[out.length - blankRun];
63
+ out.splice(out.length - blankRun, blankRun, keep);
64
+ };
65
+ for (const line of lines) {
66
+ const isBlank = line === "" || line === "\r";
67
+ if (isBlank) {
68
+ blankRun += 1;
69
+ out.push(line);
70
+ continue;
71
+ }
72
+ collapse();
73
+ blankRun = 0;
74
+ out.push(line);
75
+ }
76
+ collapse();
77
+ return out.join("\n");
78
+ });
79
+ }
package/dist/config.d.ts CHANGED
@@ -111,6 +111,14 @@ export interface CacheAwarenessConfig {
111
111
  };
112
112
  }
113
113
  export declare function loadCacheAwarenessConfig(logger?: Logger): CacheAwarenessConfig;
114
+ export interface CompressionConfig {
115
+ enabled: boolean;
116
+ sources: {
117
+ configFile: string | null;
118
+ };
119
+ }
120
+ export declare const DEFAULT_COMPRESSION_CONFIG: CompressionConfig;
121
+ export declare function loadCompressionConfig(logger?: Logger): CompressionConfig;
114
122
  export declare function minStableTokensForModel(config: CacheAwarenessConfig, modelName: string): number;
115
123
  export declare const DEFAULT_XAI_API_KEY_ENV = "XAI_API_KEY";
116
124
  export declare const DEFAULT_XAI_BASE_URL = "https://api.x.ai/v1";
package/dist/config.js CHANGED
@@ -413,6 +413,31 @@ export function loadCacheAwarenessConfig(logger = noopLogger) {
413
413
  sources: { configFile: sourcePath },
414
414
  };
415
415
  }
416
+ const CompressionSchema = z
417
+ .object({
418
+ enabled: z.boolean().default(false),
419
+ })
420
+ .strict();
421
+ export const DEFAULT_COMPRESSION_CONFIG = {
422
+ enabled: false,
423
+ sources: { configFile: null },
424
+ };
425
+ export function loadCompressionConfig(logger = noopLogger) {
426
+ const configPath = defaultGatewayConfigPath();
427
+ const { parsed, sourcePath } = readGatewayTomlFile(configPath, logger, "compression");
428
+ const raw = parsed?.compression ?? {};
429
+ let parsedCompression;
430
+ try {
431
+ parsedCompression = CompressionSchema.parse(raw);
432
+ }
433
+ catch (err) {
434
+ throw new Error(`Invalid [compression] config: ${err instanceof Error ? err.message : String(err)}`);
435
+ }
436
+ return {
437
+ enabled: parsedCompression.enabled,
438
+ sources: { configFile: sourcePath },
439
+ };
440
+ }
416
441
  export function minStableTokensForModel(config, modelName) {
417
442
  const lower = modelName.toLowerCase();
418
443
  const table = config.minStableTokensForCacheControl;
@@ -35,5 +35,6 @@ export declare function spawnCliProcess(command: string, args: string[], options
35
35
  cwd?: string;
36
36
  env: NodeJS.ProcessEnv;
37
37
  stdio: SpawnOptions["stdio"];
38
+ logger?: Logger;
38
39
  }): ChildProcess;
39
40
  export declare function executeCli(command: string, args: string[], options?: ExecuteOptions): Promise<ExecuteResult>;
package/dist/executor.js CHANGED
@@ -3,6 +3,7 @@ import { homedir } from "os";
3
3
  import { delimiter, join, dirname, extname, win32 } from "path";
4
4
  import { readdirSync, existsSync } from "fs";
5
5
  import { createCircuitBreaker, withRetry } from "./retry.js";
6
+ import { applySpawnEnvIsolation } from "./spawn-env-isolation.js";
6
7
  export function providerCommandName(command) {
7
8
  if (command === "gemini")
8
9
  return "agy";
@@ -309,9 +310,10 @@ function killWindowsProcessTree(pid) {
309
310
  return result.status === 0;
310
311
  }
311
312
  export function spawnCliProcess(command, args, options) {
313
+ const env = applySpawnEnvIsolation(options.env, options.logger);
312
314
  const detached = shouldDetachProviderProcess();
313
315
  const resolved = resolveCommandForSpawn(command, args, {
314
- envPath: pathValueFromEnv(options.env, process.platform),
316
+ envPath: pathValueFromEnv(env, process.platform),
315
317
  });
316
318
  const proc = spawn(resolved.command, resolved.args, {
317
319
  cwd: options.cwd,
@@ -319,7 +321,7 @@ export function spawnCliProcess(command, args, options) {
319
321
  windowsHide: true,
320
322
  windowsVerbatimArguments: resolved.windowsVerbatimArguments,
321
323
  stdio: options.stdio,
322
- env: options.env,
324
+ env,
323
325
  });
324
326
  if (proc.pid)
325
327
  registerProcessGroup(proc.pid);
@@ -337,6 +339,7 @@ export async function executeCli(command, args, options = {}) {
337
339
  cwd,
338
340
  stdio,
339
341
  env: { ...baseEnv, ...(extraEnv ?? {}) },
342
+ logger: options.logger,
340
343
  });
341
344
  if (stdin !== undefined && proc.stdin) {
342
345
  proc.stdin.write(stdin);
@@ -37,6 +37,13 @@ interface LoggerLike {
37
37
  info: (message: string, ...args: any[]) => void;
38
38
  error: (message: string, ...args: any[]) => void;
39
39
  }
40
+ export interface CompressionTelemetry {
41
+ route: string;
42
+ transforms: string[];
43
+ originalChars: number;
44
+ compressedChars: number;
45
+ estimatedTokensSaved: number;
46
+ }
40
47
  export declare function resolveFlightRecorderDbPath(): string | null;
41
48
  export declare class FlightRecorder {
42
49
  private db;
@@ -51,6 +58,7 @@ export declare class FlightRecorder {
51
58
  });
52
59
  logStart(entry: FlightLogStart): void;
53
60
  logComplete(correlationId: string, result: FlightLogResult): void;
61
+ recordCompressionTelemetry(correlationId: string, telemetry: CompressionTelemetry): void;
54
62
  private redactStart;
55
63
  private redactResult;
56
64
  queryRequests<T = Record<string, unknown>>(sql: string, ...params: unknown[]): T[];
@@ -60,6 +68,7 @@ export declare class FlightRecorder {
60
68
  export declare class NoopFlightRecorder {
61
69
  logStart(_entry: FlightLogStart): void;
62
70
  logComplete(_correlationId: string, _result: FlightLogResult): void;
71
+ recordCompressionTelemetry(_correlationId: string, _telemetry: CompressionTelemetry): void;
63
72
  queryRequests<T = Record<string, unknown>>(_sql: string, ..._params: unknown[]): T[];
64
73
  flush(): void;
65
74
  close(): void;
@@ -64,6 +64,25 @@ function ensureMetadataProviderSessionColumns(db) {
64
64
  db.exec("ALTER TABLE gateway_metadata ADD COLUMN stop_reason TEXT");
65
65
  }
66
66
  }
67
+ function ensureCompressionColumns(db) {
68
+ const rows = db.prepare("PRAGMA table_info(gateway_metadata)").all();
69
+ const names = new Set(rows.map((row) => (row && typeof row.name === "string" ? row.name : "")));
70
+ if (!names.has("compression_route")) {
71
+ db.exec("ALTER TABLE gateway_metadata ADD COLUMN compression_route TEXT");
72
+ }
73
+ if (!names.has("compression_transforms")) {
74
+ db.exec("ALTER TABLE gateway_metadata ADD COLUMN compression_transforms TEXT");
75
+ }
76
+ if (!names.has("compression_original_chars")) {
77
+ db.exec("ALTER TABLE gateway_metadata ADD COLUMN compression_original_chars INTEGER");
78
+ }
79
+ if (!names.has("compression_compressed_chars")) {
80
+ db.exec("ALTER TABLE gateway_metadata ADD COLUMN compression_compressed_chars INTEGER");
81
+ }
82
+ if (!names.has("compression_tokens_saved_est")) {
83
+ db.exec("ALTER TABLE gateway_metadata ADD COLUMN compression_tokens_saved_est INTEGER");
84
+ }
85
+ }
67
86
  export function resolveFlightRecorderDbPath() {
68
87
  const configured = process.env.LLM_GATEWAY_LOGS_DB;
69
88
  if (configured !== undefined) {
@@ -196,6 +215,10 @@ export class FlightRecorder {
196
215
  this.db
197
216
  .prepare("INSERT OR IGNORE INTO _migrations(version, applied_at) VALUES(7, ?)")
198
217
  .run(new Date().toISOString());
218
+ ensureCompressionColumns(this.db);
219
+ this.db
220
+ .prepare("INSERT OR IGNORE INTO _migrations(version, applied_at) VALUES(8, ?)")
221
+ .run(new Date().toISOString());
199
222
  if (process.platform !== "win32") {
200
223
  try {
201
224
  chmodSync(dbPath, 0o600);
@@ -297,6 +320,24 @@ export class FlightRecorder {
297
320
  logComplete(correlationId, result) {
298
321
  this.updateCompleteTxn(correlationId, this.redactEnabled ? this.redactResult(result) : result);
299
322
  }
323
+ recordCompressionTelemetry(correlationId, telemetry) {
324
+ this.db
325
+ .prepare(`UPDATE gateway_metadata
326
+ SET compression_route = @route,
327
+ compression_transforms = @transforms,
328
+ compression_original_chars = @original_chars,
329
+ compression_compressed_chars = @compressed_chars,
330
+ compression_tokens_saved_est = @tokens_saved_est
331
+ WHERE request_id = @id AND compression_route IS NULL`)
332
+ .run({
333
+ id: correlationId,
334
+ route: telemetry.route,
335
+ transforms: telemetry.transforms.join(","),
336
+ original_chars: telemetry.originalChars,
337
+ compressed_chars: telemetry.compressedChars,
338
+ tokens_saved_est: telemetry.estimatedTokensSaved,
339
+ });
340
+ }
300
341
  redactStart(entry) {
301
342
  return {
302
343
  ...entry,
@@ -330,6 +371,7 @@ export class FlightRecorder {
330
371
  export class NoopFlightRecorder {
331
372
  logStart(_entry) { }
332
373
  logComplete(_correlationId, _result) { }
374
+ recordCompressionTelemetry(_correlationId, _telemetry) { }
333
375
  queryRequests(_sql, ..._params) {
334
376
  return [];
335
377
  }
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ import { z } from "zod/v3";
4
4
  import { ISessionManager, type CliType, type ProviderType } from "./session-manager.js";
5
5
  import { ResourceProvider } from "./resources.js";
6
6
  import { PerformanceMetrics } from "./metrics.js";
7
- import { type PersistenceConfig, type CacheAwarenessConfig, type ProvidersConfig, type ApiProviderRuntime, type AcpConfig, type AdminConfig } from "./config.js";
7
+ import { type CompressResult } from "./compressor/index.js";
8
+ import { type PersistenceConfig, type CacheAwarenessConfig, type CompressionConfig, type ProvidersConfig, type ApiProviderRuntime, type AcpConfig, type AdminConfig } from "./config.js";
8
9
  import { DatabaseConnection } from "./db.js";
9
10
  import { type DevinAcpAgentType } from "./provider-definitions.js";
10
11
  import { AsyncJobManager } from "./async-job-manager.js";
@@ -38,6 +39,7 @@ type ExtendedToolResponse = {
38
39
  };
39
40
  reviewIntegrity?: ReviewIntegrityResult;
40
41
  warnings?: WarningEntry[];
42
+ compression?: CompressResult;
41
43
  };
42
44
  export declare const logger: {
43
45
  info: (message: string, ...args: unknown[]) => void;
@@ -76,6 +78,7 @@ export interface GatewayServerDeps {
76
78
  logger?: GatewayLogger;
77
79
  persistence?: PersistenceConfig;
78
80
  cacheAwareness?: CacheAwarenessConfig;
81
+ compression?: CompressionConfig;
79
82
  providers?: ProvidersConfig;
80
83
  acpConfig?: AcpConfig;
81
84
  adminConfig?: AdminConfig;
@@ -92,6 +95,7 @@ export interface GatewayServerRuntime {
92
95
  logger: GatewayLogger;
93
96
  persistence: PersistenceConfig;
94
97
  cacheAwareness: CacheAwarenessConfig;
98
+ compression: CompressionConfig;
95
99
  providers: ProvidersConfig;
96
100
  acpConfig: AcpConfig;
97
101
  adminConfig: AdminConfig;
@@ -169,6 +173,11 @@ export declare function extractUsageAndCost(cli: CliType, output: string, output
169
173
  cacheCreationTokens?: number;
170
174
  costUsd?: number;
171
175
  };
176
+ export declare function resolveEffectiveCompression(compression: CompressionConfig, input: {
177
+ compressResponse?: boolean;
178
+ outputFormat?: string;
179
+ outputSchemaDeclared?: boolean;
180
+ }): boolean;
172
181
  export declare function registerBaseResources(server: McpServer, runtime: GatewayServerRuntime): void;
173
182
  interface CliRequestPrep {
174
183
  corrId: string;
@@ -344,6 +353,7 @@ export declare function prepareGrokRequest(params: {
344
353
  forkSession?: boolean;
345
354
  jsonSchema?: string | Record<string, unknown>;
346
355
  }, runtime?: GatewayServerRuntime): CliRequestPrep | ExtendedToolResponse;
356
+ export declare function resolveMistralAgentMode(approvalStrategy: "legacy" | "mcp_managed" | undefined, callerMode: MistralAgentMode | undefined): MistralAgentMode;
347
357
  export declare function prepareMistralRequest(params: {
348
358
  prompt?: string;
349
359
  promptParts?: PromptParts;
@@ -374,7 +384,7 @@ export declare function buildMistralRetryPrep(params: Pick<MistralRequestParams,
374
384
  env: Record<string, string>;
375
385
  ignoredDisallowedTools: boolean;
376
386
  };
377
- export declare function buildCliResponse(cli: CliType, stdout: string, optimizeResponse: boolean, corrId: string, sessionId: string | undefined, prep: CliRequestPrep, durationMs: number, resumable?: boolean, outputFormat?: string, warnings?: WarningEntry[]): ExtendedToolResponse;
387
+ export declare function buildCliResponse(cli: CliType, stdout: string, optimizeResponse: boolean, corrId: string, sessionId: string | undefined, prep: CliRequestPrep, durationMs: number, resumable?: boolean, outputFormat?: string, warnings?: WarningEntry[], compressResponse?: boolean): ExtendedToolResponse;
378
388
  export interface GrokApiRequestParams {
379
389
  prompt?: string;
380
390
  promptParts?: PromptParts;
@@ -427,6 +437,7 @@ export interface GeminiRequestParams {
427
437
  correlationId?: string;
428
438
  optimizePrompt: boolean;
429
439
  optimizeResponse?: boolean;
440
+ compressResponse?: boolean;
430
441
  idleTimeoutMs?: number;
431
442
  forceRefresh?: boolean;
432
443
  outputFormat?: "text" | "json" | "stream-json";
@@ -482,6 +493,7 @@ export interface GrokRequestParams {
482
493
  correlationId?: string;
483
494
  optimizePrompt: boolean;
484
495
  optimizeResponse?: boolean;
496
+ compressResponse?: boolean;
485
497
  idleTimeoutMs?: number;
486
498
  forceRefresh?: boolean;
487
499
  maxTurns?: number;
@@ -541,6 +553,7 @@ export interface DevinRequestParams {
541
553
  correlationId?: string;
542
554
  optimizePrompt: boolean;
543
555
  optimizeResponse?: boolean;
556
+ compressResponse?: boolean;
544
557
  idleTimeoutMs?: number;
545
558
  forceRefresh?: boolean;
546
559
  }
@@ -580,6 +593,7 @@ export interface CursorRequestParams {
580
593
  correlationId?: string;
581
594
  optimizePrompt: boolean;
582
595
  optimizeResponse?: boolean;
596
+ compressResponse?: boolean;
583
597
  idleTimeoutMs?: number;
584
598
  forceRefresh?: boolean;
585
599
  }
@@ -620,6 +634,7 @@ export interface MistralRequestParams {
620
634
  correlationId?: string;
621
635
  optimizePrompt: boolean;
622
636
  optimizeResponse?: boolean;
637
+ compressResponse?: boolean;
623
638
  idleTimeoutMs?: number;
624
639
  forceRefresh?: boolean;
625
640
  trust?: boolean;
@@ -653,6 +668,7 @@ export declare function handleCodexRequestAsync(deps: AsyncHandlerDeps, params:
653
668
  createNewSession: boolean;
654
669
  correlationId?: string;
655
670
  optimizePrompt: boolean;
671
+ compressResponse?: boolean;
656
672
  idleTimeoutMs?: number;
657
673
  forceRefresh?: boolean;
658
674
  outputFormat?: "text" | "json";