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.
- package/README.md +27 -33
- package/bin/omni.js +917 -161
- package/gateway.js +3247 -300
- package/package.json +1 -1
- package/public/assets/{Chip-C69u2U_b.js → Chip-BB_5C1Zp.js} +1 -1
- package/public/assets/Confirm-B6aAiVbT.js +4 -0
- package/public/assets/{CopyValue-CJy2T0H6.js → CopyValue-CRQDLo7k.js} +4 -4
- package/public/assets/{Field-Sc8mDqJv.js → Field-uHZxl4fI.js} +8 -8
- package/public/assets/Lamp-B-5SjXbG.js +25 -0
- package/public/assets/{Meter-C0nUftAa.js → Meter-DI_BRUKt.js} +1 -1
- package/public/assets/Modal-CI6jk2D4.js +82 -0
- package/public/assets/{Rack-CMqGBP4I.js → Rack-D1WJswv3.js} +23 -19
- package/public/assets/{Readout-Dv2dZWtI.js → Readout-BocZ2HXP.js} +5 -5
- package/public/assets/{States-D55MhqMx.js → States-Bbiu5cHE.js} +10 -10
- package/public/assets/{Table-DBB3jdgi.js → Table-CdPWxYaz.js} +1 -1
- package/public/assets/Toggle-CiLC67Dw.js +39 -0
- package/public/assets/TokenBreakdown-B96iPBm9.js +28 -0
- package/public/assets/_app-BBOF6A0T.js +1 -0
- package/public/assets/_app.accounts-BNkhpvaB.js +54 -0
- package/public/assets/_app.console-Daz4aKhf.js +44 -0
- package/public/assets/_app.index-LO6d38oe.js +62 -0
- package/public/assets/{_app.keys-BX8k8COP.js → _app.keys-kBqLqoFf.js} +8 -8
- package/public/assets/_app.logs-_wYNS47N.js +32 -0
- package/public/assets/_app.models-Cjng8ohC.js +144 -0
- package/public/assets/_app.settings-a0FKyQAi.js +38 -0
- package/public/assets/{_app.usage-BRhEvwVr.js → _app.usage-D3KtgLrC.js} +32 -29
- package/public/assets/dist-C-IbPRiV.js +1 -0
- package/public/assets/index-PW6EvVh5.js +170 -0
- package/public/assets/{login-DaC-wVpI.js → login-CTvH_KAd.js} +8 -8
- package/public/assets/queries-D2o-X8Pj.js +144 -0
- package/public/assets/{trash-2--aH2iKg-.js → trash-2-BcZb-sCT.js} +1 -1
- package/public/index.html +2 -2
- package/public/assets/Lamp-7jD_9929.js +0 -25
- package/public/assets/Modal-CiVHSJmm.js +0 -82
- package/public/assets/Toggle-BoGjb5oi.js +0 -42
- package/public/assets/_app-p5Mz7sXD.js +0 -1
- package/public/assets/_app.accounts-B5wMO9TH.js +0 -51
- package/public/assets/_app.console-Bka7AkiL.js +0 -25
- package/public/assets/_app.index-MnQuadXb.js +0 -61
- package/public/assets/_app.logs-DD-sd4fn.js +0 -33
- package/public/assets/_app.models-CezFNL6y.js +0 -144
- package/public/assets/_app.settings-D1taAt8B.js +0 -16
- package/public/assets/index-vCuK1fRQ.js +0 -170
- 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: "" } :
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
8039
|
+
const unit = source.scope === "system" ? ["-u", source.unit] : [`--user-unit=${source.unit}`];
|
|
7611
8040
|
const result = await deps.run([
|
|
7612
8041
|
"journalctl",
|
|
7613
|
-
...
|
|
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().
|
|
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 ? {
|
|
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
|
-
|
|
22513
|
-
|
|
22514
|
-
|
|
22515
|
-
|
|
22516
|
-
|
|
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
|
|
22979
|
-
|
|
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
|
-
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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+
|
|
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
|
|
38783
|
-
const abortFromClient = () =>
|
|
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(() =>
|
|
38789
|
-
const dispatchSignal =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
38847
|
-
|
|
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:
|
|
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 (!
|
|
39045
|
-
|
|
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 {
|
|
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(
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
39538
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
39578
|
-
|
|
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
|
|
39689
|
-
applyMessageCacheControl(
|
|
39690
|
-
system.push(...
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
39829
|
-
|
|
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
|
|
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((
|
|
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 });
|