llm-cli-gateway 2.14.1 → 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 (41) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/README.md +35 -0
  3. package/dist/acp/process-manager.js +2 -1
  4. package/dist/acp/provider-registry.js +8 -8
  5. package/dist/async-job-manager.d.ts +4 -1
  6. package/dist/async-job-manager.js +15 -6
  7. package/dist/compressor/estimate.d.ts +5 -0
  8. package/dist/compressor/estimate.js +21 -0
  9. package/dist/compressor/index.d.ts +23 -0
  10. package/dist/compressor/index.js +77 -0
  11. package/dist/compressor/router.d.ts +2 -0
  12. package/dist/compressor/router.js +57 -0
  13. package/dist/compressor/transforms/ansi.d.ts +3 -0
  14. package/dist/compressor/transforms/ansi.js +89 -0
  15. package/dist/compressor/transforms/json.d.ts +1 -0
  16. package/dist/compressor/transforms/json.js +156 -0
  17. package/dist/compressor/transforms/log.d.ts +12 -0
  18. package/dist/compressor/transforms/log.js +55 -0
  19. package/dist/compressor/transforms/whitespace.d.ts +8 -0
  20. package/dist/compressor/transforms/whitespace.js +79 -0
  21. package/dist/config.d.ts +16 -0
  22. package/dist/config.js +57 -0
  23. package/dist/executor.d.ts +1 -0
  24. package/dist/executor.js +5 -2
  25. package/dist/flight-recorder.d.ts +9 -0
  26. package/dist/flight-recorder.js +42 -0
  27. package/dist/index.d.ts +18 -2
  28. package/dist/index.js +282 -88
  29. package/dist/job-store.d.ts +4 -0
  30. package/dist/job-store.js +16 -0
  31. package/dist/provider-definitions.d.ts +1 -0
  32. package/dist/provider-definitions.js +28 -10
  33. package/dist/provider-tool-capabilities.js +3 -3
  34. package/dist/request-helpers.js +1 -1
  35. package/dist/skill-loader.d.ts +24 -0
  36. package/dist/skill-loader.js +201 -0
  37. package/dist/spawn-env-isolation.d.ts +10 -0
  38. package/dist/spawn-env-isolation.js +55 -0
  39. package/dist/upstream-contracts.js +47 -27
  40. package/npm-shrinkwrap.json +2 -2
  41. package/package.json +7 -3
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mc
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { randomUUID } from "crypto";
5
5
  import { createRequire } from "module";
6
- import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync, chmodSync, } from "fs";
6
+ import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, chmodSync, } from "fs";
7
7
  import { basename, dirname, isAbsolute, join, relative } from "path";
8
8
  import { fileURLToPath } from "url";
9
9
  import { z } from "zod/v3";
@@ -21,7 +21,9 @@ import { ResourceProvider } from "./resources.js";
21
21
  import { generateResourceDescriptors, generateProviderAcpDescriptors, } from "./provider-surface-generator.js";
22
22
  import { PerformanceMetrics } from "./metrics.js";
23
23
  import { estimateTokens, optimizePrompt as optimizePromptText, optimizeResponse as optimizeResponseText, } from "./optimizer.js";
24
- import { loadConfig, loadPersistenceConfig, loadCacheAwarenessConfig, loadProvidersConfig, loadAcpConfig, loadAdminConfig, loadLimitsConfig, defaultGatewayConfigPath, isXaiProviderEnabled, enabledApiProviders, minStableTokensForModel, } from "./config.js";
24
+ import { compressDisplayText } from "./compressor/index.js";
25
+ import { loadConfig, loadPersistenceConfig, loadCacheAwarenessConfig, loadProvidersConfig, loadAcpConfig, loadAdminConfig, loadLimitsConfig, loadCompressionConfig, loadSkillsConfig, defaultGatewayConfigPath, isXaiProviderEnabled, enabledApiProviders, minStableTokensForModel, } from "./config.js";
26
+ import { loadGatewaySkills } from "./skill-loader.js";
25
27
  import { runAcpRequest } from "./acp/runtime.js";
26
28
  import { isAcpError } from "./acp/errors.js";
27
29
  import { redactSecrets } from "./secret-redaction.js";
@@ -184,27 +186,13 @@ function packageVersion() {
184
186
  }
185
187
  return "unknown";
186
188
  }
187
- function loadSkills() {
188
- const skills = [];
189
- try {
190
- const dirs = readdirSync(SKILLS_DIR, { withFileTypes: true }).filter(d => d.isDirectory());
191
- for (const dir of dirs) {
192
- const skillPath = join(SKILLS_DIR, dir.name, "SKILL.md");
193
- try {
194
- const content = readFileSync(skillPath, "utf-8");
195
- const descMatch = content.match(/^---[\s\S]*?description:\s*(.+?)$/m);
196
- const description = descMatch?.[1]?.trim() || dir.name;
197
- skills.push({ name: dir.name, content, description });
198
- }
199
- catch {
200
- }
201
- }
202
- }
203
- catch {
204
- }
205
- return skills;
206
- }
207
- const loadedSkills = loadSkills();
189
+ const skillsConfig = loadSkillsConfig(logger);
190
+ const loadedSkills = loadGatewaySkills({
191
+ bundledSkillsDir: SKILLS_DIR,
192
+ configuredPaths: skillsConfig.paths,
193
+ envSkillsPath: undefined,
194
+ logger,
195
+ });
208
196
  export function buildServerInstructions(asyncJobsEnabled, grokApiToolsEnabled = false) {
209
197
  const asyncToolsNote = asyncJobsEnabled ? " | *_request_async (async)" : "";
210
198
  const apiToolsNote = grokApiToolsEnabled ? ", grok_api_request" : "";
@@ -241,6 +229,7 @@ let resourceProvider;
241
229
  let flightRecorder = null;
242
230
  let persistenceConfig = null;
243
231
  let cacheAwarenessConfig = null;
232
+ let compressionConfig = null;
244
233
  let providersConfig = null;
245
234
  let acpConfig = null;
246
235
  let adminConfig = null;
@@ -273,6 +262,10 @@ function getCacheAwarenessConfig(runtimeLogger = logger) {
273
262
  cacheAwarenessConfig ??= loadCacheAwarenessConfig(runtimeLogger);
274
263
  return cacheAwarenessConfig;
275
264
  }
265
+ function getCompressionConfig(runtimeLogger = logger) {
266
+ compressionConfig ??= loadCompressionConfig(runtimeLogger);
267
+ return compressionConfig;
268
+ }
276
269
  function getProvidersConfig(runtimeLogger = logger) {
277
270
  providersConfig ??= loadProvidersConfig(runtimeLogger);
278
271
  return providersConfig;
@@ -481,6 +474,7 @@ export function resolveGatewayServerRuntime(deps = {}, options = {}) {
481
474
  logger: runtimeLogger,
482
475
  persistence: deps.persistence ?? getPersistenceConfig(runtimeLogger),
483
476
  cacheAwareness: deps.cacheAwareness ?? getCacheAwarenessConfig(runtimeLogger),
477
+ compression: deps.compression ?? getCompressionConfig(runtimeLogger),
484
478
  providers: deps.providers ?? getProvidersConfig(runtimeLogger),
485
479
  acpConfig: deps.acpConfig ?? getAcpConfig(runtimeLogger),
486
480
  adminConfig: deps.adminConfig ?? getAdminConfig(runtimeLogger),
@@ -558,7 +552,7 @@ export async function runAcpTransport(deps, params) {
558
552
  }
559
553
  }
560
554
  const SYNC_POLL_INTERVAL_MS = 1_000;
561
- async function awaitJobOrDefer(cli, args, corrId, idleTimeoutMs, outputFormat, forceRefresh, runtime = resolveGatewayServerRuntime(), env, onComplete, flightRecorderEntry, extractUsage, stdin, cwd) {
555
+ async function awaitJobOrDefer(cli, args, corrId, idleTimeoutMs, outputFormat, forceRefresh, runtime = resolveGatewayServerRuntime(), env, onComplete, flightRecorderEntry, extractUsage, stdin, cwd, compressResponse) {
562
556
  let onCompleteOwnedByCaller = onComplete !== undefined;
563
557
  const consumeOnComplete = () => {
564
558
  if (!onCompleteOwnedByCaller || !onComplete)
@@ -618,6 +612,7 @@ async function awaitJobOrDefer(cli, args, corrId, idleTimeoutMs, outputFormat, f
618
612
  onComplete,
619
613
  flightRecorderEntry,
620
614
  extractUsage,
615
+ compressResponse,
621
616
  });
622
617
  onCompleteOwnedByCaller = false;
623
618
  }
@@ -1179,7 +1174,7 @@ export function extractUsageAndCost(cli, output, outputFormat, ctx) {
1179
1174
  }
1180
1175
  return {};
1181
1176
  }
1182
- function buildAsyncFlightRecorderHandoff(cliName, prep, sessionId, outputFormat) {
1177
+ function buildAsyncFlightRecorderHandoff(cliName, prep, sessionId, outputFormat, optimizationApplied = false) {
1183
1178
  const cli = cliName;
1184
1179
  const fmt = outputFormat;
1185
1180
  const sid = sessionId;
@@ -1189,6 +1184,7 @@ function buildAsyncFlightRecorderHandoff(cliName, prep, sessionId, outputFormat)
1189
1184
  model: prep.resolvedModel || "default",
1190
1185
  prompt: prep.effectivePrompt,
1191
1186
  sessionId,
1187
+ optimizationApplied,
1192
1188
  stablePrefixHash: prep.stablePrefixHash ?? undefined,
1193
1189
  stablePrefixTokens: prep.stablePrefixTokens ?? undefined,
1194
1190
  cacheControlBlocks: prep.cacheControlBlocks,
@@ -1213,6 +1209,32 @@ function safeFlightComplete(correlationId, result, runtime = resolveGatewayServe
1213
1209
  runtime.logger.error("Flight recorder logComplete failed", error);
1214
1210
  }
1215
1211
  }
1212
+ export function resolveEffectiveCompression(compression, input) {
1213
+ const requested = input.compressResponse ?? compression.enabled;
1214
+ if (!requested)
1215
+ return false;
1216
+ if (input.outputFormat === "json")
1217
+ return false;
1218
+ if (input.outputSchemaDeclared)
1219
+ return false;
1220
+ return true;
1221
+ }
1222
+ function safeRecordCompression(correlationId, compression, runtime) {
1223
+ if (!compression)
1224
+ return;
1225
+ try {
1226
+ runtime.flightRecorder.recordCompressionTelemetry(correlationId, {
1227
+ route: compression.route,
1228
+ transforms: compression.transforms,
1229
+ originalChars: compression.originalChars,
1230
+ compressedChars: compression.compressedChars,
1231
+ estimatedTokensSaved: compression.estimatedTokensSaved,
1232
+ });
1233
+ }
1234
+ catch (error) {
1235
+ runtime.logger.error("Flight recorder recordCompressionTelemetry failed", error);
1236
+ }
1237
+ }
1216
1238
  function createApprovalDeniedResponse(operation, decision) {
1217
1239
  return {
1218
1240
  content: [
@@ -2223,6 +2245,14 @@ export function prepareGrokRequest(params, runtime = resolveGatewayServerRuntime
2223
2245
  stablePrefixTokens,
2224
2246
  };
2225
2247
  }
2248
+ export function resolveMistralAgentMode(approvalStrategy, callerMode) {
2249
+ if (approvalStrategy === "mcp_managed") {
2250
+ return bypassAllowedByOperator() ? "auto-approve" : "accept-edits";
2251
+ }
2252
+ if (callerMode !== undefined)
2253
+ return callerMode;
2254
+ return bypassAllowedByOperator() ? "auto-approve" : "accept-edits";
2255
+ }
2226
2256
  export function prepareMistralRequest(params, runtime = resolveGatewayServerRuntime()) {
2227
2257
  const corrId = params.correlationId || randomUUID();
2228
2258
  const cliInfo = getCliInfo();
@@ -2279,11 +2309,7 @@ export function prepareMistralRequest(params, runtime = resolveGatewayServerRunt
2279
2309
  return createApprovalDeniedResponse(params.operation, approvalDecision);
2280
2310
  }
2281
2311
  }
2282
- const effectivePermissionMode = params.approvalStrategy === "mcp_managed"
2283
- ? bypassAllowedByOperator()
2284
- ? "auto-approve"
2285
- : "accept-edits"
2286
- : (params.permissionMode ?? "auto-approve");
2312
+ const effectivePermissionMode = resolveMistralAgentMode(params.approvalStrategy, params.permissionMode);
2287
2313
  const prep = buildMistralCliInvocation({
2288
2314
  prompt: effectivePrompt,
2289
2315
  resolvedModel,
@@ -2332,11 +2358,7 @@ export function buildMistralRetryPrep(params, recoveryModel) {
2332
2358
  prompt: params.effectivePrompt,
2333
2359
  resolvedModel: recoveryModel,
2334
2360
  outputFormat: params.outputFormat,
2335
- permissionMode: params.approvalStrategy === "mcp_managed"
2336
- ? bypassAllowedByOperator()
2337
- ? "auto-approve"
2338
- : "accept-edits"
2339
- : (params.permissionMode ?? "auto-approve"),
2361
+ permissionMode: resolveMistralAgentMode(params.approvalStrategy, params.permissionMode),
2340
2362
  allowedTools: params.allowedTools,
2341
2363
  disallowedTools: params.disallowedTools,
2342
2364
  trust: params.trust,
@@ -2347,7 +2369,7 @@ export function buildMistralRetryPrep(params, recoveryModel) {
2347
2369
  addDir: params.addDir,
2348
2370
  });
2349
2371
  }
2350
- export function buildCliResponse(cli, stdout, optimizeResponse, corrId, sessionId, prep, durationMs, resumable, outputFormat, warnings) {
2372
+ export function buildCliResponse(cli, stdout, optimizeResponse, corrId, sessionId, prep, durationMs, resumable, outputFormat, warnings, compressResponse = false) {
2351
2373
  let finalStdout = stdout;
2352
2374
  if (cli === "codex" && outputFormat !== "json") {
2353
2375
  finalStdout = codexDisplayText(stdout);
@@ -2360,6 +2382,20 @@ export function buildCliResponse(cli, stdout, optimizeResponse, corrId, sessionI
2360
2382
  logOptimizationTokens("response", corrId, finalStdout, optimized);
2361
2383
  finalStdout = optimized;
2362
2384
  }
2385
+ let compression;
2386
+ if (compressResponse && outputFormat !== "json") {
2387
+ const compressed = compressDisplayText(finalStdout, {
2388
+ provider: cli,
2389
+ direction: "outbound",
2390
+ outputFormat,
2391
+ outputSchemaDeclared: false,
2392
+ lossless: true,
2393
+ });
2394
+ if (compressed.text !== finalStdout) {
2395
+ compression = compressed;
2396
+ finalStdout = compressed.text;
2397
+ }
2398
+ }
2363
2399
  if (prep.reviewIntegrity &&
2364
2400
  prep.reviewIntegrity.violations.length > 0 &&
2365
2401
  outputFormat !== "json") {
@@ -2435,6 +2471,7 @@ export function buildCliResponse(cli, stdout, optimizeResponse, corrId, sessionI
2435
2471
  missing: prep.mcpConfig.missing,
2436
2472
  }
2437
2473
  : { requested: prep.requestedMcpServers },
2474
+ ...(compression ? { compression } : {}),
2438
2475
  };
2439
2476
  if (sessionId) {
2440
2477
  response.sessionId = sessionId;
@@ -3188,8 +3225,13 @@ export async function handleGeminiRequest(deps, params) {
3188
3225
  catch (err) {
3189
3226
  return createErrorResponse("gemini_request", 1, "", corrId, err);
3190
3227
  }
3191
- const geminiFrHandoff = buildAsyncFlightRecorderHandoff("gemini", prep, params.sessionId, params.outputFormat);
3192
- const result = await awaitJobOrDefer("gemini", args, corrId, resolveIdleTimeout("gemini", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, undefined, undefined, geminiFrHandoff.flightRecorderEntry, geminiFrHandoff.extractUsage, undefined, worktreeResolution.cwd);
3228
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
3229
+ compressResponse: params.compressResponse,
3230
+ outputFormat: params.outputFormat,
3231
+ outputSchemaDeclared: false,
3232
+ });
3233
+ const geminiFrHandoff = buildAsyncFlightRecorderHandoff("gemini", prep, params.sessionId, params.outputFormat, params.optimizePrompt);
3234
+ const result = await awaitJobOrDefer("gemini", args, corrId, resolveIdleTimeout("gemini", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, undefined, undefined, geminiFrHandoff.flightRecorderEntry, geminiFrHandoff.extractUsage, undefined, worktreeResolution.cwd, effectiveCompress);
3193
3235
  if (isDeferredResponse(result)) {
3194
3236
  return buildDeferredToolResponse(result, effectiveSessionIdHint);
3195
3237
  }
@@ -3226,7 +3268,8 @@ export async function handleGeminiRequest(deps, params) {
3226
3268
  await deps.sessionManager.updateSessionUsage(effectiveSessionId);
3227
3269
  }
3228
3270
  deps.logger.info(`[${corrId}] gemini_request completed successfully in ${durationMs}ms`);
3229
- const response = buildCliResponse("gemini", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, userProvidedSession, params.outputFormat);
3271
+ const response = buildCliResponse("gemini", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, userProvidedSession, params.outputFormat, undefined, effectiveCompress);
3272
+ safeRecordCompression(corrId, response.compression, runtime);
3230
3273
  if (worktreeResolution.worktreePath) {
3231
3274
  const first = response.content[0];
3232
3275
  if (first && first.type === "text") {
@@ -3341,8 +3384,13 @@ export async function handleGeminiRequestAsync(deps, params) {
3341
3384
  }
3342
3385
  assertUpstreamCliArgs("gemini", args);
3343
3386
  assertUpstreamCliEnv("gemini", undefined);
3344
- const geminiAsyncFrHandoff = buildAsyncFlightRecorderHandoff("gemini", prep, effectiveSessionId, params.outputFormat);
3345
- const job = deps.asyncJobManager.startJob("gemini", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("gemini", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, undefined, geminiAsyncFrHandoff.flightRecorderEntry, geminiAsyncFrHandoff.extractUsage, true);
3387
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
3388
+ compressResponse: params.compressResponse,
3389
+ outputFormat: params.outputFormat,
3390
+ outputSchemaDeclared: false,
3391
+ });
3392
+ const geminiAsyncFrHandoff = buildAsyncFlightRecorderHandoff("gemini", prep, effectiveSessionId, params.outputFormat, params.optimizePrompt);
3393
+ const job = deps.asyncJobManager.startJob("gemini", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("gemini", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, undefined, geminiAsyncFrHandoff.flightRecorderEntry, geminiAsyncFrHandoff.extractUsage, true, undefined, effectiveCompress);
3346
3394
  deps.logger.info(`[${corrId}] gemini_request_async started job ${job.id}`);
3347
3395
  const asyncResponse = {
3348
3396
  success: true,
@@ -3471,8 +3519,13 @@ export async function handleGrokRequest(deps, params) {
3471
3519
  catch (err) {
3472
3520
  return createErrorResponse("grok_request", 1, "", corrId, err);
3473
3521
  }
3474
- const grokFrHandoff = buildAsyncFlightRecorderHandoff("grok", prep, params.sessionId, params.outputFormat);
3475
- const result = await awaitJobOrDefer("grok", args, corrId, resolveIdleTimeout("grok", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, undefined, undefined, grokFrHandoff.flightRecorderEntry, grokFrHandoff.extractUsage, undefined, worktreeResolution.cwd);
3522
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
3523
+ compressResponse: params.compressResponse,
3524
+ outputFormat: params.outputFormat,
3525
+ outputSchemaDeclared: false,
3526
+ });
3527
+ const grokFrHandoff = buildAsyncFlightRecorderHandoff("grok", prep, params.sessionId, params.outputFormat, params.optimizePrompt);
3528
+ const result = await awaitJobOrDefer("grok", args, corrId, resolveIdleTimeout("grok", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, undefined, undefined, grokFrHandoff.flightRecorderEntry, grokFrHandoff.extractUsage, undefined, worktreeResolution.cwd, effectiveCompress);
3476
3529
  if (isDeferredResponse(result)) {
3477
3530
  return buildDeferredToolResponse(result, sessionResult.effectiveSessionId);
3478
3531
  }
@@ -3513,7 +3566,8 @@ export async function handleGrokRequest(deps, params) {
3513
3566
  effectiveSessionId = newSession.id;
3514
3567
  }
3515
3568
  deps.logger.info(`[${corrId}] grok_request completed successfully in ${durationMs}ms`);
3516
- const response = buildCliResponse("grok", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, params.outputFormat);
3569
+ const response = buildCliResponse("grok", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, params.outputFormat, undefined, effectiveCompress);
3570
+ safeRecordCompression(corrId, response.compression, runtime);
3517
3571
  if (worktreeResolution.worktreePath) {
3518
3572
  const first = response.content[0];
3519
3573
  if (first && first.type === "text") {
@@ -3654,8 +3708,13 @@ export async function handleGrokRequestAsync(deps, params) {
3654
3708
  }
3655
3709
  assertUpstreamCliArgs("grok", args);
3656
3710
  assertUpstreamCliEnv("grok", undefined);
3657
- const grokAsyncFrHandoff = buildAsyncFlightRecorderHandoff("grok", prep, effectiveSessionId, params.outputFormat);
3658
- const job = deps.asyncJobManager.startJob("grok", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("grok", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, undefined, grokAsyncFrHandoff.flightRecorderEntry, grokAsyncFrHandoff.extractUsage, true);
3711
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
3712
+ compressResponse: params.compressResponse,
3713
+ outputFormat: params.outputFormat,
3714
+ outputSchemaDeclared: false,
3715
+ });
3716
+ const grokAsyncFrHandoff = buildAsyncFlightRecorderHandoff("grok", prep, effectiveSessionId, params.outputFormat, params.optimizePrompt);
3717
+ const job = deps.asyncJobManager.startJob("grok", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("grok", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, undefined, grokAsyncFrHandoff.flightRecorderEntry, grokAsyncFrHandoff.extractUsage, true, undefined, effectiveCompress);
3659
3718
  deps.logger.info(`[${corrId}] grok_request_async started job ${job.id}`);
3660
3719
  const asyncResponse = {
3661
3720
  success: true,
@@ -3783,8 +3842,13 @@ export async function handleDevinRequest(deps, params) {
3783
3842
  await getExistingSessionForProvider(deps.sessionManager, sessionResult.effectiveSessionId, "devin");
3784
3843
  }
3785
3844
  args.push(...sessionResult.resumeArgs);
3786
- const devinFrHandoff = buildAsyncFlightRecorderHandoff("devin", prep, params.sessionId, undefined);
3787
- const result = await awaitJobOrDefer("devin", args, corrId, resolveIdleTimeout("devin", params.idleTimeoutMs), undefined, params.forceRefresh, runtime, undefined, undefined, devinFrHandoff.flightRecorderEntry, devinFrHandoff.extractUsage);
3845
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
3846
+ compressResponse: params.compressResponse,
3847
+ outputFormat: undefined,
3848
+ outputSchemaDeclared: false,
3849
+ });
3850
+ const devinFrHandoff = buildAsyncFlightRecorderHandoff("devin", prep, params.sessionId, undefined, params.optimizePrompt);
3851
+ const result = await awaitJobOrDefer("devin", args, corrId, resolveIdleTimeout("devin", params.idleTimeoutMs), undefined, params.forceRefresh, runtime, undefined, undefined, devinFrHandoff.flightRecorderEntry, devinFrHandoff.extractUsage, undefined, undefined, effectiveCompress);
3788
3852
  if (isDeferredResponse(result)) {
3789
3853
  return buildDeferredToolResponse(result, sessionResult.effectiveSessionId);
3790
3854
  }
@@ -3823,7 +3887,8 @@ export async function handleDevinRequest(deps, params) {
3823
3887
  const newSession = await deps.sessionManager.createSession("devin", "Devin Session", `${GATEWAY_SESSION_PREFIX}${randomUUID()}`);
3824
3888
  effectiveSessionId = newSession.id;
3825
3889
  }
3826
- const response = buildCliResponse("devin", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession);
3890
+ const response = buildCliResponse("devin", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, undefined, undefined, effectiveCompress);
3891
+ safeRecordCompression(corrId, response.compression, runtime);
3827
3892
  safeFlightComplete(corrId, {
3828
3893
  response: stdout,
3829
3894
  durationMs,
@@ -3903,8 +3968,13 @@ export async function handleDevinRequestAsync(deps, params) {
3903
3968
  }
3904
3969
  assertUpstreamCliArgs("devin", args);
3905
3970
  assertUpstreamCliEnv("devin", undefined);
3906
- const devinAsyncFrHandoff = buildAsyncFlightRecorderHandoff("devin", prep, effectiveSessionId, undefined);
3907
- const job = deps.asyncJobManager.startJob("devin", args, corrId, undefined, resolveIdleTimeout("devin", params.idleTimeoutMs), undefined, params.forceRefresh, undefined, undefined, devinAsyncFrHandoff.flightRecorderEntry, devinAsyncFrHandoff.extractUsage, true);
3971
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
3972
+ compressResponse: params.compressResponse,
3973
+ outputFormat: undefined,
3974
+ outputSchemaDeclared: false,
3975
+ });
3976
+ const devinAsyncFrHandoff = buildAsyncFlightRecorderHandoff("devin", prep, effectiveSessionId, undefined, params.optimizePrompt);
3977
+ const job = deps.asyncJobManager.startJob("devin", args, corrId, undefined, resolveIdleTimeout("devin", params.idleTimeoutMs), undefined, params.forceRefresh, undefined, undefined, devinAsyncFrHandoff.flightRecorderEntry, devinAsyncFrHandoff.extractUsage, true, undefined, effectiveCompress);
3908
3978
  deps.logger.info(`[${corrId}] devin_request_async started job ${job.id}`);
3909
3979
  return {
3910
3980
  content: [
@@ -4102,8 +4172,13 @@ export async function handleCursorRequest(deps, params) {
4102
4172
  args[workspaceFlagIndex + 1] = worktreeResolution.workspace.cwd;
4103
4173
  }
4104
4174
  }
4105
- const cursorFrHandoff = buildAsyncFlightRecorderHandoff("cursor", prep, params.sessionId, params.outputFormat);
4106
- const result = await awaitJobOrDefer("cursor", args, corrId, resolveIdleTimeout("cursor", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, undefined, undefined, cursorFrHandoff.flightRecorderEntry, cursorFrHandoff.extractUsage, undefined, worktreeResolution.cwd);
4175
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
4176
+ compressResponse: params.compressResponse,
4177
+ outputFormat: params.outputFormat,
4178
+ outputSchemaDeclared: false,
4179
+ });
4180
+ const cursorFrHandoff = buildAsyncFlightRecorderHandoff("cursor", prep, params.sessionId, params.outputFormat, params.optimizePrompt);
4181
+ const result = await awaitJobOrDefer("cursor", args, corrId, resolveIdleTimeout("cursor", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, undefined, undefined, cursorFrHandoff.flightRecorderEntry, cursorFrHandoff.extractUsage, undefined, worktreeResolution.cwd, effectiveCompress);
4107
4182
  if (isDeferredResponse(result)) {
4108
4183
  return buildDeferredToolResponse(result, sessionResult.effectiveSessionId);
4109
4184
  }
@@ -4142,7 +4217,8 @@ export async function handleCursorRequest(deps, params) {
4142
4217
  const newSession = await deps.sessionManager.createSession("cursor", "Cursor Session", `${GATEWAY_SESSION_PREFIX}${randomUUID()}`);
4143
4218
  effectiveSessionId = newSession.id;
4144
4219
  }
4145
- const response = buildCliResponse("cursor", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, params.outputFormat);
4220
+ const response = buildCliResponse("cursor", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, params.outputFormat, undefined, effectiveCompress);
4221
+ safeRecordCompression(corrId, response.compression, runtime);
4146
4222
  safeFlightComplete(corrId, {
4147
4223
  response: stdout,
4148
4224
  durationMs,
@@ -4244,8 +4320,13 @@ export async function handleCursorRequestAsync(deps, params) {
4244
4320
  }
4245
4321
  assertUpstreamCliArgs("cursor", args);
4246
4322
  assertUpstreamCliEnv("cursor", undefined);
4247
- const cursorAsyncFrHandoff = buildAsyncFlightRecorderHandoff("cursor", prep, effectiveSessionId, params.outputFormat);
4248
- const job = deps.asyncJobManager.startJob("cursor", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("cursor", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, undefined, cursorAsyncFrHandoff.flightRecorderEntry, cursorAsyncFrHandoff.extractUsage, true);
4323
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
4324
+ compressResponse: params.compressResponse,
4325
+ outputFormat: params.outputFormat,
4326
+ outputSchemaDeclared: false,
4327
+ });
4328
+ const cursorAsyncFrHandoff = buildAsyncFlightRecorderHandoff("cursor", prep, effectiveSessionId, params.outputFormat, params.optimizePrompt);
4329
+ const job = deps.asyncJobManager.startJob("cursor", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("cursor", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, undefined, cursorAsyncFrHandoff.flightRecorderEntry, cursorAsyncFrHandoff.extractUsage, true, undefined, effectiveCompress);
4249
4330
  deps.logger.info(`[${corrId}] cursor_request_async started job ${job.id}`);
4250
4331
  return {
4251
4332
  content: [
@@ -4312,7 +4393,7 @@ export async function handleMistralRequest(deps, params) {
4312
4393
  stablePrefixHash: prep.stablePrefixHash ?? undefined,
4313
4394
  stablePrefixTokens: prep.stablePrefixTokens ?? undefined,
4314
4395
  }, runtime);
4315
- deps.logger.info(`[${corrId}] mistral_request invoked with model=${prep.resolvedModel || "default"}, permissionMode=${params.permissionMode || "auto-approve"}, prompt length=${prep.effectivePrompt.length}`);
4396
+ deps.logger.info(`[${corrId}] mistral_request invoked with model=${prep.resolvedModel || "default"}, permissionMode=${resolveMistralAgentMode(params.approvalStrategy, params.permissionMode)}, prompt length=${prep.effectivePrompt.length}`);
4316
4397
  try {
4317
4398
  const sessionResult = resolveMistralSessionArgs({
4318
4399
  sessionId: params.sessionId,
@@ -4338,8 +4419,13 @@ export async function handleMistralRequest(deps, params) {
4338
4419
  catch (err) {
4339
4420
  return createErrorResponse("mistral_request", 1, "", corrId, err);
4340
4421
  }
4341
- const mistralFrHandoff = buildAsyncFlightRecorderHandoff("mistral", prep, params.sessionId, params.outputFormat);
4342
- let result = await awaitJobOrDefer("mistral", args, corrId, resolveIdleTimeout("mistral", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, mistralEnv, undefined, mistralFrHandoff.flightRecorderEntry, mistralFrHandoff.extractUsage, undefined, worktreeResolution.cwd);
4422
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
4423
+ compressResponse: params.compressResponse,
4424
+ outputFormat: params.outputFormat,
4425
+ outputSchemaDeclared: false,
4426
+ });
4427
+ const mistralFrHandoff = buildAsyncFlightRecorderHandoff("mistral", prep, params.sessionId, params.outputFormat, params.optimizePrompt);
4428
+ let result = await awaitJobOrDefer("mistral", args, corrId, resolveIdleTimeout("mistral", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, runtime, mistralEnv, undefined, mistralFrHandoff.flightRecorderEntry, mistralFrHandoff.extractUsage, undefined, worktreeResolution.cwd, effectiveCompress);
4343
4429
  if (isDeferredResponse(result)) {
4344
4430
  return buildDeferredToolResponse(result, sessionResult.effectiveSessionId);
4345
4431
  }
@@ -4349,7 +4435,7 @@ export async function handleMistralRequest(deps, params) {
4349
4435
  deps.logger.info(`[${corrId}] mistral_request detected stale Vibe model selection; retrying once with ${recoveryModel}`);
4350
4436
  const retryPrep = buildMistralRetryPrep({ ...params, effectivePrompt: prep.effectivePrompt }, recoveryModel);
4351
4437
  const retryArgs = [...retryPrep.args, ...sessionResult.resumeArgs];
4352
- result = await awaitJobOrDefer("mistral", retryArgs, corrId, resolveIdleTimeout("mistral", params.idleTimeoutMs), params.outputFormat, true, runtime, retryPrep.env, undefined, mistralFrHandoff.flightRecorderEntry, mistralFrHandoff.extractUsage, undefined, worktreeResolution.cwd);
4438
+ result = await awaitJobOrDefer("mistral", retryArgs, corrId, resolveIdleTimeout("mistral", params.idleTimeoutMs), params.outputFormat, true, runtime, retryPrep.env, undefined, mistralFrHandoff.flightRecorderEntry, mistralFrHandoff.extractUsage, undefined, worktreeResolution.cwd, effectiveCompress);
4353
4439
  if (isDeferredResponse(result)) {
4354
4440
  return buildDeferredToolResponse(result, sessionResult.effectiveSessionId);
4355
4441
  }
@@ -4394,7 +4480,8 @@ export async function handleMistralRequest(deps, params) {
4394
4480
  effectiveSessionId = newSession.id;
4395
4481
  }
4396
4482
  deps.logger.info(`[${corrId}] mistral_request completed successfully in ${durationMs}ms`);
4397
- const response = buildCliResponse("mistral", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, params.outputFormat);
4483
+ const response = buildCliResponse("mistral", stdout, params.optimizeResponse ?? false, corrId, effectiveSessionId, prep, durationMs, sessionResult.userProvidedSession, params.outputFormat, undefined, effectiveCompress);
4484
+ safeRecordCompression(corrId, response.compression, runtime);
4398
4485
  if (worktreeResolution.worktreePath) {
4399
4486
  const first = response.content[0];
4400
4487
  if (first && first.type === "text") {
@@ -4502,8 +4589,13 @@ export async function handleMistralRequestAsync(deps, params) {
4502
4589
  }
4503
4590
  assertUpstreamCliArgs("mistral", args);
4504
4591
  assertUpstreamCliEnv("mistral", mistralEnv);
4505
- const mistralAsyncFrHandoff = buildAsyncFlightRecorderHandoff("mistral", prep, effectiveSessionId, params.outputFormat);
4506
- const job = deps.asyncJobManager.startJob("mistral", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("mistral", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, mistralEnv, undefined, mistralAsyncFrHandoff.flightRecorderEntry, mistralAsyncFrHandoff.extractUsage, true);
4592
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
4593
+ compressResponse: params.compressResponse,
4594
+ outputFormat: params.outputFormat,
4595
+ outputSchemaDeclared: false,
4596
+ });
4597
+ const mistralAsyncFrHandoff = buildAsyncFlightRecorderHandoff("mistral", prep, effectiveSessionId, params.outputFormat, params.optimizePrompt);
4598
+ const job = deps.asyncJobManager.startJob("mistral", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("mistral", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, mistralEnv, undefined, mistralAsyncFrHandoff.flightRecorderEntry, mistralAsyncFrHandoff.extractUsage, true, undefined, effectiveCompress);
4507
4599
  deps.logger.info(`[${corrId}] mistral_request_async started job ${job.id}`);
4508
4600
  const asyncResponse = {
4509
4601
  success: true,
@@ -4632,10 +4724,15 @@ export async function handleCodexRequestAsync(deps, params) {
4632
4724
  }
4633
4725
  assertUpstreamCliArgs("codex", args);
4634
4726
  assertUpstreamCliEnv("codex", undefined);
4635
- const codexAsyncFrHandoff = buildAsyncFlightRecorderHandoff("codex", prep, effectiveSessionId, params.outputFormat);
4727
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
4728
+ compressResponse: params.compressResponse,
4729
+ outputFormat: params.outputFormat,
4730
+ outputSchemaDeclared: params.outputSchema !== undefined,
4731
+ });
4732
+ const codexAsyncFrHandoff = buildAsyncFlightRecorderHandoff("codex", prep, effectiveSessionId, params.outputFormat, params.optimizePrompt);
4636
4733
  let job;
4637
4734
  try {
4638
- job = deps.asyncJobManager.startJob("codex", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("codex", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, prepCleanup, codexAsyncFrHandoff.flightRecorderEntry, codexAsyncFrHandoff.extractUsage, true);
4735
+ job = deps.asyncJobManager.startJob("codex", args, corrId, worktreeResolution.cwd, resolveIdleTimeout("codex", params.idleTimeoutMs), params.outputFormat, params.forceRefresh, undefined, prepCleanup, codexAsyncFrHandoff.flightRecorderEntry, codexAsyncFrHandoff.extractUsage, true, undefined, effectiveCompress);
4639
4736
  prepCleanupOwnedHere = false;
4640
4737
  }
4641
4738
  catch (startErr) {
@@ -4896,6 +4993,10 @@ export function createGatewayServer(deps = {}) {
4896
4993
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
4897
4994
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
4898
4995
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
4996
+ compressResponse: z
4997
+ .boolean()
4998
+ .optional()
4999
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
4899
5000
  idleTimeoutMs: z
4900
5001
  .number()
4901
5002
  .int()
@@ -4913,7 +5014,7 @@ export function createGatewayServer(deps = {}) {
4913
5014
  destructiveHint: true,
4914
5015
  idempotentHint: false,
4915
5016
  openWorldHint: true,
4916
- }, async ({ prompt, promptParts, model, outputFormat, sessionId, continueSession, createNewSession, allowedTools, disallowedTools, dangerouslySkipPermissions, permissionMode, agent, agents, forkSession, systemPrompt, appendSystemPrompt, maxBudgetUsd, maxTurns, effort, excludeDynamicSystemPromptSections, fallbackModel, jsonSchema, addDir, noSessionPersistence, settingSources, settings, tools, includeHookEvents, replayUserMessages, systemPromptFile, appendSystemPromptFile, name, pluginDir, pluginUrl, safeMode, bare, debug, debugFile, workspace, worktree, approvalStrategy, approvalPolicy, mcpServers, strictMcpConfig, correlationId, optimizePrompt, optimizeResponse, idleTimeoutMs, forceRefresh, }) => {
5017
+ }, async ({ prompt, promptParts, model, outputFormat, sessionId, continueSession, createNewSession, allowedTools, disallowedTools, dangerouslySkipPermissions, permissionMode, agent, agents, forkSession, systemPrompt, appendSystemPrompt, maxBudgetUsd, maxTurns, effort, excludeDynamicSystemPromptSections, fallbackModel, jsonSchema, addDir, noSessionPersistence, settingSources, settings, tools, includeHookEvents, replayUserMessages, systemPromptFile, appendSystemPromptFile, name, pluginDir, pluginUrl, safeMode, bare, debug, debugFile, workspace, worktree, approvalStrategy, approvalPolicy, mcpServers, strictMcpConfig, correlationId, optimizePrompt, optimizeResponse, compressResponse, idleTimeoutMs, forceRefresh, }) => {
4917
5018
  const startTime = Date.now();
4918
5019
  if (systemPrompt !== undefined && appendSystemPrompt !== undefined) {
4919
5020
  return createErrorResponse("claude", 1, "", correlationId, new Error("systemPrompt and appendSystemPrompt are mutually exclusive; use one or the other (not both)."));
@@ -5033,8 +5134,13 @@ export function createGatewayServer(deps = {}) {
5033
5134
  return createErrorResponse("claude_request", 1, "", corrId, err);
5034
5135
  }
5035
5136
  const effectiveIdleTimeout = outputFormat === "stream-json" ? resolveIdleTimeout("claude", idleTimeoutMs) : undefined;
5036
- const claudeSyncFrHandoff = buildAsyncFlightRecorderHandoff("claude", prep, effectiveSessionId, outputFormat);
5037
- const result = await awaitJobOrDefer("claude", args, corrId, effectiveIdleTimeout, outputFormat, forceRefresh, runtime, undefined, undefined, claudeSyncFrHandoff.flightRecorderEntry, claudeSyncFrHandoff.extractUsage, prep.stdinPayload, worktreeResolution.cwd);
5137
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
5138
+ compressResponse,
5139
+ outputFormat,
5140
+ outputSchemaDeclared: false,
5141
+ });
5142
+ const claudeSyncFrHandoff = buildAsyncFlightRecorderHandoff("claude", prep, effectiveSessionId, outputFormat, optimizePrompt);
5143
+ const result = await awaitJobOrDefer("claude", args, corrId, effectiveIdleTimeout, outputFormat, forceRefresh, runtime, undefined, undefined, claudeSyncFrHandoff.flightRecorderEntry, claudeSyncFrHandoff.extractUsage, prep.stdinPayload, worktreeResolution.cwd, effectiveCompress);
5038
5144
  if (isDeferredResponse(result)) {
5039
5145
  const deferred = buildDeferredToolResponse(result, effectiveSessionId);
5040
5146
  if (warnings.length > 0) {
@@ -5091,7 +5197,8 @@ export function createGatewayServer(deps = {}) {
5091
5197
  providerSessionId: parsed.sessionId ?? undefined,
5092
5198
  stopReason: parsed.stopReason ?? undefined,
5093
5199
  }, runtime);
5094
- const streamResponse = buildCliResponse("claude", parsed.text, optimizeResponse, corrId, effectiveSessionId, prep, durationMs, undefined, outputFormat, warnings);
5200
+ const streamResponse = buildCliResponse("claude", parsed.text, optimizeResponse, corrId, effectiveSessionId, prep, durationMs, undefined, outputFormat, warnings, effectiveCompress);
5201
+ safeRecordCompression(corrId, streamResponse.compression, runtime);
5095
5202
  if (worktreeResolution.worktreePath) {
5096
5203
  const first = streamResponse.content[0];
5097
5204
  if (first && first.type === "text") {
@@ -5112,7 +5219,8 @@ export function createGatewayServer(deps = {}) {
5112
5219
  providerSessionId: claudeMeta.sessionId,
5113
5220
  stopReason: claudeMeta.stopReason,
5114
5221
  }, runtime);
5115
- const nonStreamResponse = buildCliResponse("claude", stdout, optimizeResponse, corrId, effectiveSessionId, prep, durationMs, undefined, outputFormat, warnings);
5222
+ const nonStreamResponse = buildCliResponse("claude", stdout, optimizeResponse, corrId, effectiveSessionId, prep, durationMs, undefined, outputFormat, warnings, effectiveCompress);
5223
+ safeRecordCompression(corrId, nonStreamResponse.compression, runtime);
5116
5224
  if (worktreeResolution.worktreePath) {
5117
5225
  const first = nonStreamResponse.content[0];
5118
5226
  if (first && first.type === "text") {
@@ -5194,6 +5302,10 @@ export function createGatewayServer(deps = {}) {
5194
5302
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
5195
5303
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
5196
5304
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
5305
+ compressResponse: z
5306
+ .boolean()
5307
+ .optional()
5308
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
5197
5309
  idleTimeoutMs: z
5198
5310
  .number()
5199
5311
  .int()
@@ -5258,7 +5370,7 @@ export function createGatewayServer(deps = {}) {
5258
5370
  destructiveHint: true,
5259
5371
  idempotentHint: false,
5260
5372
  openWorldHint: true,
5261
- }, async ({ prompt, promptParts, model, fullAuto, sandboxMode, askForApproval, useLegacyFullAutoFlag, dangerouslyBypassApprovalsAndSandbox, approvalStrategy, approvalPolicy, mcpServers, sessionId, resumeLatest, createNewSession, correlationId, optimizePrompt, optimizeResponse, idleTimeoutMs, forceRefresh, outputFormat, outputSchema, search, profile, configOverrides, ephemeral, images, ignoreUserConfig, ignoreRules, workingDir, addDir, enable, disable, strictConfig, oss, localProvider, color, outputLastMessage, dangerouslyBypassHookTrust, workspace, worktree, }) => {
5373
+ }, async ({ prompt, promptParts, model, fullAuto, sandboxMode, askForApproval, useLegacyFullAutoFlag, dangerouslyBypassApprovalsAndSandbox, approvalStrategy, approvalPolicy, mcpServers, sessionId, resumeLatest, createNewSession, correlationId, optimizePrompt, optimizeResponse, compressResponse, idleTimeoutMs, forceRefresh, outputFormat, outputSchema, search, profile, configOverrides, ephemeral, images, ignoreUserConfig, ignoreRules, workingDir, addDir, enable, disable, strictConfig, oss, localProvider, color, outputLastMessage, dangerouslyBypassHookTrust, workspace, worktree, }) => {
5262
5374
  const startTime = Date.now();
5263
5375
  const prep = prepareCodexRequest({
5264
5376
  prompt,
@@ -5336,8 +5448,13 @@ export function createGatewayServer(deps = {}) {
5336
5448
  return createErrorResponse("codex_request", 1, "", corrId, err);
5337
5449
  }
5338
5450
  try {
5339
- const codexSyncFrHandoff = buildAsyncFlightRecorderHandoff("codex", prep, sessionId, outputFormat);
5340
- const result = await awaitJobOrDefer("codex", args, corrId, resolveIdleTimeout("codex", idleTimeoutMs), outputFormat, forceRefresh, runtime, undefined, prepCleanup, codexSyncFrHandoff.flightRecorderEntry, codexSyncFrHandoff.extractUsage, undefined, worktreeResolution.cwd);
5451
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
5452
+ compressResponse,
5453
+ outputFormat,
5454
+ outputSchemaDeclared: outputSchema !== undefined,
5455
+ });
5456
+ const codexSyncFrHandoff = buildAsyncFlightRecorderHandoff("codex", prep, sessionId, outputFormat, optimizePrompt);
5457
+ const result = await awaitJobOrDefer("codex", args, corrId, resolveIdleTimeout("codex", idleTimeoutMs), outputFormat, forceRefresh, runtime, undefined, prepCleanup, codexSyncFrHandoff.flightRecorderEntry, codexSyncFrHandoff.extractUsage, undefined, worktreeResolution.cwd, effectiveCompress);
5341
5458
  if (isDeferredResponse(result)) {
5342
5459
  return buildDeferredToolResponse(result, sessionId);
5343
5460
  }
@@ -5405,7 +5522,8 @@ export function createGatewayServer(deps = {}) {
5405
5522
  providerSessionId: codexMeta.sessionId,
5406
5523
  stopReason: codexMeta.stopReason,
5407
5524
  }, runtime);
5408
- const codexResponse = buildCliResponse("codex", stdout, optimizeResponse, corrId, effectiveSessionId, prep, durationMs, undefined, outputFormat);
5525
+ const codexResponse = buildCliResponse("codex", stdout, optimizeResponse, corrId, effectiveSessionId, prep, durationMs, undefined, outputFormat, undefined, effectiveCompress);
5526
+ safeRecordCompression(corrId, codexResponse.compression, runtime);
5409
5527
  if (worktreeResolution.worktreePath) {
5410
5528
  const first = codexResponse.content[0];
5411
5529
  if (first && first.type === "text") {
@@ -5598,6 +5716,10 @@ export function createGatewayServer(deps = {}) {
5598
5716
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
5599
5717
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
5600
5718
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
5719
+ compressResponse: z
5720
+ .boolean()
5721
+ .optional()
5722
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
5601
5723
  idleTimeoutMs: z
5602
5724
  .number()
5603
5725
  .int()
@@ -5726,6 +5848,10 @@ export function createGatewayServer(deps = {}) {
5726
5848
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
5727
5849
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
5728
5850
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
5851
+ compressResponse: z
5852
+ .boolean()
5853
+ .optional()
5854
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
5729
5855
  idleTimeoutMs: z
5730
5856
  .number()
5731
5857
  .int()
@@ -5882,6 +6008,10 @@ export function createGatewayServer(deps = {}) {
5882
6008
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
5883
6009
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
5884
6010
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
6011
+ compressResponse: z
6012
+ .boolean()
6013
+ .optional()
6014
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
5885
6015
  idleTimeoutMs: z
5886
6016
  .number()
5887
6017
  .int()
@@ -5982,6 +6112,10 @@ export function createGatewayServer(deps = {}) {
5982
6112
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
5983
6113
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
5984
6114
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
6115
+ compressResponse: z
6116
+ .boolean()
6117
+ .optional()
6118
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
5985
6119
  idleTimeoutMs: z
5986
6120
  .number()
5987
6121
  .int()
@@ -6024,7 +6158,7 @@ export function createGatewayServer(deps = {}) {
6024
6158
  forceRefresh,
6025
6159
  });
6026
6160
  });
6027
- server.tool("mistral_request", "Run a Mistral Vibe CLI request synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts. Defaults to --agent auto-approve (unattended tool execution); pass permissionMode plan or accept-edits for safer runs.", {
6161
+ server.tool("mistral_request", "Run a Mistral Vibe CLI request synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts. Defaults to --agent accept-edits (auto-accepts file edits; dangerous ops such as shell stay gated); pass permissionMode auto-approve (or set LLM_GATEWAY_APPROVAL_ALLOW_BYPASS) for unattended tool execution.", {
6028
6162
  prompt: z
6029
6163
  .string()
6030
6164
  .min(1, "Prompt cannot be empty")
@@ -6056,7 +6190,7 @@ export function createGatewayServer(deps = {}) {
6056
6190
  permissionMode: z
6057
6191
  .string()
6058
6192
  .optional()
6059
- .describe("Vibe --agent name. Builtins: default|plan|accept-edits|auto-approve; Vibe also accepts install-gated builtins (e.g. lean) and custom agents from ~/.vibe/agents, so any name is passed through. Defaults to auto-approve for programmatic use."),
6193
+ .describe("Vibe --agent name. Builtins: default|plan|accept-edits|auto-approve; Vibe also accepts install-gated builtins (e.g. lean) and custom agents from ~/.vibe/agents, so any name is passed through. Defaults to accept-edits; pass auto-approve (or set LLM_GATEWAY_APPROVAL_ALLOW_BYPASS) for unattended tool execution."),
6060
6194
  approvalStrategy: z
6061
6195
  .enum(["legacy", "mcp_managed"])
6062
6196
  .default("legacy")
@@ -6080,6 +6214,10 @@ export function createGatewayServer(deps = {}) {
6080
6214
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
6081
6215
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
6082
6216
  optimizeResponse: z.boolean().default(false).describe("Optimize response output"),
6217
+ compressResponse: z
6218
+ .boolean()
6219
+ .optional()
6220
+ .describe("Compress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output."),
6083
6221
  idleTimeoutMs: z
6084
6222
  .number()
6085
6223
  .int()
@@ -6276,6 +6414,10 @@ export function createGatewayServer(deps = {}) {
6276
6414
  .describe("Restrict Claude to provided MCP config only"),
6277
6415
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
6278
6416
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
6417
+ compressResponse: z
6418
+ .boolean()
6419
+ .optional()
6420
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
6279
6421
  idleTimeoutMs: z
6280
6422
  .number()
6281
6423
  .int()
@@ -6293,7 +6435,7 @@ export function createGatewayServer(deps = {}) {
6293
6435
  destructiveHint: true,
6294
6436
  idempotentHint: false,
6295
6437
  openWorldHint: true,
6296
- }, async ({ prompt, promptParts, model, outputFormat, sessionId, continueSession, createNewSession, allowedTools, disallowedTools, dangerouslySkipPermissions, permissionMode, agent, agents, forkSession, systemPrompt, appendSystemPrompt, maxBudgetUsd, maxTurns, effort, excludeDynamicSystemPromptSections, fallbackModel, jsonSchema, addDir, noSessionPersistence, settingSources, settings, tools, includeHookEvents, replayUserMessages, systemPromptFile, appendSystemPromptFile, name, pluginDir, pluginUrl, safeMode, bare, debug, debugFile, workspace, worktree, approvalStrategy, approvalPolicy, mcpServers, strictMcpConfig, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, }) => {
6438
+ }, async ({ prompt, promptParts, model, outputFormat, sessionId, continueSession, createNewSession, allowedTools, disallowedTools, dangerouslySkipPermissions, permissionMode, agent, agents, forkSession, systemPrompt, appendSystemPrompt, maxBudgetUsd, maxTurns, effort, excludeDynamicSystemPromptSections, fallbackModel, jsonSchema, addDir, noSessionPersistence, settingSources, settings, tools, includeHookEvents, replayUserMessages, systemPromptFile, appendSystemPromptFile, name, pluginDir, pluginUrl, safeMode, bare, debug, debugFile, workspace, worktree, approvalStrategy, approvalPolicy, mcpServers, strictMcpConfig, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, }) => {
6297
6439
  if (systemPrompt !== undefined && appendSystemPrompt !== undefined) {
6298
6440
  return createErrorResponse("claude", 1, "", correlationId, new Error("systemPrompt and appendSystemPrompt are mutually exclusive; use one or the other (not both)."));
6299
6441
  }
@@ -6392,8 +6534,13 @@ export function createGatewayServer(deps = {}) {
6392
6534
  : undefined;
6393
6535
  assertUpstreamCliArgs("claude", args);
6394
6536
  assertUpstreamCliEnv("claude", undefined);
6395
- const claudeAsyncFrHandoff = buildAsyncFlightRecorderHandoff("claude", prep, effectiveSessionId, outputFormat);
6396
- const job = asyncJobManager.startJob("claude", args, corrId, worktreeResolution.cwd, effectiveIdleTimeout, outputFormat, forceRefresh, undefined, undefined, claudeAsyncFrHandoff.flightRecorderEntry, claudeAsyncFrHandoff.extractUsage, true, prep.stdinPayload);
6537
+ const effectiveCompress = resolveEffectiveCompression(runtime.compression, {
6538
+ compressResponse,
6539
+ outputFormat,
6540
+ outputSchemaDeclared: false,
6541
+ });
6542
+ const claudeAsyncFrHandoff = buildAsyncFlightRecorderHandoff("claude", prep, effectiveSessionId, outputFormat, optimizePrompt);
6543
+ const job = asyncJobManager.startJob("claude", args, corrId, worktreeResolution.cwd, effectiveIdleTimeout, outputFormat, forceRefresh, undefined, undefined, claudeAsyncFrHandoff.flightRecorderEntry, claudeAsyncFrHandoff.extractUsage, true, prep.stdinPayload, effectiveCompress);
6397
6544
  logger.info(`[${corrId}] claude_request_async started job ${job.id}, outputFormat=${outputFormat}`);
6398
6545
  const asyncResponse = {
6399
6546
  success: true,
@@ -6487,6 +6634,10 @@ export function createGatewayServer(deps = {}) {
6487
6634
  createNewSession: z.boolean().default(false).describe("Force a fresh session (no resume)"),
6488
6635
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
6489
6636
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
6637
+ compressResponse: z
6638
+ .boolean()
6639
+ .optional()
6640
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
6490
6641
  idleTimeoutMs: z
6491
6642
  .number()
6492
6643
  .int()
@@ -6536,7 +6687,7 @@ export function createGatewayServer(deps = {}) {
6536
6687
  destructiveHint: true,
6537
6688
  idempotentHint: false,
6538
6689
  openWorldHint: true,
6539
- }, async ({ prompt, promptParts, model, fullAuto, sandboxMode, askForApproval, useLegacyFullAutoFlag, dangerouslyBypassApprovalsAndSandbox, approvalStrategy, approvalPolicy, mcpServers, sessionId, resumeLatest, createNewSession, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, outputFormat, outputSchema, search, profile, configOverrides, ephemeral, images, ignoreUserConfig, ignoreRules, workingDir, addDir, enable, disable, strictConfig, oss, localProvider, color, outputLastMessage, dangerouslyBypassHookTrust, workspace, worktree, }) => {
6690
+ }, async ({ prompt, promptParts, model, fullAuto, sandboxMode, askForApproval, useLegacyFullAutoFlag, dangerouslyBypassApprovalsAndSandbox, approvalStrategy, approvalPolicy, mcpServers, sessionId, resumeLatest, createNewSession, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, outputFormat, outputSchema, search, profile, configOverrides, ephemeral, images, ignoreUserConfig, ignoreRules, workingDir, addDir, enable, disable, strictConfig, oss, localProvider, color, outputLastMessage, dangerouslyBypassHookTrust, workspace, worktree, }) => {
6540
6691
  return handleCodexRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
6541
6692
  prompt,
6542
6693
  promptParts,
@@ -6554,6 +6705,7 @@ export function createGatewayServer(deps = {}) {
6554
6705
  createNewSession,
6555
6706
  correlationId,
6556
6707
  optimizePrompt,
6708
+ compressResponse,
6557
6709
  idleTimeoutMs,
6558
6710
  forceRefresh,
6559
6711
  outputFormat,
@@ -6627,6 +6779,10 @@ export function createGatewayServer(deps = {}) {
6627
6779
  LOCAL_INCLUDE_DIRS_FIELD_SUFFIX),
6628
6780
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
6629
6781
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
6782
+ compressResponse: z
6783
+ .boolean()
6784
+ .optional()
6785
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
6630
6786
  idleTimeoutMs: z
6631
6787
  .number()
6632
6788
  .int()
@@ -6676,7 +6832,7 @@ export function createGatewayServer(deps = {}) {
6676
6832
  destructiveHint: true,
6677
6833
  idempotentHint: false,
6678
6834
  openWorldHint: true,
6679
- }, async ({ prompt, promptParts, model, sessionId, resumeLatest, createNewSession, approvalMode, approvalStrategy, approvalPolicy, mcpServers, allowedTools, includeDirs, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, outputFormat, sandbox, policyFiles, adminPolicyFiles, attachments, skipTrust, yolo, project, newProject, printTimeout, workspace, worktree, }) => {
6835
+ }, async ({ prompt, promptParts, model, sessionId, resumeLatest, createNewSession, approvalMode, approvalStrategy, approvalPolicy, mcpServers, allowedTools, includeDirs, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, outputFormat, sandbox, policyFiles, adminPolicyFiles, attachments, skipTrust, yolo, project, newProject, printTimeout, workspace, worktree, }) => {
6680
6836
  return handleGeminiRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
6681
6837
  prompt,
6682
6838
  promptParts,
@@ -6692,6 +6848,7 @@ export function createGatewayServer(deps = {}) {
6692
6848
  includeDirs,
6693
6849
  correlationId,
6694
6850
  optimizePrompt,
6851
+ compressResponse,
6695
6852
  idleTimeoutMs,
6696
6853
  forceRefresh,
6697
6854
  outputFormat,
@@ -6765,6 +6922,10 @@ export function createGatewayServer(deps = {}) {
6765
6922
  .describe("Disallowed built-in tools (passed as --disallowed-tools comma list)"),
6766
6923
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
6767
6924
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
6925
+ compressResponse: z
6926
+ .boolean()
6927
+ .optional()
6928
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
6768
6929
  idleTimeoutMs: z
6769
6930
  .number()
6770
6931
  .int()
@@ -6906,7 +7067,7 @@ export function createGatewayServer(deps = {}) {
6906
7067
  destructiveHint: true,
6907
7068
  idempotentHint: false,
6908
7069
  openWorldHint: true,
6909
- }, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, alwaysApprove, permissionMode, effort, reasoningEffort, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, maxTurns, workingDir, sandbox, rules, systemPromptOverride, allow, deny, compactionMode, compactionDetail, agent, bestOfN, check, disableWebSearch, todoGate, verbatim, agents, promptFile, promptJson, single, experimentalMemory, noAltScreen, noMemory, noPlan, noSubagents, oauth, restoreCode, leaderSocket, nativeWorktree, worktreeRef, forkSession, jsonSchema, workspace, worktree, }) => {
7070
+ }, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, alwaysApprove, permissionMode, effort, reasoningEffort, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, maxTurns, workingDir, sandbox, rules, systemPromptOverride, allow, deny, compactionMode, compactionDetail, agent, bestOfN, check, disableWebSearch, todoGate, verbatim, agents, promptFile, promptJson, single, experimentalMemory, noAltScreen, noMemory, noPlan, noSubagents, oauth, restoreCode, leaderSocket, nativeWorktree, worktreeRef, forkSession, jsonSchema, workspace, worktree, }) => {
6910
7071
  return handleGrokRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
6911
7072
  prompt,
6912
7073
  promptParts,
@@ -6926,6 +7087,7 @@ export function createGatewayServer(deps = {}) {
6926
7087
  disallowedTools,
6927
7088
  correlationId,
6928
7089
  optimizePrompt,
7090
+ compressResponse,
6929
7091
  idleTimeoutMs,
6930
7092
  forceRefresh,
6931
7093
  maxTurns,
@@ -7007,6 +7169,10 @@ export function createGatewayServer(deps = {}) {
7007
7169
  createNewSession: z.boolean().default(false).describe("Force a new session"),
7008
7170
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
7009
7171
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
7172
+ compressResponse: z
7173
+ .boolean()
7174
+ .optional()
7175
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
7010
7176
  idleTimeoutMs: z
7011
7177
  .number()
7012
7178
  .int()
@@ -7024,7 +7190,7 @@ export function createGatewayServer(deps = {}) {
7024
7190
  destructiveHint: true,
7025
7191
  idempotentHint: false,
7026
7192
  openWorldHint: true,
7027
- }, async ({ prompt, model, permissionMode, promptFile, config, sandbox, exportSession, respectWorkspaceTrust, agentConfig, sessionId, resumeLatest, createNewSession, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, }) => {
7193
+ }, async ({ prompt, model, permissionMode, promptFile, config, sandbox, exportSession, respectWorkspaceTrust, agentConfig, sessionId, resumeLatest, createNewSession, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, }) => {
7028
7194
  return handleDevinRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
7029
7195
  prompt,
7030
7196
  model,
@@ -7040,6 +7206,7 @@ export function createGatewayServer(deps = {}) {
7040
7206
  createNewSession,
7041
7207
  correlationId,
7042
7208
  optimizePrompt,
7209
+ compressResponse,
7043
7210
  idleTimeoutMs,
7044
7211
  forceRefresh,
7045
7212
  });
@@ -7099,6 +7266,10 @@ export function createGatewayServer(deps = {}) {
7099
7266
  .describe("Approval policy when approvalStrategy is mcp_managed: strict|balanced|permissive (default balanced). Ignored under legacy strategy."),
7100
7267
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
7101
7268
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
7269
+ compressResponse: z
7270
+ .boolean()
7271
+ .optional()
7272
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
7102
7273
  idleTimeoutMs: z
7103
7274
  .number()
7104
7275
  .int()
@@ -7116,7 +7287,7 @@ export function createGatewayServer(deps = {}) {
7116
7287
  destructiveHint: true,
7117
7288
  idempotentHint: false,
7118
7289
  openWorldHint: true,
7119
- }, async ({ prompt, model, mode, outputFormat, force, autoReview, sandbox, trust, workspace, addDir, sessionId, resumeLatest, createNewSession, approvalStrategy, approvalPolicy, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, }) => {
7290
+ }, async ({ prompt, model, mode, outputFormat, force, autoReview, sandbox, trust, workspace, addDir, sessionId, resumeLatest, createNewSession, approvalStrategy, approvalPolicy, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, }) => {
7120
7291
  return handleCursorRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
7121
7292
  prompt,
7122
7293
  model,
@@ -7135,6 +7306,7 @@ export function createGatewayServer(deps = {}) {
7135
7306
  approvalPolicy,
7136
7307
  correlationId,
7137
7308
  optimizePrompt,
7309
+ compressResponse,
7138
7310
  idleTimeoutMs,
7139
7311
  forceRefresh,
7140
7312
  });
@@ -7167,7 +7339,7 @@ export function createGatewayServer(deps = {}) {
7167
7339
  permissionMode: z
7168
7340
  .string()
7169
7341
  .optional()
7170
- .describe("Vibe --agent name. Builtins: default|plan|accept-edits|auto-approve; Vibe also accepts install-gated builtins (e.g. lean) and custom agents from ~/.vibe/agents, so any name is passed through. Defaults to auto-approve for programmatic use."),
7342
+ .describe("Vibe --agent name. Builtins: default|plan|accept-edits|auto-approve; Vibe also accepts install-gated builtins (e.g. lean) and custom agents from ~/.vibe/agents, so any name is passed through. Defaults to accept-edits; pass auto-approve (or set LLM_GATEWAY_APPROVAL_ALLOW_BYPASS) for unattended tool execution."),
7171
7343
  approvalStrategy: z
7172
7344
  .enum(["legacy", "mcp_managed"])
7173
7345
  .default("legacy")
@@ -7190,6 +7362,10 @@ export function createGatewayServer(deps = {}) {
7190
7362
  .describe("Accepted for caller parity; Vibe has no deny-list flag, so values are ignored (a warning is logged)."),
7191
7363
  correlationId: z.string().optional().describe("Request trace ID (auto if omitted)"),
7192
7364
  optimizePrompt: z.boolean().default(false).describe("Optimize prompt before execution"),
7365
+ compressResponse: z
7366
+ .boolean()
7367
+ .optional()
7368
+ .describe("Compress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled)."),
7193
7369
  idleTimeoutMs: z
7194
7370
  .number()
7195
7371
  .int()
@@ -7227,7 +7403,7 @@ export function createGatewayServer(deps = {}) {
7227
7403
  destructiveHint: true,
7228
7404
  idempotentHint: false,
7229
7405
  openWorldHint: true,
7230
- }, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, permissionMode, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, trust, maxTurns, maxPrice, maxTokens, workingDir, addDir, workspace, worktree, }) => {
7406
+ }, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, permissionMode, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, compressResponse, idleTimeoutMs, forceRefresh, trust, maxTurns, maxPrice, maxTokens, workingDir, addDir, workspace, worktree, }) => {
7231
7407
  return handleMistralRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
7232
7408
  prompt,
7233
7409
  promptParts,
@@ -7244,6 +7420,7 @@ export function createGatewayServer(deps = {}) {
7244
7420
  disallowedTools,
7245
7421
  correlationId,
7246
7422
  optimizePrompt,
7423
+ compressResponse,
7247
7424
  idleTimeoutMs,
7248
7425
  forceRefresh,
7249
7426
  trust,
@@ -7337,6 +7514,23 @@ export function createGatewayServer(deps = {}) {
7337
7514
  result.stdout) {
7338
7515
  result.stdout = codexDisplayText(result.stdout);
7339
7516
  }
7517
+ const compressJob = asyncJobManager.getJobCompressResponse(jobId) && outputFormat !== "json";
7518
+ if (compressJob && result.stdout) {
7519
+ if (outputFormat === "stream-json" && parsed) {
7520
+ result.stdout = parsed.text;
7521
+ }
7522
+ const compressed = compressDisplayText(result.stdout, {
7523
+ provider: asyncJobManager.getJobCli(jobId) ?? "unknown",
7524
+ direction: "outbound",
7525
+ outputFormat,
7526
+ outputSchemaDeclared: false,
7527
+ lossless: true,
7528
+ });
7529
+ if (compressed.text !== result.stdout) {
7530
+ result.stdout = compressed.text;
7531
+ safeRecordCompression(result.correlationId, compressed, runtime);
7532
+ }
7533
+ }
7340
7534
  if (callerIsRemote()) {
7341
7535
  const leakedId = result.providerSessionId;
7342
7536
  delete result.providerSessionId;
@@ -7359,7 +7553,7 @@ export function createGatewayServer(deps = {}) {
7359
7553
  ...(parsed
7360
7554
  ? {
7361
7555
  parsed: {
7362
- text: parsed.text,
7556
+ ...(compressJob ? {} : { text: parsed.text }),
7363
7557
  costUsd: parsed.costUsd,
7364
7558
  usage: parsed.usage,
7365
7559
  model: parsed.model,
@@ -7367,7 +7561,7 @@ export function createGatewayServer(deps = {}) {
7367
7561
  },
7368
7562
  }
7369
7563
  : {}),
7370
- }, null, 2),
7564
+ }, null, compressJob ? 0 : 2),
7371
7565
  },
7372
7566
  ],
7373
7567
  };