omnigateway 0.1.7 → 0.2.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 (44) hide show
  1. package/README.md +27 -33
  2. package/bin/omni.js +917 -161
  3. package/gateway.js +3247 -300
  4. package/package.json +1 -1
  5. package/public/assets/{Chip-C69u2U_b.js → Chip-BB_5C1Zp.js} +1 -1
  6. package/public/assets/Confirm-B6aAiVbT.js +4 -0
  7. package/public/assets/{CopyValue-CJy2T0H6.js → CopyValue-CRQDLo7k.js} +4 -4
  8. package/public/assets/{Field-Sc8mDqJv.js → Field-uHZxl4fI.js} +8 -8
  9. package/public/assets/Lamp-B-5SjXbG.js +25 -0
  10. package/public/assets/{Meter-C0nUftAa.js → Meter-DI_BRUKt.js} +1 -1
  11. package/public/assets/Modal-CI6jk2D4.js +82 -0
  12. package/public/assets/{Rack-CMqGBP4I.js → Rack-D1WJswv3.js} +23 -19
  13. package/public/assets/{Readout-Dv2dZWtI.js → Readout-BocZ2HXP.js} +5 -5
  14. package/public/assets/{States-D55MhqMx.js → States-Bbiu5cHE.js} +10 -10
  15. package/public/assets/{Table-DBB3jdgi.js → Table-CdPWxYaz.js} +1 -1
  16. package/public/assets/Toggle-CiLC67Dw.js +39 -0
  17. package/public/assets/TokenBreakdown-B96iPBm9.js +28 -0
  18. package/public/assets/_app-BBOF6A0T.js +1 -0
  19. package/public/assets/_app.accounts-BNkhpvaB.js +54 -0
  20. package/public/assets/_app.console-Daz4aKhf.js +44 -0
  21. package/public/assets/_app.index-LO6d38oe.js +62 -0
  22. package/public/assets/{_app.keys-BX8k8COP.js → _app.keys-kBqLqoFf.js} +8 -8
  23. package/public/assets/_app.logs-_wYNS47N.js +32 -0
  24. package/public/assets/_app.models-Cjng8ohC.js +144 -0
  25. package/public/assets/_app.settings-a0FKyQAi.js +38 -0
  26. package/public/assets/{_app.usage-BRhEvwVr.js → _app.usage-D3KtgLrC.js} +32 -29
  27. package/public/assets/dist-C-IbPRiV.js +1 -0
  28. package/public/assets/index-PW6EvVh5.js +170 -0
  29. package/public/assets/{login-DaC-wVpI.js → login-CTvH_KAd.js} +8 -8
  30. package/public/assets/queries-D2o-X8Pj.js +144 -0
  31. package/public/assets/{trash-2--aH2iKg-.js → trash-2-BcZb-sCT.js} +1 -1
  32. package/public/index.html +2 -2
  33. package/public/assets/Lamp-7jD_9929.js +0 -25
  34. package/public/assets/Modal-CiVHSJmm.js +0 -82
  35. package/public/assets/Toggle-BoGjb5oi.js +0 -42
  36. package/public/assets/_app-p5Mz7sXD.js +0 -1
  37. package/public/assets/_app.accounts-B5wMO9TH.js +0 -51
  38. package/public/assets/_app.console-Bka7AkiL.js +0 -25
  39. package/public/assets/_app.index-MnQuadXb.js +0 -61
  40. package/public/assets/_app.logs-DD-sd4fn.js +0 -33
  41. package/public/assets/_app.models-CezFNL6y.js +0 -144
  42. package/public/assets/_app.settings-D1taAt8B.js +0 -16
  43. package/public/assets/index-vCuK1fRQ.js +0 -170
  44. package/public/assets/queries-2E6-CboE.js +0 -144
package/gateway.js CHANGED
@@ -5296,6 +5296,11 @@ function createAdminAuth(store, opts) {
5296
5296
  };
5297
5297
  }
5298
5298
  // packages/ir/src/capabilities.ts
5299
+ var ANTHROPIC_NATIVE_TOOLS = {
5300
+ anthropic: true,
5301
+ openai: false,
5302
+ kimi: false
5303
+ };
5299
5304
  var PROVIDER_CAPABILITIES = {
5300
5305
  anthropic: { tools: true, images: true, reasoning: true },
5301
5306
  openai: { tools: true, images: true, reasoning: true },
@@ -5497,7 +5502,13 @@ function collect(events) {
5497
5502
  model = ev.model;
5498
5503
  break;
5499
5504
  case "blockStart":
5500
- blocks.set(ev.index, ev.block.type === "toolUse" ? { kind: "toolUse", id: ev.block.id, name: ev.block.name, json: "" } : ev.block.type === "thinking" ? { kind: "thinking", text: "" } : { kind: "text", text: "" });
5505
+ blocks.set(ev.index, ev.block.type === "toolUse" ? { kind: "toolUse", id: ev.block.id, name: ev.block.name, json: "" } : ev.block.type === "thinking" ? { kind: "thinking", text: "" } : ev.block.type === "anthropicNative" ? {
5506
+ kind: "anthropicNative",
5507
+ blockType: ev.block.blockType,
5508
+ data: ev.block.data,
5509
+ json: "",
5510
+ deltas: []
5511
+ } : { kind: "text", text: "", citations: [] });
5501
5512
  break;
5502
5513
  case "blockDelta": {
5503
5514
  const acc = blocks.get(ev.index);
@@ -5511,6 +5522,14 @@ function collect(events) {
5511
5522
  acc.signature = (acc.signature ?? "") + ev.delta.signature;
5512
5523
  else if (ev.delta.type === "toolJson" && acc.kind === "toolUse")
5513
5524
  acc.json += ev.delta.partial;
5525
+ else if (ev.delta.type === "anthropicNativeJson" && acc.kind === "anthropicNative")
5526
+ acc.json += ev.delta.partial;
5527
+ else if (ev.delta.type === "anthropicNative") {
5528
+ if (acc.kind === "anthropicNative")
5529
+ acc.deltas.push(ev.delta);
5530
+ else if (acc.kind === "text" && ev.delta.deltaType === "citations_delta")
5531
+ acc.citations.push(ev.delta.data.citation);
5532
+ }
5514
5533
  break;
5515
5534
  }
5516
5535
  case "end":
@@ -5523,13 +5542,25 @@ function collect(events) {
5523
5542
  }
5524
5543
  const content = [...blocks.entries()].sort(([a], [b]) => a - b).map(([, acc]) => {
5525
5544
  if (acc.kind === "text")
5526
- return { type: "text", text: acc.text };
5545
+ return {
5546
+ type: "text",
5547
+ text: acc.text,
5548
+ ...acc.citations.length === 0 ? {} : { citations: acc.citations }
5549
+ };
5527
5550
  if (acc.kind === "thinking")
5528
5551
  return {
5529
5552
  type: "thinking",
5530
5553
  text: acc.text,
5531
5554
  ...acc.signature === undefined ? {} : { signature: acc.signature }
5532
5555
  };
5556
+ if (acc.kind === "anthropicNative") {
5557
+ let data = acc.json === "" ? acc.data : { ...acc.data, input: parseJson(acc.json) };
5558
+ for (const delta of acc.deltas) {
5559
+ if (delta.deltaType === "compaction_delta")
5560
+ data = { ...data, ...delta.data };
5561
+ }
5562
+ return { type: "anthropicNative", blockType: acc.blockType, data };
5563
+ }
5533
5564
  return { type: "toolUse", id: acc.id, name: acc.name, input: parseJson(acc.json) };
5534
5565
  });
5535
5566
  return { id, model, content, stopReason, usage };
@@ -5543,6 +5574,59 @@ function parseJson(raw) {
5543
5574
  return {};
5544
5575
  }
5545
5576
  }
5577
+ // packages/ir/src/tokens.ts
5578
+ var CHARS_PER_TOKEN = 4;
5579
+ var IMAGE_TOKENS = 1600;
5580
+ var BLOCK_OVERHEAD = 4;
5581
+ var MESSAGE_OVERHEAD = 4;
5582
+ function fromText(text) {
5583
+ return Math.ceil(text.length / CHARS_PER_TOKEN);
5584
+ }
5585
+ function blockTokens(block) {
5586
+ switch (block.type) {
5587
+ case "text":
5588
+ return BLOCK_OVERHEAD + fromText(block.text);
5589
+ case "image":
5590
+ return BLOCK_OVERHEAD + IMAGE_TOKENS;
5591
+ case "thinking":
5592
+ return BLOCK_OVERHEAD + fromText(block.text);
5593
+ case "toolUse":
5594
+ return BLOCK_OVERHEAD + fromText(block.name) + fromText(safeJson(block.input));
5595
+ case "toolResult":
5596
+ return BLOCK_OVERHEAD + fromText(block.toolUseId) + fromText(block.content);
5597
+ case "anthropicNative":
5598
+ return BLOCK_OVERHEAD + fromText(block.blockType) + fromText(safeJson(block.data));
5599
+ }
5600
+ }
5601
+ function messageTokens(message) {
5602
+ let total = MESSAGE_OVERHEAD;
5603
+ for (const block of message.content)
5604
+ total += blockTokens(block);
5605
+ return total;
5606
+ }
5607
+ function toolTokens(tool) {
5608
+ if (tool.provider === "anthropic") {
5609
+ return BLOCK_OVERHEAD + fromText(tool.name) + fromText(tool.type) + fromText(safeJson(tool.wire));
5610
+ }
5611
+ return BLOCK_OVERHEAD + fromText(tool.name) + fromText(tool.description ?? "") + fromText(safeJson(tool.inputSchema));
5612
+ }
5613
+ function safeJson(value) {
5614
+ try {
5615
+ return JSON.stringify(value) ?? "";
5616
+ } catch {
5617
+ return "";
5618
+ }
5619
+ }
5620
+ function estimateInputTokens(request) {
5621
+ let total = 0;
5622
+ for (const block of request.system ?? [])
5623
+ total += blockTokens(block);
5624
+ for (const message of request.messages)
5625
+ total += messageTokens(message);
5626
+ for (const tool of request.tools ?? [])
5627
+ total += toolTokens(tool);
5628
+ return total;
5629
+ }
5546
5630
  // packages/ir/src/validate.ts
5547
5631
  function validateRequest(req) {
5548
5632
  const seenToolUseIds = new Set;
@@ -5573,6 +5657,7 @@ function validateRequest(req) {
5573
5657
  }
5574
5658
  // packages/control/src/config.ts
5575
5659
  var MIN_KEY_LENGTH = 16;
5660
+ var TRUTHY = new Set(["1", "true", "yes", "on"]);
5576
5661
  var DECIMAL_INTEGER = /^\d+$/;
5577
5662
  function optionalText(value, fallback) {
5578
5663
  return value?.trim() || fallback;
@@ -5592,6 +5677,7 @@ function loadConfig(env) {
5592
5677
  const baseUrl = optionalText(env.OMNI_BASE_URL, derivedBaseUrl).replace(/\/+$/, "") || derivedBaseUrl;
5593
5678
  const staticDir = env.OMNI_STATIC_DIR?.trim();
5594
5679
  const logFile = env.OMNI_LOG_FILE?.trim();
5680
+ const exposeClaudeCodeAliases = TRUTHY.has((env.OMNI_EXPOSE_CLAUDE_CODE_ALIASES ?? "").trim().toLowerCase());
5595
5681
  const rawLogLevel = env.OMNI_LOG_LEVEL?.trim();
5596
5682
  const logLevel = parseLogLevel(rawLogLevel);
5597
5683
  return {
@@ -5603,9 +5689,14 @@ function loadConfig(env) {
5603
5689
  encryptionKey,
5604
5690
  baseUrl,
5605
5691
  staticDir: staticDir === undefined || staticDir.length === 0 ? null : staticDir,
5692
+ exposeClaudeCodeAliases,
5606
5693
  logFile: logFile === undefined || logFile.length === 0 ? null : logFile
5607
5694
  };
5608
5695
  }
5696
+ // packages/providers/src/betas.ts
5697
+ var CONTEXT_1M_BETA = "context-1m-2025-08-07";
5698
+ var CONTEXT_1M_TOKENS = 1e6;
5699
+
5609
5700
  // packages/providers/src/body.ts
5610
5701
  var BODY_ORDER = {
5611
5702
  anthropic: [
@@ -5713,6 +5804,119 @@ function signAnthropicBody(json) {
5713
5804
  return json.replace(needle, `cch=${computeCch(json)};`);
5714
5805
  }
5715
5806
 
5807
+ // packages/providers/src/anthropic/models.ts
5808
+ var ANTHROPIC_MODELS = {
5809
+ defaultModel: "claude-opus-5",
5810
+ models: [
5811
+ {
5812
+ id: "claude-fable-5",
5813
+ label: "Claude Fable 5",
5814
+ pricing: { input: 10, output: 50, cacheRead: 1, cacheWrite5m: 12.5, cacheWrite1h: 20 },
5815
+ limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
5816
+ },
5817
+ {
5818
+ id: "claude-opus-5",
5819
+ label: "Claude Opus 5",
5820
+ pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite5m: 6.25, cacheWrite1h: 10 },
5821
+ limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
5822
+ },
5823
+ {
5824
+ id: "claude-sonnet-5",
5825
+ label: "Claude Sonnet 5",
5826
+ pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 3.75, cacheWrite1h: 6 },
5827
+ limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
5828
+ },
5829
+ {
5830
+ id: "claude-haiku-4-5",
5831
+ label: "Claude Haiku 4.5",
5832
+ pricing: { input: 1, output: 5, cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 2 },
5833
+ limits: { contextWindow: 200000, maxOutputTokens: 64000 }
5834
+ }
5835
+ ]
5836
+ };
5837
+
5838
+ // packages/providers/src/kimi/models.ts
5839
+ var KIMI_MODELS = {
5840
+ defaultModel: "k3-256k",
5841
+ models: [
5842
+ {
5843
+ id: "k3-256k",
5844
+ label: "Kimi K3 \u2014 256K",
5845
+ pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 0, cacheWrite1h: 0 },
5846
+ limits: { contextWindow: 262144, maxOutputTokens: 131072 }
5847
+ },
5848
+ {
5849
+ id: "k3",
5850
+ label: "Kimi K3 \u2014 up to 1M",
5851
+ pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 0, cacheWrite1h: 0 },
5852
+ limits: { contextWindow: 1048576, maxOutputTokens: 131072 }
5853
+ },
5854
+ {
5855
+ id: "kimi-for-coding",
5856
+ label: "Kimi K2.7 Code",
5857
+ pricing: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite5m: 0, cacheWrite1h: 0 },
5858
+ limits: { contextWindow: 262144, maxOutputTokens: 131072 }
5859
+ },
5860
+ {
5861
+ id: "kimi-for-coding-highspeed",
5862
+ label: "Kimi K2.7 Code \u2014 High Speed",
5863
+ pricing: { input: 0.95, output: 8, cacheRead: 0.19, cacheWrite5m: 0, cacheWrite1h: 0 },
5864
+ limits: { contextWindow: 262144, maxOutputTokens: 131072 }
5865
+ }
5866
+ ]
5867
+ };
5868
+
5869
+ // packages/providers/src/openai/models.ts
5870
+ var OPENAI_MODELS = {
5871
+ defaultModel: "gpt-5.6",
5872
+ models: [
5873
+ {
5874
+ id: "gpt-5.6",
5875
+ label: "GPT-5.6 \u2014 routes to Sol",
5876
+ pricing: { input: 5, output: 30, cacheRead: 0.5, cacheWrite5m: 0, cacheWrite1h: 0 },
5877
+ limits: { contextWindow: 922000, maxOutputTokens: 128000 },
5878
+ oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
5879
+ },
5880
+ {
5881
+ id: "gpt-5.6-sol",
5882
+ label: "GPT-5.6 Sol \u2014 deepest reasoning",
5883
+ pricing: { input: 5, output: 30, cacheRead: 0.5, cacheWrite5m: 0, cacheWrite1h: 0 },
5884
+ limits: { contextWindow: 922000, maxOutputTokens: 128000 },
5885
+ oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
5886
+ },
5887
+ {
5888
+ id: "gpt-5.6-terra",
5889
+ label: "GPT-5.6 Terra \u2014 balanced",
5890
+ pricing: { input: 2, output: 12, cacheRead: 0.2, cacheWrite5m: 0, cacheWrite1h: 0 },
5891
+ limits: { contextWindow: 922000, maxOutputTokens: 128000 },
5892
+ oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
5893
+ },
5894
+ {
5895
+ id: "gpt-5.6-luna",
5896
+ label: "GPT-5.6 Luna \u2014 fastest",
5897
+ pricing: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite5m: 0, cacheWrite1h: 0 },
5898
+ limits: { contextWindow: 922000, maxOutputTokens: 128000 },
5899
+ oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
5900
+ }
5901
+ ]
5902
+ };
5903
+
5904
+ // packages/providers/src/catalog.ts
5905
+ var PROVIDER_MODEL_CATALOG = {
5906
+ anthropic: ANTHROPIC_MODELS,
5907
+ openai: OPENAI_MODELS,
5908
+ kimi: KIMI_MODELS
5909
+ };
5910
+ function catalogPricing(provider, model) {
5911
+ return PROVIDER_MODEL_CATALOG[provider]?.models.find((entry) => entry.id === model)?.pricing ?? null;
5912
+ }
5913
+ function catalogLimits(provider, model, auth = "apiKey") {
5914
+ const entry = PROVIDER_MODEL_CATALOG[provider]?.models.find((choice) => choice.id === model);
5915
+ if (entry === undefined)
5916
+ return null;
5917
+ return (auth === "oauth" ? entry.oauthLimits : undefined) ?? entry.limits;
5918
+ }
5919
+
5716
5920
  // packages/providers/src/http.ts
5717
5921
  function codeForStatus(status) {
5718
5922
  if (status === 401 || status === 403)
@@ -5974,14 +6178,248 @@ function parseRecord(record) {
5974
6178
  `) };
5975
6179
  }
5976
6180
 
6181
+ // packages/providers/src/anthropic/tools.ts
6182
+ var COMMON = ["cache_control", "strict", "defer_loading", "allowed_callers"];
6183
+ var COMMON_WITH_EXAMPLES = [...COMMON, "input_examples"];
6184
+ var searchDomains = ["max_uses", "allowed_domains", "blocked_domains"];
6185
+ var ANTHROPIC_TOOL_SPECS = {
6186
+ web_search_20250305: {
6187
+ family: "webSearch",
6188
+ name: "web_search",
6189
+ required: [],
6190
+ optional: [...COMMON, ...searchDomains, "user_location"]
6191
+ },
6192
+ web_search_20260209: {
6193
+ family: "webSearch",
6194
+ name: "web_search",
6195
+ required: [],
6196
+ optional: [...COMMON, ...searchDomains, "user_location"]
6197
+ },
6198
+ web_search_20260318: {
6199
+ family: "webSearch",
6200
+ name: "web_search",
6201
+ required: [],
6202
+ optional: [...COMMON, ...searchDomains, "user_location", "response_inclusion"]
6203
+ },
6204
+ web_fetch_20250910: {
6205
+ family: "webFetch",
6206
+ name: "web_fetch",
6207
+ required: [],
6208
+ optional: [...COMMON, ...searchDomains, "citations", "max_content_tokens"]
6209
+ },
6210
+ web_fetch_20260209: {
6211
+ family: "webFetch",
6212
+ name: "web_fetch",
6213
+ required: [],
6214
+ optional: [...COMMON, ...searchDomains, "citations", "max_content_tokens"]
6215
+ },
6216
+ web_fetch_20260309: {
6217
+ family: "webFetch",
6218
+ name: "web_fetch",
6219
+ required: [],
6220
+ optional: [...COMMON, ...searchDomains, "citations", "max_content_tokens", "use_cache"]
6221
+ },
6222
+ web_fetch_20260318: {
6223
+ family: "webFetch",
6224
+ name: "web_fetch",
6225
+ required: [],
6226
+ optional: [
6227
+ ...COMMON,
6228
+ ...searchDomains,
6229
+ "citations",
6230
+ "max_content_tokens",
6231
+ "use_cache",
6232
+ "response_inclusion"
6233
+ ]
6234
+ },
6235
+ code_execution_20250522: {
6236
+ family: "codeExecution",
6237
+ name: "code_execution",
6238
+ required: [],
6239
+ optional: [...COMMON]
6240
+ },
6241
+ code_execution_20250825: {
6242
+ family: "codeExecution",
6243
+ name: "code_execution",
6244
+ required: [],
6245
+ optional: [...COMMON]
6246
+ },
6247
+ code_execution_20260120: {
6248
+ family: "codeExecution",
6249
+ name: "code_execution",
6250
+ required: [],
6251
+ optional: [...COMMON]
6252
+ },
6253
+ code_execution_20260521: {
6254
+ family: "codeExecution",
6255
+ name: "code_execution",
6256
+ required: [],
6257
+ optional: [...COMMON]
6258
+ },
6259
+ bash_20241022: {
6260
+ family: "bash",
6261
+ name: "bash",
6262
+ required: [],
6263
+ optional: [...COMMON_WITH_EXAMPLES]
6264
+ },
6265
+ bash_20250124: {
6266
+ family: "bash",
6267
+ name: "bash",
6268
+ required: [],
6269
+ optional: [...COMMON_WITH_EXAMPLES]
6270
+ },
6271
+ text_editor_20241022: {
6272
+ family: "textEditor",
6273
+ name: "str_replace_editor",
6274
+ required: [],
6275
+ optional: [...COMMON_WITH_EXAMPLES]
6276
+ },
6277
+ text_editor_20250124: {
6278
+ family: "textEditor",
6279
+ name: "str_replace_editor",
6280
+ required: [],
6281
+ optional: [...COMMON_WITH_EXAMPLES]
6282
+ },
6283
+ text_editor_20250429: {
6284
+ family: "textEditor",
6285
+ name: "str_replace_based_edit_tool",
6286
+ required: [],
6287
+ optional: [...COMMON_WITH_EXAMPLES]
6288
+ },
6289
+ text_editor_20250728: {
6290
+ family: "textEditor",
6291
+ name: "str_replace_based_edit_tool",
6292
+ required: [],
6293
+ optional: [...COMMON_WITH_EXAMPLES, "max_characters"]
6294
+ },
6295
+ computer_20241022: {
6296
+ family: "computer",
6297
+ name: "computer",
6298
+ required: ["display_width_px", "display_height_px"],
6299
+ optional: [...COMMON_WITH_EXAMPLES, "display_number"]
6300
+ },
6301
+ computer_20250124: {
6302
+ family: "computer",
6303
+ name: "computer",
6304
+ required: ["display_width_px", "display_height_px"],
6305
+ optional: [...COMMON_WITH_EXAMPLES, "display_number"]
6306
+ },
6307
+ computer_20251124: {
6308
+ family: "computer",
6309
+ name: "computer",
6310
+ required: ["display_width_px", "display_height_px"],
6311
+ optional: [...COMMON_WITH_EXAMPLES, "display_number", "enable_zoom"]
6312
+ },
6313
+ memory_20250818: {
6314
+ family: "memory",
6315
+ name: "memory",
6316
+ required: [],
6317
+ optional: [...COMMON_WITH_EXAMPLES]
6318
+ },
6319
+ tool_search_tool_regex_20251119: {
6320
+ family: "toolSearchRegex",
6321
+ name: "tool_search_tool_regex",
6322
+ required: [],
6323
+ optional: [...COMMON]
6324
+ },
6325
+ tool_search_tool_regex: {
6326
+ family: "toolSearchRegex",
6327
+ name: "tool_search_tool_regex",
6328
+ required: [],
6329
+ optional: [...COMMON]
6330
+ },
6331
+ tool_search_tool_bm25_20251119: {
6332
+ family: "toolSearchBm25",
6333
+ name: "tool_search_tool_bm25",
6334
+ required: [],
6335
+ optional: [...COMMON]
6336
+ },
6337
+ tool_search_tool_bm25: {
6338
+ family: "toolSearchBm25",
6339
+ name: "tool_search_tool_bm25",
6340
+ required: [],
6341
+ optional: [...COMMON]
6342
+ },
6343
+ advisor_20260301: {
6344
+ family: "advisor",
6345
+ name: "advisor",
6346
+ required: ["model"],
6347
+ optional: [...COMMON, "caching", "max_uses", "max_tokens"]
6348
+ },
6349
+ mcp_toolset: {
6350
+ family: "mcpToolset",
6351
+ required: ["mcp_server_name"],
6352
+ optional: ["cache_control", "configs", "default_config"]
6353
+ }
6354
+ };
6355
+ function anthropicToolSpec(type) {
6356
+ return Object.hasOwn(ANTHROPIC_TOOL_SPECS, type) ? ANTHROPIC_TOOL_SPECS[type] : undefined;
6357
+ }
6358
+ var ANTHROPIC_TOOL_CALLERS = [
6359
+ "direct",
6360
+ "code_execution_20250825",
6361
+ "code_execution_20260120",
6362
+ "code_execution_20260521"
6363
+ ];
6364
+ var ANTHROPIC_CUSTOM_TOOL_OPTIONS = [
6365
+ "strict",
6366
+ "defer_loading",
6367
+ "allowed_callers",
6368
+ "input_examples",
6369
+ "eager_input_streaming"
6370
+ ];
6371
+ var ANTHROPIC_NATIVE_BLOCK_TYPES = new Set([
6372
+ "server_tool_use",
6373
+ "web_search_tool_result",
6374
+ "web_fetch_tool_result",
6375
+ "code_execution_tool_result",
6376
+ "bash_code_execution_tool_result",
6377
+ "text_editor_code_execution_tool_result",
6378
+ "mcp_tool_use",
6379
+ "mcp_tool_result",
6380
+ "tool_search_tool_result",
6381
+ "tool_reference",
6382
+ "advisor_tool_result",
6383
+ "advisor_result",
6384
+ "advisor_redacted_result",
6385
+ "container_upload",
6386
+ "compaction",
6387
+ "search_result",
6388
+ "document",
6389
+ "mid_conv_system",
6390
+ "tool_addition",
6391
+ "tool_removal",
6392
+ "fallback",
6393
+ "redacted_thinking"
6394
+ ]);
6395
+
5977
6396
  // packages/providers/src/anthropic/decode.ts
5978
6397
  var STOP_REASON = {
5979
6398
  end_turn: "endTurn",
5980
6399
  max_tokens: "maxTokens",
5981
6400
  stop_sequence: "stopSequence",
5982
6401
  tool_use: "toolUse",
5983
- refusal: "contentFilter"
5984
- };
6402
+ refusal: "contentFilter",
6403
+ pause_turn: "pauseTurn"
6404
+ };
6405
+ var KNOWN_EVENTS = new Set([
6406
+ "message_start",
6407
+ "content_block_start",
6408
+ "content_block_delta",
6409
+ "content_block_stop",
6410
+ "message_delta",
6411
+ "message_stop",
6412
+ "error",
6413
+ "ping"
6414
+ ]);
6415
+ var KNOWN_DELTAS = new Set([
6416
+ "text_delta",
6417
+ "thinking_delta",
6418
+ "signature_delta",
6419
+ "input_json_delta",
6420
+ "citations_delta",
6421
+ "compaction_delta"
6422
+ ]);
5985
6423
  var ERROR_TYPE = {
5986
6424
  overloaded_error: "OVERLOADED",
5987
6425
  rate_limit_error: "RATE_LIMIT",
@@ -6007,10 +6445,21 @@ async function* decodeAnthropic(messages) {
6007
6445
  let outputTokens = 0;
6008
6446
  let stopReason = "endTurn";
6009
6447
  let terminal = false;
6448
+ const nativeBlocks = new Set;
6449
+ const protocolError = (message) => ({
6450
+ type: "error",
6451
+ code: "UPSTREAM",
6452
+ message,
6453
+ retryable: false
6454
+ });
6010
6455
  for await (const msg of messages) {
6011
6456
  const d = json(msg.data);
6012
6457
  if (d === null)
6013
6458
  continue;
6459
+ if (!KNOWN_EVENTS.has(msg.event)) {
6460
+ yield protocolError(`unrecognized Anthropic stream event "${msg.event}"`);
6461
+ return;
6462
+ }
6014
6463
  switch (msg.event) {
6015
6464
  case "message_start": {
6016
6465
  const m = d.message ?? {};
@@ -6035,6 +6484,18 @@ async function* decodeAnthropic(messages) {
6035
6484
  index,
6036
6485
  block: { type: "toolUse", id: String(cb.id), name: String(cb.name) }
6037
6486
  };
6487
+ else if (cb.type !== undefined && ANTHROPIC_NATIVE_BLOCK_TYPES.has(cb.type)) {
6488
+ nativeBlocks.add(index);
6489
+ const { type: _blockType, ...data } = cb;
6490
+ yield {
6491
+ type: "blockStart",
6492
+ index,
6493
+ block: { type: "anthropicNative", blockType: cb.type, data }
6494
+ };
6495
+ } else {
6496
+ yield protocolError(`unrecognized Anthropic content block type "${String(cb.type)}"`);
6497
+ return;
6498
+ }
6038
6499
  break;
6039
6500
  }
6040
6501
  case "content_block_delta": {
@@ -6058,17 +6519,51 @@ async function* decodeAnthropic(messages) {
6058
6519
  yield {
6059
6520
  type: "blockDelta",
6060
6521
  index,
6061
- delta: { type: "toolJson", partial: delta.partial_json ?? "" }
6522
+ delta: nativeBlocks.has(index) ? { type: "anthropicNativeJson", partial: delta.partial_json ?? "" } : { type: "toolJson", partial: delta.partial_json ?? "" }
6523
+ };
6524
+ else if (delta.type === "citations_delta")
6525
+ yield {
6526
+ type: "blockDelta",
6527
+ index,
6528
+ delta: {
6529
+ type: "anthropicNative",
6530
+ deltaType: delta.type,
6531
+ data: { citation: delta.citation }
6532
+ }
6533
+ };
6534
+ else if (delta.type === "compaction_delta")
6535
+ yield {
6536
+ type: "blockDelta",
6537
+ index,
6538
+ delta: {
6539
+ type: "anthropicNative",
6540
+ deltaType: delta.type,
6541
+ data: {
6542
+ ...delta.content === undefined ? {} : { content: delta.content },
6543
+ ...delta.encrypted_content === undefined ? {} : { encrypted_content: delta.encrypted_content }
6544
+ }
6545
+ }
6062
6546
  };
6547
+ else if (delta.type === undefined || !KNOWN_DELTAS.has(delta.type)) {
6548
+ yield protocolError(`unrecognized Anthropic content block delta "${String(delta.type)}"`);
6549
+ return;
6550
+ }
6063
6551
  break;
6064
6552
  }
6065
6553
  case "content_block_stop":
6554
+ nativeBlocks.delete(d.index ?? 0);
6066
6555
  yield { type: "blockEnd", index: d.index ?? 0 };
6067
6556
  break;
6068
6557
  case "message_delta": {
6069
6558
  const reason = d.delta?.stop_reason;
6070
- if (typeof reason === "string")
6071
- stopReason = STOP_REASON[reason] ?? "endTurn";
6559
+ if (typeof reason === "string") {
6560
+ const mapped = STOP_REASON[reason];
6561
+ if (mapped === undefined) {
6562
+ yield protocolError(`unrecognized Anthropic stop reason "${reason}"`);
6563
+ return;
6564
+ }
6565
+ stopReason = mapped;
6566
+ }
6072
6567
  inputTokens = d.usage?.input_tokens ?? inputTokens;
6073
6568
  outputTokens = d.usage?.output_tokens ?? outputTokens;
6074
6569
  break;
@@ -6127,7 +6622,12 @@ function encodeBlock(b) {
6127
6622
  const cache = wireCacheControl(cacheControlOf(b));
6128
6623
  switch (b.type) {
6129
6624
  case "text":
6130
- return { type: "text", text: b.text, ...cache };
6625
+ return {
6626
+ type: "text",
6627
+ text: b.text,
6628
+ ...b.citations === undefined ? {} : { citations: b.citations },
6629
+ ...cache
6630
+ };
6131
6631
  case "image":
6132
6632
  return {
6133
6633
  type: "image",
@@ -6146,11 +6646,16 @@ function encodeBlock(b) {
6146
6646
  is_error: b.isError,
6147
6647
  ...cache
6148
6648
  };
6649
+ case "anthropicNative":
6650
+ return { ...b.data, type: b.blockType, ...cache };
6149
6651
  }
6150
6652
  }
6151
6653
  function encodeSystemTurn(content) {
6152
- return content.flatMap((b) => b.type === "text" ? [b.text] : []).join(`
6654
+ if (content.every((block) => block.type === "text")) {
6655
+ return content.map((block) => block.text).join(`
6153
6656
  `);
6657
+ }
6658
+ return content.map(encodeBlock);
6154
6659
  }
6155
6660
  function systemCacheControl(req) {
6156
6661
  const cacheable = req.messages.flatMap((message) => message.content.flatMap((block) => block.type === "thinking" ? [] : [{ role: message.role, block }]));
@@ -6162,6 +6667,23 @@ function systemCacheControl(req) {
6162
6667
  lost: markedSystemBlocks.length > (promoted === undefined ? 0 : 1)
6163
6668
  };
6164
6669
  }
6670
+ function encodeTool(t) {
6671
+ if (t.provider === "anthropic") {
6672
+ return {
6673
+ type: t.type,
6674
+ ...t.name === "" ? {} : { name: t.name },
6675
+ ...t.wire,
6676
+ ...wireCacheControl(t.cacheControl)
6677
+ };
6678
+ }
6679
+ return {
6680
+ name: t.name,
6681
+ ...t.description === undefined ? {} : { description: t.description },
6682
+ input_schema: t.inputSchema,
6683
+ ...t.options ?? {},
6684
+ ...wireCacheControl(t.cacheControl)
6685
+ };
6686
+ }
6165
6687
  function encodeToolChoice(c) {
6166
6688
  switch (c.type) {
6167
6689
  case "auto":
@@ -6216,14 +6738,8 @@ function toWire(req, model, opts) {
6216
6738
  body.temperature = req.temperature;
6217
6739
  if (req.stopSequences !== undefined)
6218
6740
  body.stop_sequences = req.stopSequences;
6219
- if (req.tools !== undefined) {
6220
- body.tools = req.tools.map((t) => ({
6221
- name: t.name,
6222
- ...t.description === undefined ? {} : { description: t.description },
6223
- input_schema: t.inputSchema,
6224
- ...wireCacheControl(t.cacheControl)
6225
- }));
6226
- }
6741
+ if (req.tools !== undefined)
6742
+ body.tools = req.tools.map(encodeTool);
6227
6743
  if (req.toolChoice !== undefined)
6228
6744
  body.tool_choice = encodeToolChoice(req.toolChoice);
6229
6745
  if (req.reasoning !== undefined) {
@@ -6270,6 +6786,15 @@ var anthropicAdapter = {
6270
6786
  ["Accept", "text/event-stream"]
6271
6787
  ];
6272
6788
  const betas = new Set(req.request.betas ?? []);
6789
+ const notes = [...degradations];
6790
+ if (betas.has(CONTEXT_1M_BETA)) {
6791
+ const limits = catalogLimits("anthropic", req.model, oauth ? "oauth" : "apiKey");
6792
+ const window2 = limits?.contextWindow;
6793
+ if (window2 !== undefined && window2 < CONTEXT_1M_TOKENS) {
6794
+ betas.delete(CONTEXT_1M_BETA);
6795
+ notes.push("anthropic:context-1m-dropped");
6796
+ }
6797
+ }
6273
6798
  if (oauth) {
6274
6799
  protocol.push(["Authorization", `Bearer ${req.credentials.accessToken}`]);
6275
6800
  betas.add(OAUTH_BETA);
@@ -6297,121 +6822,9 @@ var anthropicAdapter = {
6297
6822
  throw await httpError(res, "anthropic");
6298
6823
  if (res.body === null)
6299
6824
  throw new GatewayError("UPSTREAM", "empty response body", { provider: "anthropic" });
6300
- return { events: decodeAnthropic(parseSse(res.body)), degradations };
6825
+ return { events: decodeAnthropic(parseSse(res.body)), degradations: notes };
6301
6826
  }
6302
6827
  };
6303
- // packages/providers/src/anthropic/models.ts
6304
- var ANTHROPIC_MODELS = {
6305
- defaultModel: "claude-opus-5",
6306
- models: [
6307
- {
6308
- id: "claude-fable-5",
6309
- label: "Claude Fable 5",
6310
- pricing: { input: 10, output: 50, cacheRead: 1, cacheWrite5m: 12.5, cacheWrite1h: 20 },
6311
- limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
6312
- },
6313
- {
6314
- id: "claude-opus-5",
6315
- label: "Claude Opus 5",
6316
- pricing: { input: 5, output: 25, cacheRead: 0.5, cacheWrite5m: 6.25, cacheWrite1h: 10 },
6317
- limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
6318
- },
6319
- {
6320
- id: "claude-sonnet-5",
6321
- label: "Claude Sonnet 5",
6322
- pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 3.75, cacheWrite1h: 6 },
6323
- limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
6324
- },
6325
- {
6326
- id: "claude-haiku-4-5",
6327
- label: "Claude Haiku 4.5",
6328
- pricing: { input: 1, output: 5, cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 2 },
6329
- limits: { contextWindow: 200000, maxOutputTokens: 64000 }
6330
- }
6331
- ]
6332
- };
6333
-
6334
- // packages/providers/src/kimi/models.ts
6335
- var KIMI_MODELS = {
6336
- defaultModel: "k3-256k",
6337
- models: [
6338
- {
6339
- id: "k3-256k",
6340
- label: "Kimi K3 \u2014 256K",
6341
- pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 0, cacheWrite1h: 0 },
6342
- limits: { contextWindow: 262144, maxOutputTokens: 131072 }
6343
- },
6344
- {
6345
- id: "k3",
6346
- label: "Kimi K3 \u2014 up to 1M",
6347
- pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 0, cacheWrite1h: 0 },
6348
- limits: { contextWindow: 1048576, maxOutputTokens: 131072 }
6349
- },
6350
- {
6351
- id: "kimi-for-coding",
6352
- label: "Kimi K2.7 Code",
6353
- pricing: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite5m: 0, cacheWrite1h: 0 },
6354
- limits: { contextWindow: 262144, maxOutputTokens: 131072 }
6355
- },
6356
- {
6357
- id: "kimi-for-coding-highspeed",
6358
- label: "Kimi K2.7 Code \u2014 High Speed",
6359
- pricing: { input: 0.95, output: 8, cacheRead: 0.19, cacheWrite5m: 0, cacheWrite1h: 0 },
6360
- limits: { contextWindow: 262144, maxOutputTokens: 131072 }
6361
- }
6362
- ]
6363
- };
6364
-
6365
- // packages/providers/src/openai/models.ts
6366
- var OPENAI_MODELS = {
6367
- defaultModel: "gpt-5.6",
6368
- models: [
6369
- {
6370
- id: "gpt-5.6",
6371
- label: "GPT-5.6 \u2014 routes to Sol",
6372
- pricing: { input: 5, output: 30, cacheRead: 0.5, cacheWrite5m: 0, cacheWrite1h: 0 },
6373
- limits: { contextWindow: 922000, maxOutputTokens: 128000 },
6374
- oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
6375
- },
6376
- {
6377
- id: "gpt-5.6-sol",
6378
- label: "GPT-5.6 Sol \u2014 deepest reasoning",
6379
- pricing: { input: 5, output: 30, cacheRead: 0.5, cacheWrite5m: 0, cacheWrite1h: 0 },
6380
- limits: { contextWindow: 922000, maxOutputTokens: 128000 },
6381
- oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
6382
- },
6383
- {
6384
- id: "gpt-5.6-terra",
6385
- label: "GPT-5.6 Terra \u2014 balanced",
6386
- pricing: { input: 2, output: 12, cacheRead: 0.2, cacheWrite5m: 0, cacheWrite1h: 0 },
6387
- limits: { contextWindow: 922000, maxOutputTokens: 128000 },
6388
- oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
6389
- },
6390
- {
6391
- id: "gpt-5.6-luna",
6392
- label: "GPT-5.6 Luna \u2014 fastest",
6393
- pricing: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite5m: 0, cacheWrite1h: 0 },
6394
- limits: { contextWindow: 922000, maxOutputTokens: 128000 },
6395
- oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
6396
- }
6397
- ]
6398
- };
6399
-
6400
- // packages/providers/src/catalog.ts
6401
- var PROVIDER_MODEL_CATALOG = {
6402
- anthropic: ANTHROPIC_MODELS,
6403
- openai: OPENAI_MODELS,
6404
- kimi: KIMI_MODELS
6405
- };
6406
- function catalogPricing(provider, model) {
6407
- return PROVIDER_MODEL_CATALOG[provider]?.models.find((entry) => entry.id === model)?.pricing ?? null;
6408
- }
6409
- function catalogLimits(provider, model, auth = "apiKey") {
6410
- const entry = PROVIDER_MODEL_CATALOG[provider]?.models.find((choice) => choice.id === model);
6411
- if (entry === undefined)
6412
- return null;
6413
- return (auth === "oauth" ? entry.oauthLimits : undefined) ?? entry.limits;
6414
- }
6415
6828
  // packages/providers/src/http-client.ts
6416
6829
  import { request as httpRequest } from "http";
6417
6830
  import { request as httpsRequest } from "https";
@@ -6637,6 +7050,8 @@ function toChatWire(req, model) {
6637
7050
  if (!degradations.includes(d))
6638
7051
  degradations.push(d);
6639
7052
  };
7053
+ if (req.betas?.includes(CONTEXT_1M_BETA))
7054
+ note("kimi:context-1m-dropped");
6640
7055
  const messages = [];
6641
7056
  const system = req.system?.flatMap((b) => b.type === "text" ? [b.text] : []).join(`
6642
7057
 
@@ -6671,6 +7086,9 @@ function toChatWire(req, model) {
6671
7086
  content: block.content
6672
7087
  });
6673
7088
  break;
7089
+ case "anthropicNative":
7090
+ note("kimi:anthropic-native-block-dropped");
7091
+ break;
6674
7092
  }
6675
7093
  }
6676
7094
  if (toolCalls.length > 0) {
@@ -6698,7 +7116,10 @@ function toChatWire(req, model) {
6698
7116
  if (req.stopSequences !== undefined)
6699
7117
  body.stop = req.stopSequences;
6700
7118
  if (req.tools !== undefined) {
6701
- body.tools = req.tools.map((t) => ({
7119
+ const custom = req.tools.filter((t) => t.provider === "custom");
7120
+ if (custom.length !== req.tools.length)
7121
+ note("kimi:anthropic-tool-dropped");
7122
+ body.tools = custom.map((t) => ({
6702
7123
  type: "function",
6703
7124
  function: { name: t.name, description: t.description, parameters: t.inputSchema }
6704
7125
  }));
@@ -6913,6 +7334,8 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
6913
7334
  if (!degradations.includes(d))
6914
7335
  degradations.push(d);
6915
7336
  };
7337
+ if (req.betas?.includes(CONTEXT_1M_BETA))
7338
+ note("openai:context-1m-dropped");
6916
7339
  for (const message of req.messages) {
6917
7340
  const parts = [];
6918
7341
  const inlined = message.role === "system";
@@ -6963,6 +7386,9 @@ ${block.text}
6963
7386
  output: block.content
6964
7387
  });
6965
7388
  break;
7389
+ case "anthropicNative":
7390
+ note("openai:anthropic-native-block-dropped");
7391
+ break;
6966
7392
  }
6967
7393
  }
6968
7394
  flush();
@@ -6986,7 +7412,10 @@ ${block.text}
6986
7412
  body.temperature = req.temperature;
6987
7413
  }
6988
7414
  if (req.tools !== undefined) {
6989
- body.tools = req.tools.map((t) => ({
7415
+ const custom = req.tools.filter((t) => t.provider === "custom");
7416
+ if (custom.length !== req.tools.length)
7417
+ note("openai:anthropic-tool-dropped");
7418
+ body.tools = custom.map((t) => ({
6990
7419
  type: "function",
6991
7420
  name: t.name,
6992
7421
  description: t.description,
@@ -7607,12 +8036,10 @@ async function readSource(deps, source, lines) {
7607
8036
  return "";
7608
8037
  if (source.kind === "file")
7609
8038
  return deps.readFile(source.path, lines) ?? "";
7610
- const scope = source.scope === "system" ? [] : ["--user"];
8039
+ const unit = source.scope === "system" ? ["-u", source.unit] : [`--user-unit=${source.unit}`];
7611
8040
  const result = await deps.run([
7612
8041
  "journalctl",
7613
- ...scope,
7614
- "-u",
7615
- source.unit,
8042
+ ...unit,
7616
8043
  "-n",
7617
8044
  String(lines),
7618
8045
  "--no-pager",
@@ -21919,7 +22346,9 @@ var dryRunSchema = exports_external.object({
21919
22346
  reasoning: exports_external.boolean().default(false)
21920
22347
  }).strict();
21921
22348
  var modelSchema = exports_external.object({
21922
- id: exports_external.string().min(1),
22349
+ id: exports_external.string().min(1).refine((value) => !value.toLowerCase().startsWith("claude/"), {
22350
+ message: 'model id must not start with "claude/": that prefix is reserved for discovery mirrors'
22351
+ }),
21923
22352
  strategy: exports_external.enum(["score", "priority", "roundRobin", "weighted"]),
21924
22353
  isAlias: exports_external.boolean(),
21925
22354
  targets: exports_external.array(exports_external.object({
@@ -21958,11 +22387,12 @@ var settingsSchema = exports_external.object({
21958
22387
  recency: exports_external.number()
21959
22388
  }).strict(),
21960
22389
  maxAttempts: exports_external.number().int().min(1).max(10),
21961
- requestDeadlineMs: exports_external.number().int().positive(),
22390
+ requestDeadlineMs: exports_external.number().int().min(0),
21962
22391
  breakerThreshold: exports_external.number().int().min(1),
21963
22392
  breakerCooldownMs: exports_external.number().int().positive(),
21964
22393
  logRetentionDays: exports_external.number().int().min(1),
21965
- quotaPollIntervalMs: exports_external.number().int().min(0)
22394
+ quotaPollIntervalMs: exports_external.number().int().min(0),
22395
+ rtkEnabled: exports_external.boolean()
21966
22396
  });
21967
22397
  var credentialPatchSchema = exports_external.object({
21968
22398
  label: exports_external.string().min(1).optional(),
@@ -22078,6 +22508,11 @@ async function buildSnapshot(store, now) {
22078
22508
  }
22079
22509
 
22080
22510
  // packages/router/src/filters.ts
22511
+ function needsAnthropicNative(request2) {
22512
+ if (request2.tools?.some((t) => t.provider === "anthropic") === true)
22513
+ return true;
22514
+ return request2.messages.some((m) => m.content.some((b) => b.type === "anthropicNative"));
22515
+ }
22081
22516
  function requiredCapabilities(request2) {
22082
22517
  const images = request2.messages.some((m) => m.content.some((b) => b.type === "image"));
22083
22518
  return {
@@ -22094,10 +22529,11 @@ function eligible(input) {
22094
22529
  const { request: request2, model, snapshot, now } = input;
22095
22530
  const { breakerThreshold, breakerCooldownMs } = snapshot.settings;
22096
22531
  const need = requiredCapabilities(request2);
22532
+ const needNative = needsAnthropicNative(request2);
22097
22533
  const pairs = [];
22098
22534
  const excluded = [];
22099
22535
  for (const target of model.targets) {
22100
- const missing = ["tools", "images", "reasoning"].find((cap) => need[cap] && !target.capabilities[cap]);
22536
+ const missing = needNative && !ANTHROPIC_NATIVE_TOOLS[target.provider] ? "anthropicTools" : ["tools", "images", "reasoning"].find((cap) => need[cap] && !target.capabilities[cap]);
22101
22537
  for (const credential of snapshot.credentials) {
22102
22538
  if (credential.provider !== target.provider)
22103
22539
  continue;
@@ -22405,7 +22841,11 @@ async function dryRun(deps, modelId, input) {
22405
22841
  }
22406
22842
  ],
22407
22843
  stream: false,
22408
- ...need.tools ? { tools: [{ name: "probe", description: "", inputSchema: { type: "object" } }] } : {},
22844
+ ...need.tools ? {
22845
+ tools: [
22846
+ { provider: "custom", name: "probe", description: "", inputSchema: { type: "object" } }
22847
+ ]
22848
+ } : {},
22409
22849
  ...need.reasoning ? { reasoning: { mode: "adaptive" } } : {}
22410
22850
  };
22411
22851
  const result = rank({ request: probe, model, snapshot, now, rand: 0 });
@@ -22473,7 +22913,8 @@ var DEFAULT_SETTINGS = {
22473
22913
  breakerThreshold: 3,
22474
22914
  breakerCooldownMs: 30000,
22475
22915
  logRetentionDays: 30,
22476
- quotaPollIntervalMs: 300000
22916
+ quotaPollIntervalMs: 300000,
22917
+ rtkEnabled: false
22477
22918
  };
22478
22919
 
22479
22920
  // packages/store/src/sqlite/config.ts
@@ -22509,12 +22950,18 @@ function createConfigRepo(db, emit = () => {}) {
22509
22950
  const raw = readRaw(SETTINGS_KEY);
22510
22951
  if (raw === null)
22511
22952
  return DEFAULT_SETTINGS;
22512
- const stored = JSON.parse(raw);
22513
- return {
22514
- ...DEFAULT_SETTINGS,
22515
- ...stored,
22516
- weights: { ...DEFAULT_SETTINGS.weights, ...stored.weights }
22517
- };
22953
+ try {
22954
+ const parsed = JSON.parse(raw);
22955
+ const stored = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
22956
+ return {
22957
+ ...DEFAULT_SETTINGS,
22958
+ ...stored,
22959
+ rtkEnabled: stored.rtkEnabled === true,
22960
+ weights: { ...DEFAULT_SETTINGS.weights, ...stored.weights }
22961
+ };
22962
+ } catch {
22963
+ return DEFAULT_SETTINGS;
22964
+ }
22518
22965
  },
22519
22966
  async putSettings(patch) {
22520
22967
  const current = await this.getSettings();
@@ -22956,6 +23403,20 @@ ALTER TABLE request_logs ADD COLUMN state TEXT NOT NULL DEFAULT 'done';
22956
23403
  CREATE INDEX idx_request_logs_pending ON request_logs(state) WHERE state = 'pending';
22957
23404
  `;
22958
23405
 
23406
+ // packages/store/src/sqlite/migrations/005_rtk_metrics.sql
23407
+ var _005_rtk_metrics_default = `ALTER TABLE request_logs ADD COLUMN rtk_applied INTEGER NOT NULL DEFAULT 0;
23408
+ ALTER TABLE request_logs ADD COLUMN rtk_filter_hits INTEGER NOT NULL DEFAULT 0;
23409
+ ALTER TABLE request_logs ADD COLUMN rtk_original_code_units INTEGER NOT NULL DEFAULT 0;
23410
+ ALTER TABLE request_logs ADD COLUMN rtk_compressed_code_units INTEGER NOT NULL DEFAULT 0;
23411
+ ALTER TABLE request_logs ADD COLUMN rtk_estimated_tokens_saved INTEGER NOT NULL DEFAULT 0;
23412
+ ALTER TABLE request_logs ADD COLUMN rtk_filters TEXT NOT NULL DEFAULT '[]';
23413
+ `;
23414
+
23415
+ // packages/store/src/sqlite/migrations/006_rtk_usage.sql
23416
+ var _006_rtk_usage_default = `ALTER TABLE usage_daily ADD COLUMN rtk_saved_tokens INTEGER NOT NULL DEFAULT 0;
23417
+ ALTER TABLE usage_daily ADD COLUMN rtk_applied_requests INTEGER NOT NULL DEFAULT 0;
23418
+ `;
23419
+
22959
23420
  // packages/store/src/sqlite/rollup.ts
22960
23421
  function startOfLocalDay(at) {
22961
23422
  const day = new Date(at);
@@ -22966,8 +23427,8 @@ var UPSERT = `
22966
23427
  INSERT INTO usage_daily
22967
23428
  (day, provider, credential_id, requested_model, resolved_model, api_key_id,
22968
23429
  requests, errors, input_tokens, output_tokens, cache_read_tokens,
22969
- cache_write_tokens, cost_usd, duration_ms_sum)
22970
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
23430
+ cache_write_tokens, rtk_saved_tokens, rtk_applied_requests, cost_usd, duration_ms_sum)
23431
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
22971
23432
  ON CONFLICT (day, provider, credential_id, requested_model, resolved_model, api_key_id)
22972
23433
  DO UPDATE SET
22973
23434
  requests = requests + excluded.requests,
@@ -22975,8 +23436,10 @@ var UPSERT = `
22975
23436
  input_tokens = input_tokens + excluded.input_tokens,
22976
23437
  output_tokens = output_tokens + excluded.output_tokens,
22977
23438
  cache_read_tokens = cache_read_tokens + excluded.cache_read_tokens,
22978
- cache_write_tokens = cache_write_tokens + excluded.cache_write_tokens,
22979
- cost_usd = cost_usd + excluded.cost_usd,
23439
+ cache_write_tokens = cache_write_tokens + excluded.cache_write_tokens,
23440
+ rtk_saved_tokens = rtk_saved_tokens + excluded.rtk_saved_tokens,
23441
+ rtk_applied_requests = rtk_applied_requests + excluded.rtk_applied_requests,
23442
+ cost_usd = cost_usd + excluded.cost_usd,
22980
23443
  duration_ms_sum = duration_ms_sum + excluded.duration_ms_sum`;
22981
23444
  function keyOf(log) {
22982
23445
  return [
@@ -22996,6 +23459,8 @@ function countersOf(log) {
22996
23459
  outputTokens: log.outputTokens,
22997
23460
  cacheReadTokens: log.cacheReadTokens,
22998
23461
  cacheWriteTokens: log.cacheWriteTokens,
23462
+ rtkSavedTokens: log.rtkEstimatedTokensSaved,
23463
+ rtkAppliedRequests: log.rtkApplied ? 1 : 0,
22999
23464
  costUsd: log.costUsd,
23000
23465
  durationMsSum: log.durationMs
23001
23466
  };
@@ -23009,6 +23474,8 @@ function upsert(db, key, c) {
23009
23474
  c.outputTokens,
23010
23475
  c.cacheReadTokens,
23011
23476
  c.cacheWriteTokens,
23477
+ c.rtkSavedTokens,
23478
+ c.rtkAppliedRequests,
23012
23479
  c.costUsd,
23013
23480
  c.durationMsSum
23014
23481
  ]);
@@ -23039,6 +23506,8 @@ function backfillDaily(db) {
23039
23506
  outputTokens: 0,
23040
23507
  cacheReadTokens: 0,
23041
23508
  cacheWriteTokens: 0,
23509
+ rtkSavedTokens: 0,
23510
+ rtkAppliedRequests: 0,
23042
23511
  costUsd: 0,
23043
23512
  durationMsSum: 0
23044
23513
  };
@@ -23057,13 +23526,42 @@ function backfillDaily(db) {
23057
23526
  upsert(db, group.key, group.counters);
23058
23527
  return groups.size;
23059
23528
  }
23529
+ function backfillRtkUsage(db) {
23530
+ const groups = new Map;
23531
+ for (const row of db.query(`SELECT at, api_key_id, requested_model, resolved_provider, resolved_model, credential_id,
23532
+ rtk_applied, rtk_estimated_tokens_saved
23533
+ FROM request_logs
23534
+ WHERE state = 'done'`).all()) {
23535
+ const key = [
23536
+ startOfLocalDay(row.at),
23537
+ row.resolved_provider ?? "",
23538
+ row.credential_id ?? "",
23539
+ row.requested_model,
23540
+ row.resolved_model ?? "",
23541
+ row.api_key_id ?? ""
23542
+ ];
23543
+ const id = key.join("\x00");
23544
+ const group = groups.get(id) ?? { key, saved: 0, applied: 0 };
23545
+ group.saved += row.rtk_estimated_tokens_saved;
23546
+ group.applied += row.rtk_applied === 1 ? 1 : 0;
23547
+ groups.set(id, group);
23548
+ }
23549
+ for (const { key, saved, applied } of groups.values()) {
23550
+ db.run(`UPDATE usage_daily
23551
+ SET rtk_saved_tokens = ?, rtk_applied_requests = ?
23552
+ WHERE day = ? AND provider = ? AND credential_id = ? AND requested_model = ?
23553
+ AND resolved_model = ? AND api_key_id = ?`, [saved, applied, ...key]);
23554
+ }
23555
+ }
23060
23556
 
23061
23557
  // packages/store/src/sqlite/db.ts
23062
23558
  var MIGRATIONS = [
23063
23559
  { id: 1, sql: _001_init_default },
23064
23560
  { id: 2, sql: _002_usage_daily_default, after: backfillDaily },
23065
23561
  { id: 3, sql: _003_quota_snapshot_default },
23066
- { id: 4, sql: _004_request_state_default }
23562
+ { id: 4, sql: _004_request_state_default },
23563
+ { id: 5, sql: _005_rtk_metrics_default },
23564
+ { id: 6, sql: _006_rtk_usage_default, after: backfillRtkUsage }
23067
23565
  ];
23068
23566
  function openDb(path) {
23069
23567
  const db = new Database(path, { create: true });
@@ -23132,7 +23630,38 @@ function createKeyRepo(db) {
23132
23630
  }
23133
23631
  };
23134
23632
  }
23633
+ // packages/rtk/src/catalog.ts
23634
+ var RTK_FILTER_IDS = [
23635
+ "git-diff",
23636
+ "git-status",
23637
+ "git-log",
23638
+ "grep",
23639
+ "path-list",
23640
+ "numbered-read",
23641
+ "build-output",
23642
+ "test-output",
23643
+ "deduplicate-log",
23644
+ "smart-truncate",
23645
+ "lint-output",
23646
+ "package-output",
23647
+ "tree-output",
23648
+ "git-operation",
23649
+ "docker-build"
23650
+ ];
23651
+ var FILTER_IDS = new Set(RTK_FILTER_IDS);
23652
+ function isRtkFilterId(value) {
23653
+ return FILTER_IDS.has(value);
23654
+ }
23655
+
23135
23656
  // packages/store/src/sqlite/usage.ts
23657
+ function parseRtkFilters(raw) {
23658
+ try {
23659
+ const parsed = JSON.parse(raw);
23660
+ return Array.isArray(parsed) ? parsed.filter(isRtkFilterId) : [];
23661
+ } catch {
23662
+ return [];
23663
+ }
23664
+ }
23136
23665
  var toLog = (r) => ({
23137
23666
  id: r.id,
23138
23667
  state: r.state === "pending" ? "pending" : "done",
@@ -23152,7 +23681,13 @@ var toLog = (r) => ({
23152
23681
  ttftMs: r.ttft_ms,
23153
23682
  durationMs: r.duration_ms,
23154
23683
  costUsd: r.cost_usd,
23155
- degradations: JSON.parse(r.degradations)
23684
+ degradations: JSON.parse(r.degradations),
23685
+ rtkApplied: r.rtk_applied === 1,
23686
+ rtkFilterHits: r.rtk_filter_hits,
23687
+ rtkOriginalCodeUnits: r.rtk_original_code_units,
23688
+ rtkCompressedCodeUnits: r.rtk_compressed_code_units,
23689
+ rtkEstimatedTokensSaved: r.rtk_estimated_tokens_saved,
23690
+ rtkFilters: parseRtkFilters(r.rtk_filters)
23156
23691
  });
23157
23692
  var GROUP_COLUMN = {
23158
23693
  raw: {
@@ -23197,8 +23732,9 @@ function label(value) {
23197
23732
  var COLUMNS = `(id, state, at, api_key_id, requested_model, resolved_provider, resolved_model,
23198
23733
  credential_id, attempts, status, error_code, input_tokens, output_tokens,
23199
23734
  cache_read_tokens, cache_write_tokens, ttft_ms, duration_ms, cost_usd,
23200
- degradations)`;
23201
- var PLACEHOLDERS = "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
23735
+ degradations, rtk_applied, rtk_filter_hits, rtk_original_code_units,
23736
+ rtk_compressed_code_units, rtk_estimated_tokens_saved, rtk_filters)`;
23737
+ var PLACEHOLDERS = "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
23202
23738
  function values(log, state) {
23203
23739
  return [
23204
23740
  log.id,
@@ -23219,7 +23755,13 @@ function values(log, state) {
23219
23755
  log.ttftMs,
23220
23756
  log.durationMs,
23221
23757
  log.costUsd,
23222
- JSON.stringify(log.degradations)
23758
+ JSON.stringify(log.degradations),
23759
+ log.rtkApplied === true ? 1 : 0,
23760
+ log.rtkFilterHits ?? 0,
23761
+ log.rtkOriginalCodeUnits ?? 0,
23762
+ log.rtkCompressedCodeUnits ?? 0,
23763
+ log.rtkEstimatedTokensSaved ?? 0,
23764
+ JSON.stringify(log.rtkFilters ?? [])
23223
23765
  ];
23224
23766
  }
23225
23767
  var COMPLETE = `INSERT INTO request_logs ${COLUMNS} VALUES ${PLACEHOLDERS}
@@ -23240,7 +23782,13 @@ var COMPLETE = `INSERT INTO request_logs ${COLUMNS} VALUES ${PLACEHOLDERS}
23240
23782
  ttft_ms = excluded.ttft_ms,
23241
23783
  duration_ms = excluded.duration_ms,
23242
23784
  cost_usd = excluded.cost_usd,
23243
- degradations = excluded.degradations`;
23785
+ degradations = excluded.degradations,
23786
+ rtk_applied = excluded.rtk_applied,
23787
+ rtk_filter_hits = excluded.rtk_filter_hits,
23788
+ rtk_original_code_units = excluded.rtk_original_code_units,
23789
+ rtk_compressed_code_units = excluded.rtk_compressed_code_units,
23790
+ rtk_estimated_tokens_saved = excluded.rtk_estimated_tokens_saved,
23791
+ rtk_filters = excluded.rtk_filters`;
23244
23792
  function createUsageRepo(db) {
23245
23793
  const complete = db.transaction((log) => {
23246
23794
  db.run(COMPLETE, values(log, "done"));
@@ -23285,6 +23833,8 @@ function createUsageRepo(db) {
23285
23833
  COALESCE(SUM(output_tokens), 0) AS output_tokens,
23286
23834
  COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,
23287
23835
  COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,
23836
+ COALESCE(SUM(${daily ? "rtk_saved_tokens" : "rtk_estimated_tokens_saved"}), 0) AS rtk_saved_tokens,
23837
+ COALESCE(SUM(${daily ? "rtk_applied_requests" : "CASE WHEN rtk_applied = 1 THEN 1 ELSE 0 END"}), 0) AS rtk_applied_requests,
23288
23838
  COALESCE(SUM(cost_usd), 0) AS cost_usd
23289
23839
  FROM ${daily ? "usage_daily" : "request_logs"}
23290
23840
  WHERE ${daily ? "" : "state = 'done' AND "}${timeColumn} >= ? AND ${timeColumn} <= ?
@@ -23298,6 +23848,8 @@ function createUsageRepo(db) {
23298
23848
  outputTokens: r.output_tokens,
23299
23849
  cacheReadTokens: r.cache_read_tokens,
23300
23850
  cacheWriteTokens: r.cache_write_tokens,
23851
+ rtkSavedTokens: r.rtk_saved_tokens,
23852
+ rtkAppliedRequests: r.rtk_applied_requests,
23301
23853
  costUsd: r.cost_usd,
23302
23854
  errors: r.errors,
23303
23855
  durationMsSum: r.duration_ms_sum
@@ -23373,6 +23925,60 @@ async function createKey(store, input) {
23373
23925
  async function revokeKey(store, id) {
23374
23926
  await store.keys.revoke(id);
23375
23927
  }
23928
+ // packages/control/src/modelLimits.ts
23929
+ function narrower(a, b) {
23930
+ const context = [a.contextWindow, b.contextWindow].filter((n) => n !== undefined);
23931
+ const output = [a.maxOutputTokens, b.maxOutputTokens].filter((n) => n !== undefined);
23932
+ return {
23933
+ ...context.length === 0 ? {} : { contextWindow: Math.min(...context) },
23934
+ ...output.length === 0 ? {} : { maxOutputTokens: Math.min(...output) }
23935
+ };
23936
+ }
23937
+ function targetLimits(target, auths) {
23938
+ const ways = auths.size === 0 ? ["apiKey"] : [...auths];
23939
+ let listed = {};
23940
+ for (const auth of ways) {
23941
+ const entry = catalogLimits(target.provider, target.model, auth);
23942
+ if (entry === null)
23943
+ continue;
23944
+ listed = narrower(listed, {
23945
+ contextWindow: entry.contextWindow,
23946
+ maxOutputTokens: entry.maxOutputTokens
23947
+ });
23948
+ }
23949
+ const contextWindow = target.contextWindow ?? listed.contextWindow;
23950
+ const maxOutputTokens = target.maxOutputTokens ?? listed.maxOutputTokens;
23951
+ return {
23952
+ ...contextWindow === undefined ? {} : { contextWindow },
23953
+ ...maxOutputTokens === undefined ? {} : { maxOutputTokens }
23954
+ };
23955
+ }
23956
+ function servingAuths(credentials) {
23957
+ const byProvider = new Map;
23958
+ for (const credential of credentials) {
23959
+ if (!credential.enabled)
23960
+ continue;
23961
+ const ways = byProvider.get(credential.provider) ?? new Set;
23962
+ ways.add(credential.authType);
23963
+ byProvider.set(credential.provider, ways);
23964
+ }
23965
+ return byProvider;
23966
+ }
23967
+ function resolveModelLimits(model, credentials) {
23968
+ const auths = servingAuths(credentials);
23969
+ let limits = {};
23970
+ for (const target of model.targets) {
23971
+ limits = narrower(limits, targetLimits(target, auths.get(target.provider) ?? new Set));
23972
+ }
23973
+ return limits;
23974
+ }
23975
+ function modelDisplayName(model) {
23976
+ const only = model.targets.length === 1 ? model.targets[0] : undefined;
23977
+ if (only === undefined)
23978
+ return model.id;
23979
+ const labelled = PROVIDER_MODEL_CATALOG[only.provider]?.models.find((choice) => choice.id === only.model);
23980
+ return labelled?.label ?? model.id;
23981
+ }
23376
23982
  // packages/control/src/models.ts
23377
23983
  async function listModels(store) {
23378
23984
  return store.config.listModels();
@@ -23789,6 +24395,122 @@ async function putSettings(store, input) {
23789
24395
  await store.config.putSettings(settings);
23790
24396
  return settings;
23791
24397
  }
24398
+ // packages/control/src/setup.ts
24399
+ var KEY_PLACEHOLDER = "<your OmniGateway key>";
24400
+ async function describeModelsForSetup(store) {
24401
+ const models = await listModels(store);
24402
+ const credentials = (await listCredentials(store)).map((credential) => ({
24403
+ provider: credential.provider,
24404
+ authType: credential.authType,
24405
+ enabled: credential.enabled
24406
+ }));
24407
+ return models.map((model) => ({
24408
+ model,
24409
+ limits: resolveModelLimits(model, credentials),
24410
+ label: modelDisplayName(model)
24411
+ }));
24412
+ }
24413
+ var CLAUDE_MAPPING_KEYS = {
24414
+ defaultModel: "ANTHROPIC_MODEL",
24415
+ fableModel: "ANTHROPIC_DEFAULT_FABLE_MODEL",
24416
+ opusModel: "ANTHROPIC_DEFAULT_OPUS_MODEL",
24417
+ sonnetModel: "ANTHROPIC_DEFAULT_SONNET_MODEL",
24418
+ haikuModel: "ANTHROPIC_DEFAULT_HAIKU_MODEL"
24419
+ };
24420
+ function settingsObject(existing) {
24421
+ if (existing === undefined)
24422
+ return {};
24423
+ try {
24424
+ const parsed = JSON.parse(existing);
24425
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
24426
+ throw new Error("settings root is not an object");
24427
+ }
24428
+ return parsed;
24429
+ } catch (error51) {
24430
+ const reason = error51 instanceof Error ? error51.message : "invalid JSON";
24431
+ throw new Error(`cannot parse existing settings.json: ${reason}`);
24432
+ }
24433
+ }
24434
+ function claudeSettings(described, input, mapping, existing) {
24435
+ if (mapping.defaultModel === "")
24436
+ throw new Error("default model is required");
24437
+ const ids = new Set(described.map(({ model }) => model.id));
24438
+ const visibleId = (slot, id) => {
24439
+ if (!ids.has(id))
24440
+ throw new Error(`${slot} names unknown virtual model "${id}"`);
24441
+ const useMirror = input.discoveryMirrors === true && !/^(?:claude|anthropic)/i.test(id);
24442
+ return useMirror ? `claude/${id}` : id;
24443
+ };
24444
+ const settings = settingsObject(existing);
24445
+ const currentEnv = settings.env;
24446
+ const env2 = typeof currentEnv === "object" && currentEnv !== null && !Array.isArray(currentEnv) ? { ...currentEnv } : {};
24447
+ for (const key of Object.values(CLAUDE_MAPPING_KEYS))
24448
+ delete env2[key];
24449
+ delete env2.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
24450
+ env2.ANTHROPIC_BASE_URL = input.baseUrl;
24451
+ env2.ANTHROPIC_AUTH_TOKEN = input.apiKey ?? KEY_PLACEHOLDER;
24452
+ env2.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1";
24453
+ for (const [slot, key] of Object.entries(CLAUDE_MAPPING_KEYS)) {
24454
+ const id = mapping[slot];
24455
+ if (id !== undefined && id !== "")
24456
+ env2[key] = visibleId(slot, id);
24457
+ }
24458
+ return {
24459
+ path: "settings.json",
24460
+ contents: `${JSON.stringify({ ...settings, env: env2 }, null, 2)}
24461
+ `
24462
+ };
24463
+ }
24464
+ function opencodeConfig(described, input, mapping) {
24465
+ if (mapping.defaultModel === "")
24466
+ throw new Error("default model is required");
24467
+ const byId = new Map(described.map((entry) => [entry.model.id, entry]));
24468
+ const selected = [];
24469
+ const seen = new Set;
24470
+ for (const slot of Object.keys(CLAUDE_MAPPING_KEYS)) {
24471
+ const id = mapping[slot];
24472
+ if (id === undefined || id === "")
24473
+ continue;
24474
+ const entry = byId.get(id);
24475
+ if (entry === undefined)
24476
+ throw new Error(`${slot} names unknown virtual model "${id}"`);
24477
+ if (!seen.has(id)) {
24478
+ seen.add(id);
24479
+ selected.push(entry);
24480
+ }
24481
+ }
24482
+ const models = {};
24483
+ for (const { model, limits, label: label2 } of selected) {
24484
+ const limit = limits.contextWindow === undefined ? undefined : {
24485
+ context: limits.contextWindow,
24486
+ ...limits.maxOutputTokens === undefined ? {} : { output: limits.maxOutputTokens }
24487
+ };
24488
+ models[model.id] = { name: label2, ...limit === undefined ? {} : { limit } };
24489
+ }
24490
+ const contents = `${JSON.stringify({
24491
+ $schema: "https://opencode.ai/config.json",
24492
+ model: `omnigateway/${mapping.defaultModel}`,
24493
+ provider: {
24494
+ omnigateway: {
24495
+ npm: "@ai-sdk/openai-compatible",
24496
+ name: "OmniGateway",
24497
+ options: {
24498
+ baseURL: `${input.baseUrl.replace(/\/+$/, "").replace(/(?:\/v1)+$/i, "")}/v1`,
24499
+ apiKey: input.apiKey ?? KEY_PLACEHOLDER
24500
+ },
24501
+ models
24502
+ }
24503
+ }
24504
+ }, null, 2)}
24505
+ `;
24506
+ return { path: "opencode.json", contents };
24507
+ }
24508
+ async function setupFiles(store, client, input, mapping) {
24509
+ const described = await describeModelsForSetup(store);
24510
+ if (mapping === undefined)
24511
+ throw new Error(`defaultModel is required for ${client} setup`);
24512
+ return client === "opencode" ? [opencodeConfig(described, input, mapping)] : [claudeSettings(described, input, mapping)];
24513
+ }
23792
24514
  // packages/control/src/tail.ts
23793
24515
  import { closeSync, fstatSync, openSync, readSync, statSync } from "fs";
23794
24516
  var CHUNK = 64 * 1024;
@@ -26759,7 +27481,7 @@ __export(exports_type3, {
26759
27481
  // node_modules/.bun/@sinclair+typebox@0.34.52/node_modules/@sinclair/typebox/build/esm/type/type/index.mjs
26760
27482
  var Type = exports_type3;
26761
27483
 
26762
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/index.mjs
27484
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/index.mjs
26763
27485
  var import_fast_decode_uri_component4 = __toESM(require_fast_decode_uri_component(), 1);
26764
27486
  // node_modules/.bun/@sinclair+typebox@0.34.52/node_modules/@sinclair/typebox/build/esm/system/evaluate.mjs
26765
27487
  function Evaluate(...args) {
@@ -30637,7 +31359,7 @@ var TypeCompiler;
30637
31359
  TypeCompiler2.Compile = Compile;
30638
31360
  })(TypeCompiler || (TypeCompiler = {}));
30639
31361
 
30640
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/universal/utils.mjs
31362
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/universal/utils.mjs
30641
31363
  var isBun = typeof Bun < "u";
30642
31364
  function isCloudflareWorker() {
30643
31365
  try {
@@ -30649,7 +31371,7 @@ function isCloudflareWorker() {
30649
31371
  return false;
30650
31372
  }
30651
31373
 
30652
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/universal/file.mjs
31374
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/universal/file.mjs
30653
31375
  var mime = {
30654
31376
  aac: "audio/aac",
30655
31377
  abw: "application/x-abiword",
@@ -30776,7 +31498,7 @@ class ElysiaFile {
30776
31498
  }
30777
31499
  }
30778
31500
 
30779
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/utils.mjs
31501
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/utils.mjs
30780
31502
  var replaceUrlPath = (url2, pathname) => {
30781
31503
  const pathStartIndex = url2.indexOf("/", 11), queryIndex = url2.indexOf("?", pathStartIndex);
30782
31504
  return queryIndex === -1 ? `${url2.slice(0, pathStartIndex)}${pathname.charCodeAt(0) === 47 ? "" : "/"}${pathname}` : `${url2.slice(0, pathStartIndex)}${pathname.charCodeAt(0) === 47 ? "" : "/"}${pathname}${url2.slice(queryIndex)}`;
@@ -31250,7 +31972,7 @@ var emptySchema = {
31250
31972
  response: true
31251
31973
  };
31252
31974
 
31253
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/error.mjs
31975
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/error.mjs
31254
31976
  var env2 = typeof Bun < "u" ? Bun.env : typeof process < "u" ? process?.env : undefined;
31255
31977
  var ERROR_CODE2 = Symbol("ElysiaErrorCode");
31256
31978
  var isProduction = (env2?.NODE_ENV ?? env2?.ENV) === "production";
@@ -31499,7 +32221,7 @@ class ValidationError extends Error {
31499
32221
  }
31500
32222
  }
31501
32223
 
31502
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/type-system/utils.mjs
32224
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/type-system/utils.mjs
31503
32225
  var tryParse = (v, schema) => {
31504
32226
  try {
31505
32227
  return JSON.parse(v);
@@ -31581,7 +32303,7 @@ var validateFile = (options, value) => {
31581
32303
  return true;
31582
32304
  };
31583
32305
 
31584
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/type-system/format.mjs
32306
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/type-system/format.mjs
31585
32307
  var fullFormats = {
31586
32308
  date: date5,
31587
32309
  time: getTime(true),
@@ -31720,7 +32442,7 @@ exports_format.Has("date") || exports_format.Set("date", (value) => {
31720
32442
  }
31721
32443
  });
31722
32444
 
31723
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/type-system/index.mjs
32445
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/type-system/index.mjs
31724
32446
  var t = Object.assign({}, Type);
31725
32447
  createType("UnionEnum", (schema, value) => (typeof value == "number" || typeof value == "string" || value === null) && schema.enum.includes(value)), createType("ArrayBuffer", (schema, value) => value instanceof ArrayBuffer);
31726
32448
  var internalFiles = createType("Files", (options, value) => {
@@ -32043,7 +32765,7 @@ t.BooleanString = ElysiaType.BooleanString, t.ObjectString = ElysiaType.ObjectSt
32043
32765
  }
32044
32766
  })), t.Nullable = ElysiaType.Nullable, t.MaybeEmpty = ElysiaType.MaybeEmpty, t.Cookie = ElysiaType.Cookie, t.Date = ElysiaType.Date, t.UnionEnum = ElysiaType.UnionEnum, t.NoValidate = ElysiaType.NoValidate, t.Form = ElysiaType.Form, t.ArrayBuffer = ElysiaType.ArrayBuffer, t.Uint8Array = ElysiaType.Uint8Array;
32045
32767
 
32046
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/sucrose.mjs
32768
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/sucrose.mjs
32047
32769
  var separateFunction = (code) => {
32048
32770
  code.startsWith("async") && (code = code.slice(5)), code = code.trimStart();
32049
32771
  let index = -1;
@@ -32307,7 +33029,7 @@ var sucrose = (lifeCycle, inference = {
32307
33029
  return inference;
32308
33030
  };
32309
33031
 
32310
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/cookies.mjs
33032
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/cookies.mjs
32311
33033
  var import_cookie = __toESM(require_dist(), 1);
32312
33034
  var import_fast_decode_uri_component = __toESM(require_fast_decode_uri_component(), 1);
32313
33035
  var hashString = (str) => {
@@ -32508,7 +33230,7 @@ var serializeCookie = (cookies) => {
32508
33230
  return set2.length === 1 ? set2[0] : set2;
32509
33231
  };
32510
33232
 
32511
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/utils.mjs
33233
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/utils.mjs
32512
33234
  var handleFile = (response, set2, request2) => {
32513
33235
  if (!isBun && response instanceof Promise)
32514
33236
  return response.then((res) => handleFile(res, set2, request2));
@@ -32765,7 +33487,7 @@ async function tee(source, branches = 2) {
32765
33487
  return Array.from({ length: branches }, makeIterator);
32766
33488
  }
32767
33489
 
32768
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/web-standard/handler.mjs
33490
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/web-standard/handler.mjs
32769
33491
  var handleElysiaFile = (file2, set2 = {
32770
33492
  headers: {}
32771
33493
  }, request2) => {
@@ -33082,7 +33804,7 @@ var handleStream = createStreamHandler({
33082
33804
  mapCompactResponse
33083
33805
  });
33084
33806
 
33085
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/web-standard/index.mjs
33807
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/web-standard/index.mjs
33086
33808
  var WebStandardAdapter = {
33087
33809
  name: "web-standard",
33088
33810
  isWebStandard: true,
@@ -33219,7 +33941,7 @@ const error404=new Response(error404Message,{status:404})
33219
33941
  }
33220
33942
  };
33221
33943
 
33222
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/bun/handler.mjs
33944
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/bun/handler.mjs
33223
33945
  var mapResponse2 = (response, set2, request2) => {
33224
33946
  if (isNotEmpty(set2.headers) || set2.status !== 200 || set2.cookie)
33225
33947
  switch (handleSet(set2), response?.constructor?.name) {
@@ -33491,10 +34213,10 @@ var handleStream2 = createStreamHandler({
33491
34213
  mapCompactResponse: mapCompactResponse2
33492
34214
  });
33493
34215
 
33494
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/compose.mjs
34216
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/compose.mjs
33495
34217
  var import_fast_decode_uri_component3 = __toESM(require_fast_decode_uri_component(), 1);
33496
34218
 
33497
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/parse-query.mjs
34219
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/parse-query.mjs
33498
34220
  var import_fast_decode_uri_component2 = __toESM(require_fast_decode_uri_component(), 1);
33499
34221
  var KEY_HAS_PLUS = 1;
33500
34222
  var KEY_NEEDS_DECODE = 2;
@@ -33620,7 +34342,7 @@ function parseQuery(input) {
33620
34342
  }
33621
34343
  }
33622
34344
 
33623
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/trace.mjs
34345
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/trace.mjs
33624
34346
  var ELYSIA_TRACE = Symbol("ElysiaTrace");
33625
34347
  var createProcess = () => {
33626
34348
  const { promise: promise2, resolve } = Promise.withResolvers(), { promise: end, resolve: resolveEnd } = Promise.withResolvers(), { promise: error51, resolve: resolveError } = Promise.withResolvers(), callbacks = [], callbacksEnd = [];
@@ -34061,7 +34783,7 @@ var createMirror = (schema, {
34061
34783
  });
34062
34784
  };
34063
34785
 
34064
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/replace-schema.mjs
34786
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/replace-schema.mjs
34065
34787
  var replaceSchemaTypeFromManyOptions = (schema, options) => {
34066
34788
  if (Array.isArray(options)) {
34067
34789
  let result = schema;
@@ -34159,7 +34881,7 @@ var coerceFormData = () => (_coerceFormData || (_coerceFormData = [
34159
34881
  }
34160
34882
  ]), _coerceFormData);
34161
34883
 
34162
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/schema.mjs
34884
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/schema.mjs
34163
34885
  var isOptional = (schema) => schema ? schema?.[Kind] === "Import" && schema.References ? schema.References().some(isOptional) : (schema.schema && (schema = schema.schema), !!schema && (OptionalKind in schema)) : false;
34164
34886
  var hasAdditionalProperties = (_schema) => {
34165
34887
  if (!_schema)
@@ -34946,7 +35668,7 @@ var getCookieValidator = ({
34946
35668
  };
34947
35669
  var unwrapImportSchema = (schema) => schema && schema[Kind] === "Import" && schema.$defs[schema.$ref][Kind] === "Object" ? schema.$defs[schema.$ref] : schema;
34948
35670
 
34949
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/compose.mjs
35671
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/compose.mjs
34950
35672
  var allocateIf = (value, condition) => condition ? value : "";
34951
35673
  var defaultParsers = [
34952
35674
  "json",
@@ -36095,7 +36817,7 @@ return mapResponse(${saveResponse}error,set${adapter.mapResponseContext})}`;
36095
36817
  });
36096
36818
  };
36097
36819
 
36098
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/bun/compose.mjs
36820
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/bun/compose.mjs
36099
36821
  var allocateIf2 = (value, condition) => condition ? value : "";
36100
36822
  var createContext = (app, route, inference, isInline = false) => {
36101
36823
  let fnLiteral = "";
@@ -36146,7 +36868,7 @@ var createBunRouteHandler = (app, route) => {
36146
36868
  });
36147
36869
  };
36148
36870
 
36149
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/bun/handler-native.mjs
36871
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/bun/handler-native.mjs
36150
36872
  var createNativeStaticHandler = (handle, hooks, set2) => {
36151
36873
  if (typeof handle == "function" || handle instanceof Blob)
36152
36874
  return;
@@ -36162,7 +36884,7 @@ var createNativeStaticHandler = (handle, hooks, set2) => {
36162
36884
  }) : () => response.clone();
36163
36885
  };
36164
36886
 
36165
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/ws/index.mjs
36887
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/ws/index.mjs
36166
36888
  var websocket = {
36167
36889
  open(ws) {
36168
36890
  ws.data.open?.(ws);
@@ -36265,7 +36987,7 @@ var createHandleWSResponse = (responseValidator) => {
36265
36987
  return handleWSResponse;
36266
36988
  };
36267
36989
 
36268
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/adapter/bun/index.mjs
36990
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/adapter/bun/index.mjs
36269
36991
  var optionalParam = /:.+?\?(?=\/|$)/;
36270
36992
  var getPossibleParams = (path) => {
36271
36993
  const match = optionalParam.exec(path);
@@ -36549,10 +37271,10 @@ for(const [k,v] of c.request.headers.entries())c.headers[k]=v
36549
37271
  }
36550
37272
  };
36551
37273
 
36552
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/universal/env.mjs
37274
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/universal/env.mjs
36553
37275
  var env3 = isBun ? Bun.env : typeof process < "u" && process?.env ? process.env : {};
36554
37276
 
36555
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/dynamic-handle.mjs
37277
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/dynamic-handle.mjs
36556
37278
  var ARRAY_INDEX_REGEX = /^(.+)\[(\d+)\]$/;
36557
37279
  var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
36558
37280
  var isDangerousKey = (key) => {
@@ -36988,7 +37710,7 @@ var createDynamicErrorHandler = (app) => {
36988
37710
  };
36989
37711
  };
36990
37712
 
36991
- // node_modules/.bun/elysia@1.4.29+cb62960704ad082f/node_modules/elysia/dist/index.mjs
37713
+ // node_modules/.bun/elysia@1.4.29+5b33ebcc42722450/node_modules/elysia/dist/index.mjs
36992
37714
  var _a3;
36993
37715
  _a3 = Symbol.dispose;
36994
37716
  var _Elysia = class _Elysia2 {
@@ -38503,6 +39225,30 @@ function adminRoutes(deps) {
38503
39225
  await requireAdmin(request2, deps.admin);
38504
39226
  await removeModel(deps.store, params.id);
38505
39227
  return { ok: true };
39228
+ }).get("/api/agent-setup", async ({ request: request2, query }) => {
39229
+ await requireAdmin(request2, deps.admin);
39230
+ const client = query.client === "opencode" ? "opencode" : "claude";
39231
+ const defaultModel = query.defaultModel;
39232
+ if (!defaultModel) {
39233
+ throw new GatewayError("BAD_REQUEST", `defaultModel is required for ${client} setup`);
39234
+ }
39235
+ try {
39236
+ return {
39237
+ client,
39238
+ files: await setupFiles(deps.store, client, {
39239
+ baseUrl: deps.baseUrl,
39240
+ discoveryMirrors: deps.discoveryMirrors === true
39241
+ }, {
39242
+ defaultModel,
39243
+ ...query.fableModel ? { fableModel: query.fableModel } : {},
39244
+ ...query.opusModel ? { opusModel: query.opusModel } : {},
39245
+ ...query.sonnetModel ? { sonnetModel: query.sonnetModel } : {},
39246
+ ...query.haikuModel ? { haikuModel: query.haikuModel } : {}
39247
+ })
39248
+ };
39249
+ } catch (error51) {
39250
+ throw new GatewayError("BAD_REQUEST", error51 instanceof Error ? error51.message : "invalid Claude model mapping");
39251
+ }
38506
39252
  }).get("/api/keys", async ({ request: request2 }) => {
38507
39253
  await requireAdmin(request2, deps.admin);
38508
39254
  return { keys: await listKeys(deps.store) };
@@ -38607,6 +39353,1797 @@ function extractToken(header) {
38607
39353
  return match === null ? value : match[1].trim();
38608
39354
  }
38609
39355
 
39356
+ // packages/rtk/src/command.ts
39357
+ var UNSUPPORTED_OUTPUT = new Set(["--json", "--sarif"]);
39358
+ function tokenize(command) {
39359
+ if (command.length > 16384 || /[\r\n`]/.test(command) || command.includes("$(") || command.includes("<(") || command.includes(">("))
39360
+ return;
39361
+ const tokens2 = [];
39362
+ let word = "";
39363
+ let wordStarted = false;
39364
+ let quote;
39365
+ const pushWord = () => {
39366
+ if (wordStarted)
39367
+ tokens2.push({ kind: "word", value: word });
39368
+ word = "";
39369
+ wordStarted = false;
39370
+ };
39371
+ for (let i = 0;i < command.length; i++) {
39372
+ const char = command[i];
39373
+ if (char === undefined)
39374
+ continue;
39375
+ if (quote !== undefined) {
39376
+ if (char === quote)
39377
+ quote = undefined;
39378
+ else if (char === "\\" && quote === '"' && command[i + 1] !== undefined)
39379
+ word += command[++i];
39380
+ else
39381
+ word += char;
39382
+ continue;
39383
+ }
39384
+ if (char === "'" || char === '"') {
39385
+ quote = char;
39386
+ wordStarted = true;
39387
+ continue;
39388
+ }
39389
+ if (/\s/.test(char)) {
39390
+ pushWord();
39391
+ continue;
39392
+ }
39393
+ if (";&|<>".includes(char) || char === "$" && command[i + 1] === "(") {
39394
+ pushWord();
39395
+ const next = command[i + 1];
39396
+ const value = next !== undefined && (next === char || char === ">" && next === ">") ? char + command[++i] : char;
39397
+ tokens2.push({ kind: "operator", value });
39398
+ continue;
39399
+ }
39400
+ word += char;
39401
+ wordStarted = true;
39402
+ }
39403
+ if (quote !== undefined)
39404
+ return;
39405
+ pushWord();
39406
+ return tokens2.length <= 256 ? tokens2 : undefined;
39407
+ }
39408
+ function unwrap(tokens2) {
39409
+ let words = tokens2;
39410
+ const operatorIndexes = words.flatMap((token, index) => token.kind === "operator" ? [index] : []);
39411
+ if (operatorIndexes.length > 1)
39412
+ return;
39413
+ if (operatorIndexes.length === 1) {
39414
+ const index = operatorIndexes[0];
39415
+ if (index === undefined || words[index]?.value !== "&&" || words[0]?.kind !== "word" || words[0].value !== "cd" || index !== 2)
39416
+ return;
39417
+ words = words.slice(index + 1);
39418
+ }
39419
+ if (words.some((token) => token.kind === "operator"))
39420
+ return;
39421
+ const values2 = words.map((token) => token.value);
39422
+ while (/^[A-Za-z_][A-Za-z0-9_]*=/.test(values2[0] ?? ""))
39423
+ values2.shift();
39424
+ if (values2[0] === "env") {
39425
+ values2.shift();
39426
+ while (values2.length > 0) {
39427
+ const value = values2.at(0);
39428
+ if (value === "-i" || value === "--ignore-environment" || /^[A-Za-z_][A-Za-z0-9_]*=/.test(value ?? ""))
39429
+ values2.shift();
39430
+ else if (value === "-u") {
39431
+ if (values2[1] === undefined)
39432
+ return;
39433
+ values2.splice(0, 2);
39434
+ } else if (value?.startsWith("--unset="))
39435
+ values2.shift();
39436
+ else if (value === "--")
39437
+ values2.shift();
39438
+ else
39439
+ break;
39440
+ }
39441
+ }
39442
+ if (values2[0] === "timeout") {
39443
+ values2.shift();
39444
+ while (values2[0]?.startsWith("-")) {
39445
+ const option = values2.shift();
39446
+ if (option === "--")
39447
+ break;
39448
+ if (option === "-s" || option === "-k") {
39449
+ if (values2.shift() === undefined)
39450
+ return;
39451
+ } else if (!option?.startsWith("--signal=") && !option?.startsWith("--kill-after="))
39452
+ return;
39453
+ }
39454
+ if (values2.shift() === undefined)
39455
+ return;
39456
+ }
39457
+ return values2.length > 0 ? values2 : undefined;
39458
+ }
39459
+ function scriptFamily(name) {
39460
+ if (["test", "test:unit", "test:integration", "test:e2e"].includes(name) || name.startsWith("test:"))
39461
+ return "test-output";
39462
+ if (["lint", "typecheck", "check"].includes(name) || name.startsWith("lint:") || name.startsWith("typecheck:"))
39463
+ return "lint-output";
39464
+ return "build-output";
39465
+ }
39466
+ function classifyGrep(executable, args) {
39467
+ let heading = false;
39468
+ let beforeContext = 0;
39469
+ let afterContext = 0;
39470
+ let lineNumber = false;
39471
+ let operands = 0;
39472
+ for (let index = 0;index < args.length; index++) {
39473
+ const argument = args[index] ?? "";
39474
+ if (argument === "--") {
39475
+ operands += args.length - index - 1;
39476
+ break;
39477
+ }
39478
+ if (!argument.startsWith("-")) {
39479
+ operands++;
39480
+ continue;
39481
+ }
39482
+ if (["--json", "--files", "--replace", "-r", "--files-with-matches", "-l", "-P"].includes(argument))
39483
+ return;
39484
+ if (argument === "--heading")
39485
+ heading = true;
39486
+ else if (argument === "--no-heading")
39487
+ heading = false;
39488
+ else if (argument === "-n" || argument === "--line-number")
39489
+ lineNumber = true;
39490
+ else if (["-C", "-A", "-B", "--context", "--after-context", "--before-context"].includes(argument)) {
39491
+ const count = args[++index];
39492
+ if (count === undefined || !/^\d+$/.test(count))
39493
+ return;
39494
+ const value = Number(count);
39495
+ if (argument === "-C" || argument === "--context") {
39496
+ beforeContext = value;
39497
+ afterContext = value;
39498
+ } else if (argument === "-A" || argument === "--after-context")
39499
+ afterContext = value;
39500
+ else
39501
+ beforeContext = value;
39502
+ } else if (/^-[CAB]\d+$/.test(argument)) {
39503
+ const value = Number(argument.slice(2));
39504
+ if (argument[1] === "C") {
39505
+ beforeContext = value;
39506
+ afterContext = value;
39507
+ } else if (argument[1] === "A")
39508
+ afterContext = value;
39509
+ else
39510
+ beforeContext = value;
39511
+ } else if (/^--(?:context|after-context|before-context)=\d+$/.test(argument)) {
39512
+ const value = Number(argument.slice(argument.indexOf("=") + 1));
39513
+ if (argument.startsWith("--context=")) {
39514
+ beforeContext = value;
39515
+ afterContext = value;
39516
+ } else if (argument.startsWith("--after-context="))
39517
+ afterContext = value;
39518
+ else
39519
+ beforeContext = value;
39520
+ } else if (!["-i", "--ignore-case", "-F", "--fixed-strings", "-w", "--word-regexp"].includes(argument))
39521
+ return;
39522
+ }
39523
+ if (operands === 0)
39524
+ return;
39525
+ return {
39526
+ family: "grep",
39527
+ executable,
39528
+ grepMode: { heading, lineNumber, beforeContext, afterContext }
39529
+ };
39530
+ }
39531
+ function direct(executable, args) {
39532
+ if (executable.length === 0)
39533
+ return;
39534
+ if (executable === "rg" || executable === "grep")
39535
+ return classifyGrep(executable, args);
39536
+ const subcommand = args[0];
39537
+ if (executable === "git") {
39538
+ if (subcommand === "diff")
39539
+ return { family: "git-diff", executable, subcommand };
39540
+ if (subcommand === "status")
39541
+ return { family: "git-status", executable, subcommand };
39542
+ if (subcommand === "log")
39543
+ return { family: "git-log", executable, subcommand };
39544
+ if (["branch", "switch", "checkout", "push", "pull", "fetch"].includes(subcommand ?? ""))
39545
+ return { family: "git-operation", executable, subcommand: subcommand ?? "" };
39546
+ if (subcommand === "ls-files")
39547
+ return { family: "path-list", executable, subcommand };
39548
+ }
39549
+ if (executable === "docker" && (subcommand === "build" || subcommand === "buildx" && args[1] === "build" || subcommand === "compose" && args[1] === "build"))
39550
+ return { family: "docker-build", executable, subcommand };
39551
+ if (executable === "tree") {
39552
+ const options = args.filter((argument) => argument.startsWith("-"));
39553
+ if (options.some((option) => option !== "-F" && option !== "--classify"))
39554
+ return;
39555
+ return {
39556
+ family: "tree-output",
39557
+ executable,
39558
+ ...options.length === 0 ? {} : { subcommand: "classified" }
39559
+ };
39560
+ }
39561
+ if (executable === "ls") {
39562
+ const options = args.filter((arg) => arg.startsWith("-"));
39563
+ if (options.some((option) => !/^-+[alRh]+$/.test(option)))
39564
+ return;
39565
+ const recursive = options.some((option) => option.includes("R"));
39566
+ const long = options.some((option) => option.includes("l"));
39567
+ if (!recursive && !long)
39568
+ return;
39569
+ return {
39570
+ family: "tree-output",
39571
+ executable,
39572
+ subcommand: recursive ? long ? "recursive-long" : "recursive-plain" : "long"
39573
+ };
39574
+ }
39575
+ if (["find", "glob"].includes(executable))
39576
+ return { family: "path-list", executable };
39577
+ if (["sed", "cat", "head", "tail", "awk", "nl"].includes(executable))
39578
+ return { family: "numbered-read", executable };
39579
+ if (executable === "tsc" || executable === "eslint" || executable === "golangci-lint" || executable === "biome" && ["check", "lint"].includes(subcommand ?? "") || executable === "ruff" && subcommand === "check" || executable === "cargo" && subcommand === "clippy")
39580
+ return {
39581
+ family: "lint-output",
39582
+ executable,
39583
+ ...subcommand === undefined ? {} : { subcommand }
39584
+ };
39585
+ if (["vitest", "jest", "pytest"].includes(executable) || executable === "go" && subcommand === "test")
39586
+ return {
39587
+ family: "test-output",
39588
+ executable,
39589
+ ...subcommand === undefined ? {} : { subcommand }
39590
+ };
39591
+ if (executable === "bun" && ["add", "install", "update", "remove"].includes(subcommand ?? "") || executable === "npm" && ["install", "update", "audit"].includes(subcommand ?? "") || executable === "pnpm" && ["install", "update"].includes(subcommand ?? "") || executable === "yarn" && ["install", "up"].includes(subcommand ?? "") || executable === "cargo" && ["add", "update", "fetch"].includes(subcommand ?? "") || executable === "pip" && subcommand === "install" || executable === "uv" && ["sync", "add", "remove"].includes(subcommand ?? ""))
39592
+ return { family: "package-output", executable, subcommand: subcommand ?? "" };
39593
+ if (executable === "bun" && subcommand === "test" || executable === "npm" && subcommand === "test" || executable === "cargo" && subcommand === "test")
39594
+ return { family: "test-output", executable, subcommand };
39595
+ if (executable === "bun" && subcommand === "build" || executable === "cargo" && ["build", "check"].includes(subcommand ?? ""))
39596
+ return { family: "build-output", executable, subcommand: subcommand ?? "" };
39597
+ return;
39598
+ }
39599
+ function classifyCommand(command) {
39600
+ const tokens2 = tokenize(command);
39601
+ if (tokens2 === undefined)
39602
+ return;
39603
+ const words = unwrap(tokens2);
39604
+ if (words === undefined)
39605
+ return;
39606
+ if (words.some((word) => UNSUPPORTED_OUTPUT.has(word) || /^(?:--format|--output-format|--reporter)=/.test(word)))
39607
+ return;
39608
+ for (let index = 0;index < words.length; index++) {
39609
+ if (!["--format", "--output-format", "--reporter"].includes(words[index] ?? ""))
39610
+ continue;
39611
+ if (words[index + 1] === undefined)
39612
+ return;
39613
+ return;
39614
+ }
39615
+ const executable = words[0];
39616
+ if (executable === undefined)
39617
+ return;
39618
+ if (executable === "bun" && words[1] === "run" || executable === "npm" && words[1] === "run") {
39619
+ let index = 2;
39620
+ if (words[index] === "--")
39621
+ index++;
39622
+ const script = words[index];
39623
+ return script === undefined || script.length === 0 ? undefined : { family: scriptFamily(script), executable, subcommand: "run" };
39624
+ }
39625
+ if (executable === "bun" && words[1] === "x" || executable === "bunx") {
39626
+ let index = executable === "bun" ? 2 : 1;
39627
+ let sawBun = false;
39628
+ let sawSeparator = false;
39629
+ while (words[index]?.startsWith("-")) {
39630
+ const option = words[index++];
39631
+ if (option === "--bun" && !sawBun && !sawSeparator)
39632
+ sawBun = true;
39633
+ else if (option === "--" && !sawSeparator)
39634
+ sawSeparator = true;
39635
+ else
39636
+ return;
39637
+ }
39638
+ const wrapped = words[index];
39639
+ return wrapped === undefined || wrapped.length === 0 || wrapped === "--" ? undefined : direct(wrapped, words.slice(index + 1));
39640
+ }
39641
+ if (executable === "npx") {
39642
+ let index = 1;
39643
+ let sawYes = false;
39644
+ let sawSeparator = false;
39645
+ while (words[index]?.startsWith("-")) {
39646
+ const option = words[index++];
39647
+ if ((option === "--yes" || option === "-y") && !sawYes && !sawSeparator)
39648
+ sawYes = true;
39649
+ else if (option === "--" && !sawSeparator)
39650
+ sawSeparator = true;
39651
+ else
39652
+ return;
39653
+ }
39654
+ const wrapped = words[index];
39655
+ return wrapped === undefined || wrapped.length === 0 || wrapped === "--" ? undefined : direct(wrapped, words.slice(index + 1));
39656
+ }
39657
+ return direct(executable, words.slice(1));
39658
+ }
39659
+
39660
+ // packages/rtk/src/detect.ts
39661
+ function distinctRows(lines, patterns) {
39662
+ const rows = new Set;
39663
+ for (let index = 0;index < lines.length; index++)
39664
+ if (patterns.some((pattern) => pattern.test(lines[index] ?? "")))
39665
+ rows.add(index);
39666
+ return rows;
39667
+ }
39668
+ function inferBuildOrTest(lines) {
39669
+ const bunBuildA = distinctRows(lines, [/^\$?\s*bun (?:run|build)\b/, /^bun build v/]);
39670
+ const bunBuildB = distinctRows(lines, [
39671
+ /^(?:Bundled |Build (?:completed|failed)|\S+\.(?:js|css|map)\s+\d)/
39672
+ ]);
39673
+ if ([...bunBuildA].some((row) => [...bunBuildB].some((other) => other !== row)))
39674
+ return "build-output";
39675
+ const cargoA = distinctRows(lines, [/^(?:Compiling |Checking |\$?\s*cargo (?:build|check)\b)/]);
39676
+ const cargoB = distinctRows(lines, [
39677
+ /^Finished .+ target/,
39678
+ /^(?:error|warning)\[[A-Z]\d+\]:/,
39679
+ /^\s*--> \S+:\d+:\d+/
39680
+ ]);
39681
+ if ([...cargoA].some((row) => [...cargoB].some((other) => other !== row)))
39682
+ return "build-output";
39683
+ const compiler = distinctRows(lines, [/^\S.+:\d+:\d+.*(?:error|warning).*(?:TS\d+|[A-Z]\d+)/]);
39684
+ const buildSummary = distinctRows(lines, [
39685
+ /^(?:Build|Compilation).*(?:failed|completed|errors?)/
39686
+ ]);
39687
+ if (compiler.size >= 2 || [...compiler].some((row) => [...buildSummary].some((other) => other !== row)))
39688
+ return "build-output";
39689
+ const bunTestA = distinctRows(lines, [/^(?:bun test v|vitest|jest|PASS |FAIL |Test Files)/i]);
39690
+ const bunTestB = distinctRows(lines, [
39691
+ /^(?:\d+ (?:pass|fail)|Ran \d+ tests?|Tests?:|Test Files)/
39692
+ ]);
39693
+ if ([...bunTestA].some((row) => [...bunTestB].some((other) => other !== row)))
39694
+ return "test-output";
39695
+ const pytestA = distinctRows(lines, [/^={2,} test session starts/, /^collected \d+ items/]);
39696
+ const pytestB = distinctRows(lines, [/^={2,} short test summary/, /\d+ (?:passed|failed|error)/]);
39697
+ if ([...pytestA].some((row) => [...pytestB].some((other) => other !== row)))
39698
+ return "test-output";
39699
+ const goA = distinctRows(lines, [/^=== RUN /, /^\$?\s*go test\b/]);
39700
+ const goB = distinctRows(lines, [/^--- (?:PASS|FAIL):/, /^(?:ok|FAIL)\s+\S/]);
39701
+ if ([...goA].some((row) => [...goB].some((other) => other !== row)))
39702
+ return "test-output";
39703
+ return;
39704
+ }
39705
+
39706
+ // packages/rtk/src/filters/shared.ts
39707
+ var MAX_OUTPUT = 250000;
39708
+
39709
+ class ParserBudget {
39710
+ inputCodeUnits;
39711
+ records = 0;
39712
+ codeUnits = 0;
39713
+ constructor(inputCodeUnits) {
39714
+ this.inputCodeUnits = inputCodeUnits;
39715
+ }
39716
+ chargeRecords(count) {
39717
+ this.records += count;
39718
+ return this.records <= 1e5;
39719
+ }
39720
+ chargeCodeUnits(count) {
39721
+ this.codeUnits += count;
39722
+ return this.codeUnits <= this.inputCodeUnits * 3;
39723
+ }
39724
+ }
39725
+ function scanText(text) {
39726
+ const lines = [];
39727
+ const budget = new ParserBudget(text.length);
39728
+ let start = 0;
39729
+ for (let index = 0;index < text.length; index++) {
39730
+ const code = text.charCodeAt(index);
39731
+ if (code !== 10 && code !== 13)
39732
+ continue;
39733
+ if (!budget.chargeRecords(1))
39734
+ return;
39735
+ const line2 = text.slice(start, index);
39736
+ if (!budget.chargeCodeUnits(line2.length))
39737
+ return;
39738
+ lines.push(line2);
39739
+ if (code === 13 && text.charCodeAt(index + 1) === 10)
39740
+ index++;
39741
+ start = index + 1;
39742
+ }
39743
+ if (!budget.chargeRecords(1))
39744
+ return;
39745
+ const line = text.slice(start);
39746
+ if (!budget.chargeCodeUnits(line.length))
39747
+ return;
39748
+ lines.push(line);
39749
+ return { text, lines, budget };
39750
+ }
39751
+ function renderGaps(input, selected, describe3) {
39752
+ const output = [];
39753
+ if (!input.budget.chargeRecords(selected.size))
39754
+ return;
39755
+ let previous = -1;
39756
+ for (const index of [...selected].sort((left, right) => left - right)) {
39757
+ if (previous >= 0 && index > previous + 1) {
39758
+ const marker = describe3(previous + 1, index - 1);
39759
+ if (marker !== undefined) {
39760
+ if (!input.budget.chargeCodeUnits(marker.length))
39761
+ return;
39762
+ output.push(marker);
39763
+ }
39764
+ }
39765
+ const line = input.lines[index];
39766
+ if (line !== undefined) {
39767
+ if (!input.budget.chargeCodeUnits(line.length))
39768
+ return;
39769
+ output.push(line);
39770
+ }
39771
+ previous = index;
39772
+ }
39773
+ return output.join(`
39774
+ `);
39775
+ }
39776
+ function renderSelection(input, selected, unit = "lines") {
39777
+ return renderGaps(input, selected, (start, end) => `... ${end - start + 1} ${unit} omitted ...`);
39778
+ }
39779
+ function selectBlock(input, selected, block) {
39780
+ const count = block.end - block.start + 1;
39781
+ if (!input.budget.chargeRecords(count))
39782
+ return false;
39783
+ for (let index = block.start;index <= block.end; index++)
39784
+ selected.add(index);
39785
+ return true;
39786
+ }
39787
+ function diagnosticBlocks(input, primary) {
39788
+ const starts = [];
39789
+ for (let index = 0;index < input.lines.length; index++) {
39790
+ if (!primary.test(input.lines[index] ?? ""))
39791
+ continue;
39792
+ if (!input.budget.chargeRecords(1))
39793
+ return;
39794
+ starts.push(index);
39795
+ }
39796
+ const blocks = [];
39797
+ for (let offset = 0;offset < starts.length; offset++) {
39798
+ const start = starts[offset];
39799
+ if (start === undefined || !input.budget.chargeRecords(1))
39800
+ return;
39801
+ const next = starts[offset + 1] ?? input.lines.length;
39802
+ let end = start;
39803
+ while (end + 1 < next) {
39804
+ const line = input.lines[end + 1] ?? "";
39805
+ if (!/^(?:\s|\||\^|~|help:|note:|=|-->|Caused by:|at\s|detail$)/.test(line))
39806
+ break;
39807
+ end++;
39808
+ }
39809
+ const header = input.lines[start] ?? "";
39810
+ blocks.push({
39811
+ start,
39812
+ end,
39813
+ severity: /\bwarning\b/i.test(header) ? "warning" : "error",
39814
+ identity: header
39815
+ });
39816
+ }
39817
+ return blocks;
39818
+ }
39819
+
39820
+ // packages/rtk/src/filters/build.ts
39821
+ var DIAGNOSTIC = /^(?:[^\n]+:\d+:\d+.*(?:error|warning)|(?:error|warning)(?:\[[^\]]+\])?:|panic:|\s*--> \S+:\d+:\d+)/i;
39822
+ var SEMANTIC = /^(?:bun build v|Compiling \S|Checking \S|Downloading \S|Downloaded \S|Running `.+`|Finished .+ target|Build (?:completed|failed)|Bundled |\S*(?:dist|build|target)[/\\]\S+|\S+\.(?:js|css|map|wasm)\s+\d|sourcemap)/i;
39823
+ var PROGRESS = /^progress \d+$|^(?:Compiling|Downloading) repeated\b/i;
39824
+ var CONTINUATION = /^(?:\s|\||\^|~|help:|note:|Caused by:|at\s)/;
39825
+ function compressBuild(input) {
39826
+ const { text, lines } = input;
39827
+ const selected = new Set;
39828
+ const compileRows = new Set;
39829
+ let inDiagnostic = false;
39830
+ for (let index = 0;index < lines.length; index++) {
39831
+ const line = lines[index] ?? "";
39832
+ if (line.length === 0 || PROGRESS.test(line)) {
39833
+ if (/^(?:Compiling|Downloading) repeated/.test(line))
39834
+ compileRows.add(index);
39835
+ continue;
39836
+ }
39837
+ if (DIAGNOSTIC.test(line))
39838
+ inDiagnostic = true;
39839
+ else if (inDiagnostic && CONTINUATION.test(line)) {
39840
+ selected.add(index);
39841
+ continue;
39842
+ } else
39843
+ inDiagnostic = false;
39844
+ if (!DIAGNOSTIC.test(line) && !SEMANTIC.test(line))
39845
+ return text;
39846
+ if (!input.budget.chargeRecords(1))
39847
+ return text;
39848
+ selected.add(index);
39849
+ }
39850
+ if (selected.size === 0 || !lines.some((line) => /^(?:Finished|Build |Bundled )/.test(line)))
39851
+ return text;
39852
+ let rendered = renderGaps(input, selected, (start, end) => {
39853
+ let compile2 = 0;
39854
+ for (let index = start;index <= end; index++)
39855
+ if (compileRows.has(index))
39856
+ compile2++;
39857
+ const others = end - start + 1 - compile2;
39858
+ const parts = [];
39859
+ if (compile2 > 0)
39860
+ parts.push(`... ${compile2} compile/download rows omitted ...`);
39861
+ if (others > 0)
39862
+ parts.push(`... ${others} lines omitted ...`);
39863
+ return parts.length === 0 ? undefined : parts.join(`
39864
+ `);
39865
+ });
39866
+ if (rendered === undefined)
39867
+ return text;
39868
+ const indexes = [...selected];
39869
+ const first = Math.min(...indexes);
39870
+ const last = Math.max(...indexes);
39871
+ const describeOutside = (from, to) => {
39872
+ let compile2 = 0;
39873
+ for (let index = from;index < to; index++)
39874
+ if (compileRows.has(index))
39875
+ compile2++;
39876
+ const others = to - from - compile2;
39877
+ const parts = [];
39878
+ if (compile2 > 0)
39879
+ parts.push(`... ${compile2} compile/download rows omitted ...`);
39880
+ if (others > 0)
39881
+ parts.push(`... ${others} lines omitted ...`);
39882
+ return parts.length === 0 ? undefined : parts.join(`
39883
+ `);
39884
+ };
39885
+ const leading = describeOutside(0, first);
39886
+ const trailing = describeOutside(last + 1, lines.length);
39887
+ if (leading !== undefined)
39888
+ rendered = `${leading}
39889
+ ${rendered}`;
39890
+ if (trailing !== undefined)
39891
+ rendered = `${rendered}
39892
+ ${trailing}`;
39893
+ return rendered.length > MAX_OUTPUT ? text : rendered;
39894
+ }
39895
+
39896
+ // packages/rtk/src/filters/diagnostics.ts
39897
+ var PRIMARY = /^(?:[^\n]+\(\d+,\d+\):\s+(?:error|warning)\s+TS\d+:|[^\n]+:\d+:\d+(?::|\s).+|[^\n]+\n\s*\d+:\d+\s+(?:error|warning)\s|\s*\d+:\d+\s+(?:error|warning)\s|(?:error|warning)(?:\[[^\]]+\])?:)/i;
39898
+ var SUMMARY = /(?:Found \d+ errors?(?: and \d+ warnings?)?(?: in \d+ files?)?|\d+ problems?(?: \([^)\n]*\))?|Checked \d+ files?|could not compile|\d+ issues?)\.?$/i;
39899
+ function compressDiagnostics(input) {
39900
+ const { text, lines } = input;
39901
+ const blocks = diagnosticBlocks(input, PRIMARY);
39902
+ if (blocks === undefined || blocks.length === 0)
39903
+ return text;
39904
+ const summary = lines.findLastIndex((line) => SUMMARY.test(line));
39905
+ if (summary < 0)
39906
+ return text;
39907
+ const selected = new Set([0, summary]);
39908
+ const errors4 = blocks.filter((block) => block.severity === "error");
39909
+ const warningByIdentity = new Map;
39910
+ for (const block of blocks)
39911
+ if (block.severity === "warning" && !warningByIdentity.has(block.identity))
39912
+ warningByIdentity.set(block.identity, block);
39913
+ const warnings = [...warningByIdentity.values()];
39914
+ for (const block of [...errors4, ...warnings.slice(0, 20)])
39915
+ if (!selectBlock(input, selected, block))
39916
+ return text;
39917
+ const omittedWarningRows = new Set;
39918
+ const omittedWarningStarts = new Set;
39919
+ for (const block of warnings.slice(20)) {
39920
+ if (!input.budget.chargeRecords(block.end - block.start + 1))
39921
+ return text;
39922
+ let whole = true;
39923
+ for (let index = block.start;index <= block.end; index++)
39924
+ whole &&= !selected.has(index);
39925
+ if (!whole)
39926
+ continue;
39927
+ omittedWarningStarts.add(block.start);
39928
+ for (let index = block.start;index <= block.end; index++)
39929
+ omittedWarningRows.add(index);
39930
+ }
39931
+ const describe3 = (from, to) => {
39932
+ let warningBlocks = 0;
39933
+ let otherRows = 0;
39934
+ for (let index = from;index < to; index++) {
39935
+ if (omittedWarningStarts.has(index))
39936
+ warningBlocks++;
39937
+ if (!omittedWarningRows.has(index))
39938
+ otherRows++;
39939
+ }
39940
+ const parts = [];
39941
+ if (warningBlocks > 0)
39942
+ parts.push(`... ${warningBlocks} warnings omitted ...`);
39943
+ if (otherRows > 0)
39944
+ parts.push(`... ${otherRows} lines omitted ...`);
39945
+ return parts.length === 0 ? undefined : parts.join(`
39946
+ `);
39947
+ };
39948
+ let rendered = renderGaps(input, selected, (start, end) => describe3(start, end + 1));
39949
+ if (rendered === undefined)
39950
+ return text;
39951
+ const indexes = [...selected];
39952
+ const leading = describe3(0, Math.min(...indexes));
39953
+ const trailing = describe3(Math.max(...indexes) + 1, lines.length);
39954
+ if (leading !== undefined)
39955
+ rendered = `${leading}
39956
+ ${rendered}`;
39957
+ if (trailing !== undefined)
39958
+ rendered = `${rendered}
39959
+ ${trailing}`;
39960
+ if (rendered.length > MAX_OUTPUT)
39961
+ return text;
39962
+ for (const block of errors4)
39963
+ for (let index = block.start;index <= block.end; index++)
39964
+ if (!rendered.includes(lines[index] ?? ""))
39965
+ return text;
39966
+ return rendered;
39967
+ }
39968
+
39969
+ // packages/rtk/src/filters/docker.ts
39970
+ var SEMANTIC2 = /^(?:#\d+\s+(?:\[[^\]]+\].*(?:FROM|RUN|COPY|ADD|load build definition)|(?:\d+(?:\.\d+)?\s+)?(?:Dockerfile:|ERROR|error|warning|caused|Caused|failed|exit code|exporting|naming|writing|DONE|CACHED|command:|digest:|manifest|provenance))|Dockerfile:\d+|naming to |digest:|manifest |provenance |image id |Step \d+\/\d+|Successfully built|Successfully tagged|ERROR|failed to solve)/;
39971
+ var CONTINUATION2 = /^(?:#\d+\s+(?:\d+(?:\.\d+)?\s+)?\s+(?:command:|caused by|Caused by:|at\s)|\s+(?:command:|caused by|Caused by:|at\s)|Dockerfile:\d+)/;
39972
+ var PROGRESS2 = /^(?:#\d+\s+\d+(?:\.\d+)?\s+)(?:\d+% transferring|\d+(?:\.\d+)?s$)|^#\d+\s+(?:transferring|extracting|downloading)\b/i;
39973
+ function compressDocker(input) {
39974
+ const { text, lines } = input;
39975
+ const selected = new Set;
39976
+ const cached2 = new Set;
39977
+ for (let index = 0;index < lines.length; index++) {
39978
+ const line = lines[index] ?? "";
39979
+ if (line.length === 0 || PROGRESS2.test(line))
39980
+ continue;
39981
+ if (CONTINUATION2.test(line)) {
39982
+ if (selected.size === 0)
39983
+ return text;
39984
+ selected.add(index);
39985
+ continue;
39986
+ }
39987
+ if (!SEMANTIC2.test(line))
39988
+ return text;
39989
+ if (/\bCACHED\b/.test(line)) {
39990
+ const key = line.replace(/\s+\d+(?:\.\d+)?s$/, "");
39991
+ if (cached2.has(key))
39992
+ continue;
39993
+ cached2.add(key);
39994
+ }
39995
+ if (!input.budget.chargeRecords(1))
39996
+ return text;
39997
+ selected.add(index);
39998
+ }
39999
+ if (selected.size === 0)
40000
+ return text;
40001
+ let rendered = renderSelection(input, selected);
40002
+ if (rendered === undefined)
40003
+ return text;
40004
+ const indexes = [...selected];
40005
+ const leading = Math.min(...indexes);
40006
+ const trailing = lines.length - 1 - Math.max(...indexes);
40007
+ if (leading > 0)
40008
+ rendered = `... ${leading} lines omitted ...
40009
+ ${rendered}`;
40010
+ if (trailing > 0)
40011
+ rendered = `${rendered}
40012
+ ... ${trailing} lines omitted ...`;
40013
+ return rendered.length <= MAX_OUTPUT ? rendered : text;
40014
+ }
40015
+
40016
+ // packages/rtk/src/filters/git.ts
40017
+ var DIFF_HEADER_ROW = "diff --(?:git|cc|combined) ";
40018
+ var DIFF_PAIR_ROW = "(?:--- |\\+\\+\\+ |@@+ )";
40019
+ var DIFF_DETAIL_ROW = "(?:index [0-9a-f][0-9a-f,]*\\.\\.|(?:old|new|new file|deleted file) mode |mode [0-7][0-7,]*\\.\\.|(?:similarity|dissimilarity) index |(?:rename|copy) (?:from|to) |Binary files |GIT binary patch$|(?:literal|delta) \\d+$|\\\\ No newline|[ +-]*[-+]| .+files? changed)";
40020
+ var LOG_COMMIT_ROW = "commit [0-9a-f]{4,}(?: \\(|$)";
40021
+ var LOG_BODY_ROW = "(?:Author:|Date:| {4}[ \\t]*\\S)";
40022
+ var LOG_DETAIL_ROW = "(?:Merge: |AuthorDate:|Commit:|CommitDate:|Reflog:|Tag:| \\S.*\\|\\s+\\d+| .+files? changed)";
40023
+ var LOG_SEPARATOR_ROW = "\\s*$";
40024
+ var GIT_DIFF_ANCHOR = new RegExp(`^(?:${DIFF_HEADER_ROW}|${DIFF_PAIR_ROW}|${DIFF_DETAIL_ROW})`);
40025
+ var GIT_LOG_ANCHOR = new RegExp(`^(?:${LOG_COMMIT_ROW}|${LOG_BODY_ROW}|${LOG_DETAIL_ROW}|${LOG_SEPARATOR_ROW})`);
40026
+ var GIT_DIFF_EVIDENCE_HEADER = new RegExp(`^${DIFF_HEADER_ROW}`, "m");
40027
+ var GIT_DIFF_EVIDENCE_PAIR = new RegExp(`^${DIFF_PAIR_ROW}`, "m");
40028
+ var GIT_LOG_EVIDENCE_COMMIT = new RegExp(`^${LOG_COMMIT_ROW}`, "m");
40029
+ var GIT_LOG_EVIDENCE_BODY = new RegExp(`^${LOG_BODY_ROW}`, "m");
40030
+ var SEMANTIC3 = /^(?:\* |\+ | {2}|Already on|Switched to|Your branch|HEAD is now|From |To |!?\s*\[| \* | - |error:|fatal:|CONFLICT|Everything up-to-date|Updating |Fast-forward|remote:|## |On branch|rebase |merge |cherry-pick |revert |bisect |[0-9a-f]+\.\.[0-9a-f]+\s+\S+\s+->\s+\S+|\s+\S.+\|\s+\d+|\s+\d+ files? changed|Automatic merge failed|\s+(?:modified|deleted|new file|renamed|copied):)/;
40031
+ var PROGRESS3 = /^(?:remote: )?(?:Enumerating|Counting|Compressing|Receiving|Resolving|Writing) objects|^(?:remote: )?Total \d+|^\s*\d+% \(|^(?:remote )?progress \d+$/;
40032
+ function compressGitOperation(input) {
40033
+ const { text, lines } = input;
40034
+ const selected = new Set;
40035
+ for (let index = 0;index < lines.length; index++) {
40036
+ const line = lines[index] ?? "";
40037
+ if (line.length === 0 || PROGRESS3.test(line))
40038
+ continue;
40039
+ if (!SEMANTIC3.test(line))
40040
+ return text;
40041
+ selected.add(index);
40042
+ }
40043
+ if (selected.size === 0)
40044
+ return text;
40045
+ let rendered = renderSelection(input, selected);
40046
+ if (rendered === undefined)
40047
+ return text;
40048
+ const indexes = [...selected];
40049
+ const leading = Math.min(...indexes);
40050
+ const trailing = lines.length - 1 - Math.max(...indexes);
40051
+ if (leading > 0)
40052
+ rendered = `... ${leading} lines omitted ...
40053
+ ${rendered}`;
40054
+ if (trailing > 0)
40055
+ rendered = `${rendered}
40056
+ ... ${trailing} lines omitted ...`;
40057
+ return rendered.length <= MAX_OUTPUT ? rendered : text;
40058
+ }
40059
+
40060
+ // packages/rtk/src/filters/listings.ts
40061
+ var LONG = /^[bcdlps-][rwxStTs-]{9}\s+\d+\s+\S+\s+\S+\s+\d+\s+\S+\s+\d+\s+(?:\d{2}:\d{2}|\d{4})\s+.+$/;
40062
+ var SUMMARY2 = /^\d+ director(?:y|ies), \d+ files?$/;
40063
+ var TREE_ROW = /^((?:\u2502 {3}| {4})*)(\u251C\u2500\u2500 |\u2514\u2500\u2500 )(.+)$/;
40064
+ function renderGroups(input, groups) {
40065
+ const output = [];
40066
+ let omittedGroups = 0;
40067
+ let omittedEntries = 0;
40068
+ const append = (fragment) => {
40069
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(fragment.length))
40070
+ return false;
40071
+ output.push(fragment);
40072
+ return true;
40073
+ };
40074
+ const flushOmitted = () => {
40075
+ if (omittedGroups === 0)
40076
+ return true;
40077
+ const marker = `... ${omittedGroups} ${omittedGroups === 1 ? "directory" : "directories"} omitted containing ${omittedEntries} ${omittedEntries === 1 ? "entry" : "entries"} ...`;
40078
+ omittedGroups = 0;
40079
+ omittedEntries = 0;
40080
+ return append(marker);
40081
+ };
40082
+ for (let groupIndex = 0;groupIndex < groups.length; groupIndex++) {
40083
+ const group = groups[groupIndex];
40084
+ if (group === undefined || !input.budget.chargeRecords(1))
40085
+ return;
40086
+ const retain = groups.length <= 40 || groupIndex < 20 || groupIndex >= groups.length - 20;
40087
+ if (!retain) {
40088
+ omittedGroups++;
40089
+ omittedEntries += group.entryCount;
40090
+ continue;
40091
+ }
40092
+ if (!flushOmitted())
40093
+ return;
40094
+ const prefixCount = group.rows.length - group.entryCount;
40095
+ for (let rowIndex = 0;rowIndex < group.rows.length; rowIndex++) {
40096
+ const row = group.rows[rowIndex];
40097
+ if (row === undefined || !input.budget.chargeRecords(1))
40098
+ return;
40099
+ const entryIndex = rowIndex - prefixCount;
40100
+ const retainEntry = entryIndex < 0 || group.entryCount <= 12 || entryIndex < 6 || entryIndex >= group.entryCount - 6;
40101
+ if (retainEntry && !append(row))
40102
+ return;
40103
+ }
40104
+ if (group.entryCount > 12) {
40105
+ const count = group.entryCount - 12;
40106
+ if (!append(`... ${count} ${count === 1 ? "entry" : "entries"} omitted from ${group.key} ...`))
40107
+ return;
40108
+ }
40109
+ }
40110
+ if (!flushOmitted())
40111
+ return;
40112
+ const rendered = output.join(`
40113
+ `);
40114
+ return rendered.length <= MAX_OUTPUT ? rendered : undefined;
40115
+ }
40116
+ function subtreeCounts(input, node, classified) {
40117
+ if (!input.budget.chargeRecords(1))
40118
+ return;
40119
+ if (node.children.length === 0)
40120
+ return {
40121
+ directories: node.classifiedDirectory ? 1 : 0,
40122
+ entries: node.classifiedDirectory ? 0 : 1,
40123
+ ambiguous: !classified
40124
+ };
40125
+ let directories = 1;
40126
+ let entries = 0;
40127
+ let ambiguous = false;
40128
+ for (const child of node.children) {
40129
+ const count = subtreeCounts(input, child, classified);
40130
+ if (count === undefined)
40131
+ return;
40132
+ directories += count.directories;
40133
+ entries += count.entries;
40134
+ ambiguous ||= count.ambiguous;
40135
+ }
40136
+ return { directories, entries, ambiguous };
40137
+ }
40138
+ function appendSubtree(input, output, node, classified) {
40139
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(node.line.length))
40140
+ return false;
40141
+ output.push(node.line);
40142
+ const retainedValues = node.children.length <= 12 ? node.children : [...node.children.slice(0, 6), ...node.children.slice(-6)];
40143
+ if (!input.budget.chargeRecords(retainedValues.length))
40144
+ return false;
40145
+ const retained = new Set(retainedValues);
40146
+ let omitted = [];
40147
+ const flushOmitted = () => {
40148
+ if (omitted.length === 0)
40149
+ return true;
40150
+ let directories = 0;
40151
+ let entries = 0;
40152
+ let ambiguous = false;
40153
+ for (const child of omitted) {
40154
+ const count = subtreeCounts(input, child, classified);
40155
+ if (count === undefined)
40156
+ return false;
40157
+ directories += count.directories;
40158
+ entries += count.entries;
40159
+ ambiguous ||= count.ambiguous;
40160
+ }
40161
+ if (ambiguous)
40162
+ return false;
40163
+ const marker = directories === 0 ? `... ${entries} ${entries === 1 ? "entry" : "entries"} omitted from ${node.key} ...` : `... ${directories} ${directories === 1 ? "directory" : "directories"} omitted containing ${entries} ${entries === 1 ? "entry" : "entries"} ...`;
40164
+ if (!input.budget.chargeCodeUnits(marker.length))
40165
+ return false;
40166
+ output.push(marker);
40167
+ omitted = [];
40168
+ return true;
40169
+ };
40170
+ for (const child of node.children) {
40171
+ if (!input.budget.chargeRecords(1))
40172
+ return false;
40173
+ if (!retained.has(child)) {
40174
+ omitted.push(child);
40175
+ continue;
40176
+ }
40177
+ if (!flushOmitted() || !appendSubtree(input, output, child, classified))
40178
+ return false;
40179
+ }
40180
+ return flushOmitted();
40181
+ }
40182
+ function tree(input, lines, classified) {
40183
+ const root = lines[0];
40184
+ const summary = lines.at(-1);
40185
+ if (lines.length < 3 || root === undefined || /[\u2502\u251C\u2514]/.test(root) || summary === undefined || !SUMMARY2.test(summary))
40186
+ return input.text;
40187
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(root.length))
40188
+ return input.text;
40189
+ const rootNode = { key: root, line: root, classifiedDirectory: true, children: [] };
40190
+ const stack = [rootNode];
40191
+ for (const line of lines.slice(1, -1)) {
40192
+ const match = line.match(TREE_ROW);
40193
+ const depth = (match?.[1]?.length ?? -1) / 4;
40194
+ const parent = stack[depth];
40195
+ const name = match?.[3];
40196
+ if (!Number.isInteger(depth) || parent === undefined || name === undefined)
40197
+ return input.text;
40198
+ const plainName = name.replace(/ -> .+$/, "").replace(/[/@*=>|]$/, "");
40199
+ const key = `${parent.key}/${plainName}`;
40200
+ if (!input.budget.chargeRecords(3) || !input.budget.chargeCodeUnits(key.length))
40201
+ return input.text;
40202
+ const node = {
40203
+ key,
40204
+ line,
40205
+ classifiedDirectory: classified && name.endsWith("/"),
40206
+ children: []
40207
+ };
40208
+ parent.children.push(node);
40209
+ stack.length = depth + 1;
40210
+ stack.push(node);
40211
+ }
40212
+ const output = [];
40213
+ if (!appendSubtree(input, output, rootNode, classified))
40214
+ return input.text;
40215
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(summary.length))
40216
+ return input.text;
40217
+ output.push(summary);
40218
+ const rendered = output.join(`
40219
+ `);
40220
+ return rendered.length <= MAX_OUTPUT ? rendered : input.text;
40221
+ }
40222
+ function recursiveLs(input, long) {
40223
+ const groups = [];
40224
+ let current;
40225
+ let sawTotal = false;
40226
+ for (const line of input.lines) {
40227
+ if (line.length === 0)
40228
+ continue;
40229
+ if (/^.+:$/.test(line)) {
40230
+ if (current !== undefined && (long && !sawTotal || current.entryCount === 0))
40231
+ return input.text;
40232
+ const key = line.slice(0, -1);
40233
+ if (!input.budget.chargeRecords(3) || !input.budget.chargeCodeUnits(key.length + line.length))
40234
+ return input.text;
40235
+ current = { key, rows: [line], entryCount: 0 };
40236
+ groups.push(current);
40237
+ sawTotal = false;
40238
+ continue;
40239
+ }
40240
+ if (current === undefined)
40241
+ return input.text;
40242
+ if (/^total \d+$/.test(line)) {
40243
+ if (!long || sawTotal || current.entryCount > 0)
40244
+ return input.text;
40245
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(line.length))
40246
+ return input.text;
40247
+ current.rows.push(line);
40248
+ sawTotal = true;
40249
+ continue;
40250
+ }
40251
+ if (long && (!sawTotal || !LONG.test(line)) || !long && !/^[^/\\:\n]+$/.test(line))
40252
+ return input.text;
40253
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(line.length))
40254
+ return input.text;
40255
+ current.rows.push(line);
40256
+ current.entryCount++;
40257
+ }
40258
+ if (current === undefined || long && !sawTotal || current.entryCount === 0)
40259
+ return input.text;
40260
+ return renderGroups(input, groups) ?? input.text;
40261
+ }
40262
+ var RELATIVE_PATH = /^(?![[{`|])(?!.+:\d+(?::|$))[^\s:\n]+(?:[/\\][^\s:\n]+)*$/;
40263
+ var GATED_PROSE = /\s(?:is|are|the|this|that|because|and|with|from|into|were)\s/i;
40264
+ var GATED_TABLE = /^\|.*\|$/;
40265
+ var GATED_STRUCTURE = /^(?:```|\{|\[|`|\|)/;
40266
+ var GATED_DRIVE = /^[A-Za-z]:[/\\]/;
40267
+ function hasIllegalControl(line) {
40268
+ for (let index = 0;index < line.length; index++) {
40269
+ const code = line.charCodeAt(index);
40270
+ if (code === 9)
40271
+ continue;
40272
+ if (code < 32 || code === 127)
40273
+ return true;
40274
+ }
40275
+ return false;
40276
+ }
40277
+ function gatedPath(line) {
40278
+ if (line.length === 0 || hasIllegalControl(line))
40279
+ return false;
40280
+ if (line !== line.trim())
40281
+ return false;
40282
+ if (GATED_STRUCTURE.test(line) || GATED_TABLE.test(line) || GATED_PROSE.test(line))
40283
+ return false;
40284
+ const drive = GATED_DRIVE.test(line);
40285
+ if (line.indexOf(":", drive ? 2 : 0) >= 0)
40286
+ return false;
40287
+ const separator = line.search(/[/\\]/);
40288
+ if (separator < 0)
40289
+ return !/\s/.test(line);
40290
+ return !/\s/.test(line.slice(0, separator));
40291
+ }
40292
+ function paths(input, commandGated) {
40293
+ const groups = new Map;
40294
+ const ordered = [];
40295
+ for (const line of input.lines) {
40296
+ if (line.length === 0)
40297
+ continue;
40298
+ if (!(commandGated ? gatedPath(line) : RELATIVE_PATH.test(line)))
40299
+ return input.text;
40300
+ const separator = Math.max(line.lastIndexOf("/"), line.lastIndexOf("\\"));
40301
+ const key = separator < 0 ? "." : line.slice(0, separator) || ".";
40302
+ let group = groups.get(key);
40303
+ if (group === undefined) {
40304
+ if (!input.budget.chargeRecords(2) || !input.budget.chargeCodeUnits(key.length))
40305
+ return input.text;
40306
+ group = { key, rows: [], entryCount: 0 };
40307
+ groups.set(key, group);
40308
+ ordered.push(group);
40309
+ }
40310
+ if (!input.budget.chargeRecords(1))
40311
+ return input.text;
40312
+ group.rows.push(line);
40313
+ group.entryCount++;
40314
+ }
40315
+ if (ordered.length === 0)
40316
+ return input.text;
40317
+ return renderGroups(input, ordered) ?? input.text;
40318
+ }
40319
+ function longLs(input) {
40320
+ let header;
40321
+ const rows = [];
40322
+ for (const line of input.lines) {
40323
+ if (line.length === 0)
40324
+ continue;
40325
+ if (/^total \d+$/.test(line)) {
40326
+ if (header !== undefined || rows.length > 0)
40327
+ return input.text;
40328
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(line.length))
40329
+ return input.text;
40330
+ header = line;
40331
+ continue;
40332
+ }
40333
+ if (header === undefined || !LONG.test(line))
40334
+ return input.text;
40335
+ if (!input.budget.chargeRecords(1))
40336
+ return input.text;
40337
+ rows.push(line);
40338
+ }
40339
+ if (header === undefined || rows.length === 0)
40340
+ return input.text;
40341
+ const rendered = renderGroups(input, [{ key: ".", rows, entryCount: rows.length }]);
40342
+ if (rendered === undefined)
40343
+ return input.text;
40344
+ const output = `${header}
40345
+ ${rendered}`;
40346
+ return output.length <= MAX_OUTPUT ? output : input.text;
40347
+ }
40348
+ function nonemptyLines(input) {
40349
+ const lines = [];
40350
+ for (const line of input.lines) {
40351
+ if (line.length === 0)
40352
+ continue;
40353
+ if (!input.budget.chargeRecords(1))
40354
+ return;
40355
+ lines.push(line);
40356
+ }
40357
+ return lines;
40358
+ }
40359
+ function compressListing(input, executable, subcommand, commandGated = false) {
40360
+ if (executable === "ls" && subcommand === "recursive-long")
40361
+ return recursiveLs(input, true);
40362
+ if (executable === "ls" && subcommand === "recursive-plain")
40363
+ return recursiveLs(input, false);
40364
+ if (executable === "ls")
40365
+ return longLs(input);
40366
+ if (executable === "tree") {
40367
+ const lines = nonemptyLines(input);
40368
+ if (lines === undefined)
40369
+ return input.text;
40370
+ return tree(input, lines, subcommand === "classified");
40371
+ }
40372
+ return paths(input, commandGated);
40373
+ }
40374
+
40375
+ // packages/rtk/src/filters/packages.ts
40376
+ var MUTATION = /(?:^|\s)(?:added|removed|updated|upgraded|downgraded|installed)\s+\S|lockfile|package-lock|blocked.*script|postinstall|lifecycle|vulnerabilit|peer.*conflict|resolution.*conflict|generated\s+\S/i;
40377
+ var SUMMARY3 = /(?:installed|added|removed|updated|audited) \d+ packages?|found \d+ vulnerabilities|Saved lockfile/i;
40378
+ var PROGRESS4 = /^(?:download|Resolving|Progress:|Packages:|Fetching|Downloaded|Using cached|Collecting)\b/i;
40379
+ function diagnosticStart(line, executable) {
40380
+ const lower = line.toLowerCase();
40381
+ if (executable === "npm" && /^npm (?:warn|warning|error)\b/.test(lower))
40382
+ return lower.startsWith("npm error") ? "error" : "warning";
40383
+ if (executable === "pnpm" && /^(?:warn(?:ing)?\b|err_pnpm_|error\b)/i.test(line))
40384
+ return /^(?:err_pnpm_|error\b)/i.test(line) ? "error" : "warning";
40385
+ if (executable === "yarn" && /^YN\d{4}:/.test(line))
40386
+ return /^YN(?:0009|0018|0028):/.test(line) ? "error" : "warning";
40387
+ if (["cargo", "uv", "bun"].includes(executable) && /^(?:warning|error):/i.test(line))
40388
+ return /^error:/i.test(line) ? "error" : "warning";
40389
+ if (executable === "pip" && /^(?:WARNING|ERROR):/.test(line))
40390
+ return line.startsWith("ERROR") ? "error" : "warning";
40391
+ return;
40392
+ }
40393
+ function stableIdentity(line, executable, severity) {
40394
+ let normalized = line;
40395
+ if (executable === "npm") {
40396
+ normalized = normalized.replace(/^npm (?:warn|warning|error)\s+/i, "").replace(/^\[\d+\/\d+\]\s+/, "").replace(/^workspace\s+[^:]+:\s*/i, "");
40397
+ } else if (executable === "pnpm") {
40398
+ normalized = normalized.replace(/^(?:WARN(?:ING)?|ERR_PNPM_[A-Z_]+|ERROR)\s+/i, "");
40399
+ } else if (executable === "yarn") {
40400
+ normalized = normalized.replace(/^(YN\d{4}:)\s*(?:\[[^\]]+\]\s*)?/, "$1 ");
40401
+ } else {
40402
+ normalized = normalized.replace(/^(?:warning|error):\s*/i, "");
40403
+ }
40404
+ return `${executable}\x00${severity}\x00${normalized}`;
40405
+ }
40406
+ function blocks(input, executable) {
40407
+ const { lines } = input;
40408
+ const result = [];
40409
+ for (let index = 0;index < lines.length; index++) {
40410
+ const line = lines[index] ?? "";
40411
+ const severity = diagnosticStart(line, executable);
40412
+ if (severity === undefined) {
40413
+ if (/^(?:DIAGNOSTIC|WARN(?:ING)?|ERR(?:OR)?|npm (?!install\b)|YN\d{4}:)/i.test(line) && !PROGRESS4.test(line))
40414
+ return;
40415
+ continue;
40416
+ }
40417
+ let end = index;
40418
+ while (end + 1 < lines.length) {
40419
+ const continuation = lines[end + 1] ?? "";
40420
+ if (SUMMARY3.test(continuation) || PROGRESS4.test(continuation))
40421
+ break;
40422
+ const nextSeverity = diagnosticStart(continuation, executable);
40423
+ if (nextSeverity !== undefined) {
40424
+ const continuationMessage = continuation.replace(/^npm (?:warn|error)\s+/i, "");
40425
+ if (!/^(?:required by|While resolving|Found:|Could not resolve)/i.test(continuationMessage))
40426
+ break;
40427
+ } else if (!/^(?:\s|Caused by:|note:|help:)/i.test(continuation)) {
40428
+ break;
40429
+ }
40430
+ end++;
40431
+ }
40432
+ if (!input.budget.chargeRecords(1))
40433
+ return;
40434
+ const identity = stableIdentity(line, executable, severity);
40435
+ if (!input.budget.chargeCodeUnits(identity.length))
40436
+ return;
40437
+ result.push({ start: index, end, severity, identity });
40438
+ index = end;
40439
+ }
40440
+ return result;
40441
+ }
40442
+ function compressPackages(input, executable) {
40443
+ const { text, lines } = input;
40444
+ const parsed = blocks(input, executable);
40445
+ if (parsed === undefined)
40446
+ return text;
40447
+ const byIdentity = new Map;
40448
+ for (const block of parsed) {
40449
+ if (byIdentity.has(block.identity))
40450
+ continue;
40451
+ if (!input.budget.chargeRecords(1))
40452
+ return text;
40453
+ byIdentity.set(block.identity, block);
40454
+ }
40455
+ if (!input.budget.chargeRecords(byIdentity.size))
40456
+ return text;
40457
+ const unique = [...byIdentity.values()];
40458
+ const errors4 = unique.filter((block) => block.severity === "error");
40459
+ const warnings = unique.filter((block) => block.severity === "warning");
40460
+ const selected = new Set;
40461
+ for (const block of [...errors4, ...warnings.slice(0, 20)])
40462
+ for (let index = block.start;index <= block.end; index++) {
40463
+ if (!input.budget.chargeRecords(1))
40464
+ return text;
40465
+ selected.add(index);
40466
+ }
40467
+ const diagnosticRows = new Set;
40468
+ for (const block of parsed)
40469
+ for (let index = block.start;index <= block.end; index++) {
40470
+ if (!input.budget.chargeRecords(1))
40471
+ return text;
40472
+ diagnosticRows.add(index);
40473
+ }
40474
+ for (let index = 0;index < lines.length; index++)
40475
+ if (!diagnosticRows.has(index) && (MUTATION.test(lines[index] ?? "") || SUMMARY3.test(lines[index] ?? "")))
40476
+ selected.add(index);
40477
+ if (selected.size === 0 || !lines.some((line) => SUMMARY3.test(line)))
40478
+ return text;
40479
+ const omittedWarningRows = new Set;
40480
+ const omittedWarningStarts = new Set;
40481
+ for (const block of warnings.slice(20)) {
40482
+ if (!input.budget.chargeRecords(block.end - block.start + 1))
40483
+ return text;
40484
+ let whole = true;
40485
+ for (let index = block.start;index <= block.end; index++)
40486
+ whole &&= !selected.has(index);
40487
+ if (!whole)
40488
+ continue;
40489
+ omittedWarningStarts.add(block.start);
40490
+ for (let index = block.start;index <= block.end; index++)
40491
+ omittedWarningRows.add(index);
40492
+ }
40493
+ const describe3 = (from, to) => {
40494
+ let warningBlocks = 0;
40495
+ let otherRows = 0;
40496
+ for (let index = from;index < to; index++) {
40497
+ if (omittedWarningStarts.has(index))
40498
+ warningBlocks++;
40499
+ if (!omittedWarningRows.has(index))
40500
+ otherRows++;
40501
+ }
40502
+ const parts = [];
40503
+ if (warningBlocks > 0)
40504
+ parts.push(`... ${warningBlocks} warnings omitted ...`);
40505
+ if (otherRows > 0)
40506
+ parts.push(`... ${otherRows} lines omitted ...`);
40507
+ return parts.length === 0 ? undefined : parts.join(`
40508
+ `);
40509
+ };
40510
+ let rendered = renderGaps(input, selected, (start, end) => describe3(start, end + 1));
40511
+ if (rendered === undefined)
40512
+ return text;
40513
+ const indexes = [...selected];
40514
+ const leading = describe3(0, Math.min(...indexes));
40515
+ const trailing = describe3(Math.max(...indexes) + 1, lines.length);
40516
+ if (leading !== undefined)
40517
+ rendered = `${leading}
40518
+ ${rendered}`;
40519
+ if (trailing !== undefined)
40520
+ rendered = `${rendered}
40521
+ ${trailing}`;
40522
+ if (rendered.length > MAX_OUTPUT)
40523
+ return text;
40524
+ for (const block of errors4)
40525
+ for (let index = block.start;index <= block.end; index++)
40526
+ if (!rendered.includes(lines[index] ?? ""))
40527
+ return text;
40528
+ return rendered;
40529
+ }
40530
+
40531
+ // packages/rtk/src/filters/search.ts
40532
+ var FULL = /^((?:[A-Za-z]:\\[^\n:]+|[^\n:]+)):(\d+):(.+)$/;
40533
+ var CONTEXT = /^((?:[A-Za-z]:\\[^\n]+|[^\n]+))-(\d+)-(.+)$/;
40534
+ var HEADING_MATCH = /^\d+:.+$/;
40535
+ var HEADING_CONTEXT = /^\d+-.+$/;
40536
+ var PATH = /^(?:[A-Za-z]:\\|[./~])?[^\n:]+$/;
40537
+ function retainedRecords(group, mode) {
40538
+ const matches = group.records.flatMap((record2, index) => record2.kind === "match" ? [index] : []);
40539
+ const retained = new Set(matches.length <= 12 ? matches : [...matches.slice(0, 6), ...matches.slice(-6)]);
40540
+ const selected = new Set;
40541
+ for (const match of retained) {
40542
+ selected.add(match);
40543
+ for (let index = match - 1;index >= 0; index--) {
40544
+ const record2 = group.records[index];
40545
+ if (record2?.kind === "match")
40546
+ break;
40547
+ if (record2?.kind === "separator")
40548
+ selected.add(index);
40549
+ }
40550
+ for (let index = match + 1;index < group.records.length; index++) {
40551
+ const record2 = group.records[index];
40552
+ if (record2?.kind === "match")
40553
+ break;
40554
+ if (record2?.kind === "separator")
40555
+ selected.add(index);
40556
+ }
40557
+ let before = mode.beforeContext;
40558
+ for (let index = match - 1;index >= 0 && before > 0; index--) {
40559
+ const record2 = group.records[index];
40560
+ if (record2?.kind === "match")
40561
+ break;
40562
+ if (record2?.kind === "context")
40563
+ before--;
40564
+ if (record2 !== undefined)
40565
+ selected.add(index);
40566
+ }
40567
+ let after = mode.afterContext;
40568
+ for (let index = match + 1;index < group.records.length && after > 0; index++) {
40569
+ const record2 = group.records[index];
40570
+ if (record2?.kind === "match")
40571
+ break;
40572
+ if (record2?.kind === "context")
40573
+ after--;
40574
+ if (record2 !== undefined)
40575
+ selected.add(index);
40576
+ }
40577
+ }
40578
+ for (let index = 0;index < group.records.length; index++)
40579
+ if (group.records[index]?.kind === "heading")
40580
+ selected.add(index);
40581
+ return {
40582
+ records: group.records.filter((_2, index) => selected.has(index)),
40583
+ omittedMatches: matches.length - retained.size
40584
+ };
40585
+ }
40586
+ function render(input, groups, mode) {
40587
+ if (!input.budget.chargeRecords(groups.length))
40588
+ return;
40589
+ const base = groups.length <= 40 ? groups : [...groups.slice(0, 20), ...groups.slice(-20)];
40590
+ const retained = new Set(base);
40591
+ for (const group of groups)
40592
+ if (group.matches === 1)
40593
+ retained.add(group);
40594
+ const output = [];
40595
+ let omitted = [];
40596
+ const flushOmitted = () => {
40597
+ if (omitted.length === 0)
40598
+ return;
40599
+ const matches = omitted.reduce((sum, group) => sum + group.matches, 0);
40600
+ output.push(`... ${omitted.length} ${omitted.length === 1 ? "file" : "files"} omitted containing ${matches} ${matches === 1 ? "match" : "matches"} ...`);
40601
+ omitted = [];
40602
+ };
40603
+ for (const group of groups) {
40604
+ if (!retained.has(group)) {
40605
+ omitted.push(group);
40606
+ continue;
40607
+ }
40608
+ flushOmitted();
40609
+ const selection = retainedRecords(group, mode);
40610
+ if (!input.budget.chargeRecords(selection.records.length))
40611
+ return;
40612
+ output.push(...selection.records.map((record2) => record2.text));
40613
+ if (selection.omittedMatches > 0) {
40614
+ const unit = selection.omittedMatches === 1 ? "match" : "matches";
40615
+ output.push(`... ${selection.omittedMatches} ${unit} omitted from ${group.file} ...`);
40616
+ }
40617
+ }
40618
+ flushOmitted();
40619
+ const content = output.join(`
40620
+ `);
40621
+ return input.budget.chargeCodeUnits(content.length) && content.length <= MAX_OUTPUT ? content : undefined;
40622
+ }
40623
+ function compressGrep(input, mode) {
40624
+ const groups = new Map;
40625
+ let heading;
40626
+ let activeFile;
40627
+ let pendingSeparator = false;
40628
+ for (const line of input.lines) {
40629
+ if (line === "--") {
40630
+ if (activeFile === undefined || pendingSeparator)
40631
+ return input.text;
40632
+ pendingSeparator = true;
40633
+ continue;
40634
+ }
40635
+ if (mode.heading && PATH.test(line) && !HEADING_MATCH.test(line) && !HEADING_CONTEXT.test(line)) {
40636
+ heading = line;
40637
+ activeFile = line;
40638
+ const group2 = groups.get(line) ?? { file: line, records: [], matches: 0 };
40639
+ if (!input.budget.chargeRecords(1))
40640
+ return input.text;
40641
+ group2.records.push({ kind: "heading", text: line });
40642
+ groups.set(line, group2);
40643
+ continue;
40644
+ }
40645
+ const full = line.match(FULL);
40646
+ const context = mode.beforeContext > 0 || mode.afterContext > 0 ? line.match(CONTEXT) : null;
40647
+ const file3 = mode.heading ? heading : full?.[1] ?? context?.[1];
40648
+ const matched = mode.heading ? HEADING_MATCH.test(line) : full !== null;
40649
+ const validContext = mode.heading ? (mode.beforeContext > 0 || mode.afterContext > 0) && HEADING_CONTEXT.test(line) : context !== null;
40650
+ if (file3 === undefined || !matched && !validContext)
40651
+ return input.text;
40652
+ if (pendingSeparator && file3 !== activeFile)
40653
+ return input.text;
40654
+ const group = groups.get(file3) ?? { file: file3, records: [], matches: 0 };
40655
+ const addedRecords = pendingSeparator ? 2 : 1;
40656
+ if (!input.budget.chargeRecords(addedRecords))
40657
+ return input.text;
40658
+ if (pendingSeparator)
40659
+ group.records.push({ kind: "separator", text: "--" });
40660
+ group.records.push({ kind: matched ? "match" : "context", text: line });
40661
+ if (matched)
40662
+ group.matches++;
40663
+ groups.set(file3, group);
40664
+ activeFile = file3;
40665
+ pendingSeparator = false;
40666
+ }
40667
+ if (groups.size === 0 || pendingSeparator)
40668
+ return input.text;
40669
+ return render(input, [...groups.values()], mode) ?? input.text;
40670
+ }
40671
+
40672
+ // packages/rtk/src/filters/status.ts
40673
+ var HEADER = /^(?:## .+|On branch .+|HEAD detached at .+|HEAD detached from .+)$/;
40674
+ var OPERATION = /^(?:(?:(?:interactive )?rebase|merge|cherry-pick|revert|bisect)(?: in progress| currently|ing|ing in progress| .*)|You are currently rebasing .+|All conflicts fixed but you are still merging\.)/i;
40675
+ var CHATTER = /^ {2}\((?:use |fix conflicts|all conflicts|no commands remaining).+\)$/i;
40676
+ var RELATION = /^(?:Your branch (?:is ahead of|is behind|and .+ have diverged).*[,.]|and have \d+ and \d+ different commits each, respectively\.)$/;
40677
+ var SECTION = /^(?:Changes to be committed|Changes not staged for commit|Unmerged paths|Untracked files):$/;
40678
+ var FINAL = /^(?:nothing to commit, working tree clean|no changes added to commit .+|nothing added to commit but untracked files present .+)$/;
40679
+ var LONG_RECORD = /^\t(?:modified|deleted|new file|renamed|copied|both modified|both added|added by us|added by them|deleted by us|deleted by them):\s+.+$/;
40680
+ var XY = new Set([
40681
+ " M",
40682
+ "M ",
40683
+ "MM",
40684
+ " A",
40685
+ "A ",
40686
+ "AM",
40687
+ " D",
40688
+ "D ",
40689
+ "DM",
40690
+ " R",
40691
+ "R ",
40692
+ "RM",
40693
+ " C",
40694
+ "C ",
40695
+ "CM",
40696
+ "??",
40697
+ "!!",
40698
+ "DD",
40699
+ "AU",
40700
+ "UD",
40701
+ "UA",
40702
+ "DU",
40703
+ "AA",
40704
+ "UU"
40705
+ ]);
40706
+ function statusRecord(line) {
40707
+ if (line.length < 3 || !XY.has(line.slice(0, 2)))
40708
+ return false;
40709
+ const separator = line[2];
40710
+ if (separator !== " " && separator !== "\t")
40711
+ return false;
40712
+ const path = line.slice(3);
40713
+ if (path.length === 0)
40714
+ return false;
40715
+ if (line[0] === "R" || line[1] === "R" || line[0] === "C" || line[1] === "C")
40716
+ return /^.+ -> .+$/.test(path);
40717
+ return true;
40718
+ }
40719
+ function append(input, output, line) {
40720
+ if (!input.budget.chargeRecords(1) || !input.budget.chargeCodeUnits(line.length))
40721
+ return false;
40722
+ output.push(line);
40723
+ return true;
40724
+ }
40725
+ function compressGitStatus(input) {
40726
+ const output = [];
40727
+ let section;
40728
+ let long = false;
40729
+ let sawRecord = false;
40730
+ for (const line of input.lines) {
40731
+ if (line.length === 0)
40732
+ continue;
40733
+ if (!input.budget.chargeRecords(1))
40734
+ return input.text;
40735
+ if (SECTION.test(line)) {
40736
+ long = true;
40737
+ section = line === "Untracked files:" ? "untracked" : "tracked";
40738
+ if (!append(input, output, line))
40739
+ return input.text;
40740
+ continue;
40741
+ }
40742
+ if (HEADER.test(line) || RELATION.test(line) || OPERATION.test(line) || FINAL.test(line)) {
40743
+ if (!append(input, output, line))
40744
+ return input.text;
40745
+ continue;
40746
+ }
40747
+ if (CHATTER.test(line))
40748
+ continue;
40749
+ if (long) {
40750
+ const record2 = section === "untracked" ? /^\t\S.+$/.test(line) : LONG_RECORD.test(line);
40751
+ if (!record2)
40752
+ return input.text;
40753
+ sawRecord = true;
40754
+ if (!append(input, output, line))
40755
+ return input.text;
40756
+ continue;
40757
+ }
40758
+ if (!statusRecord(line))
40759
+ return input.text;
40760
+ sawRecord = true;
40761
+ if (!append(input, output, line))
40762
+ return input.text;
40763
+ }
40764
+ if (!sawRecord)
40765
+ return input.text;
40766
+ const rendered = output.join(`
40767
+ `);
40768
+ return rendered.length <= MAX_OUTPUT ? rendered : input.text;
40769
+ }
40770
+
40771
+ // packages/rtk/src/filters/tests.ts
40772
+ function isFailureStart(line, executable) {
40773
+ if (executable === "vitest")
40774
+ return /^\s*FAIL\s{2}\S.+\s>\s/.test(line);
40775
+ if (executable === "jest")
40776
+ return /^\s*\u25CF\s/.test(line);
40777
+ if (executable === "bun")
40778
+ return /^\s*(?:FAIL\s|UnhandledPromiseRejection|Uncaught exception|panic:|error:.*(?:hook|unhandled rejection))/.test(line);
40779
+ if (executable === "pytest")
40780
+ return /^\s*(?:FAILED\s|={2,} FAILURES ={2,}|ERROR collecting)/.test(line);
40781
+ if (executable === "go")
40782
+ return /^\s*(?:--- FAIL:|# \S|FAIL\s+\S+\s+\[build failed\])/.test(line);
40783
+ return /^\s*(?:FAIL\b|--- FAIL:|FAILED\b|={2,} FAILURES ={2,}|panic:|ERROR collecting|\u25CF )/.test(line);
40784
+ }
40785
+ function isSummary(line, executable) {
40786
+ if (executable === "bun")
40787
+ return /^(?:\d+ (?:pass|fail|skip|todo)|Ran \d+ tests?|error: \d+ unhandled)/.test(line);
40788
+ if (executable === "vitest")
40789
+ return /^(?:Test Files|Tests |Snapshots |Snapshots:|Projects? |Shards? |Attachments? |Retries? )/i.test(line);
40790
+ if (executable === "jest")
40791
+ return /^(?:Test Suites:|Tests:|Snapshots:)/.test(line);
40792
+ if (executable === "pytest")
40793
+ return /(?:\d+ (?:passed|failed|errors?|skipped|xfailed|xpassed))(?:,| in|$)/.test(line) || /^=+ short test summary/.test(line);
40794
+ if (executable === "go")
40795
+ return /^(?:--- SKIP:|(?:ok|FAIL)\s+\S)/.test(line);
40796
+ return /^(?:\d+ (?:pass|fail|skip|todo)|Ran \d+ tests?|Tests?:|Test Files|Snapshots:|test result:|(?:ok|FAIL)\s+\S|=+ .* (?:passed|failed|error|skipped))/i.test(line);
40797
+ }
40798
+ function isFailureSummary(line, executable) {
40799
+ if (executable === "bun")
40800
+ return /^(?:[1-9]\d* fail|error: [1-9]\d* unhandled)/.test(line);
40801
+ if (["vitest", "jest"].includes(executable))
40802
+ return /(?:^|\s)[1-9]\d* failed/.test(line);
40803
+ if (executable === "pytest")
40804
+ return /[1-9]\d* (?:failed|errors?)/.test(line);
40805
+ if (executable === "go")
40806
+ return /^FAIL\s+\S/.test(line);
40807
+ return /(?:[1-9]\d* fail|[1-9]\d* failed|FAIL\s+\S)/.test(line);
40808
+ }
40809
+ function compressTests(input, executable = "unknown") {
40810
+ const { text, lines } = input;
40811
+ const selected = new Set;
40812
+ const starts = [];
40813
+ let hasFailureSummary = false;
40814
+ for (let index = 0;index < lines.length; index++) {
40815
+ const line = lines[index] ?? "";
40816
+ if (isFailureStart(line, executable))
40817
+ starts.push(index);
40818
+ if (isSummary(line, executable))
40819
+ selected.add(index);
40820
+ if (isFailureSummary(line, executable))
40821
+ hasFailureSummary = true;
40822
+ }
40823
+ if (hasFailureSummary && starts.length === 0)
40824
+ return text;
40825
+ for (let offset = 0;offset < starts.length; offset++) {
40826
+ const start = starts[offset];
40827
+ if (start === undefined || !input.budget.chargeRecords(1))
40828
+ return text;
40829
+ const nextFailure = starts[offset + 1] ?? lines.length;
40830
+ let end = start;
40831
+ while (end + 1 < nextFailure) {
40832
+ const line = lines[end + 1] ?? "";
40833
+ if (/^progress \d+$/.test(line) || isSummary(line, executable))
40834
+ break;
40835
+ end++;
40836
+ }
40837
+ const count = end - start + 1;
40838
+ if (!input.budget.chargeRecords(count))
40839
+ return text;
40840
+ for (let index = start;index <= end; index++)
40841
+ selected.add(index);
40842
+ }
40843
+ if (selected.size === 0)
40844
+ return text;
40845
+ let rendered = renderGaps(input, selected, (start, end) => `... ${end - start + 1} lines omitted ...`);
40846
+ if (rendered === undefined)
40847
+ return text;
40848
+ const indexes = [...selected];
40849
+ const leading = Math.min(...indexes);
40850
+ const trailing = lines.length - 1 - Math.max(...indexes);
40851
+ if (leading > 0)
40852
+ rendered = `... ${leading} lines omitted ...
40853
+ ${rendered}`;
40854
+ if (trailing > 0)
40855
+ rendered = `${rendered}
40856
+ ... ${trailing} lines omitted ...`;
40857
+ if (rendered.length > MAX_OUTPUT)
40858
+ return text;
40859
+ for (const start of starts)
40860
+ if (!rendered.includes(lines[start] ?? ""))
40861
+ return text;
40862
+ return rendered;
40863
+ }
40864
+
40865
+ // packages/rtk/src/index.ts
40866
+ var MIN_INPUT = 500;
40867
+ var MAX_INPUT = 1e6;
40868
+ var MAX_OUTPUT2 = 250000;
40869
+ var SHELL = new Set(["bash", "shell", "terminal", "exec", "run_command", "execute_command"]);
40870
+ var NON_SHELL = new Set([
40871
+ "read",
40872
+ "edit",
40873
+ "write",
40874
+ "glob",
40875
+ "grep_search",
40876
+ "search",
40877
+ "web_search",
40878
+ "web_fetch",
40879
+ "read_file",
40880
+ "list_directory",
40881
+ "find_files",
40882
+ "code_search",
40883
+ "apply_patch"
40884
+ ]);
40885
+ function emptyReport(errors4 = 0) {
40886
+ return {
40887
+ applied: false,
40888
+ filterHits: 0,
40889
+ originalCodeUnits: 0,
40890
+ compressedCodeUnits: 0,
40891
+ estimatedTokensSaved: 0,
40892
+ filters: [],
40893
+ skippedInternalErrors: errors4
40894
+ };
40895
+ }
40896
+ function normalizeName(name) {
40897
+ return name.toLowerCase().replace(/[-./\s]+/g, "_");
40898
+ }
40899
+ function originOf(tool) {
40900
+ if (tool === undefined)
40901
+ return "unknown";
40902
+ const name = normalizeName(tool.name);
40903
+ if (SHELL.has(name))
40904
+ return "shell";
40905
+ if (NON_SHELL.has(name))
40906
+ return "non-shell";
40907
+ return "unknown";
40908
+ }
40909
+ function extractCommand(input) {
40910
+ if (typeof input === "string")
40911
+ return input.length === 0 ? undefined : input;
40912
+ if (input === null || typeof input !== "object" || Array.isArray(input))
40913
+ return;
40914
+ if (Object.getPrototypeOf(input) !== Object.prototype)
40915
+ return;
40916
+ const object2 = input;
40917
+ for (const key of ["command", "cmd", "script"]) {
40918
+ if (!Object.hasOwn(object2, key))
40919
+ continue;
40920
+ const value = object2[key];
40921
+ if (typeof value === "string" && value.length > 0)
40922
+ return value;
40923
+ }
40924
+ return;
40925
+ }
40926
+ function prefix(lines) {
40927
+ return lines.slice(0, 64).join(`
40928
+ `).slice(0, 4096);
40929
+ }
40930
+ function sampleRows(lines) {
40931
+ return lines.length <= 128 ? lines : [...lines.slice(0, 64), ...lines.slice(-64)];
40932
+ }
40933
+ function detect(input, command, origin) {
40934
+ const { lines } = input;
40935
+ const sample = prefix(lines);
40936
+ const classification = origin === "shell" && command !== undefined ? classifyCommand(command) : undefined;
40937
+ if (origin === "shell" && command !== undefined && classification === undefined)
40938
+ return;
40939
+ if (classification !== undefined)
40940
+ return { id: classification.family, classification };
40941
+ if (GIT_DIFF_EVIDENCE_HEADER.test(sample) && GIT_DIFF_EVIDENCE_PAIR.test(sample))
40942
+ return { id: "git-diff" };
40943
+ if (/^(?:On branch |## |Changes |Untracked files:)/m.test(sample) && /^(?:[ MADRCU?!]{2} |\s+(?:modified|deleted|new file):)/m.test(sample))
40944
+ return { id: "git-status" };
40945
+ if (GIT_LOG_EVIDENCE_COMMIT.test(sample) && GIT_LOG_EVIDENCE_BODY.test(sample))
40946
+ return { id: "git-log" };
40947
+ if (origin === "unknown") {
40948
+ const inferred = inferBuildOrTest(sampleRows(lines));
40949
+ if (inferred !== undefined)
40950
+ return { id: inferred };
40951
+ }
40952
+ const inferredGrepRows = lines.filter((line) => /^(?:[A-Za-z]:\\.+|[^\n:]+):\d+:.+$/.test(line));
40953
+ if (origin === "unknown" && inferredGrepRows.length >= 3 && inferredGrepRows.length / Math.max(1, lines.filter((line) => line.length > 0).length) >= 0.8)
40954
+ return {
40955
+ id: "grep",
40956
+ classification: {
40957
+ family: "grep",
40958
+ executable: "inferred",
40959
+ grepMode: { heading: false, lineNumber: true, beforeContext: 0, afterContext: 0 }
40960
+ }
40961
+ };
40962
+ let candidates = 0;
40963
+ let pathLines = 0;
40964
+ let conflicts = 0;
40965
+ for (const line of lines) {
40966
+ if (line.length === 0)
40967
+ continue;
40968
+ candidates++;
40969
+ if (/^(?![[{`|])(?!.+:\d+(?::|$))[^\s:\n]+(?:[/\\][^\s:\n]+)*$/.test(line))
40970
+ pathLines++;
40971
+ if (/\s(?:is|are|the|this|that)\s/i.test(line) || /^(?:```|\{|\[)|\|.+\|$/.test(line))
40972
+ conflicts++;
40973
+ }
40974
+ if (candidates >= 10 && pathLines / candidates >= 0.8 && conflicts / candidates <= 0.1)
40975
+ return { id: "path-list" };
40976
+ if (origin === "shell" && (sample.match(/^\s*\d+[\t |:].+$/gm)?.length ?? 0) >= 10)
40977
+ return { id: "numbered-read" };
40978
+ return;
40979
+ }
40980
+ function keepRegions(input, head, tail) {
40981
+ const selected = new Set;
40982
+ if (!input.budget.chargeRecords(head + tail))
40983
+ return input.text;
40984
+ for (let index = 0;index < Math.min(head, input.lines.length); index++)
40985
+ selected.add(index);
40986
+ for (let index = Math.max(head, input.lines.length - tail);index < input.lines.length; index++)
40987
+ selected.add(index);
40988
+ return renderSelection(input, selected) ?? input.text;
40989
+ }
40990
+ function deduplicate(input) {
40991
+ const selected = new Set;
40992
+ let previous;
40993
+ for (let index = 0;index < input.lines.length; index++) {
40994
+ const line = input.lines[index] ?? "";
40995
+ if (line === previous)
40996
+ continue;
40997
+ if (!input.budget.chargeRecords(1))
40998
+ return input.text;
40999
+ selected.add(index);
41000
+ previous = line;
41001
+ }
41002
+ return renderSelection(input, selected) ?? input.text;
41003
+ }
41004
+ function keepAnchors(input, isAnchor, head, tail) {
41005
+ const selected = new Set;
41006
+ for (let index = 0;index < input.lines.length; index++) {
41007
+ if (index < head || index >= input.lines.length - tail || isAnchor(input.lines[index] ?? "")) {
41008
+ if (!input.budget.chargeRecords(1))
41009
+ return input.text;
41010
+ selected.add(index);
41011
+ }
41012
+ }
41013
+ return renderSelection(input, selected) ?? input.text;
41014
+ }
41015
+ function specialized(input, id, classification) {
41016
+ const { text: content, lines } = input;
41017
+ if (id === "git-status")
41018
+ return compressGitStatus(input);
41019
+ if (id === "lint-output")
41020
+ return compressDiagnostics(input);
41021
+ if (id === "build-output")
41022
+ return compressBuild(input);
41023
+ if (id === "test-output")
41024
+ return compressTests(input, classification?.executable);
41025
+ if (id === "package-output")
41026
+ return compressPackages(input, classification?.executable ?? "unknown");
41027
+ if (id === "git-operation")
41028
+ return compressGitOperation(input);
41029
+ if (id === "docker-build")
41030
+ return compressDocker(input);
41031
+ if (id === "tree-output" || id === "path-list")
41032
+ return compressListing(input, classification?.executable ?? "find", classification?.subcommand, classification !== undefined);
41033
+ if (id === "grep" && classification?.grepMode !== undefined)
41034
+ return compressGrep(input, classification.grepMode);
41035
+ if (!input.budget.chargeRecords(lines.length))
41036
+ return content;
41037
+ switch (id) {
41038
+ case "git-diff":
41039
+ return keepAnchors(input, (line) => GIT_DIFF_ANCHOR.test(line), 20, 12);
41040
+ case "git-log":
41041
+ return keepAnchors(input, (line) => GIT_LOG_ANCHOR.test(line), 20, 12);
41042
+ case "grep":
41043
+ return keepRegions(input, 40, 20);
41044
+ case "numbered-read":
41045
+ return lines.length >= 250 ? keepRegions(input, 100, 50) : content;
41046
+ case "deduplicate-log":
41047
+ return deduplicate(input);
41048
+ case "smart-truncate":
41049
+ return keepRegions(input, 200, 100);
41050
+ }
41051
+ }
41052
+ function accept(original, candidate) {
41053
+ return candidate.length > 0 && candidate.length < original.length && candidate.length <= MAX_OUTPUT2 ? candidate : undefined;
41054
+ }
41055
+ function filter(input, origin, command) {
41056
+ const { text: content, lines } = input;
41057
+ const detection = detect(input, command, origin);
41058
+ if (detection !== undefined) {
41059
+ const { id, classification } = detection;
41060
+ const first = accept(content, specialized(input, id, classification));
41061
+ if (first === undefined)
41062
+ return;
41063
+ return { content: first, filters: [id] };
41064
+ }
41065
+ if (origin !== "shell")
41066
+ return;
41067
+ if (lines.length >= 20) {
41068
+ const compact = accept(content, deduplicate(input));
41069
+ if (compact !== undefined)
41070
+ return { content: compact, filters: ["deduplicate-log"] };
41071
+ }
41072
+ if (lines.length >= 500) {
41073
+ const compact = accept(content, specialized(input, "smart-truncate"));
41074
+ if (compact !== undefined)
41075
+ return { content: compact, filters: ["smart-truncate"] };
41076
+ }
41077
+ return;
41078
+ }
41079
+ function transformRequest(request2, config2) {
41080
+ if (!config2.enabled)
41081
+ return { request: request2, report: emptyReport() };
41082
+ try {
41083
+ const uses = new Map;
41084
+ let changed = false;
41085
+ let originalCodeUnits = 0;
41086
+ let compressedCodeUnits = 0;
41087
+ let filterHits = 0;
41088
+ let skippedInternalErrors = 0;
41089
+ const filterOrder = [];
41090
+ const messages = request2.messages.map((message) => {
41091
+ let messageChanged = false;
41092
+ const content = message.content.map((block) => {
41093
+ if (block.type === "toolUse") {
41094
+ uses.set(block.id, block);
41095
+ return block;
41096
+ }
41097
+ if (block.type !== "toolResult" || block.isError === true || block.cacheControl !== undefined || block.content.length < MIN_INPUT || block.content.length > MAX_INPUT)
41098
+ return block;
41099
+ const use = uses.get(block.toolUseId);
41100
+ const origin = originOf(use);
41101
+ if (origin === "non-shell")
41102
+ return block;
41103
+ try {
41104
+ const command = origin === "shell" && use !== undefined ? extractCommand(use.input) : undefined;
41105
+ const bounded = scanText(block.content);
41106
+ if (bounded === undefined)
41107
+ return block;
41108
+ const result = filter(bounded, origin, command);
41109
+ if (result === undefined)
41110
+ return block;
41111
+ changed = true;
41112
+ messageChanged = true;
41113
+ originalCodeUnits += block.content.length;
41114
+ compressedCodeUnits += result.content.length;
41115
+ filterHits += result.filters.length;
41116
+ for (const id of result.filters)
41117
+ if (!filterOrder.includes(id))
41118
+ filterOrder.push(id);
41119
+ return { ...block, content: result.content };
41120
+ } catch {
41121
+ skippedInternalErrors++;
41122
+ return block;
41123
+ }
41124
+ });
41125
+ return messageChanged ? { ...message, content } : message;
41126
+ });
41127
+ if (!changed)
41128
+ return { request: request2, report: { ...emptyReport(), skippedInternalErrors } };
41129
+ const transformed = { ...request2, messages };
41130
+ return {
41131
+ request: transformed,
41132
+ report: {
41133
+ applied: true,
41134
+ filterHits,
41135
+ originalCodeUnits,
41136
+ compressedCodeUnits,
41137
+ estimatedTokensSaved: Math.max(0, estimateInputTokens(request2) - estimateInputTokens(transformed)),
41138
+ filters: filterOrder,
41139
+ skippedInternalErrors
41140
+ }
41141
+ };
41142
+ } catch {
41143
+ return { request: request2, report: emptyReport(1) };
41144
+ }
41145
+ }
41146
+
38610
41147
  // apps/gateway/src/logging.ts
38611
41148
  function requestLogDefaults(id, at) {
38612
41149
  return {
@@ -38628,7 +41165,13 @@ function requestLogDefaults(id, at) {
38628
41165
  ttftMs: null,
38629
41166
  durationMs: 0,
38630
41167
  costUsd: 0,
38631
- degradations: []
41168
+ degradations: [],
41169
+ rtkApplied: false,
41170
+ rtkFilterHits: 0,
41171
+ rtkOriginalCodeUnits: 0,
41172
+ rtkCompressedCodeUnits: 0,
41173
+ rtkEstimatedTokensSaved: 0,
41174
+ rtkFilters: []
38632
41175
  };
38633
41176
  }
38634
41177
  function newCompletedRequestLog(id, at, overrides) {
@@ -38763,11 +41306,12 @@ async function dispatch(request2, deps, signal, requestId) {
38763
41306
  const logger2 = deps.logger ?? noopLogger;
38764
41307
  const startedAt = deps.now();
38765
41308
  const snapshot = await deps.snapshots.get(startedAt);
38766
- const deadlineAt = startedAt + snapshot.settings.requestDeadlineMs;
41309
+ const deadlineAt = snapshot.settings.requestDeadlineMs === 0 ? null : startedAt + snapshot.settings.requestDeadlineMs;
38767
41310
  const log = newCompletedRequestLog(requestId, startedAt, {
38768
41311
  requestedModel: request2.model,
38769
41312
  status: 0
38770
41313
  });
41314
+ let dispatchRequest = request2;
38771
41315
  const fail = (code, message) => {
38772
41316
  log.errorCode = code;
38773
41317
  log.status = HTTP_STATUS[code];
@@ -38779,36 +41323,45 @@ async function dispatch(request2, deps, signal, requestId) {
38779
41323
  log: () => log
38780
41324
  };
38781
41325
  };
38782
- const deadlineController = new AbortController;
38783
- const abortFromClient = () => deadlineController.abort(signal.reason);
41326
+ const dispatchController = new AbortController;
41327
+ const abortFromClient = () => dispatchController.abort(signal.reason);
38784
41328
  if (signal.aborted)
38785
41329
  abortFromClient();
38786
41330
  else
38787
41331
  signal.addEventListener("abort", abortFromClient, { once: true });
38788
- const deadlineTimer = setTimeout(() => deadlineController.abort(new GatewayError("TIMEOUT", "request deadline exceeded")), Math.max(0, deadlineAt - deps.now()));
38789
- const dispatchSignal = deadlineController.signal;
41332
+ const deadlineTimer = deadlineAt === null ? null : setTimeout(() => dispatchController.abort(new GatewayError("TIMEOUT", "request deadline exceeded")), Math.max(0, deadlineAt - deps.now()));
41333
+ const dispatchSignal = dispatchController.signal;
38790
41334
  const clearDeadline = () => {
38791
- clearTimeout(deadlineTimer);
41335
+ if (deadlineTimer !== null)
41336
+ clearTimeout(deadlineTimer);
38792
41337
  signal.removeEventListener("abort", abortFromClient);
38793
41338
  };
38794
41339
  const checkCancellation = () => {
38795
- if (!dispatchSignal.aborted)
38796
- return;
38797
41340
  if (signal.aborted)
38798
41341
  throw signal.reason;
38799
- throw new GatewayError("TIMEOUT", "request deadline exceeded");
41342
+ if (deadlineAt !== null && (dispatchSignal.aborted || deps.now() >= deadlineAt))
41343
+ throw new GatewayError("TIMEOUT", "request deadline exceeded");
38800
41344
  };
38801
41345
  let model;
38802
41346
  try {
38803
41347
  checkCancellation();
38804
- model = resolveModel(request2.model, snapshot);
41348
+ const transformed = transformRequest(request2, { enabled: snapshot.settings.rtkEnabled });
41349
+ dispatchRequest = transformed.request;
41350
+ log.rtkApplied = transformed.report.applied;
41351
+ log.rtkFilterHits = transformed.report.filterHits;
41352
+ log.rtkOriginalCodeUnits = transformed.report.originalCodeUnits;
41353
+ log.rtkCompressedCodeUnits = transformed.report.compressedCodeUnits;
41354
+ log.rtkEstimatedTokensSaved = transformed.report.estimatedTokensSaved;
41355
+ log.rtkFilters = transformed.report.filters;
41356
+ checkCancellation();
41357
+ model = resolveModel(dispatchRequest.model, snapshot);
38805
41358
  } catch (error51) {
38806
41359
  const { code } = classify(error51);
38807
41360
  clearDeadline();
38808
41361
  return fail(code, error51 instanceof Error ? error51.message : "unresolvable model");
38809
41362
  }
38810
41363
  const { candidates, excluded } = rank({
38811
- request: request2,
41364
+ request: dispatchRequest,
38812
41365
  model,
38813
41366
  snapshot,
38814
41367
  now: startedAt,
@@ -38822,10 +41375,11 @@ async function dispatch(request2, deps, signal, requestId) {
38822
41375
  count: candidates.length
38823
41376
  });
38824
41377
  for (const e of excluded) {
38825
- log.degradations.push(`excluded:${e.credentialId}:${e.reason}`);
41378
+ const capabilityOnly = e.reason === "capability:anthropicTools";
41379
+ log.degradations.push(capabilityOnly ? `excluded:${e.reason}` : `excluded:${e.credentialId}:${e.reason}`);
38826
41380
  logger2.debug("routing candidate excluded", {
38827
41381
  requestId,
38828
- credentialId: e.credentialId,
41382
+ ...capabilityOnly ? {} : { credentialId: e.credentialId },
38829
41383
  reason: e.reason
38830
41384
  });
38831
41385
  }
@@ -38843,11 +41397,14 @@ async function dispatch(request2, deps, signal, requestId) {
38843
41397
  let lastError = null;
38844
41398
  candidateLoop:
38845
41399
  for (let i = 0;i < maxAttempts; i++) {
38846
- if (dispatchSignal.aborted && !signal.aborted) {
38847
- lastError = new GatewayError("TIMEOUT", "request deadline exceeded");
41400
+ try {
41401
+ checkCancellation();
41402
+ } catch (error51) {
41403
+ if (signal.aborted)
41404
+ throw signal.reason;
41405
+ lastError = error51 instanceof GatewayError ? error51 : new GatewayError("TIMEOUT", "request deadline exceeded");
38848
41406
  break;
38849
41407
  }
38850
- checkCancellation();
38851
41408
  const candidate = candidates[i];
38852
41409
  log.attempts = i + 1;
38853
41410
  log.credentialId = candidate.credential.id;
@@ -38879,7 +41436,7 @@ async function dispatch(request2, deps, signal, requestId) {
38879
41436
  try {
38880
41437
  const result = await waitForCancellation(attempt({
38881
41438
  candidate,
38882
- request: request2,
41439
+ request: dispatchRequest,
38883
41440
  adapter: deps.adapters[candidate.target.provider],
38884
41441
  http: deps.http,
38885
41442
  now: attemptNow,
@@ -38964,7 +41521,7 @@ async function dispatch(request2, deps, signal, requestId) {
38964
41521
  } catch (error51) {
38965
41522
  if (signal.aborted)
38966
41523
  throw signal.reason;
38967
- const classifiedError = dispatchSignal.aborted ? { code: "TIMEOUT" } : classify(error51);
41524
+ const classifiedError = deadlineAt !== null && dispatchSignal.aborted ? { code: "TIMEOUT" } : classify(error51);
38968
41525
  const { code: code2, retryAfterMs } = classifiedError;
38969
41526
  const message = error51 instanceof Error ? error51.message : "attempt failed";
38970
41527
  lastError = retryAfterMs === undefined ? new GatewayError(code2, message) : new GatewayError(code2, message, { retryAfterMs });
@@ -38984,7 +41541,7 @@ async function dispatch(request2, deps, signal, requestId) {
38984
41541
  } catch (refreshError) {
38985
41542
  if (signal.aborted)
38986
41543
  throw signal.reason;
38987
- const classified = dispatchSignal.aborted ? { code: "TIMEOUT" } : classify(refreshError);
41544
+ const classified = deadlineAt !== null && dispatchSignal.aborted ? { code: "TIMEOUT" } : classify(refreshError);
38988
41545
  const refreshMessage = refreshError instanceof Error ? refreshError.message : "credential refresh failed";
38989
41546
  lastError = classified.retryAfterMs === undefined ? new GatewayError(classified.code, refreshMessage) : new GatewayError(classified.code, refreshMessage, {
38990
41547
  retryAfterMs: classified.retryAfterMs
@@ -39041,8 +41598,8 @@ async function dispatch(request2, deps, signal, requestId) {
39041
41598
  };
39042
41599
  } finally {
39043
41600
  clearDeadline();
39044
- if (!deadlineController.signal.aborted)
39045
- deadlineController.abort();
41601
+ if (!dispatchController.signal.aborted)
41602
+ dispatchController.abort();
39046
41603
  }
39047
41604
  }
39048
41605
  return { events: run(), log: () => log };
@@ -39069,7 +41626,8 @@ var STOP_REASON2 = {
39069
41626
  maxTokens: "max_tokens",
39070
41627
  stopSequence: "stop_sequence",
39071
41628
  toolUse: "tool_use",
39072
- contentFilter: "refusal"
41629
+ contentFilter: "refusal",
41630
+ pauseTurn: "pause_turn"
39073
41631
  };
39074
41632
  var ERROR_TYPE2 = {
39075
41633
  AUTH: "authentication_error",
@@ -39125,7 +41683,7 @@ async function* anthropicStream(events, requestId) {
39125
41683
  suppressed.add(event.index);
39126
41684
  break;
39127
41685
  }
39128
- const content_block = b.type === "text" ? { type: "text", text: "" } : b.type === "thinking" ? { type: "thinking", thinking: "" } : { type: "tool_use", id: b.id, name: b.name, input: {} };
41686
+ const content_block = b.type === "text" ? { type: "text", text: "" } : b.type === "thinking" ? { type: "thinking", thinking: "" } : b.type === "anthropicNative" ? { ...b.data, type: b.blockType } : { type: "tool_use", id: b.id, name: b.name, input: {} };
39129
41687
  const index = nextOutIndex++;
39130
41688
  outIndex.set(event.index, index);
39131
41689
  yield frame("content_block_start", {
@@ -39139,7 +41697,7 @@ async function* anthropicStream(events, requestId) {
39139
41697
  if (suppressed.has(event.index))
39140
41698
  break;
39141
41699
  const d = event.delta;
39142
- const delta2 = d.type === "text" ? { type: "text_delta", text: d.text } : d.type === "thinking" ? { type: "thinking_delta", thinking: d.text } : d.type === "thinkingSignature" ? { type: "signature_delta", signature: d.signature } : { type: "input_json_delta", partial_json: d.partial };
41700
+ const delta2 = d.type === "text" ? { type: "text_delta", text: d.text } : d.type === "thinking" ? { type: "thinking_delta", thinking: d.text } : d.type === "thinkingSignature" ? { type: "signature_delta", signature: d.signature } : d.type === "anthropicNative" ? { type: d.deltaType, ...d.data } : { type: "input_json_delta", partial_json: d.partial };
39143
41701
  yield frame("content_block_delta", {
39144
41702
  type: "content_block_delta",
39145
41703
  index: outIndex.get(event.index) ?? event.index,
@@ -39186,11 +41744,17 @@ function anthropicResponse(collected, requestId) {
39186
41744
  content: collected.content.filter((b) => b.type !== "thinking" || b.signature !== undefined && b.signature !== "").map((b) => {
39187
41745
  switch (b.type) {
39188
41746
  case "text":
39189
- return { type: "text", text: b.text };
41747
+ return {
41748
+ type: "text",
41749
+ text: b.text,
41750
+ ...b.citations === undefined ? {} : { citations: b.citations }
41751
+ };
39190
41752
  case "thinking":
39191
41753
  return { type: "thinking", thinking: b.text, signature: b.signature };
39192
41754
  case "toolUse":
39193
41755
  return { type: "tool_use", id: b.id, name: b.name, input: b.input };
41756
+ case "anthropicNative":
41757
+ return { ...b.data, type: b.blockType };
39194
41758
  default:
39195
41759
  return { type: "text", text: "" };
39196
41760
  }
@@ -39224,7 +41788,8 @@ var FINISH2 = {
39224
41788
  maxTokens: "length",
39225
41789
  stopSequence: "stop",
39226
41790
  toolUse: "tool_calls",
39227
- contentFilter: "content_filter"
41791
+ contentFilter: "content_filter",
41792
+ pauseTurn: "stop"
39228
41793
  };
39229
41794
  var ERROR_TYPE3 = {
39230
41795
  AUTH: { type: "invalid_request_error", code: "invalid_api_key" },
@@ -39361,11 +41926,199 @@ function openaiErrorBody(code, message) {
39361
41926
  return { error: { message, type: e.type, code: e.code } };
39362
41927
  }
39363
41928
 
41929
+ // apps/gateway/src/ingress/anthropicTools.ts
41930
+ var TOOL_FIELDS = {
41931
+ cache_control: cacheControlSchema.nullable(),
41932
+ strict: exports_external.boolean().nullable(),
41933
+ defer_loading: exports_external.boolean().nullable(),
41934
+ allowed_callers: exports_external.array(exports_external.enum(ANTHROPIC_TOOL_CALLERS)).nullable(),
41935
+ input_examples: exports_external.array(exports_external.record(exports_external.string(), exports_external.unknown())).nullable(),
41936
+ eager_input_streaming: exports_external.boolean().nullable(),
41937
+ max_uses: exports_external.number().int().positive().nullable(),
41938
+ allowed_domains: exports_external.array(exports_external.string()).nullable(),
41939
+ blocked_domains: exports_external.array(exports_external.string()).nullable(),
41940
+ user_location: exports_external.object({
41941
+ type: exports_external.literal("approximate"),
41942
+ city: exports_external.string().optional(),
41943
+ region: exports_external.string().optional(),
41944
+ country: exports_external.string().optional(),
41945
+ timezone: exports_external.string().optional()
41946
+ }).nullable(),
41947
+ citations: exports_external.object({ enabled: exports_external.boolean() }).nullable(),
41948
+ max_content_tokens: exports_external.number().int().positive().nullable(),
41949
+ use_cache: exports_external.boolean().nullable(),
41950
+ response_inclusion: exports_external.enum(["full", "excluded"]).nullable(),
41951
+ display_width_px: exports_external.number().int().positive(),
41952
+ display_height_px: exports_external.number().int().positive(),
41953
+ display_number: exports_external.number().int().nullable(),
41954
+ enable_zoom: exports_external.boolean().nullable(),
41955
+ max_characters: exports_external.number().int().positive().nullable(),
41956
+ model: exports_external.string().min(1),
41957
+ caching: cacheControlSchema.nullable(),
41958
+ max_tokens: exports_external.number().int().positive().nullable(),
41959
+ mcp_server_name: exports_external.string().min(1),
41960
+ configs: exports_external.record(exports_external.string(), exports_external.unknown()).nullable(),
41961
+ default_config: exports_external.record(exports_external.string(), exports_external.unknown()).nullable()
41962
+ };
41963
+ var customToolSchema = exports_external.object({
41964
+ type: exports_external.literal("custom").nullish(),
41965
+ name: exports_external.string().min(1),
41966
+ description: exports_external.string().optional(),
41967
+ input_schema: exports_external.record(exports_external.string(), exports_external.unknown()),
41968
+ cache_control: cacheControlSchema.nullish()
41969
+ });
41970
+ function fail(path, message) {
41971
+ throw new GatewayError("BAD_REQUEST", `${path}: ${message}`);
41972
+ }
41973
+ function field(path, name, value) {
41974
+ const schema = TOOL_FIELDS[name];
41975
+ if (schema === undefined)
41976
+ fail(`${path}.${name}`, `unsupported field "${name}"`);
41977
+ const parsed = schema.safeParse(value);
41978
+ if (!parsed.success) {
41979
+ fail(`${path}.${name}`, parsed.error.issues[0]?.message ?? "invalid value");
41980
+ }
41981
+ return parsed.data;
41982
+ }
41983
+ function parseAnthropicTool(raw, type, path, mcpServerNames) {
41984
+ const spec = anthropicToolSpec(type);
41985
+ if (spec === undefined)
41986
+ fail(`${path}.type`, `unrecognized tool type "${type}"`);
41987
+ if (spec.name !== undefined && raw.name !== spec.name) {
41988
+ fail(`${path}.name`, `${type} must be declared with name "${spec.name}"`);
41989
+ }
41990
+ if (spec.name === undefined && raw.name !== undefined) {
41991
+ fail(`${path}.name`, `${type} does not take a name`);
41992
+ }
41993
+ for (const required2 of spec.required) {
41994
+ if (raw[required2] === undefined)
41995
+ fail(`${path}.${required2}`, `${type} requires ${required2}`);
41996
+ }
41997
+ const allowed = new Set([...spec.required, ...spec.optional]);
41998
+ const wire = {};
41999
+ let cacheControl;
42000
+ for (const [key, value] of Object.entries(raw)) {
42001
+ if (key === "type" || key === "name")
42002
+ continue;
42003
+ if (!allowed.has(key))
42004
+ fail(`${path}.${key}`, `${type} does not accept "${key}"`);
42005
+ const parsed = field(path, key, value);
42006
+ if (key === "cache_control") {
42007
+ cacheControl = irCacheControl(parsed === null ? undefined : parsed).cacheControl;
42008
+ continue;
42009
+ }
42010
+ if (parsed !== null)
42011
+ wire[key] = parsed;
42012
+ }
42013
+ if (wire.allowed_domains !== undefined && wire.blocked_domains !== undefined) {
42014
+ fail(`${path}.blocked_domains`, "allowed_domains and blocked_domains are mutually exclusive");
42015
+ }
42016
+ if (spec.family === "mcpToolset") {
42017
+ const server = wire.mcp_server_name;
42018
+ if (typeof server === "string" && !mcpServerNames.has(server)) {
42019
+ fail(`${path}.mcp_server_name`, `no mcp_servers entry named "${server}"`);
42020
+ }
42021
+ }
42022
+ return {
42023
+ provider: "anthropic",
42024
+ family: spec.family,
42025
+ type,
42026
+ name: spec.name ?? "",
42027
+ wire,
42028
+ ...cacheControl === undefined ? {} : { cacheControl }
42029
+ };
42030
+ }
42031
+ function parseCustomTool(raw, path) {
42032
+ const parsed = customToolSchema.safeParse(raw);
42033
+ if (!parsed.success) {
42034
+ const issue2 = parsed.error.issues[0];
42035
+ fail(`${path}${issue2?.path.length ? `.${issue2.path.join(".")}` : ""}`, issue2?.message ?? "invalid tool");
42036
+ }
42037
+ const options = {};
42038
+ for (const [key, value] of Object.entries(raw)) {
42039
+ if (["type", "name", "description", "input_schema", "cache_control"].includes(key))
42040
+ continue;
42041
+ if (!ANTHROPIC_CUSTOM_TOOL_OPTIONS.includes(key)) {
42042
+ fail(`${path}.${key}`, `unsupported field "${key}"`);
42043
+ }
42044
+ const value_ = field(path, key, value);
42045
+ if (value_ !== null)
42046
+ options[key] = value_;
42047
+ }
42048
+ return {
42049
+ provider: "custom",
42050
+ name: parsed.data.name,
42051
+ ...parsed.data.description === undefined ? {} : { description: parsed.data.description },
42052
+ inputSchema: parsed.data.input_schema,
42053
+ ...irCacheControl(parsed.data.cache_control ?? undefined),
42054
+ ...Object.keys(options).length === 0 ? {} : { options }
42055
+ };
42056
+ }
42057
+ function parseTools(raw, mcpServerNames) {
42058
+ return raw.map((entry, index) => {
42059
+ const path = `tools.${index}`;
42060
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
42061
+ fail(path, "expected a tool definition object");
42062
+ }
42063
+ const tool = entry;
42064
+ const type = tool.type;
42065
+ if (type === undefined || type === null || type === "custom") {
42066
+ return parseCustomTool(tool, path);
42067
+ }
42068
+ if (typeof type !== "string")
42069
+ fail(`${path}.type`, "expected a string");
42070
+ return parseAnthropicTool(tool, type, path, mcpServerNames);
42071
+ });
42072
+ }
42073
+ function mcpServerNames(body2) {
42074
+ const servers = body2.mcp_servers;
42075
+ if (!Array.isArray(servers))
42076
+ return new Set;
42077
+ const names = new Set;
42078
+ for (const server of servers) {
42079
+ if (typeof server === "object" && server !== null) {
42080
+ const name = server.name;
42081
+ if (typeof name === "string")
42082
+ names.add(name);
42083
+ }
42084
+ }
42085
+ return names;
42086
+ }
42087
+
42088
+ // apps/gateway/src/ingress/model.ts
42089
+ var DISCOVERY_PREFIX = "claude/";
42090
+ var ONE_M_SUFFIX = "[1m]";
42091
+ function normalizeClientModel(raw, betas2 = []) {
42092
+ let model = raw.trim();
42093
+ let wantsOneM = false;
42094
+ if (model.toLowerCase().endsWith(ONE_M_SUFFIX)) {
42095
+ const stripped = model.slice(0, -ONE_M_SUFFIX.length).trim();
42096
+ if (stripped.length > 0) {
42097
+ model = stripped;
42098
+ wantsOneM = true;
42099
+ }
42100
+ }
42101
+ if (model.toLowerCase().startsWith(DISCOVERY_PREFIX)) {
42102
+ const stripped = model.slice(DISCOVERY_PREFIX.length);
42103
+ if (stripped.length > 0)
42104
+ model = stripped;
42105
+ }
42106
+ const merged = [...betas2];
42107
+ if (wantsOneM && !merged.includes(CONTEXT_1M_BETA))
42108
+ merged.push(CONTEXT_1M_BETA);
42109
+ return { model, betas: merged };
42110
+ }
42111
+
39364
42112
  // apps/gateway/src/ingress/anthropic.ts
39365
42113
  var textBlock = exports_external.object({
39366
42114
  type: exports_external.literal("text"),
39367
42115
  text: exports_external.string(),
39368
- cache_control: cacheControlSchema.optional()
42116
+ cache_control: cacheControlSchema.optional(),
42117
+ citations: exports_external.array(exports_external.unknown()).optional()
42118
+ });
42119
+ var midConversationTextBlock = textBlock.extend({
42120
+ cache_control: cacheControlSchema.nullable().optional(),
42121
+ citations: exports_external.array(exports_external.unknown()).nullable().optional()
39369
42122
  });
39370
42123
  var imageBlock = exports_external.object({
39371
42124
  type: exports_external.literal("image"),
@@ -39402,9 +42155,137 @@ var block = exports_external.discriminatedUnion("type", [
39402
42155
  toolUseBlock,
39403
42156
  toolResultBlock
39404
42157
  ]);
42158
+ var nativeBase = {
42159
+ cache_control: cacheControlSchema.nullable().optional()
42160
+ };
42161
+ var nativeResultContent = exports_external.unknown().refine((value) => value !== null, {
42162
+ message: "expected native result content"
42163
+ });
42164
+ var caller = exports_external.discriminatedUnion("type", [
42165
+ exports_external.object({ type: exports_external.literal("direct") }).strict(),
42166
+ exports_external.object({
42167
+ type: exports_external.enum([
42168
+ "code_execution_20250825",
42169
+ "code_execution_20260120",
42170
+ "code_execution_20260521"
42171
+ ]),
42172
+ tool_id: exports_external.string()
42173
+ }).strict()
42174
+ ]).optional();
42175
+ var documentSource = exports_external.discriminatedUnion("type", [
42176
+ exports_external.object({
42177
+ type: exports_external.literal("base64"),
42178
+ media_type: exports_external.literal("application/pdf"),
42179
+ data: exports_external.string()
42180
+ }).strict(),
42181
+ exports_external.object({ type: exports_external.literal("text"), media_type: exports_external.literal("text/plain"), data: exports_external.string() }).strict(),
42182
+ exports_external.object({ type: exports_external.literal("content"), content: exports_external.array(exports_external.unknown()) }).strict(),
42183
+ exports_external.object({ type: exports_external.literal("url"), url: exports_external.string() }).strict(),
42184
+ exports_external.object({ type: exports_external.literal("file"), file_id: exports_external.string() }).strict()
42185
+ ]);
42186
+ var citationsConfig = exports_external.object({ enabled: exports_external.boolean().optional() }).strict();
42187
+ var fallbackModel = exports_external.object({ model: exports_external.string() }).strict();
42188
+ var toolChangeReference = exports_external.discriminatedUnion("type", [
42189
+ exports_external.object({ type: exports_external.literal("tool_reference"), name: exports_external.string() }).strict(),
42190
+ exports_external.object({ type: exports_external.literal("mcp_tool_reference"), server_name: exports_external.string(), name: exports_external.string() }).strict(),
42191
+ exports_external.object({ type: exports_external.literal("mcp_toolset_reference"), server_name: exports_external.string() }).strict()
42192
+ ]);
42193
+ function nativeToolChange(type) {
42194
+ return exports_external.object({ type: exports_external.literal(type), tool: toolChangeReference, ...nativeBase }).strict();
42195
+ }
42196
+ var toolAddition = nativeToolChange("tool_addition");
42197
+ var toolRemoval = nativeToolChange("tool_removal");
42198
+ var midConversationSystem = exports_external.object({
42199
+ type: exports_external.literal("mid_conv_system"),
42200
+ content: exports_external.array(exports_external.discriminatedUnion("type", [midConversationTextBlock.strict(), toolAddition, toolRemoval])),
42201
+ ...nativeBase
42202
+ }).strict();
42203
+ var nativeSchemas = {
42204
+ server_tool_use: exports_external.object({
42205
+ type: exports_external.literal("server_tool_use"),
42206
+ id: exports_external.string(),
42207
+ name: exports_external.enum([
42208
+ "advisor",
42209
+ "web_search",
42210
+ "web_fetch",
42211
+ "code_execution",
42212
+ "bash_code_execution",
42213
+ "text_editor_code_execution",
42214
+ "tool_search_tool_regex",
42215
+ "tool_search_tool_bm25"
42216
+ ]),
42217
+ input: exports_external.unknown(),
42218
+ caller,
42219
+ ...nativeBase
42220
+ }).strict(),
42221
+ web_search_tool_result: nativeResult("web_search_tool_result", true),
42222
+ web_fetch_tool_result: nativeResult("web_fetch_tool_result", true),
42223
+ code_execution_tool_result: nativeResult("code_execution_tool_result"),
42224
+ bash_code_execution_tool_result: nativeResult("bash_code_execution_tool_result"),
42225
+ text_editor_code_execution_tool_result: nativeResult("text_editor_code_execution_tool_result"),
42226
+ tool_search_tool_result: nativeResult("tool_search_tool_result"),
42227
+ advisor_tool_result: nativeResult("advisor_tool_result"),
42228
+ mcp_tool_use: exports_external.object({
42229
+ type: exports_external.literal("mcp_tool_use"),
42230
+ id: exports_external.string(),
42231
+ name: exports_external.string(),
42232
+ server_name: exports_external.string(),
42233
+ input: exports_external.unknown(),
42234
+ ...nativeBase
42235
+ }).strict(),
42236
+ mcp_tool_result: exports_external.object({
42237
+ type: exports_external.literal("mcp_tool_result"),
42238
+ tool_use_id: exports_external.string(),
42239
+ content: exports_external.union([exports_external.string(), exports_external.array(exports_external.unknown())]).optional(),
42240
+ is_error: exports_external.boolean().optional(),
42241
+ ...nativeBase
42242
+ }).strict(),
42243
+ container_upload: exports_external.object({ type: exports_external.literal("container_upload"), file_id: exports_external.string(), ...nativeBase }).strict(),
42244
+ compaction: exports_external.object({
42245
+ type: exports_external.literal("compaction"),
42246
+ content: exports_external.string().nullable(),
42247
+ encrypted_content: exports_external.string().nullable().optional(),
42248
+ ...nativeBase
42249
+ }).strict(),
42250
+ search_result: exports_external.object({
42251
+ type: exports_external.literal("search_result"),
42252
+ source: exports_external.string(),
42253
+ title: exports_external.string(),
42254
+ content: exports_external.array(exports_external.unknown()),
42255
+ citations: citationsConfig.optional(),
42256
+ ...nativeBase
42257
+ }).strict(),
42258
+ redacted_thinking: exports_external.object({ type: exports_external.literal("redacted_thinking"), data: exports_external.string() }).strict(),
42259
+ document: exports_external.object({
42260
+ type: exports_external.literal("document"),
42261
+ source: documentSource,
42262
+ citations: citationsConfig.nullable().optional(),
42263
+ context: exports_external.string().nullable().optional(),
42264
+ title: exports_external.string().nullable().optional(),
42265
+ ...nativeBase
42266
+ }).strict(),
42267
+ mid_conv_system: midConversationSystem,
42268
+ tool_addition: toolAddition,
42269
+ tool_removal: toolRemoval,
42270
+ fallback: exports_external.object({
42271
+ type: exports_external.literal("fallback"),
42272
+ from: fallbackModel,
42273
+ to: fallbackModel,
42274
+ trigger: exports_external.unknown().optional()
42275
+ }).strict()
42276
+ };
42277
+ function nativeResult(type, hasCaller = false) {
42278
+ return exports_external.object({
42279
+ type: exports_external.literal(type),
42280
+ tool_use_id: exports_external.string(),
42281
+ content: nativeResultContent,
42282
+ ...hasCaller ? { caller } : {},
42283
+ ...nativeBase
42284
+ }).strict();
42285
+ }
39405
42286
  var message = exports_external.object({
39406
42287
  role: exports_external.enum(["user", "assistant", "system"]),
39407
- content: exports_external.union([exports_external.string(), exports_external.array(block)])
42288
+ content: exports_external.union([exports_external.string(), exports_external.array(exports_external.unknown())])
39408
42289
  });
39409
42290
  var schema = exports_external.object({
39410
42291
  model: exports_external.string().min(1),
@@ -39414,12 +42295,7 @@ var schema = exports_external.object({
39414
42295
  temperature: exports_external.number().optional(),
39415
42296
  stop_sequences: exports_external.array(exports_external.string()).optional(),
39416
42297
  stream: exports_external.boolean().optional(),
39417
- tools: exports_external.array(exports_external.object({
39418
- name: exports_external.string(),
39419
- description: exports_external.string().optional(),
39420
- input_schema: exports_external.record(exports_external.string(), exports_external.unknown()),
39421
- cache_control: cacheControlSchema.optional()
39422
- })).optional(),
42298
+ tools: exports_external.array(exports_external.unknown()).optional(),
39423
42299
  tool_choice: exports_external.union([
39424
42300
  exports_external.object({ type: exports_external.enum(["auto", "any", "none"]) }),
39425
42301
  exports_external.object({ type: exports_external.literal("tool"), name: exports_external.string() })
@@ -39462,7 +42338,12 @@ function flattenToolResult(content) {
39462
42338
  function toIrBlock(b) {
39463
42339
  switch (b.type) {
39464
42340
  case "text":
39465
- return { type: "text", text: b.text, ...irCacheControl(b.cache_control) };
42341
+ return {
42342
+ type: "text",
42343
+ text: b.text,
42344
+ ...b.citations === undefined ? {} : { citations: b.citations },
42345
+ ...irCacheControl(b.cache_control)
42346
+ };
39466
42347
  case "image":
39467
42348
  return {
39468
42349
  type: "image",
@@ -39494,6 +42375,69 @@ function toIrBlock(b) {
39494
42375
  };
39495
42376
  }
39496
42377
  }
42378
+ var nativeRoles = {
42379
+ server_tool_use: "assistant",
42380
+ web_search_tool_result: "assistant",
42381
+ web_fetch_tool_result: "assistant",
42382
+ code_execution_tool_result: "assistant",
42383
+ bash_code_execution_tool_result: "assistant",
42384
+ text_editor_code_execution_tool_result: "assistant",
42385
+ tool_search_tool_result: "assistant",
42386
+ advisor_tool_result: "assistant",
42387
+ mcp_tool_use: "assistant",
42388
+ mcp_tool_result: "user",
42389
+ container_upload: "user",
42390
+ compaction: "assistant",
42391
+ search_result: "user",
42392
+ redacted_thinking: "assistant",
42393
+ document: "user",
42394
+ mid_conv_system: "system",
42395
+ tool_addition: "system",
42396
+ tool_removal: "system",
42397
+ fallback: "assistant"
42398
+ };
42399
+ function readBlock(raw, role, path) {
42400
+ if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
42401
+ const type = raw.type;
42402
+ if (typeof type === "string" && ANTHROPIC_NATIVE_BLOCK_TYPES.has(type)) {
42403
+ const nativeSchema = nativeSchemas[type];
42404
+ const nativeRole = nativeRoles[type];
42405
+ if (nativeSchema === undefined || nativeRole === undefined) {
42406
+ throw new GatewayError("BAD_REQUEST", `${path}.type: block type "${type}" is not legal in request history`);
42407
+ }
42408
+ if (role !== nativeRole) {
42409
+ throw new GatewayError("BAD_REQUEST", `${path}: block type "${type}" is not legal in ${role} messages`);
42410
+ }
42411
+ const parsed2 = nativeSchema.safeParse(raw);
42412
+ if (!parsed2.success) {
42413
+ const issue2 = parsed2.error.issues[0];
42414
+ const issuePath = issue2?.code === "unrecognized_keys" ? [...issue2.path, issue2.keys[0]] : issue2?.path;
42415
+ const suffix = issuePath?.length ? `.${issuePath.join(".")}` : "";
42416
+ throw new GatewayError("BAD_REQUEST", `${path}${suffix}: ${issue2?.message ?? "invalid native content block"}`);
42417
+ }
42418
+ const { type: _type, cache_control, ...data } = parsed2.data;
42419
+ return {
42420
+ type: "anthropicNative",
42421
+ blockType: type,
42422
+ data,
42423
+ ...cache_control === undefined || cache_control === null ? {} : irCacheControl(cache_control)
42424
+ };
42425
+ }
42426
+ }
42427
+ const parsed = block.safeParse(raw);
42428
+ if (!parsed.success) {
42429
+ const issue2 = parsed.error.issues[0];
42430
+ if (issue2?.code === "invalid_union" || issue2?.path.at(-1) === "type") {
42431
+ const type = raw?.type;
42432
+ if (typeof type === "string") {
42433
+ throw new GatewayError("BAD_REQUEST", `${path}.type: unrecognized block type "${type}"`);
42434
+ }
42435
+ }
42436
+ const suffix = issue2?.path.length ? `.${issue2.path.join(".")}` : "";
42437
+ throw new GatewayError("BAD_REQUEST", `${path}${suffix}: ${issue2?.message ?? "invalid content block"}`);
42438
+ }
42439
+ return toIrBlock(parsed.data);
42440
+ }
39497
42441
  function toIrToolChoice(c) {
39498
42442
  return c.type === "tool" ? { type: "tool", name: c.name } : { type: c.type };
39499
42443
  }
@@ -39533,17 +42477,25 @@ function parseAnthropicRequest(body2, headers) {
39533
42477
  throw new GatewayError("BAD_REQUEST", "request body must be a JSON object");
39534
42478
  }
39535
42479
  const parsed = parseOrThrow2(schema, body2);
39536
- const messages = parsed.messages.map((m) => ({
39537
- role: m.role,
39538
- content: typeof m.content === "string" ? [{ type: "text", text: m.content }] : m.content.map(toIrBlock)
39539
- }));
42480
+ const messages = parsed.messages.map((m, i) => {
42481
+ const content = typeof m.content === "string" ? [{ type: "text", text: m.content }] : m.content.map((b, j) => readBlock(b, m.role, `messages.${i}.content.${j}`));
42482
+ if (m.role === "system") {
42483
+ const previous = parsed.messages[i - 1];
42484
+ const next = parsed.messages[i + 1];
42485
+ if (previous === undefined || next !== undefined && next.role !== "assistant") {
42486
+ throw new GatewayError("BAD_REQUEST", `messages.${i}: system message must follow another message and be last or precede an assistant message`);
42487
+ }
42488
+ }
42489
+ return { role: m.role, content };
42490
+ });
39540
42491
  const system = parsed.system === undefined ? undefined : typeof parsed.system === "string" ? [{ type: "text", text: parsed.system }] : parsed.system.map((b) => ({
39541
42492
  type: "text",
39542
42493
  text: b.text,
39543
42494
  ...irCacheControl(b.cache_control)
39544
42495
  }));
42496
+ const named = normalizeClientModel(parsed.model, readBetas(headers));
39545
42497
  const request2 = {
39546
- model: parsed.model,
42498
+ model: named.model,
39547
42499
  messages,
39548
42500
  stream: parsed.stream ?? false
39549
42501
  };
@@ -39556,12 +42508,7 @@ function parseAnthropicRequest(body2, headers) {
39556
42508
  if (parsed.stop_sequences !== undefined)
39557
42509
  request2.stopSequences = parsed.stop_sequences;
39558
42510
  if (parsed.tools !== undefined) {
39559
- request2.tools = parsed.tools.map((t2) => ({
39560
- name: t2.name,
39561
- ...t2.description !== undefined && { description: t2.description },
39562
- inputSchema: t2.input_schema,
39563
- ...irCacheControl(t2.cache_control)
39564
- }));
42511
+ request2.tools = parseTools(parsed.tools, mcpServerNames(body2));
39565
42512
  }
39566
42513
  if (parsed.tool_choice !== undefined)
39567
42514
  request2.toolChoice = toIrToolChoice(parsed.tool_choice);
@@ -39574,9 +42521,8 @@ function parseAnthropicRequest(body2, headers) {
39574
42521
  const extras = extraFields(body2, KNOWN);
39575
42522
  if (extras !== undefined)
39576
42523
  request2.vendor = { anthropic: extras };
39577
- const betas = readBetas(headers);
39578
- if (betas.length > 0)
39579
- request2.betas = betas;
42524
+ if (named.betas.length > 0)
42525
+ request2.betas = named.betas;
39580
42526
  return validateRequest(request2);
39581
42527
  }
39582
42528
 
@@ -39685,9 +42631,9 @@ function parseOpenAIRequest(body2) {
39685
42631
  const messages = [];
39686
42632
  for (const m of parsed.messages) {
39687
42633
  if (m.role === "system" || m.role === "developer") {
39688
- const blocks = contentBlocks(m.content);
39689
- applyMessageCacheControl(blocks, m.cache_control);
39690
- system.push(...blocks);
42634
+ const blocks2 = contentBlocks(m.content);
42635
+ applyMessageCacheControl(blocks2, m.cache_control);
42636
+ system.push(...blocks2);
39691
42637
  continue;
39692
42638
  }
39693
42639
  if (m.role === "tool") {
@@ -39725,7 +42671,7 @@ function parseOpenAIRequest(body2) {
39725
42671
  throw new GatewayError("BAD_REQUEST", "messages: at least one non-system message is required");
39726
42672
  }
39727
42673
  const request2 = {
39728
- model: parsed.model,
42674
+ model: normalizeClientModel(parsed.model).model,
39729
42675
  messages,
39730
42676
  stream: parsed.stream ?? false
39731
42677
  };
@@ -39741,6 +42687,7 @@ function parseOpenAIRequest(body2) {
39741
42687
  }
39742
42688
  if (parsed.tools !== undefined) {
39743
42689
  request2.tools = parsed.tools.map((t2) => ({
42690
+ provider: "custom",
39744
42691
  name: t2.function.name,
39745
42692
  ...t2.function.description !== undefined && { description: t2.function.description },
39746
42693
  inputSchema: t2.function.parameters ?? { type: "object" },
@@ -39759,65 +42706,13 @@ function parseOpenAIRequest(body2) {
39759
42706
 
39760
42707
  // apps/gateway/src/routes/models.ts
39761
42708
  var CREATED_AT = new Date(0).toISOString();
39762
- function narrower(a, b) {
39763
- const context = [a.contextWindow, b.contextWindow].filter((n) => n !== undefined);
39764
- const output = [a.maxOutputTokens, b.maxOutputTokens].filter((n) => n !== undefined);
39765
- return {
39766
- ...context.length === 0 ? {} : { contextWindow: Math.min(...context) },
39767
- ...output.length === 0 ? {} : { maxOutputTokens: Math.min(...output) }
39768
- };
39769
- }
39770
- function targetLimits(target, auths) {
39771
- const ways = auths.size === 0 ? ["apiKey"] : [...auths];
39772
- let listed = {};
39773
- for (const auth of ways) {
39774
- const entry = catalogLimits(target.provider, target.model, auth);
39775
- if (entry === null)
39776
- continue;
39777
- listed = narrower(listed, {
39778
- contextWindow: entry.contextWindow,
39779
- maxOutputTokens: entry.maxOutputTokens
39780
- });
39781
- }
39782
- const contextWindow = target.contextWindow ?? listed.contextWindow;
39783
- const maxOutputTokens = target.maxOutputTokens ?? listed.maxOutputTokens;
39784
- return {
39785
- ...contextWindow === undefined ? {} : { contextWindow },
39786
- ...maxOutputTokens === undefined ? {} : { maxOutputTokens }
39787
- };
39788
- }
39789
- function limitsOf(model, authsByProvider) {
39790
- let limits = {};
39791
- for (const target of model.targets) {
39792
- limits = narrower(limits, targetLimits(target, authsByProvider.get(target.provider) ?? new Set));
39793
- }
39794
- return limits;
39795
- }
39796
- function displayName(model) {
39797
- const only = model.targets.length === 1 ? model.targets[0] : undefined;
39798
- if (only === undefined)
39799
- return model.id;
39800
- const labelled = PROVIDER_MODEL_CATALOG[only.provider]?.models.find((choice) => choice.id === only.model);
39801
- return labelled?.label ?? model.id;
39802
- }
39803
- function servingAuths(credentials) {
39804
- const byProvider = new Map;
39805
- for (const credential of credentials) {
39806
- if (!credential.enabled)
39807
- continue;
39808
- const ways = byProvider.get(credential.provider) ?? new Set;
39809
- ways.add(credential.authType);
39810
- byProvider.set(credential.provider, ways);
39811
- }
39812
- return byProvider;
39813
- }
39814
42709
  function describeModel(model, credentials) {
39815
- const limits = limitsOf(model, servingAuths(credentials));
42710
+ const limits = resolveModelLimits(model, credentials);
39816
42711
  return {
39817
42712
  id: model.id,
39818
42713
  object: "model",
39819
42714
  type: "model",
39820
- display_name: displayName(model),
42715
+ display_name: modelDisplayName(model),
39821
42716
  created: 0,
39822
42717
  created_at: CREATED_AT,
39823
42718
  owned_by: "omnigateway",
@@ -39825,8 +42720,29 @@ function describeModel(model, credentials) {
39825
42720
  ...limits.maxOutputTokens === undefined ? {} : { max_tokens: limits.maxOutputTokens }
39826
42721
  };
39827
42722
  }
39828
- function modelListBody(models, credentials) {
39829
- const data = models.map((model) => describeModel(model, credentials));
42723
+ var ALREADY_CLAUDE = /^(?:claude|anthropic)/i;
42724
+ var MIRROR_PREFIX = "claude/";
42725
+ function discoveryMirrors(data) {
42726
+ const taken = new Set(data.map((entry) => entry.id));
42727
+ const mirrors = [];
42728
+ for (const entry of data) {
42729
+ if (ALREADY_CLAUDE.test(entry.id))
42730
+ continue;
42731
+ const id = `${MIRROR_PREFIX}${entry.id}`;
42732
+ if (taken.has(id))
42733
+ continue;
42734
+ mirrors.push({
42735
+ ...entry,
42736
+ id,
42737
+ root: entry.id,
42738
+ display_name: `${entry.display_name} (OmniGateway)`
42739
+ });
42740
+ }
42741
+ return mirrors;
42742
+ }
42743
+ function modelListBody(models, credentials, options = {}) {
42744
+ const described = models.map((model) => describeModel(model, credentials));
42745
+ const data = options.discoveryMirrors === true ? [...described, ...discoveryMirrors(described)] : described;
39830
42746
  return {
39831
42747
  object: "list",
39832
42748
  data,
@@ -40022,13 +42938,21 @@ function proxyRoutes(deps) {
40022
42938
  snapshots: deps.snapshots ?? createRoutingSnapshotCache(deps.store, logger2),
40023
42939
  keepaliveMs: deps.keepaliveMs ?? KEEPALIVE_MS
40024
42940
  };
40025
- return new Elysia().post("/v1/messages", ({ request: request2 }) => handle(dispatchDeps, rateLimiter, "anthropic", request2)).post("/v1/chat/completions", ({ request: request2 }) => handle(dispatchDeps, rateLimiter, "openai", request2)).get("/v1/models", async ({ request: request2 }) => {
42941
+ return new Elysia().post("/v1/messages", ({ request: request2, server }) => {
42942
+ server?.timeout(request2, 0);
42943
+ return handle(dispatchDeps, rateLimiter, "anthropic", request2);
42944
+ }).post("/v1/chat/completions", ({ request: request2, server }) => {
42945
+ server?.timeout(request2, 0);
42946
+ return handle(dispatchDeps, rateLimiter, "openai", request2);
42947
+ }).get("/v1/models", async ({ request: request2 }) => {
40026
42948
  try {
40027
42949
  const key = await authenticateApiKey(deps.store, apiKeyHeader(request2.headers));
40028
42950
  const snapshot = await dispatchDeps.snapshots.get(deps.now());
40029
42951
  const models = [...snapshot.models.values()];
40030
42952
  const visibleModels = key.modelAllowlist === null ? models : models.filter((model) => key.modelAllowlist?.includes(model.id));
40031
- return Response.json(modelListBody(visibleModels, snapshot.credentials));
42953
+ return Response.json(modelListBody(visibleModels, snapshot.credentials, {
42954
+ discoveryMirrors: deps.discoveryMirrors === true
42955
+ }));
40032
42956
  } catch (error51) {
40033
42957
  const gatewayError = asGatewayError(error51);
40034
42958
  logger2.error("model listing failed", {
@@ -40038,6 +42962,25 @@ function proxyRoutes(deps) {
40038
42962
  });
40039
42963
  return errorResponse("anthropic", gatewayError.code, gatewayError.message);
40040
42964
  }
42965
+ }).post("/v1/messages/count_tokens", async ({ request: request2 }) => {
42966
+ try {
42967
+ const key = await authenticateApiKey(deps.store, apiKeyHeader(request2.headers));
42968
+ rateLimiter.consume(key.id, key.rateLimitPerMin);
42969
+ const body2 = await request2.json();
42970
+ const chatRequest = parseAnthropicRequest(body2, request2.headers);
42971
+ if (key.modelAllowlist !== null && !key.modelAllowlist.includes(chatRequest.model)) {
42972
+ throw new GatewayError("AUTH", `model "${chatRequest.model}" is not allowed for this API key`);
42973
+ }
42974
+ return Response.json({ input_tokens: estimateInputTokens(chatRequest) });
42975
+ } catch (error51) {
42976
+ const gatewayError = asGatewayError(error51);
42977
+ logger2.warn("token count failed", {
42978
+ status: HTTP_STATUS[gatewayError.code],
42979
+ code: gatewayError.code,
42980
+ reason: gatewayError.message
42981
+ });
42982
+ return errorResponse("anthropic", gatewayError.code, gatewayError.message);
42983
+ }
40041
42984
  }).onError(({ error: error51 }) => {
40042
42985
  const gatewayError = asGatewayError(error51);
40043
42986
  logger2.error("unhandled proxy route error", {
@@ -40085,10 +43028,13 @@ function createApp(deps) {
40085
43028
  refresh,
40086
43029
  requestId,
40087
43030
  rateLimiter,
40088
- logger: logger2
43031
+ logger: logger2,
43032
+ discoveryMirrors: deps.discoveryMirrors === true
40089
43033
  })).use(adminRoutes({
40090
43034
  store: deps.store,
40091
43035
  admin,
43036
+ baseUrl: deps.baseUrl,
43037
+ discoveryMirrors: deps.discoveryMirrors === true,
40092
43038
  now,
40093
43039
  sessionTtlMs: ADMIN_SESSION_TTL_MS,
40094
43040
  logger: logger2,
@@ -40114,7 +43060,7 @@ function createApp(deps) {
40114
43060
  } catch {
40115
43061
  return error51();
40116
43062
  }
40117
- const protectedPrefix = ["/api", "/v1", "/oauth"].some((prefix) => decodedPath === prefix || decodedPath.startsWith(`${prefix}/`));
43063
+ const protectedPrefix = ["/api", "/v1", "/oauth"].some((prefix2) => decodedPath === prefix2 || decodedPath.startsWith(`${prefix2}/`));
40118
43064
  if (protectedPrefix)
40119
43065
  return error51();
40120
43066
  const requestedPath = decodedPath === "/" ? "/index.html" : decodedPath;
@@ -40331,7 +43277,8 @@ async function main() {
40331
43277
  refresh,
40332
43278
  staticDir,
40333
43279
  logger: logger2,
40334
- console: console2
43280
+ console: console2,
43281
+ discoveryMirrors: config2.exposeClaudeCodeAliases
40335
43282
  });
40336
43283
  const stopMaintenance = startMaintenance({ store, now, logger: logger2 });
40337
43284
  const stopRefreshScheduler = startRefreshScheduler({ store, refresh, now, logger: logger2 });