omnigateway 0.7.1 → 0.7.3
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 +6 -4
- package/bin/omni.js +122 -56
- package/gateway.js +832 -93
- package/package.json +1 -1
- package/public/assets/{Chip-BWxO0uV7.js → Chip-BOyBT5TP.js} +1 -1
- package/public/assets/{CopyValue-DIR5A6PG.js → CopyValue-DRHHQlN_.js} +3 -3
- package/public/assets/{Field-DI5YTYOX.js → Field-DK5zaBVA.js} +1 -1
- package/public/assets/Lamp-ZlMzNs5N.js +25 -0
- package/public/assets/{Panel-BCpZVY4U.js → Panel-CYQvfI3L.js} +19 -19
- package/public/assets/Rack-D798XvPQ.js +466 -0
- package/public/assets/{Readout-B0TZE8aA.js → Readout-D6-aurU8.js} +1 -1
- package/public/assets/{RequestTable-D4z82uxG.js → RequestTable-CEBhwDs7.js} +2 -2
- package/public/assets/{SummaryDeck-CzozuXOu.js → SummaryDeck-DBCSHihY.js} +2 -2
- package/public/assets/{Toggle-ByxBCMfb.js → Toggle-CdCCoDEo.js} +1 -1
- package/public/assets/{TokenBreakdown-BMEiZhRX.js → TokenBreakdown-DDI9uTPW.js} +1 -1
- package/public/assets/{WindowChart-nxC4SCRC.js → WindowChart-C-Y6U3WF.js} +2 -2
- package/public/assets/_app-BWNEo1e-.js +1 -0
- package/public/assets/_app.accounts-CLLLwN77.js +59 -0
- package/public/assets/{_app.console-D6lrTxJt.js → _app.console-Dr9qxU7J.js} +3 -3
- package/public/assets/{_app.database-Y3lFDxoP.js → _app.database-D0W0pcxC.js} +4 -4
- package/public/assets/{_app.index-DUFa7RRT.js → _app.index-CyxnfhVX.js} +8 -8
- package/public/assets/{_app.keys-DRfXCzMJ.js → _app.keys-D9qmw9Tj.js} +11 -11
- package/public/assets/{_app.logs-BQT3kFZr.js → _app.logs-DtXUZETW.js} +4 -4
- package/public/assets/{_app.models-CDpbIYHW.js → _app.models-CNxwXyFl.js} +11 -11
- package/public/assets/{_app.plugins._pluginId-jaswB8Z5.js → _app.plugins._pluginId-87Ox_hkW.js} +1 -1
- package/public/assets/_app.plugins._pluginId-CZWipH1n.js +2 -0
- package/public/assets/_app.settings-DjiMSl1Y.js +88 -0
- package/public/assets/{_app.usage-BaT54Vee.js → _app.usage-CZz9raYR.js} +6 -6
- package/public/assets/{chevron-right-0adI8395.js → chevron-right-CPoaXYHw.js} +1 -1
- package/public/assets/client-CZnyYbay.js +39 -0
- package/public/assets/{index-BRrBGt1i.js → index-DNSPtYpM.js} +3 -3
- package/public/assets/{login-BSWCo_Fz.js → login-BtlMmyKj.js} +3 -3
- package/public/assets/login-dV42ZQIA.js +2 -0
- package/public/assets/plus-_zo43Lvf.js +1 -0
- package/public/assets/{preload-helper-CD37DT-E.js → preload-helper-4wSmu2-E.js} +1 -1
- package/public/assets/{shared-dShKzjig.js → shared-OJcoRCqT.js} +1 -1
- package/public/assets/{stream-BD4FhzLn.js → stream-CEb81tzM.js} +1 -1
- package/public/assets/{trash-2-DrDlpCqO.js → trash-2-BjpqTubo.js} +1 -1
- package/public/index.html +8 -8
- package/public/assets/Lamp-DN2EKL4m.js +0 -25
- package/public/assets/Rack-B03tpeW-.js +0 -466
- package/public/assets/_app-D9B6OIjd.js +0 -1
- package/public/assets/_app.accounts-BiRGhH3s.js +0 -59
- package/public/assets/_app.plugins._pluginId-CtEAGvad.js +0 -2
- package/public/assets/_app.settings-CG63splg.js +0 -58
- package/public/assets/client-_6YMm6vh.js +0 -39
- package/public/assets/login-C7v-Fr28.js +0 -2
- package/public/assets/plus-B_f8M9yB.js +0 -1
package/gateway.js
CHANGED
|
@@ -6879,6 +6879,10 @@ class GatewayError extends Error {
|
|
|
6879
6879
|
}
|
|
6880
6880
|
// packages/ir/src/logger.ts
|
|
6881
6881
|
var LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
6882
|
+
function safeToken(value) {
|
|
6883
|
+
const text = typeof value === "string" ? value : String(value);
|
|
6884
|
+
return /^[A-Za-z0-9_.:/+-]{1,64}$/.test(text) ? text : "(unprintable)";
|
|
6885
|
+
}
|
|
6882
6886
|
var FIELD_ORDER = [
|
|
6883
6887
|
"requestId",
|
|
6884
6888
|
"surface",
|
|
@@ -6916,6 +6920,12 @@ var FIELD_ORDER = [
|
|
|
6916
6920
|
"reason"
|
|
6917
6921
|
];
|
|
6918
6922
|
var REASON_MAX = 200;
|
|
6923
|
+
var MODEL_MAX = 120;
|
|
6924
|
+
var CAPS = {
|
|
6925
|
+
reason: REASON_MAX,
|
|
6926
|
+
model: MODEL_MAX,
|
|
6927
|
+
requestedModel: MODEL_MAX
|
|
6928
|
+
};
|
|
6919
6929
|
var LEVEL_COLOR = {
|
|
6920
6930
|
debug: "\x1B[2;37m",
|
|
6921
6931
|
info: "\x1B[36m",
|
|
@@ -6941,7 +6951,8 @@ function formatLine(level, at, msg, fields, color) {
|
|
|
6941
6951
|
const value = fields[key];
|
|
6942
6952
|
if (value === undefined)
|
|
6943
6953
|
continue;
|
|
6944
|
-
const
|
|
6954
|
+
const cap = CAPS[key];
|
|
6955
|
+
const capped = cap !== undefined && typeof value === "string" && value.length > cap ? `${value.slice(0, cap)}\u2026` : value;
|
|
6945
6956
|
parts.push(`${key}=${renderValue(capped)}`);
|
|
6946
6957
|
}
|
|
6947
6958
|
return parts.length === 0 ? head : `${head} ${parts.join(" ")}`;
|
|
@@ -23325,6 +23336,9 @@ function codecAdapter(id, capabilities2, codec2, origins) {
|
|
|
23325
23336
|
};
|
|
23326
23337
|
}
|
|
23327
23338
|
|
|
23339
|
+
// packages/providers/src/body.ts
|
|
23340
|
+
import { createHash } from "crypto";
|
|
23341
|
+
|
|
23328
23342
|
// packages/providers/src/headers.ts
|
|
23329
23343
|
var SAFE = /^[\x20-\x7E]{1,200}$/;
|
|
23330
23344
|
function env(name, fallback) {
|
|
@@ -23380,14 +23394,14 @@ function mergeHeaders(base, overrides) {
|
|
|
23380
23394
|
|
|
23381
23395
|
// packages/providers/src/anthropic/profile.ts
|
|
23382
23396
|
var host = stainlessHost(process.platform, process.arch);
|
|
23383
|
-
var ANTHROPIC_CLI_VERSION = env("OMNI_ANTHROPIC_CLI_VERSION", "2.1.
|
|
23397
|
+
var ANTHROPIC_CLI_VERSION = env("OMNI_ANTHROPIC_CLI_VERSION", "2.1.258");
|
|
23384
23398
|
var anthropicProfile = {
|
|
23385
23399
|
headers: [
|
|
23386
23400
|
["User-Agent", env("OMNI_UA_ANTHROPIC", `claude-cli/${ANTHROPIC_CLI_VERSION} (external, cli)`)],
|
|
23387
23401
|
["x-app", "cli"],
|
|
23388
23402
|
["anthropic-dangerous-direct-browser-access", "true"],
|
|
23389
23403
|
["X-Stainless-Lang", "js"],
|
|
23390
|
-
["X-Stainless-Package-Version", env("OMNI_ANTHROPIC_STAINLESS_PACKAGE_VERSION", "0.
|
|
23404
|
+
["X-Stainless-Package-Version", env("OMNI_ANTHROPIC_STAINLESS_PACKAGE_VERSION", "0.112.1")],
|
|
23391
23405
|
["X-Stainless-OS", envOrNull("OMNI_ANTHROPIC_STAINLESS_OS") ?? host.os],
|
|
23392
23406
|
["X-Stainless-Arch", envOrNull("OMNI_ANTHROPIC_STAINLESS_ARCH") ?? host.arch],
|
|
23393
23407
|
["X-Stainless-Runtime", "node"],
|
|
@@ -23629,19 +23643,18 @@ function orderFields(obj, order) {
|
|
|
23629
23643
|
}
|
|
23630
23644
|
return out;
|
|
23631
23645
|
}
|
|
23632
|
-
var BUILD_REVISION = envOr("OMNI_ANTHROPIC_BUILD_REVISION", "250");
|
|
23633
|
-
var CLI_VERSION = envOr("OMNI_ANTHROPIC_CLI_VERSION", "2.1.219");
|
|
23634
23646
|
var CCH_PLACEHOLDER = "00000";
|
|
23635
23647
|
var CCH_SEED = 0x6e52736ac806831en;
|
|
23636
23648
|
var CCH_MASK = 0xfffffn;
|
|
23649
|
+
var CCV_SALT = "59cf53e54c78";
|
|
23637
23650
|
var BILLING_PREFIX = "x-anthropic-billing-header:";
|
|
23638
23651
|
var AGENT_PREAMBLE = "You are a Claude agent, built on Anthropic's Claude Agent SDK.";
|
|
23639
|
-
function
|
|
23640
|
-
const
|
|
23641
|
-
return
|
|
23652
|
+
function ccVersionSuffix(firstUserText) {
|
|
23653
|
+
const picked = [4, 7, 20].map((i) => firstUserText[i] ?? "0").join("");
|
|
23654
|
+
return createHash("sha256").update(`${CCV_SALT}${picked}${ANTHROPIC_CLI_VERSION}`).digest("hex").slice(0, 3);
|
|
23642
23655
|
}
|
|
23643
|
-
function billingBlock() {
|
|
23644
|
-
return `${BILLING_PREFIX} cc_version=${
|
|
23656
|
+
function billingBlock(firstUserText) {
|
|
23657
|
+
return `${BILLING_PREFIX} cc_version=${ANTHROPIC_CLI_VERSION}.${ccVersionSuffix(firstUserText)}; ` + `cc_entrypoint=cli; cch=${CCH_PLACEHOLDER};`;
|
|
23645
23658
|
}
|
|
23646
23659
|
var BANNED_SUBSTRINGS = [
|
|
23647
23660
|
"github.com/anomalyco/opencode",
|
|
@@ -23659,7 +23672,7 @@ var REWRITES = [
|
|
|
23659
23672
|
"Environment context you are running in:"
|
|
23660
23673
|
]
|
|
23661
23674
|
];
|
|
23662
|
-
function applyAnthropicSystem(system) {
|
|
23675
|
+
function applyAnthropicSystem(system, firstUserText) {
|
|
23663
23676
|
const kept = [];
|
|
23664
23677
|
for (const block of system) {
|
|
23665
23678
|
const text = block.text.split(/\n{2,}/).filter((p) => !BANNED_SUBSTRINGS.some((b) => p.includes(b))).filter((p) => !IDENTITY_PREFIXES.some((i) => p.trimStart().startsWith(i))).filter((p) => !p.includes(BILLING_PREFIX)).filter((p) => p.trim() !== AGENT_PREAMBLE).join(`
|
|
@@ -23676,17 +23689,26 @@ function applyAnthropicSystem(system) {
|
|
|
23676
23689
|
});
|
|
23677
23690
|
}
|
|
23678
23691
|
}
|
|
23679
|
-
return [
|
|
23692
|
+
return [
|
|
23693
|
+
{ type: "text", text: billingBlock(firstUserText) },
|
|
23694
|
+
{ type: "text", text: AGENT_PREAMBLE },
|
|
23695
|
+
...kept
|
|
23696
|
+
];
|
|
23680
23697
|
}
|
|
23681
23698
|
function computeCch(body) {
|
|
23682
23699
|
const digest = Bun.hash.xxHash64(Buffer.from(body, "utf8"), CCH_SEED);
|
|
23683
23700
|
return (digest & CCH_MASK).toString(16).padStart(5, "0");
|
|
23684
23701
|
}
|
|
23702
|
+
var BILLING_ANCHOR = `"system":[{"type":"text","text":"${BILLING_PREFIX}`;
|
|
23685
23703
|
function signAnthropicBody(json2) {
|
|
23686
23704
|
const needle = `cch=${CCH_PLACEHOLDER};`;
|
|
23687
|
-
|
|
23705
|
+
const anchor = json2.indexOf(BILLING_ANCHOR);
|
|
23706
|
+
if (anchor < 0)
|
|
23688
23707
|
return json2;
|
|
23689
|
-
|
|
23708
|
+
const at = json2.indexOf(needle, anchor);
|
|
23709
|
+
if (at < 0)
|
|
23710
|
+
return json2;
|
|
23711
|
+
return `${json2.slice(0, at)}cch=${computeCch(json2)};${json2.slice(at + needle.length)}`;
|
|
23690
23712
|
}
|
|
23691
23713
|
|
|
23692
23714
|
// packages/providers/src/catalog.ts
|
|
@@ -24665,9 +24687,11 @@ var anthropicCodec = {
|
|
|
24665
24687
|
cloak,
|
|
24666
24688
|
autoCache: input.autoCacheEnabled === true
|
|
24667
24689
|
});
|
|
24690
|
+
const firstUser = input.request.messages.find((m) => m.role === "user");
|
|
24691
|
+
const firstText = firstUser?.content.find((b) => b.type === "text");
|
|
24668
24692
|
const withSystem = {
|
|
24669
24693
|
...body,
|
|
24670
|
-
system: applyAnthropicSystem(body.system ?? []),
|
|
24694
|
+
system: applyAnthropicSystem(body.system ?? [], firstText?.text ?? ""),
|
|
24671
24695
|
stream: true
|
|
24672
24696
|
};
|
|
24673
24697
|
const protocol = [
|
|
@@ -26110,10 +26134,10 @@ function toCustomResponsesWire(req, model) {
|
|
|
26110
26134
|
note("custom:context-1m-dropped");
|
|
26111
26135
|
for (const message of req.messages) {
|
|
26112
26136
|
const parts = [];
|
|
26113
|
-
const
|
|
26114
|
-
if (
|
|
26115
|
-
note("custom:system-turn-
|
|
26116
|
-
const role =
|
|
26137
|
+
const asDeveloper = message.role === "system";
|
|
26138
|
+
if (asDeveloper)
|
|
26139
|
+
note("custom:system-turn-as-developer");
|
|
26140
|
+
const role = asDeveloper ? "developer" : message.role;
|
|
26117
26141
|
const flush = () => {
|
|
26118
26142
|
if (parts.length === 0)
|
|
26119
26143
|
return;
|
|
@@ -26125,9 +26149,7 @@ function toCustomResponsesWire(req, model) {
|
|
|
26125
26149
|
case "text":
|
|
26126
26150
|
parts.push({
|
|
26127
26151
|
type: role === "assistant" ? "output_text" : "input_text",
|
|
26128
|
-
text:
|
|
26129
|
-
${block.text}
|
|
26130
|
-
</system-reminder>` : block.text
|
|
26152
|
+
text: block.text
|
|
26131
26153
|
});
|
|
26132
26154
|
break;
|
|
26133
26155
|
case "image":
|
|
@@ -26205,7 +26227,7 @@ function metadata(data, fail) {
|
|
|
26205
26227
|
function endpointUrl(origin, basePath, protocol) {
|
|
26206
26228
|
const suffix = protocol === "chat_completions" ? "chat/completions" : "responses";
|
|
26207
26229
|
const base = `${origin}${basePath}`.replace(/\/+$/, "");
|
|
26208
|
-
return
|
|
26230
|
+
return /\/v\d+$/i.test(base) ? `${base}/${suffix}` : `${base}/v1/${suffix}`;
|
|
26209
26231
|
}
|
|
26210
26232
|
function protocolOf(state, fail) {
|
|
26211
26233
|
if (state !== null && typeof state === "object") {
|
|
@@ -26246,7 +26268,7 @@ var customCodec = {
|
|
|
26246
26268
|
// packages/providers/src/custom/index.ts
|
|
26247
26269
|
var customAdapter = codecAdapter("custom", customDescriptor.capabilities, customCodec);
|
|
26248
26270
|
// packages/providers/src/grok/codec.ts
|
|
26249
|
-
import { createHash as
|
|
26271
|
+
import { createHash as createHash3 } from "crypto";
|
|
26250
26272
|
|
|
26251
26273
|
// packages/providers/src/grok/decode.ts
|
|
26252
26274
|
var ERROR_CODE = {
|
|
@@ -26445,7 +26467,7 @@ async function* decodeGrokResponses(messages) {
|
|
|
26445
26467
|
}
|
|
26446
26468
|
|
|
26447
26469
|
// packages/providers/src/grok/wire.ts
|
|
26448
|
-
import { createHash } from "crypto";
|
|
26470
|
+
import { createHash as createHash2 } from "crypto";
|
|
26449
26471
|
var MAX_TOOLS = 200;
|
|
26450
26472
|
function encodeToolChoice2(c) {
|
|
26451
26473
|
switch (c.type) {
|
|
@@ -26461,7 +26483,7 @@ function encodeToolChoice2(c) {
|
|
|
26461
26483
|
}
|
|
26462
26484
|
function promptCacheKey(instructions, firstInput) {
|
|
26463
26485
|
const stable = JSON.stringify({ instructions, firstInput });
|
|
26464
|
-
return
|
|
26486
|
+
return createHash2("sha256").update(stable).digest("hex").slice(0, 32);
|
|
26465
26487
|
}
|
|
26466
26488
|
function toGrokWire(req, model) {
|
|
26467
26489
|
const degradations = [];
|
|
@@ -26474,10 +26496,10 @@ function toGrokWire(req, model) {
|
|
|
26474
26496
|
note("grok:context-1m-dropped");
|
|
26475
26497
|
for (const message of req.messages) {
|
|
26476
26498
|
const parts = [];
|
|
26477
|
-
const
|
|
26478
|
-
if (
|
|
26479
|
-
note("grok:system-turn-
|
|
26480
|
-
const role =
|
|
26499
|
+
const asDeveloper = message.role === "system";
|
|
26500
|
+
if (asDeveloper)
|
|
26501
|
+
note("grok:system-turn-as-developer");
|
|
26502
|
+
const role = asDeveloper ? "developer" : message.role;
|
|
26481
26503
|
const flush = () => {
|
|
26482
26504
|
if (parts.length === 0)
|
|
26483
26505
|
return;
|
|
@@ -26489,9 +26511,7 @@ function toGrokWire(req, model) {
|
|
|
26489
26511
|
case "text":
|
|
26490
26512
|
parts.push({
|
|
26491
26513
|
type: role === "assistant" ? "output_text" : "input_text",
|
|
26492
|
-
text:
|
|
26493
|
-
${block.text}
|
|
26494
|
-
</system-reminder>` : block.text
|
|
26514
|
+
text: block.text
|
|
26495
26515
|
});
|
|
26496
26516
|
break;
|
|
26497
26517
|
case "image":
|
|
@@ -26574,7 +26594,7 @@ var PROXY_URL = "https://cli-chat-proxy.grok.com/v1/responses";
|
|
|
26574
26594
|
var API_URL = "https://api.x.ai/v1/responses";
|
|
26575
26595
|
var CONV_NAMESPACE = "omni-grok-conv";
|
|
26576
26596
|
function derivedUuid(value) {
|
|
26577
|
-
const h =
|
|
26597
|
+
const h = createHash3("sha256").update(`${CONV_NAMESPACE}:${value}`).digest("hex");
|
|
26578
26598
|
const variant = (Number.parseInt(h[16], 16) & 3 | 8).toString(16);
|
|
26579
26599
|
return [
|
|
26580
26600
|
h.slice(0, 8),
|
|
@@ -27283,6 +27303,7 @@ var ERROR_CODE2 = {
|
|
|
27283
27303
|
content_policy_violation: "CONTENT_FILTER"
|
|
27284
27304
|
};
|
|
27285
27305
|
var KNOWN_EVENTS3 = new Set([
|
|
27306
|
+
"keepalive",
|
|
27286
27307
|
"response.created",
|
|
27287
27308
|
"response.queued",
|
|
27288
27309
|
"response.in_progress",
|
|
@@ -27316,7 +27337,8 @@ function json7(data) {
|
|
|
27316
27337
|
return null;
|
|
27317
27338
|
}
|
|
27318
27339
|
}
|
|
27319
|
-
async function* decodeResponses(messages) {
|
|
27340
|
+
async function* decodeResponses(messages, options = {}) {
|
|
27341
|
+
const nativeReasoning = options.nativeReasoning === true;
|
|
27320
27342
|
const indices = new Map;
|
|
27321
27343
|
let next = 0;
|
|
27322
27344
|
const irIndex = (outputIndex, contentIndex = 0) => {
|
|
@@ -27361,7 +27383,7 @@ async function* decodeResponses(messages) {
|
|
|
27361
27383
|
yield {
|
|
27362
27384
|
type: "blockStart",
|
|
27363
27385
|
index: irIndex(d.output_index ?? 0),
|
|
27364
|
-
block: { type: "thinking" }
|
|
27386
|
+
block: nativeReasoning ? { type: "providerNative", provider: "openai", blockType: "reasoning", data: {} } : { type: "thinking" }
|
|
27365
27387
|
};
|
|
27366
27388
|
} else if (item.type === "function_call") {
|
|
27367
27389
|
sawToolCall = true;
|
|
@@ -27394,7 +27416,12 @@ async function* decodeResponses(messages) {
|
|
|
27394
27416
|
yield {
|
|
27395
27417
|
type: "blockDelta",
|
|
27396
27418
|
index: irIndex(d.output_index ?? 0),
|
|
27397
|
-
delta:
|
|
27419
|
+
delta: nativeReasoning ? {
|
|
27420
|
+
type: "providerNative",
|
|
27421
|
+
provider: "openai",
|
|
27422
|
+
deltaType: "reasoning_summary_text.delta",
|
|
27423
|
+
data: { text: String(d.delta ?? "") }
|
|
27424
|
+
} : { type: "thinking", text: String(d.delta ?? "") }
|
|
27398
27425
|
};
|
|
27399
27426
|
break;
|
|
27400
27427
|
case "response.function_call_arguments.delta":
|
|
@@ -27410,6 +27437,20 @@ async function* decodeResponses(messages) {
|
|
|
27410
27437
|
case "response.output_item.done": {
|
|
27411
27438
|
const outputIndex = d.output_index ?? 0;
|
|
27412
27439
|
if (ownsBlock.delete(outputIndex)) {
|
|
27440
|
+
const item = d.item ?? {};
|
|
27441
|
+
if (nativeReasoning && item.type === "reasoning") {
|
|
27442
|
+
yield {
|
|
27443
|
+
type: "blockDelta",
|
|
27444
|
+
index: irIndex(outputIndex),
|
|
27445
|
+
delta: {
|
|
27446
|
+
type: "providerNative",
|
|
27447
|
+
provider: "openai",
|
|
27448
|
+
deltaType: "response.output_item.done",
|
|
27449
|
+
fold: "merge",
|
|
27450
|
+
data: item
|
|
27451
|
+
}
|
|
27452
|
+
};
|
|
27453
|
+
}
|
|
27413
27454
|
yield { type: "blockEnd", index: irIndex(outputIndex) };
|
|
27414
27455
|
}
|
|
27415
27456
|
break;
|
|
@@ -27469,7 +27510,7 @@ async function* decodeResponses(messages) {
|
|
|
27469
27510
|
}
|
|
27470
27511
|
|
|
27471
27512
|
// packages/providers/src/openai/wire.ts
|
|
27472
|
-
import { createHash as
|
|
27513
|
+
import { createHash as createHash4 } from "crypto";
|
|
27473
27514
|
function suppliedKey(req) {
|
|
27474
27515
|
const vendor = req.vendor?.openai;
|
|
27475
27516
|
for (const name of ["prompt_cache_key", "session_id"]) {
|
|
@@ -27481,7 +27522,24 @@ function suppliedKey(req) {
|
|
|
27481
27522
|
}
|
|
27482
27523
|
function cacheKey(req, instructions, firstInput) {
|
|
27483
27524
|
const stable = req.conversationId !== undefined && req.conversationId.length > 0 ? JSON.stringify({ conversation: req.conversationId }) : JSON.stringify({ instructions, firstInput: firstInput ?? null });
|
|
27484
|
-
return
|
|
27525
|
+
return createHash4("sha256").update(stable).digest("hex").slice(0, 32);
|
|
27526
|
+
}
|
|
27527
|
+
function repairOrphanedCalls(input) {
|
|
27528
|
+
const answered = new Set;
|
|
27529
|
+
for (const item of input) {
|
|
27530
|
+
const record2 = item;
|
|
27531
|
+
if (record2.type === "function_call_output" && typeof record2.call_id === "string") {
|
|
27532
|
+
answered.add(record2.call_id);
|
|
27533
|
+
}
|
|
27534
|
+
}
|
|
27535
|
+
for (let i = input.length - 1;i >= 0; i--) {
|
|
27536
|
+
const record2 = input[i];
|
|
27537
|
+
if (record2.type !== "function_call" || typeof record2.call_id !== "string")
|
|
27538
|
+
continue;
|
|
27539
|
+
if (answered.has(record2.call_id))
|
|
27540
|
+
continue;
|
|
27541
|
+
input.splice(i + 1, 0, { type: "function_call_output", call_id: record2.call_id, output: "" });
|
|
27542
|
+
}
|
|
27485
27543
|
}
|
|
27486
27544
|
function encodeToolChoice5(c) {
|
|
27487
27545
|
switch (c.type) {
|
|
@@ -27506,10 +27564,10 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
|
|
|
27506
27564
|
note("openai:context-1m-dropped");
|
|
27507
27565
|
for (const message of req.messages) {
|
|
27508
27566
|
const parts = [];
|
|
27509
|
-
const
|
|
27510
|
-
if (
|
|
27511
|
-
note("openai:system-turn-
|
|
27512
|
-
const role =
|
|
27567
|
+
const asDeveloper = message.role === "system";
|
|
27568
|
+
if (asDeveloper)
|
|
27569
|
+
note("openai:system-turn-as-developer");
|
|
27570
|
+
const role = asDeveloper ? "developer" : message.role;
|
|
27513
27571
|
const flush = () => {
|
|
27514
27572
|
if (parts.length === 0)
|
|
27515
27573
|
return;
|
|
@@ -27521,9 +27579,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
|
|
|
27521
27579
|
case "text":
|
|
27522
27580
|
parts.push({
|
|
27523
27581
|
type: role === "assistant" ? "output_text" : "input_text",
|
|
27524
|
-
text:
|
|
27525
|
-
${block.text}
|
|
27526
|
-
</system-reminder>` : block.text
|
|
27582
|
+
text: block.text
|
|
27527
27583
|
});
|
|
27528
27584
|
break;
|
|
27529
27585
|
case "image":
|
|
@@ -27555,12 +27611,19 @@ ${block.text}
|
|
|
27555
27611
|
});
|
|
27556
27612
|
break;
|
|
27557
27613
|
case "providerNative":
|
|
27614
|
+
if (block.provider === "openai") {
|
|
27615
|
+
flush();
|
|
27616
|
+
const { id: _id, ...rest } = block.data;
|
|
27617
|
+
input.push({ type: block.blockType, ...rest });
|
|
27618
|
+
break;
|
|
27619
|
+
}
|
|
27558
27620
|
note("openai:anthropic-native-block-dropped");
|
|
27559
27621
|
break;
|
|
27560
27622
|
}
|
|
27561
27623
|
}
|
|
27562
27624
|
flush();
|
|
27563
27625
|
}
|
|
27626
|
+
repairOrphanedCalls(input);
|
|
27564
27627
|
const body = { model, input, stream: req.stream, store: false };
|
|
27565
27628
|
const instructions = systemText(req.system, "openai", note);
|
|
27566
27629
|
if (instructions !== undefined && instructions.length > 0)
|
|
@@ -27624,7 +27687,10 @@ var openaiCodec = {
|
|
|
27624
27687
|
throw input.fail("AUTH", "openai credential has no token");
|
|
27625
27688
|
}
|
|
27626
27689
|
const headers = orderHeaders(mergeHeaders(openaiProfile.headers, protocol), openaiProfile.order);
|
|
27690
|
+
const include = body.include;
|
|
27691
|
+
const nativeReasoning = Array.isArray(include) && include.includes("reasoning.encrypted_content");
|
|
27627
27692
|
return {
|
|
27693
|
+
decodeState: { nativeReasoning },
|
|
27628
27694
|
request: {
|
|
27629
27695
|
url: oauth ? OAUTH_URL2 : API_URL3,
|
|
27630
27696
|
method: "POST",
|
|
@@ -27634,8 +27700,9 @@ var openaiCodec = {
|
|
|
27634
27700
|
degradations
|
|
27635
27701
|
};
|
|
27636
27702
|
},
|
|
27637
|
-
decode({ body }) {
|
|
27638
|
-
|
|
27703
|
+
decode({ body, decodeState }) {
|
|
27704
|
+
const state = decodeState;
|
|
27705
|
+
return decodeResponses(parseSse(body), { nativeReasoning: state?.nativeReasoning === true });
|
|
27639
27706
|
}
|
|
27640
27707
|
};
|
|
27641
27708
|
|
|
@@ -27819,8 +27886,10 @@ function parseOrThrow(schema, body2) {
|
|
|
27819
27886
|
if (result.success)
|
|
27820
27887
|
return result.data;
|
|
27821
27888
|
const issue2 = result.error.issues[0];
|
|
27822
|
-
const
|
|
27823
|
-
|
|
27889
|
+
const segments = issue2?.path ?? [];
|
|
27890
|
+
const path = segments.length === 0 ? "(root)" : segments.map((s) => safeToken(String(s))).join(".");
|
|
27891
|
+
const detail = issue2 === undefined ? "invalid request" : issue2.code === "unrecognized_keys" ? `unrecognized key "${safeToken(issue2.keys[0])}"` : issue2.message;
|
|
27892
|
+
throw new GatewayError("BAD_REQUEST", `${path}: ${detail}`);
|
|
27824
27893
|
}
|
|
27825
27894
|
function optionalNumber(value, fallback) {
|
|
27826
27895
|
if (value === undefined)
|
|
@@ -28180,10 +28249,13 @@ function bestPositive(values2) {
|
|
|
28180
28249
|
return positive.length > 0 ? Math.min(...positive) : null;
|
|
28181
28250
|
}
|
|
28182
28251
|
var EXPECTED_OUTPUT_TOKENS = 1000;
|
|
28183
|
-
function
|
|
28252
|
+
function estimateTokens(request2) {
|
|
28184
28253
|
const cachedTok = estimateCachedInputTokens(request2);
|
|
28185
28254
|
const freshTok = Math.max(0, estimateInputTokens(request2) - cachedTok);
|
|
28186
28255
|
const outTok = Math.min(request2.maxTokens ?? EXPECTED_OUTPUT_TOKENS, EXPECTED_OUTPUT_TOKENS);
|
|
28256
|
+
return { cachedTok, freshTok, outTok };
|
|
28257
|
+
}
|
|
28258
|
+
function requestCost(target, { cachedTok, freshTok, outTok }) {
|
|
28187
28259
|
return freshTok * target.costPerMTok.input + cachedTok * cacheReadRate(target.costPerMTok) + outTok * target.costPerMTok.output;
|
|
28188
28260
|
}
|
|
28189
28261
|
function healthScore(h) {
|
|
@@ -28196,7 +28268,8 @@ function score(pairs, input) {
|
|
|
28196
28268
|
const tiers = pairs.map((p) => p.target.tier);
|
|
28197
28269
|
const minTier = Math.min(...tiers);
|
|
28198
28270
|
const maxTier = Math.max(...tiers);
|
|
28199
|
-
const
|
|
28271
|
+
const tokens2 = estimateTokens(input.request);
|
|
28272
|
+
const costs = pairs.map((p) => requestCost(p.target, tokens2));
|
|
28200
28273
|
const bestCost = bestPositive(costs);
|
|
28201
28274
|
const bestLatency = bestPositive(pairs.flatMap((p) => {
|
|
28202
28275
|
const h = snapshot.health.get(healthKey(p.credential.id, p.target.model));
|
|
@@ -28326,13 +28399,13 @@ function resolveModel(name, snapshot, providers = PROVIDER_DESCRIPTORS) {
|
|
|
28326
28399
|
if (descriptor2 !== undefined && prefix !== "custom" && rest.length > 0) {
|
|
28327
28400
|
return synthesize(prefix, rest, descriptor2);
|
|
28328
28401
|
}
|
|
28329
|
-
throw new GatewayError("NO_CANDIDATES", `unknown provider "${prefix}" in model "${name}"`);
|
|
28402
|
+
throw new GatewayError("NO_CANDIDATES", `unknown provider "${safeToken(prefix)}" in model "${safeToken(name)}"`);
|
|
28330
28403
|
}
|
|
28331
28404
|
for (const [prefix, provider, descriptor2] of prefixProviders(providers)) {
|
|
28332
28405
|
if (name.startsWith(prefix))
|
|
28333
28406
|
return synthesize(provider, name, descriptor2);
|
|
28334
28407
|
}
|
|
28335
|
-
throw new GatewayError("NO_CANDIDATES", `model "${name}" is not a configured virtual model and its provider could not be inferred`);
|
|
28408
|
+
throw new GatewayError("NO_CANDIDATES", `model "${safeToken(name)}" is not a configured virtual model and its provider could not be inferred`);
|
|
28336
28409
|
}
|
|
28337
28410
|
|
|
28338
28411
|
// packages/router/src/index.ts
|
|
@@ -29021,16 +29094,16 @@ async function createKey(store, input) {
|
|
|
29021
29094
|
}
|
|
29022
29095
|
async function setKeyLimits(store, id, input, now = Date.now()) {
|
|
29023
29096
|
const body2 = parseOrThrow(keyLimitsSchema, input);
|
|
29024
|
-
const key =
|
|
29025
|
-
if (key ===
|
|
29097
|
+
const key = await store.keys.get(id);
|
|
29098
|
+
if (key === null)
|
|
29026
29099
|
throw new GatewayError("BAD_REQUEST", "no such api key");
|
|
29027
29100
|
await store.keys.setLimits(id, body2.limits);
|
|
29028
29101
|
return toSummary(store, { ...key, limits: body2.limits }, now);
|
|
29029
29102
|
}
|
|
29030
29103
|
async function setKeyModels(store, id, input, now = Date.now()) {
|
|
29031
29104
|
const body2 = parseOrThrow(keyModelsSchema, input);
|
|
29032
|
-
const key =
|
|
29033
|
-
if (key ===
|
|
29105
|
+
const key = await store.keys.get(id);
|
|
29106
|
+
if (key === null)
|
|
29034
29107
|
throw new GatewayError("BAD_REQUEST", "no such api key");
|
|
29035
29108
|
await store.keys.setModelAllowlist(id, body2.modelAllowlist);
|
|
29036
29109
|
return toSummary(store, { ...key, modelAllowlist: body2.modelAllowlist }, now);
|
|
@@ -45483,6 +45556,367 @@ function openaiRateLimitHeaders(headroom, now) {
|
|
|
45483
45556
|
return headers;
|
|
45484
45557
|
}
|
|
45485
45558
|
|
|
45559
|
+
// apps/gateway/src/egress/responses.ts
|
|
45560
|
+
var STATUS = {
|
|
45561
|
+
endTurn: { status: "completed" },
|
|
45562
|
+
toolUse: { status: "completed" },
|
|
45563
|
+
stopSequence: { status: "completed" },
|
|
45564
|
+
pauseTurn: { status: "completed" },
|
|
45565
|
+
maxTokens: { status: "incomplete", reason: "max_output_tokens" },
|
|
45566
|
+
contentFilter: { status: "incomplete", reason: "content_filter" }
|
|
45567
|
+
};
|
|
45568
|
+
function usageBody2(usage) {
|
|
45569
|
+
const input = promptTokens(usage);
|
|
45570
|
+
return {
|
|
45571
|
+
input_tokens: input,
|
|
45572
|
+
input_tokens_details: { cached_tokens: usage.cacheReadTokens },
|
|
45573
|
+
output_tokens: usage.outputTokens,
|
|
45574
|
+
output_tokens_details: { reasoning_tokens: 0 },
|
|
45575
|
+
total_tokens: input + usage.outputTokens
|
|
45576
|
+
};
|
|
45577
|
+
}
|
|
45578
|
+
var CONTENT_INDEX = 0;
|
|
45579
|
+
function customToolInput(raw) {
|
|
45580
|
+
try {
|
|
45581
|
+
const parsed2 = JSON.parse(raw);
|
|
45582
|
+
if (typeof parsed2 === "object" && parsed2 !== null && "input" in parsed2) {
|
|
45583
|
+
const inner = parsed2.input;
|
|
45584
|
+
if (typeof inner === "string")
|
|
45585
|
+
return inner;
|
|
45586
|
+
}
|
|
45587
|
+
} catch {}
|
|
45588
|
+
return raw;
|
|
45589
|
+
}
|
|
45590
|
+
function renderItem(item, status2) {
|
|
45591
|
+
const done = status2 === "completed";
|
|
45592
|
+
switch (item.kind) {
|
|
45593
|
+
case "message":
|
|
45594
|
+
return {
|
|
45595
|
+
id: item.id,
|
|
45596
|
+
type: "message",
|
|
45597
|
+
status: status2,
|
|
45598
|
+
role: "assistant",
|
|
45599
|
+
content: done ? [{ type: "output_text", text: item.text, annotations: [] }] : []
|
|
45600
|
+
};
|
|
45601
|
+
case "reasoning":
|
|
45602
|
+
return {
|
|
45603
|
+
id: item.id,
|
|
45604
|
+
type: "reasoning",
|
|
45605
|
+
status: status2,
|
|
45606
|
+
summary: done && item.text !== "" ? [{ type: "summary_text", text: item.text }] : []
|
|
45607
|
+
};
|
|
45608
|
+
case "function_call":
|
|
45609
|
+
return {
|
|
45610
|
+
id: item.id,
|
|
45611
|
+
type: "function_call",
|
|
45612
|
+
status: status2,
|
|
45613
|
+
call_id: item.callId,
|
|
45614
|
+
name: item.toolName,
|
|
45615
|
+
arguments: done ? item.text : ""
|
|
45616
|
+
};
|
|
45617
|
+
case "custom_tool_call":
|
|
45618
|
+
return {
|
|
45619
|
+
id: item.id,
|
|
45620
|
+
type: "custom_tool_call",
|
|
45621
|
+
status: status2,
|
|
45622
|
+
call_id: item.callId,
|
|
45623
|
+
name: item.toolName,
|
|
45624
|
+
input: done ? customToolInput(item.text) : ""
|
|
45625
|
+
};
|
|
45626
|
+
case "native":
|
|
45627
|
+
return item.native;
|
|
45628
|
+
}
|
|
45629
|
+
}
|
|
45630
|
+
async function* responsesStream(events, render) {
|
|
45631
|
+
let model = "";
|
|
45632
|
+
let sequence = 0;
|
|
45633
|
+
let terminated = false;
|
|
45634
|
+
const frame2 = (event, data) => ({
|
|
45635
|
+
event,
|
|
45636
|
+
data: JSON.stringify({ type: event, sequence_number: ++sequence, ...data })
|
|
45637
|
+
});
|
|
45638
|
+
const output = [];
|
|
45639
|
+
const snapshot = (status2, extra) => ({
|
|
45640
|
+
id: `resp_${render.requestId}`,
|
|
45641
|
+
object: "response",
|
|
45642
|
+
created_at: render.created,
|
|
45643
|
+
status: status2,
|
|
45644
|
+
model,
|
|
45645
|
+
output,
|
|
45646
|
+
...extra
|
|
45647
|
+
});
|
|
45648
|
+
let nextOutputIndex = 0;
|
|
45649
|
+
const state = { open: null };
|
|
45650
|
+
const ID_PREFIX = {
|
|
45651
|
+
message: "msg",
|
|
45652
|
+
reasoning: "rs",
|
|
45653
|
+
function_call: "fc",
|
|
45654
|
+
custom_tool_call: "ctc",
|
|
45655
|
+
native: "item"
|
|
45656
|
+
};
|
|
45657
|
+
const open = (irIndex, kind, seed) => {
|
|
45658
|
+
const outputIndex = nextOutputIndex++;
|
|
45659
|
+
const id = seed?.callId !== undefined && seed.callId !== "" ? `${ID_PREFIX[kind]}_${seed.callId}` : `${ID_PREFIX[kind]}_${render.requestId}_${outputIndex}`;
|
|
45660
|
+
state.open = {
|
|
45661
|
+
irIndex,
|
|
45662
|
+
outputIndex,
|
|
45663
|
+
id,
|
|
45664
|
+
kind,
|
|
45665
|
+
text: "",
|
|
45666
|
+
toolName: "",
|
|
45667
|
+
callId: "",
|
|
45668
|
+
native: {},
|
|
45669
|
+
...seed
|
|
45670
|
+
};
|
|
45671
|
+
return state.open;
|
|
45672
|
+
};
|
|
45673
|
+
const itemBody = (item, status2) => renderItem(item, status2);
|
|
45674
|
+
function* closeCurrent() {
|
|
45675
|
+
const item = state.open;
|
|
45676
|
+
if (item === null)
|
|
45677
|
+
return;
|
|
45678
|
+
state.open = null;
|
|
45679
|
+
const at = { item_id: item.id, output_index: item.outputIndex, content_index: CONTENT_INDEX };
|
|
45680
|
+
switch (item.kind) {
|
|
45681
|
+
case "message":
|
|
45682
|
+
yield frame2("response.output_text.done", { ...at, text: item.text });
|
|
45683
|
+
yield frame2("response.content_part.done", {
|
|
45684
|
+
...at,
|
|
45685
|
+
part: { type: "output_text", text: item.text, annotations: [] }
|
|
45686
|
+
});
|
|
45687
|
+
break;
|
|
45688
|
+
case "reasoning":
|
|
45689
|
+
yield frame2("response.reasoning_summary_text.done", {
|
|
45690
|
+
item_id: item.id,
|
|
45691
|
+
output_index: item.outputIndex,
|
|
45692
|
+
summary_index: CONTENT_INDEX,
|
|
45693
|
+
text: item.text
|
|
45694
|
+
});
|
|
45695
|
+
yield frame2("response.reasoning_summary_part.done", {
|
|
45696
|
+
item_id: item.id,
|
|
45697
|
+
output_index: item.outputIndex,
|
|
45698
|
+
summary_index: CONTENT_INDEX,
|
|
45699
|
+
part: { type: "summary_text", text: item.text }
|
|
45700
|
+
});
|
|
45701
|
+
break;
|
|
45702
|
+
case "function_call":
|
|
45703
|
+
yield frame2("response.function_call_arguments.done", {
|
|
45704
|
+
item_id: item.id,
|
|
45705
|
+
output_index: item.outputIndex,
|
|
45706
|
+
arguments: item.text
|
|
45707
|
+
});
|
|
45708
|
+
break;
|
|
45709
|
+
case "custom_tool_call": {
|
|
45710
|
+
const input = customToolInput(item.text);
|
|
45711
|
+
yield frame2("response.custom_tool_call_input.delta", {
|
|
45712
|
+
item_id: item.id,
|
|
45713
|
+
output_index: item.outputIndex,
|
|
45714
|
+
delta: input
|
|
45715
|
+
});
|
|
45716
|
+
yield frame2("response.custom_tool_call_input.done", {
|
|
45717
|
+
item_id: item.id,
|
|
45718
|
+
output_index: item.outputIndex,
|
|
45719
|
+
input
|
|
45720
|
+
});
|
|
45721
|
+
break;
|
|
45722
|
+
}
|
|
45723
|
+
case "native":
|
|
45724
|
+
break;
|
|
45725
|
+
}
|
|
45726
|
+
const body2 = itemBody(item, "completed");
|
|
45727
|
+
output.push(body2);
|
|
45728
|
+
yield frame2("response.output_item.done", { output_index: item.outputIndex, item: body2 });
|
|
45729
|
+
}
|
|
45730
|
+
function* closeChecked(irIndex) {
|
|
45731
|
+
if (state.open === null || state.open.irIndex !== irIndex)
|
|
45732
|
+
return;
|
|
45733
|
+
yield* closeCurrent();
|
|
45734
|
+
}
|
|
45735
|
+
for await (const event of events) {
|
|
45736
|
+
switch (event.type) {
|
|
45737
|
+
case "start":
|
|
45738
|
+
model = event.model;
|
|
45739
|
+
yield frame2("response.created", { response: snapshot("in_progress") });
|
|
45740
|
+
yield frame2("response.in_progress", { response: snapshot("in_progress") });
|
|
45741
|
+
break;
|
|
45742
|
+
case "blockStart": {
|
|
45743
|
+
if (state.open !== null && state.open.irIndex === event.index)
|
|
45744
|
+
break;
|
|
45745
|
+
yield* closeCurrent();
|
|
45746
|
+
const block = event.block;
|
|
45747
|
+
const kind = block.type === "text" ? "message" : block.type === "thinking" ? "reasoning" : block.type === "toolUse" ? render.customToolNames.has(block.name) ? "custom_tool_call" : "function_call" : "native";
|
|
45748
|
+
const item = open(event.index, kind, block.type === "toolUse" ? { callId: block.id, toolName: block.name } : block.type === "providerNative" ? { native: { type: block.blockType, ...block.data } } : {});
|
|
45749
|
+
yield frame2("response.output_item.added", {
|
|
45750
|
+
output_index: item.outputIndex,
|
|
45751
|
+
item: itemBody(item, "in_progress")
|
|
45752
|
+
});
|
|
45753
|
+
if (kind === "message") {
|
|
45754
|
+
yield frame2("response.content_part.added", {
|
|
45755
|
+
item_id: item.id,
|
|
45756
|
+
output_index: item.outputIndex,
|
|
45757
|
+
content_index: CONTENT_INDEX,
|
|
45758
|
+
part: { type: "output_text", text: "", annotations: [] }
|
|
45759
|
+
});
|
|
45760
|
+
}
|
|
45761
|
+
if (kind === "reasoning") {
|
|
45762
|
+
yield frame2("response.reasoning_summary_part.added", {
|
|
45763
|
+
item_id: item.id,
|
|
45764
|
+
output_index: item.outputIndex,
|
|
45765
|
+
summary_index: CONTENT_INDEX,
|
|
45766
|
+
part: { type: "summary_text", text: "" }
|
|
45767
|
+
});
|
|
45768
|
+
}
|
|
45769
|
+
break;
|
|
45770
|
+
}
|
|
45771
|
+
case "blockDelta": {
|
|
45772
|
+
const item = state.open;
|
|
45773
|
+
if (item === null || item.irIndex !== event.index)
|
|
45774
|
+
break;
|
|
45775
|
+
const delta2 = event.delta;
|
|
45776
|
+
if (delta2.type === "text" && item.kind === "message") {
|
|
45777
|
+
item.text += delta2.text;
|
|
45778
|
+
yield frame2("response.output_text.delta", {
|
|
45779
|
+
item_id: item.id,
|
|
45780
|
+
output_index: item.outputIndex,
|
|
45781
|
+
content_index: CONTENT_INDEX,
|
|
45782
|
+
delta: delta2.text
|
|
45783
|
+
});
|
|
45784
|
+
}
|
|
45785
|
+
if (delta2.type === "thinking" && item.kind === "reasoning") {
|
|
45786
|
+
item.text += delta2.text;
|
|
45787
|
+
yield frame2("response.reasoning_summary_text.delta", {
|
|
45788
|
+
item_id: item.id,
|
|
45789
|
+
output_index: item.outputIndex,
|
|
45790
|
+
summary_index: CONTENT_INDEX,
|
|
45791
|
+
delta: delta2.text
|
|
45792
|
+
});
|
|
45793
|
+
}
|
|
45794
|
+
if (delta2.type === "toolJson") {
|
|
45795
|
+
item.text += delta2.partial;
|
|
45796
|
+
if (item.kind === "function_call") {
|
|
45797
|
+
yield frame2("response.function_call_arguments.delta", {
|
|
45798
|
+
item_id: item.id,
|
|
45799
|
+
output_index: item.outputIndex,
|
|
45800
|
+
delta: delta2.partial
|
|
45801
|
+
});
|
|
45802
|
+
}
|
|
45803
|
+
}
|
|
45804
|
+
if (delta2.type === "providerNative" && item.kind === "native") {
|
|
45805
|
+
if (delta2.deltaType === "reasoning_summary_text.delta") {
|
|
45806
|
+
yield frame2("response.reasoning_summary_text.delta", {
|
|
45807
|
+
item_id: item.id,
|
|
45808
|
+
output_index: item.outputIndex,
|
|
45809
|
+
summary_index: CONTENT_INDEX,
|
|
45810
|
+
delta: String(delta2.data.text ?? "")
|
|
45811
|
+
});
|
|
45812
|
+
}
|
|
45813
|
+
if (delta2.fold === "merge") {
|
|
45814
|
+
item.native = { ...item.native, ...delta2.data };
|
|
45815
|
+
}
|
|
45816
|
+
}
|
|
45817
|
+
break;
|
|
45818
|
+
}
|
|
45819
|
+
case "blockEnd":
|
|
45820
|
+
yield* closeChecked(event.index);
|
|
45821
|
+
break;
|
|
45822
|
+
case "end": {
|
|
45823
|
+
yield* closeCurrent();
|
|
45824
|
+
const { status: status2, reason } = STATUS[event.stopReason];
|
|
45825
|
+
terminated = true;
|
|
45826
|
+
yield frame2(status2 === "completed" ? "response.completed" : "response.incomplete", {
|
|
45827
|
+
response: snapshot(status2, {
|
|
45828
|
+
...reason === undefined ? {} : { incomplete_details: { reason } },
|
|
45829
|
+
usage: usageBody2(event.usage)
|
|
45830
|
+
})
|
|
45831
|
+
});
|
|
45832
|
+
break;
|
|
45833
|
+
}
|
|
45834
|
+
case "error":
|
|
45835
|
+
yield* closeCurrent();
|
|
45836
|
+
terminated = true;
|
|
45837
|
+
yield frame2("response.failed", {
|
|
45838
|
+
response: snapshot("failed", {
|
|
45839
|
+
error: { code: ERROR_TYPE3[event.code].code, message: event.message }
|
|
45840
|
+
})
|
|
45841
|
+
});
|
|
45842
|
+
break;
|
|
45843
|
+
}
|
|
45844
|
+
}
|
|
45845
|
+
if (!terminated) {
|
|
45846
|
+
yield* closeCurrent();
|
|
45847
|
+
yield frame2("response.failed", {
|
|
45848
|
+
response: snapshot("failed", {
|
|
45849
|
+
error: { code: "stream_disconnected", message: "stream closed before response.completed" }
|
|
45850
|
+
})
|
|
45851
|
+
});
|
|
45852
|
+
}
|
|
45853
|
+
yield { event: "message", data: "[DONE]" };
|
|
45854
|
+
}
|
|
45855
|
+
function responsesResponse(collected, render) {
|
|
45856
|
+
const output = [];
|
|
45857
|
+
let index = 0;
|
|
45858
|
+
for (const block of collected.content) {
|
|
45859
|
+
const outputIndex = index++;
|
|
45860
|
+
const at = { irIndex: outputIndex, outputIndex, toolName: "", callId: "", native: {} };
|
|
45861
|
+
if (block.type === "text") {
|
|
45862
|
+
output.push(renderItem({
|
|
45863
|
+
...at,
|
|
45864
|
+
kind: "message",
|
|
45865
|
+
id: `msg_${render.requestId}_${outputIndex}`,
|
|
45866
|
+
text: block.text
|
|
45867
|
+
}, "completed"));
|
|
45868
|
+
}
|
|
45869
|
+
if (block.type === "thinking") {
|
|
45870
|
+
output.push(renderItem({
|
|
45871
|
+
...at,
|
|
45872
|
+
kind: "reasoning",
|
|
45873
|
+
id: `rs_${render.requestId}_${outputIndex}`,
|
|
45874
|
+
text: block.text
|
|
45875
|
+
}, "completed"));
|
|
45876
|
+
}
|
|
45877
|
+
if (block.type === "toolUse") {
|
|
45878
|
+
const custom2 = render.customToolNames.has(block.name);
|
|
45879
|
+
const kind = custom2 ? "custom_tool_call" : "function_call";
|
|
45880
|
+
output.push(renderItem({
|
|
45881
|
+
...at,
|
|
45882
|
+
kind,
|
|
45883
|
+
id: `${custom2 ? "ctc" : "fc"}_${block.id}`,
|
|
45884
|
+
text: JSON.stringify(block.input),
|
|
45885
|
+
toolName: block.name,
|
|
45886
|
+
callId: block.id
|
|
45887
|
+
}, "completed"));
|
|
45888
|
+
}
|
|
45889
|
+
if (block.type === "providerNative" && block.provider === "openai") {
|
|
45890
|
+
output.push(renderItem({
|
|
45891
|
+
...at,
|
|
45892
|
+
kind: "native",
|
|
45893
|
+
id: `item_${render.requestId}_${outputIndex}`,
|
|
45894
|
+
text: "",
|
|
45895
|
+
native: { type: block.blockType, ...block.data }
|
|
45896
|
+
}, "completed"));
|
|
45897
|
+
}
|
|
45898
|
+
}
|
|
45899
|
+
const { status: status2, reason } = STATUS[collected.stopReason];
|
|
45900
|
+
return {
|
|
45901
|
+
id: `resp_${render.requestId}`,
|
|
45902
|
+
object: "response",
|
|
45903
|
+
created_at: render.created,
|
|
45904
|
+
status: status2,
|
|
45905
|
+
model: collected.model,
|
|
45906
|
+
output,
|
|
45907
|
+
store: false,
|
|
45908
|
+
...reason === undefined ? {} : { incomplete_details: { reason } },
|
|
45909
|
+
usage: usageBody2(collected.usage)
|
|
45910
|
+
};
|
|
45911
|
+
}
|
|
45912
|
+
function responsesErrorBody(code, message) {
|
|
45913
|
+
const { type, code: errorCode } = ERROR_TYPE3[code];
|
|
45914
|
+
return { error: { type, code: errorCode, message, param: null } };
|
|
45915
|
+
}
|
|
45916
|
+
function responsesRateLimitHeaders(headroom, now) {
|
|
45917
|
+
return openaiRateLimitHeaders(headroom, now);
|
|
45918
|
+
}
|
|
45919
|
+
|
|
45486
45920
|
// apps/gateway/src/ingress/schemas.ts
|
|
45487
45921
|
var cacheControlSchema = exports_external.object({
|
|
45488
45922
|
type: exports_external.literal("ephemeral"),
|
|
@@ -45511,8 +45945,19 @@ function parseOrThrow2(schema, body2) {
|
|
|
45511
45945
|
if (result.success)
|
|
45512
45946
|
return result.data;
|
|
45513
45947
|
const issue2 = result.error.issues[0];
|
|
45514
|
-
|
|
45515
|
-
|
|
45948
|
+
throw new GatewayError("BAD_REQUEST", `${issuePath(issue2)}: ${zodDetail(issue2)}`);
|
|
45949
|
+
}
|
|
45950
|
+
function issuePath(issue2) {
|
|
45951
|
+
const segments = issue2?.path ?? [];
|
|
45952
|
+
return segments.length === 0 ? "(root)" : segments.map((s) => safeToken(String(s))).join(".");
|
|
45953
|
+
}
|
|
45954
|
+
function zodDetail(issue2) {
|
|
45955
|
+
if (issue2 === undefined)
|
|
45956
|
+
return "invalid request";
|
|
45957
|
+
if (issue2.code === "unrecognized_keys") {
|
|
45958
|
+
return `unrecognized key "${safeToken(issue2.keys[0])}"`;
|
|
45959
|
+
}
|
|
45960
|
+
return issue2.message;
|
|
45516
45961
|
}
|
|
45517
45962
|
function isRecord7(value) {
|
|
45518
45963
|
return typeof value === "object" && value !== null;
|
|
@@ -45528,7 +45973,8 @@ function extraFields(body2, known) {
|
|
|
45528
45973
|
var CONVERSATION_HEADERS = [
|
|
45529
45974
|
"x-session-id",
|
|
45530
45975
|
"x-session-affinity",
|
|
45531
|
-
"x-deepseek-harness-session-id"
|
|
45976
|
+
"x-deepseek-harness-session-id",
|
|
45977
|
+
"session-id"
|
|
45532
45978
|
];
|
|
45533
45979
|
function readConversationHeader(headers) {
|
|
45534
45980
|
for (const name of CONVERSATION_HEADERS) {
|
|
@@ -45573,7 +46019,7 @@ function readSidecarImage(raw, declaredMediaType) {
|
|
|
45573
46019
|
};
|
|
45574
46020
|
}
|
|
45575
46021
|
if (!mediaType.startsWith("image/")) {
|
|
45576
|
-
return { ok: false, reason: "not-an-image", detail: `${mediaType} is not an image` };
|
|
46022
|
+
return { ok: false, reason: "not-an-image", detail: `${safeToken(mediaType)} is not an image` };
|
|
45577
46023
|
}
|
|
45578
46024
|
return { ok: true, mediaType, data: resolved.data };
|
|
45579
46025
|
}
|
|
@@ -48866,7 +49312,7 @@ async function dispatch(request2, deps, signal, requestId) {
|
|
|
48866
49312
|
}
|
|
48867
49313
|
if (candidates.length === 0) {
|
|
48868
49314
|
clearDeadline();
|
|
48869
|
-
return fail("NO_CANDIDATES", `no eligible credential for model "${request2.model}"`);
|
|
49315
|
+
return fail("NO_CANDIDATES", `no eligible credential for model "${safeToken(request2.model)}"`);
|
|
48870
49316
|
}
|
|
48871
49317
|
const maxAttempts = Math.min(snapshot.settings.maxAttempts, candidates.length);
|
|
48872
49318
|
const head = candidates[0];
|
|
@@ -48990,7 +49436,9 @@ async function dispatch(request2, deps, signal, requestId) {
|
|
|
48990
49436
|
if (event.type === "error") {
|
|
48991
49437
|
terminal = true;
|
|
48992
49438
|
if (!committed && RETRYABLE[event.code]) {
|
|
48993
|
-
throw new GatewayError(event.code, event.message
|
|
49439
|
+
throw new GatewayError(event.code, event.message, {
|
|
49440
|
+
provider: candidate.target.provider
|
|
49441
|
+
});
|
|
48994
49442
|
}
|
|
48995
49443
|
committed = true;
|
|
48996
49444
|
log.status = HTTP_STATUS[event.code];
|
|
@@ -49266,18 +49714,18 @@ function fail(path, message) {
|
|
|
49266
49714
|
}
|
|
49267
49715
|
function field(path, name, value) {
|
|
49268
49716
|
const schema = TOOL_FIELDS[name];
|
|
49269
|
-
if (schema === undefined)
|
|
49270
|
-
fail(`${path}.${name}`, `unsupported field "${name}"`);
|
|
49271
|
-
const parsed2 = schema.safeParse(value);
|
|
49272
|
-
if (!parsed2.success) {
|
|
49273
|
-
fail(`${path}.${name}`, parsed2.error.issues[0]?.message ?? "invalid value");
|
|
49717
|
+
if (schema === undefined) {
|
|
49718
|
+
fail(`${path}.${safeToken(name)}`, `unsupported field "${safeToken(name)}"`);
|
|
49274
49719
|
}
|
|
49720
|
+
const parsed2 = schema.safeParse(value);
|
|
49721
|
+
if (!parsed2.success)
|
|
49722
|
+
fail(`${path}.${safeToken(name)}`, zodDetail(parsed2.error.issues[0]));
|
|
49275
49723
|
return parsed2.data;
|
|
49276
49724
|
}
|
|
49277
49725
|
function parseAnthropicTool(raw, type, path, mcpServerNames) {
|
|
49278
49726
|
const spec = anthropicToolSpec(type);
|
|
49279
49727
|
if (spec === undefined)
|
|
49280
|
-
fail(`${path}.type`, `unrecognized tool type "${type}"`);
|
|
49728
|
+
fail(`${path}.type`, `unrecognized tool type "${safeToken(type)}"`);
|
|
49281
49729
|
if (spec.name !== undefined && raw.name !== spec.name) {
|
|
49282
49730
|
fail(`${path}.name`, `${type} must be declared with name "${spec.name}"`);
|
|
49283
49731
|
}
|
|
@@ -49294,8 +49742,9 @@ function parseAnthropicTool(raw, type, path, mcpServerNames) {
|
|
|
49294
49742
|
for (const [key, value] of Object.entries(raw)) {
|
|
49295
49743
|
if (key === "type" || key === "name")
|
|
49296
49744
|
continue;
|
|
49297
|
-
if (!allowed.has(key))
|
|
49298
|
-
fail(`${path}.${key}`, `${type} does not accept "${key}"`);
|
|
49745
|
+
if (!allowed.has(key)) {
|
|
49746
|
+
fail(`${path}.${safeToken(key)}`, `${type} does not accept "${safeToken(key)}"`);
|
|
49747
|
+
}
|
|
49299
49748
|
const parsed2 = field(path, key, value);
|
|
49300
49749
|
if (key === "cache_control") {
|
|
49301
49750
|
cacheControl = irCacheControl(parsed2 === null ? undefined : parsed2).cacheControl;
|
|
@@ -49310,7 +49759,7 @@ function parseAnthropicTool(raw, type, path, mcpServerNames) {
|
|
|
49310
49759
|
if (spec.family === "mcpToolset") {
|
|
49311
49760
|
const server = wire.mcp_server_name;
|
|
49312
49761
|
if (typeof server === "string" && !mcpServerNames.has(server)) {
|
|
49313
|
-
fail(`${path}.mcp_server_name`, `no mcp_servers entry named "${server}"`);
|
|
49762
|
+
fail(`${path}.mcp_server_name`, `no mcp_servers entry named "${safeToken(server)}"`);
|
|
49314
49763
|
}
|
|
49315
49764
|
}
|
|
49316
49765
|
return {
|
|
@@ -49334,7 +49783,7 @@ function parseCustomTool(raw, path) {
|
|
|
49334
49783
|
if (["type", "name", "description", "input_schema", "cache_control"].includes(key))
|
|
49335
49784
|
continue;
|
|
49336
49785
|
if (!ANTHROPIC_CUSTOM_TOOL_OPTIONS.includes(key)) {
|
|
49337
|
-
fail(`${path}.${key}`, `unsupported field "${key}"`);
|
|
49786
|
+
fail(`${path}.${safeToken(key)}`, `unsupported field "${safeToken(key)}"`);
|
|
49338
49787
|
}
|
|
49339
49788
|
const value_ = field(path, key, value);
|
|
49340
49789
|
if (value_ !== null)
|
|
@@ -49381,6 +49830,7 @@ function mcpServerNames(body2) {
|
|
|
49381
49830
|
}
|
|
49382
49831
|
|
|
49383
49832
|
// apps/gateway/src/ingress/model.ts
|
|
49833
|
+
var MODEL_NAME_MAX = 200;
|
|
49384
49834
|
var ONE_M_SUFFIX2 = "[1m]";
|
|
49385
49835
|
function normalizeClientModel(raw, betas2 = []) {
|
|
49386
49836
|
let model = raw.trim();
|
|
@@ -49577,7 +50027,7 @@ var message = exports_external.object({
|
|
|
49577
50027
|
content: exports_external.union([exports_external.string(), exports_external.array(exports_external.unknown())])
|
|
49578
50028
|
});
|
|
49579
50029
|
var schema = exports_external.object({
|
|
49580
|
-
model: exports_external.string().min(1),
|
|
50030
|
+
model: exports_external.string().min(1).max(MODEL_NAME_MAX),
|
|
49581
50031
|
messages: exports_external.array(message).min(1),
|
|
49582
50032
|
system: exports_external.union([exports_external.string(), exports_external.array(textBlock)]).optional(),
|
|
49583
50033
|
max_tokens: exports_external.number().int().positive().optional(),
|
|
@@ -49701,9 +50151,10 @@ function readBlock(raw, role, path) {
|
|
|
49701
50151
|
const parsed3 = nativeSchema.safeParse(raw);
|
|
49702
50152
|
if (!parsed3.success) {
|
|
49703
50153
|
const issue2 = parsed3.error.issues[0];
|
|
49704
|
-
const
|
|
49705
|
-
const
|
|
49706
|
-
|
|
50154
|
+
const unknownKey = issue2?.code === "unrecognized_keys" ? safeToken(issue2.keys[0]) : null;
|
|
50155
|
+
const issuePath2 = unknownKey === null ? issue2?.path : [...issue2?.path ?? [], unknownKey];
|
|
50156
|
+
const suffix = issuePath2?.length ? `.${issuePath2.join(".")}` : "";
|
|
50157
|
+
throw new GatewayError("BAD_REQUEST", `${path}${suffix}: ${zodDetail(issue2)}`);
|
|
49707
50158
|
}
|
|
49708
50159
|
const { type: _type, cache_control, ...data } = parsed3.data;
|
|
49709
50160
|
return {
|
|
@@ -49721,11 +50172,11 @@ function readBlock(raw, role, path) {
|
|
|
49721
50172
|
if (issue2?.code === "invalid_union" || issue2?.path.at(-1) === "type") {
|
|
49722
50173
|
const type = raw?.type;
|
|
49723
50174
|
if (typeof type === "string") {
|
|
49724
|
-
throw new GatewayError("BAD_REQUEST", `${path}.type: unrecognized block type "${type}"`);
|
|
50175
|
+
throw new GatewayError("BAD_REQUEST", `${path}.type: unrecognized block type "${safeToken(type)}"`);
|
|
49725
50176
|
}
|
|
49726
50177
|
}
|
|
49727
50178
|
const suffix = issue2?.path.length ? `.${issue2.path.join(".")}` : "";
|
|
49728
|
-
throw new GatewayError("BAD_REQUEST", `${path}${suffix}: ${issue2
|
|
50179
|
+
throw new GatewayError("BAD_REQUEST", `${path}${suffix}: ${zodDetail(issue2)}`);
|
|
49729
50180
|
}
|
|
49730
50181
|
return toIrBlock(parsed2.data);
|
|
49731
50182
|
}
|
|
@@ -49872,7 +50323,7 @@ function sidecarImages(m) {
|
|
|
49872
50323
|
return blocks2;
|
|
49873
50324
|
}
|
|
49874
50325
|
var schema2 = exports_external.object({
|
|
49875
|
-
model: exports_external.string().min(1),
|
|
50326
|
+
model: exports_external.string().min(1).max(MODEL_NAME_MAX),
|
|
49876
50327
|
messages: exports_external.array(message2).min(1),
|
|
49877
50328
|
max_tokens: exports_external.number().int().positive().optional(),
|
|
49878
50329
|
max_completion_tokens: exports_external.number().int().positive().optional(),
|
|
@@ -50031,6 +50482,265 @@ function parseOpenAIRequest(body2, headers) {
|
|
|
50031
50482
|
return validateRequest(request2);
|
|
50032
50483
|
}
|
|
50033
50484
|
|
|
50485
|
+
// apps/gateway/src/ingress/responses.ts
|
|
50486
|
+
import { createHash as createHash5 } from "crypto";
|
|
50487
|
+
var reasoning = exports_external.object({
|
|
50488
|
+
effort: exports_external.enum(REASONING_EFFORTS).optional(),
|
|
50489
|
+
summary: exports_external.string().optional()
|
|
50490
|
+
});
|
|
50491
|
+
var schema3 = exports_external.object({
|
|
50492
|
+
model: exports_external.string().min(1).max(MODEL_NAME_MAX),
|
|
50493
|
+
input: exports_external.union([exports_external.string(), exports_external.array(exports_external.unknown())]),
|
|
50494
|
+
tools: exports_external.array(exports_external.unknown()).optional(),
|
|
50495
|
+
instructions: exports_external.string().optional(),
|
|
50496
|
+
max_output_tokens: exports_external.number().int().positive().optional(),
|
|
50497
|
+
temperature: exports_external.number().optional(),
|
|
50498
|
+
stream: exports_external.boolean().optional(),
|
|
50499
|
+
reasoning: reasoning.optional(),
|
|
50500
|
+
tool_choice: exports_external.union([
|
|
50501
|
+
exports_external.enum(["auto", "none", "required"]),
|
|
50502
|
+
exports_external.object({ type: exports_external.enum(["function", "custom"]), name: exports_external.string() })
|
|
50503
|
+
]).optional(),
|
|
50504
|
+
previous_response_id: exports_external.string().nullish(),
|
|
50505
|
+
store: exports_external.boolean().nullish(),
|
|
50506
|
+
background: exports_external.boolean().nullish(),
|
|
50507
|
+
prompt_cache_key: exports_external.string().nullish()
|
|
50508
|
+
});
|
|
50509
|
+
var KNOWN3 = [
|
|
50510
|
+
"model",
|
|
50511
|
+
"input",
|
|
50512
|
+
"instructions",
|
|
50513
|
+
"tools",
|
|
50514
|
+
"tool_choice",
|
|
50515
|
+
"stream",
|
|
50516
|
+
"store",
|
|
50517
|
+
"reasoning",
|
|
50518
|
+
"background",
|
|
50519
|
+
"previous_response_id",
|
|
50520
|
+
"max_output_tokens",
|
|
50521
|
+
"temperature",
|
|
50522
|
+
"metadata",
|
|
50523
|
+
"user"
|
|
50524
|
+
];
|
|
50525
|
+
function refuseStatefulFields(parsed2) {
|
|
50526
|
+
if (typeof parsed2.previous_response_id === "string" && parsed2.previous_response_id.length > 0) {
|
|
50527
|
+
throw new GatewayError("BAD_REQUEST", "previous_response_id: this gateway stores no responses, so prior state cannot be resumed");
|
|
50528
|
+
}
|
|
50529
|
+
if (parsed2.store === true) {
|
|
50530
|
+
throw new GatewayError("BAD_REQUEST", "store: this gateway stores no responses; send store: false or omit it");
|
|
50531
|
+
}
|
|
50532
|
+
}
|
|
50533
|
+
function readCacheKey(raw) {
|
|
50534
|
+
if (typeof raw !== "string")
|
|
50535
|
+
return;
|
|
50536
|
+
const trimmed = raw.trim();
|
|
50537
|
+
return trimmed.length > 0 && trimmed.length <= 512 ? trimmed : undefined;
|
|
50538
|
+
}
|
|
50539
|
+
function toIrToolChoice3(c) {
|
|
50540
|
+
if (typeof c === "string")
|
|
50541
|
+
return c === "required" ? { type: "any" } : { type: c };
|
|
50542
|
+
return { type: "tool", name: c.name };
|
|
50543
|
+
}
|
|
50544
|
+
function toIrReasoning2(r) {
|
|
50545
|
+
return {
|
|
50546
|
+
mode: "adaptive",
|
|
50547
|
+
...r.effort === undefined ? {} : { effort: r.effort },
|
|
50548
|
+
...r.summary === "none" ? { display: "omitted" } : {}
|
|
50549
|
+
};
|
|
50550
|
+
}
|
|
50551
|
+
function clampCallId(raw) {
|
|
50552
|
+
return raw.length <= 64 ? raw : createHash5("sha256").update(raw).digest("hex");
|
|
50553
|
+
}
|
|
50554
|
+
function roleOf(raw) {
|
|
50555
|
+
if (raw === "assistant")
|
|
50556
|
+
return "assistant";
|
|
50557
|
+
if (raw === "system" || raw === "developer")
|
|
50558
|
+
return "system";
|
|
50559
|
+
return "user";
|
|
50560
|
+
}
|
|
50561
|
+
function contentPart(part2) {
|
|
50562
|
+
if (!isRecord7(part2))
|
|
50563
|
+
throw new GatewayError("BAD_REQUEST", "input: content part must be an object");
|
|
50564
|
+
const type = part2.type;
|
|
50565
|
+
if (type === "input_text" || type === "output_text") {
|
|
50566
|
+
return { type: "text", text: String(part2.text ?? "") };
|
|
50567
|
+
}
|
|
50568
|
+
if (type === "input_image") {
|
|
50569
|
+
const url2 = typeof part2.image_url === "string" ? part2.image_url : "";
|
|
50570
|
+
if (!url2.startsWith("data:"))
|
|
50571
|
+
return null;
|
|
50572
|
+
const { mediaType, data } = parseDataUrl(url2);
|
|
50573
|
+
return { type: "image", mediaType, data };
|
|
50574
|
+
}
|
|
50575
|
+
throw new GatewayError("BAD_REQUEST", `input: unsupported content part type "${safeToken(type)}"`);
|
|
50576
|
+
}
|
|
50577
|
+
function messageBlocks(content) {
|
|
50578
|
+
if (typeof content === "string")
|
|
50579
|
+
return [{ type: "text", text: content }];
|
|
50580
|
+
if (!Array.isArray(content))
|
|
50581
|
+
return [];
|
|
50582
|
+
const blocks2 = [];
|
|
50583
|
+
for (const part2 of content) {
|
|
50584
|
+
const block2 = contentPart(part2);
|
|
50585
|
+
if (block2 !== null)
|
|
50586
|
+
blocks2.push(block2);
|
|
50587
|
+
}
|
|
50588
|
+
return blocks2;
|
|
50589
|
+
}
|
|
50590
|
+
function nativeBlock(item, blockType) {
|
|
50591
|
+
const { type: _type, ...data } = item;
|
|
50592
|
+
return { type: "providerNative", provider: "openai", blockType, data };
|
|
50593
|
+
}
|
|
50594
|
+
function readInputItems(items) {
|
|
50595
|
+
const dropped = new Set;
|
|
50596
|
+
const messages = [];
|
|
50597
|
+
const push = (role, content) => {
|
|
50598
|
+
if (content.length > 0)
|
|
50599
|
+
messages.push({ role, content });
|
|
50600
|
+
};
|
|
50601
|
+
for (const raw of items) {
|
|
50602
|
+
if (!isRecord7(raw))
|
|
50603
|
+
throw new GatewayError("BAD_REQUEST", "input: item must be an object");
|
|
50604
|
+
const type = raw.type ?? (raw.role === undefined ? undefined : "message");
|
|
50605
|
+
switch (type) {
|
|
50606
|
+
case "message":
|
|
50607
|
+
push(roleOf(raw.role), messageBlocks(raw.content));
|
|
50608
|
+
break;
|
|
50609
|
+
case "function_call":
|
|
50610
|
+
case "custom_tool_call": {
|
|
50611
|
+
const name = typeof raw.name === "string" ? raw.name : "";
|
|
50612
|
+
const callId = typeof raw.call_id === "string" ? raw.call_id : "";
|
|
50613
|
+
if (name === "" || callId === "") {
|
|
50614
|
+
if (callId !== "")
|
|
50615
|
+
dropped.add(callId);
|
|
50616
|
+
else
|
|
50617
|
+
dropped.add("");
|
|
50618
|
+
break;
|
|
50619
|
+
}
|
|
50620
|
+
const input = type === "custom_tool_call" ? { input: typeof raw.input === "string" ? raw.input : "" } : jsonArguments(raw.arguments, clampCallId(callId));
|
|
50621
|
+
push("assistant", [{ type: "toolUse", id: clampCallId(callId), name, input }]);
|
|
50622
|
+
break;
|
|
50623
|
+
}
|
|
50624
|
+
case "function_call_output":
|
|
50625
|
+
case "custom_tool_call_output": {
|
|
50626
|
+
const callId = typeof raw.call_id === "string" ? raw.call_id : "";
|
|
50627
|
+
if (dropped.has(callId))
|
|
50628
|
+
break;
|
|
50629
|
+
push("user", [
|
|
50630
|
+
{
|
|
50631
|
+
type: "toolResult",
|
|
50632
|
+
toolUseId: clampCallId(callId),
|
|
50633
|
+
content: typeof raw.output === "string" ? raw.output : JSON.stringify(raw.output ?? ""),
|
|
50634
|
+
isError: false
|
|
50635
|
+
}
|
|
50636
|
+
]);
|
|
50637
|
+
break;
|
|
50638
|
+
}
|
|
50639
|
+
case "reasoning":
|
|
50640
|
+
case "local_shell_call":
|
|
50641
|
+
push("assistant", [nativeBlock(raw, String(type))]);
|
|
50642
|
+
break;
|
|
50643
|
+
case "local_shell_call_output":
|
|
50644
|
+
push("user", [nativeBlock(raw, "local_shell_call_output")]);
|
|
50645
|
+
break;
|
|
50646
|
+
case "item_reference":
|
|
50647
|
+
throw new GatewayError("BAD_REQUEST", "input: item_reference names a stored item, and this gateway stores no responses");
|
|
50648
|
+
default:
|
|
50649
|
+
throw new GatewayError("BAD_REQUEST", `input: unsupported item type "${safeToken(type)}"`);
|
|
50650
|
+
}
|
|
50651
|
+
}
|
|
50652
|
+
return messages;
|
|
50653
|
+
}
|
|
50654
|
+
function jsonArguments(raw, callId) {
|
|
50655
|
+
const text = typeof raw === "string" ? raw : "";
|
|
50656
|
+
try {
|
|
50657
|
+
const parsed2 = text === "" ? {} : JSON.parse(text);
|
|
50658
|
+
return isRecord7(parsed2) ? parsed2 : { value: parsed2 };
|
|
50659
|
+
} catch {
|
|
50660
|
+
throw new GatewayError("BAD_REQUEST", `input: arguments for call ${safeToken(callId)} are not valid JSON`);
|
|
50661
|
+
}
|
|
50662
|
+
}
|
|
50663
|
+
var TOOL_NAME = /^[A-Za-z0-9_-]{1,128}$/;
|
|
50664
|
+
function readTools(raw) {
|
|
50665
|
+
const tools2 = [];
|
|
50666
|
+
for (const entry of raw) {
|
|
50667
|
+
if (!isRecord7(entry))
|
|
50668
|
+
throw new GatewayError("BAD_REQUEST", "tools: each tool must be an object");
|
|
50669
|
+
const type = typeof entry.type === "string" ? entry.type : "";
|
|
50670
|
+
const declared = typeof entry.name === "string" ? entry.name : "";
|
|
50671
|
+
if (type === "function" || type === "custom") {
|
|
50672
|
+
if (!TOOL_NAME.test(declared)) {
|
|
50673
|
+
throw new GatewayError("BAD_REQUEST", `tools: a tool name must match ${TOOL_NAME.source}`);
|
|
50674
|
+
}
|
|
50675
|
+
const description = typeof entry.description === "string" ? entry.description : undefined;
|
|
50676
|
+
tools2.push({
|
|
50677
|
+
kind: "portable",
|
|
50678
|
+
name: declared,
|
|
50679
|
+
...description === undefined ? {} : { description },
|
|
50680
|
+
inputSchema: type === "custom" ? { type: "object", properties: { input: { type: "string" } }, required: ["input"] } : isRecord7(entry.parameters) ? entry.parameters : { type: "object" }
|
|
50681
|
+
});
|
|
50682
|
+
continue;
|
|
50683
|
+
}
|
|
50684
|
+
const name = declared === "" ? type : declared;
|
|
50685
|
+
if (!TOOL_NAME.test(name)) {
|
|
50686
|
+
throw new GatewayError("BAD_REQUEST", `tools: a tool name must match ${TOOL_NAME.source}`);
|
|
50687
|
+
}
|
|
50688
|
+
const { type: _type, name: _name, ...wire } = entry;
|
|
50689
|
+
tools2.push({ kind: "provider", provider: "openai", type, name, wire });
|
|
50690
|
+
}
|
|
50691
|
+
return tools2;
|
|
50692
|
+
}
|
|
50693
|
+
function customToolNames(body2) {
|
|
50694
|
+
const names = new Set;
|
|
50695
|
+
if (!isRecord7(body2) || !Array.isArray(body2.tools))
|
|
50696
|
+
return names;
|
|
50697
|
+
for (const entry of body2.tools) {
|
|
50698
|
+
if (isRecord7(entry) && entry.type === "custom" && typeof entry.name === "string") {
|
|
50699
|
+
names.add(entry.name);
|
|
50700
|
+
}
|
|
50701
|
+
}
|
|
50702
|
+
return names;
|
|
50703
|
+
}
|
|
50704
|
+
function parseResponsesRequest(body2, headers) {
|
|
50705
|
+
if (typeof body2 !== "object" || body2 === null) {
|
|
50706
|
+
throw new GatewayError("BAD_REQUEST", "request body must be a JSON object");
|
|
50707
|
+
}
|
|
50708
|
+
const parsed2 = parseOrThrow2(schema3, body2);
|
|
50709
|
+
refuseStatefulFields(parsed2);
|
|
50710
|
+
const messages = typeof parsed2.input === "string" ? [{ role: "user", content: [{ type: "text", text: parsed2.input }] }] : readInputItems(parsed2.input);
|
|
50711
|
+
if (messages.length === 0) {
|
|
50712
|
+
throw new GatewayError("BAD_REQUEST", "input: at least one input item is required");
|
|
50713
|
+
}
|
|
50714
|
+
const named = normalizeClientModel(parsed2.model);
|
|
50715
|
+
const request2 = {
|
|
50716
|
+
model: named.model,
|
|
50717
|
+
messages,
|
|
50718
|
+
stream: parsed2.stream ?? false
|
|
50719
|
+
};
|
|
50720
|
+
if (parsed2.instructions !== undefined && parsed2.instructions.length > 0) {
|
|
50721
|
+
request2.system = [{ type: "text", text: parsed2.instructions }];
|
|
50722
|
+
}
|
|
50723
|
+
if (parsed2.max_output_tokens !== undefined)
|
|
50724
|
+
request2.maxTokens = parsed2.max_output_tokens;
|
|
50725
|
+
if (parsed2.temperature !== undefined)
|
|
50726
|
+
request2.temperature = parsed2.temperature;
|
|
50727
|
+
if (parsed2.tools !== undefined && parsed2.tools.length > 0)
|
|
50728
|
+
request2.tools = readTools(parsed2.tools);
|
|
50729
|
+
if (parsed2.tool_choice !== undefined)
|
|
50730
|
+
request2.toolChoice = toIrToolChoice3(parsed2.tool_choice);
|
|
50731
|
+
if (parsed2.reasoning !== undefined)
|
|
50732
|
+
request2.reasoning = toIrReasoning2(parsed2.reasoning);
|
|
50733
|
+
if (named.betas.length > 0)
|
|
50734
|
+
request2.betas = named.betas;
|
|
50735
|
+
const conversation = readCacheKey(parsed2.prompt_cache_key) ?? readConversationHeader(headers);
|
|
50736
|
+
if (conversation !== undefined)
|
|
50737
|
+
request2.conversationId = conversation;
|
|
50738
|
+
const extras = extraFields(body2, KNOWN3);
|
|
50739
|
+
if (extras !== undefined)
|
|
50740
|
+
request2.vendor = { openai: extras };
|
|
50741
|
+
return validateRequest(request2);
|
|
50742
|
+
}
|
|
50743
|
+
|
|
50034
50744
|
// apps/gateway/src/routes/models.ts
|
|
50035
50745
|
var CREATED_AT = new Date(0).toISOString();
|
|
50036
50746
|
function describeModel(model, credentials) {
|
|
@@ -50060,6 +50770,10 @@ function modelListBody(models, credentials) {
|
|
|
50060
50770
|
|
|
50061
50771
|
// apps/gateway/src/routes/proxy.ts
|
|
50062
50772
|
var KEEPALIVE_MS = 1e4;
|
|
50773
|
+
var RESPONSES_KEEPALIVE_MS = 4000;
|
|
50774
|
+
function keepaliveFor(surface, configured2) {
|
|
50775
|
+
return surface === "responses" ? Math.min(configured2, RESPONSES_KEEPALIVE_MS) : configured2;
|
|
50776
|
+
}
|
|
50063
50777
|
var KEEPALIVE = Symbol("keepalive");
|
|
50064
50778
|
function withKeepalive(pending, ms) {
|
|
50065
50779
|
let timer;
|
|
@@ -50075,10 +50789,18 @@ var SSE_HEADERS = {
|
|
|
50075
50789
|
"x-accel-buffering": "no"
|
|
50076
50790
|
};
|
|
50077
50791
|
function errorBody(surface, code, message3) {
|
|
50078
|
-
|
|
50792
|
+
if (surface === "anthropic")
|
|
50793
|
+
return anthropicErrorBody(code, message3);
|
|
50794
|
+
if (surface === "responses")
|
|
50795
|
+
return responsesErrorBody(code, message3);
|
|
50796
|
+
return openaiErrorBody(code, message3);
|
|
50079
50797
|
}
|
|
50080
50798
|
function rateLimitHeaders(surface, headroom, now) {
|
|
50081
|
-
|
|
50799
|
+
if (surface === "anthropic")
|
|
50800
|
+
return anthropicRateLimitHeaders(headroom);
|
|
50801
|
+
if (surface === "responses")
|
|
50802
|
+
return responsesRateLimitHeaders(headroom, now);
|
|
50803
|
+
return openaiRateLimitHeaders(headroom, now);
|
|
50082
50804
|
}
|
|
50083
50805
|
function afterThisRequest(headroom) {
|
|
50084
50806
|
const requests = headroom.requests;
|
|
@@ -50237,9 +50959,14 @@ async function handle(deps, rateLimiter, surface, request2) {
|
|
|
50237
50959
|
const body2 = await request2.json();
|
|
50238
50960
|
if (captured !== null)
|
|
50239
50961
|
captured.client.request = body2;
|
|
50240
|
-
const chatRequest = surface === "anthropic" ? parseAnthropicRequest(body2, request2.headers) : parseOpenAIRequest(body2, request2.headers);
|
|
50962
|
+
const chatRequest = surface === "anthropic" ? parseAnthropicRequest(body2, request2.headers) : surface === "responses" ? parseResponsesRequest(body2, request2.headers) : parseOpenAIRequest(body2, request2.headers);
|
|
50963
|
+
const render2 = () => ({
|
|
50964
|
+
requestId,
|
|
50965
|
+
created: Math.floor(deps.now() / 1000),
|
|
50966
|
+
customToolNames: customToolNames(body2)
|
|
50967
|
+
});
|
|
50241
50968
|
if (key.modelAllowlist !== null && !key.modelAllowlist.includes(chatRequest.model)) {
|
|
50242
|
-
throw new GatewayError("AUTH", `model "${chatRequest.model}" is not allowed for this API key`);
|
|
50969
|
+
throw new GatewayError("AUTH", `model "${safeToken(chatRequest.model)}" is not allowed for this API key`);
|
|
50243
50970
|
}
|
|
50244
50971
|
requestedModel = chatRequest.model;
|
|
50245
50972
|
let began = false;
|
|
@@ -50286,7 +51013,7 @@ async function handle(deps, rateLimiter, surface, request2) {
|
|
|
50286
51013
|
await finishLog(deps.store, completed, keyId, deps.logger, writeBodies, debit, deps.emit, deps.broadcaster);
|
|
50287
51014
|
};
|
|
50288
51015
|
if (chatRequest.stream) {
|
|
50289
|
-
const frames = surface === "anthropic" ? anthropicStream(dispatched.events, requestId) : openaiStream(dispatched.events, requestId, Math.floor(deps.now() / 1000));
|
|
51016
|
+
const frames = surface === "anthropic" ? anthropicStream(dispatched.events, requestId) : surface === "responses" ? responsesStream(dispatched.events, render2()) : openaiStream(dispatched.events, requestId, Math.floor(deps.now() / 1000));
|
|
50290
51017
|
let onFrame;
|
|
50291
51018
|
if (captured !== null) {
|
|
50292
51019
|
const sink = createFrameSink();
|
|
@@ -50298,7 +51025,7 @@ async function handle(deps, rateLimiter, surface, request2) {
|
|
|
50298
51025
|
release?.();
|
|
50299
51026
|
await log(cancelled, failure2);
|
|
50300
51027
|
};
|
|
50301
|
-
const response = sseResponse(frames, finish, deps.keepaliveMs, dispatched.events, limitHeaders(), onFrame);
|
|
51028
|
+
const response = sseResponse(frames, finish, keepaliveFor(surface, deps.keepaliveMs), dispatched.events, limitHeaders(), onFrame);
|
|
50302
51029
|
streaming = true;
|
|
50303
51030
|
return response;
|
|
50304
51031
|
}
|
|
@@ -50306,7 +51033,7 @@ async function handle(deps, rateLimiter, surface, request2) {
|
|
|
50306
51033
|
for await (const event of dispatched.events)
|
|
50307
51034
|
events.push(event);
|
|
50308
51035
|
const failure = events.find((e) => e.type === "error");
|
|
50309
|
-
const responseBody = failure !== undefined ? errorBody(surface, failure.code, failure.message) : surface === "anthropic" ? anthropicResponse(collect(events), requestId) : openaiResponse(collect(events), requestId, Math.floor(deps.now() / 1000));
|
|
51036
|
+
const responseBody = failure !== undefined ? errorBody(surface, failure.code, failure.message) : surface === "anthropic" ? anthropicResponse(collect(events), requestId) : surface === "responses" ? responsesResponse(collect(events), render2()) : openaiResponse(collect(events), requestId, Math.floor(deps.now() / 1000));
|
|
50310
51037
|
if (captured !== null)
|
|
50311
51038
|
captured.client.response = responseBody;
|
|
50312
51039
|
await log();
|
|
@@ -50349,6 +51076,9 @@ function proxyRoutes(deps) {
|
|
|
50349
51076
|
return new Elysia().post("/v1/messages", ({ request: request2, server }) => {
|
|
50350
51077
|
server?.timeout(request2, 0);
|
|
50351
51078
|
return handle(dispatchDeps, rateLimiter, "anthropic", request2);
|
|
51079
|
+
}).post("/v1/responses", ({ request: request2, server }) => {
|
|
51080
|
+
server?.timeout(request2, 0);
|
|
51081
|
+
return handle(dispatchDeps, rateLimiter, "responses", request2);
|
|
50352
51082
|
}).post("/v1/chat/completions", ({ request: request2, server }) => {
|
|
50353
51083
|
server?.timeout(request2, 0);
|
|
50354
51084
|
return handle(dispatchDeps, rateLimiter, "openai", request2);
|
|
@@ -50375,7 +51105,7 @@ function proxyRoutes(deps) {
|
|
|
50375
51105
|
const body2 = await request2.json();
|
|
50376
51106
|
const chatRequest = parseAnthropicRequest(body2, request2.headers);
|
|
50377
51107
|
if (key.modelAllowlist !== null && !key.modelAllowlist.includes(chatRequest.model)) {
|
|
50378
|
-
throw new GatewayError("AUTH", `model "${chatRequest.model}" is not allowed for this API key`);
|
|
51108
|
+
throw new GatewayError("AUTH", `model "${safeToken(chatRequest.model)}" is not allowed for this API key`);
|
|
50379
51109
|
}
|
|
50380
51110
|
const { settings } = await dispatchDeps.snapshots.get(deps.now());
|
|
50381
51111
|
const counted = injectPonytail(chatRequest, { mode: settings.ponytailMode }).request;
|
|
@@ -50592,7 +51322,10 @@ function streamRoutes(deps) {
|
|
|
50592
51322
|
send(ws, { ...head, type: "error", topic: frame2.topic, message: "no source" });
|
|
50593
51323
|
return;
|
|
50594
51324
|
}
|
|
50595
|
-
deps.registry.subscribe(id, frame2.topic)
|
|
51325
|
+
if (!deps.registry.subscribe(id, frame2.topic)) {
|
|
51326
|
+
send(ws, { ...head, type: "error", topic: frame2.topic, message: "too many topics" });
|
|
51327
|
+
return;
|
|
51328
|
+
}
|
|
50596
51329
|
send(ws, { ...head, type: "ack", topic: frame2.topic });
|
|
50597
51330
|
if (frame2.sinceSeq !== undefined) {
|
|
50598
51331
|
const slice = deps.ring.since(frame2.topic, frame2.sinceSeq);
|
|
@@ -50958,14 +51691,15 @@ function createSocketRegistry(deps = {}) {
|
|
|
50958
51691
|
subscribe(id, topic) {
|
|
50959
51692
|
const connection = connections.get(id);
|
|
50960
51693
|
if (connection === undefined)
|
|
50961
|
-
return;
|
|
51694
|
+
return false;
|
|
50962
51695
|
if (connection.topics.size >= MAX_TOPICS_PER_CONNECTION && !connection.topics.has(topic)) {
|
|
50963
|
-
return;
|
|
51696
|
+
return false;
|
|
50964
51697
|
}
|
|
50965
51698
|
connection.topics.add(topic);
|
|
50966
51699
|
const subscribers = index.get(topic) ?? new Set;
|
|
50967
51700
|
subscribers.add(id);
|
|
50968
51701
|
index.set(topic, subscribers);
|
|
51702
|
+
return true;
|
|
50969
51703
|
},
|
|
50970
51704
|
unsubscribe(id, topic) {
|
|
50971
51705
|
const connection = connections.get(id);
|
|
@@ -51109,8 +51843,13 @@ function createRing(limits) {
|
|
|
51109
51843
|
// apps/gateway/src/app.ts
|
|
51110
51844
|
var ADMIN_SESSION_TTL_MS = 12 * 60 * 60 * 1000;
|
|
51111
51845
|
var QUIESCE_MESSAGE = "the gateway is briefly quiesced for database maintenance";
|
|
51846
|
+
var QUIESCE_BODY = {
|
|
51847
|
+
"/v1/chat/completions": (m) => openaiErrorBody("OVERLOADED", m),
|
|
51848
|
+
"/v1/responses": (m) => responsesErrorBody("OVERLOADED", m)
|
|
51849
|
+
};
|
|
51112
51850
|
function quiesceResponse(path) {
|
|
51113
|
-
const
|
|
51851
|
+
const render2 = QUIESCE_BODY[path];
|
|
51852
|
+
const body2 = render2 === undefined ? anthropicErrorBody("OVERLOADED", QUIESCE_MESSAGE) : render2(QUIESCE_MESSAGE);
|
|
51114
51853
|
return new Response(JSON.stringify(body2), {
|
|
51115
51854
|
status: HTTP_STATUS.OVERLOADED,
|
|
51116
51855
|
headers: { "content-type": "application/json", "retry-after": "5" }
|