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/README.md
CHANGED
|
@@ -21,9 +21,10 @@ omni start
|
|
|
21
21
|
|
|
22
22
|
## What it does
|
|
23
23
|
|
|
24
|
-
- **Speaks
|
|
25
|
-
`POST /v1/chat/completions` (OpenAI)
|
|
26
|
-
|
|
24
|
+
- **Speaks three dialects.** `POST /v1/messages` (Anthropic),
|
|
25
|
+
`POST /v1/chat/completions` (OpenAI) and `POST /v1/responses` (OpenAI
|
|
26
|
+
Responses, which is the only API Codex CLI speaks), including streaming,
|
|
27
|
+
translated to whichever provider actually serves the request.
|
|
27
28
|
- **Filters bulky tool history, optionally.** Built-in RTK filters shorten
|
|
28
29
|
eligible large or repetitive shell and recognizable command output before
|
|
29
30
|
provider dispatch, preserve errors and non-tool-result content, and default off.
|
|
@@ -289,6 +290,7 @@ Everything above is also available in the browser at
|
|
|
289
290
|
| --- | --- | --- |
|
|
290
291
|
| `POST` | `/v1/messages` | Anthropic Messages API |
|
|
291
292
|
| `POST` | `/v1/chat/completions` | OpenAI Chat Completions API |
|
|
293
|
+
| `POST` | `/v1/responses` | OpenAI Responses API (stateless: no stored responses, no `previous_response_id`) |
|
|
292
294
|
| `POST` | `/v1/messages/count_tokens` | Anthropic-compatible local token estimation (authenticated) |
|
|
293
295
|
| `GET` | `/v1/models` | Listing in both dialects, filtered by your key's allowlist |
|
|
294
296
|
| `GET` | `/health` | Unauthenticated liveness check |
|
|
@@ -315,7 +317,7 @@ Most tools that accept a custom base URL work unchanged: set it to
|
|
|
315
317
|
|
|
316
318
|
Every response carries the limit headers of the surface you asked on, so an SDK
|
|
317
319
|
backs off using the code it already ships — the Anthropic dialect on
|
|
318
|
-
`/v1/messages`, the OpenAI one on `/v1/chat/completions`:
|
|
320
|
+
`/v1/messages`, the OpenAI one on `/v1/chat/completions` and `/v1/responses`:
|
|
319
321
|
|
|
320
322
|
```http
|
|
321
323
|
anthropic-ratelimit-requests-limit: 2000 x-ratelimit-limit-requests: 2000
|
package/bin/omni.js
CHANGED
|
@@ -1753,6 +1753,10 @@ class GatewayError extends Error {
|
|
|
1753
1753
|
}
|
|
1754
1754
|
// packages/ir/src/logger.ts
|
|
1755
1755
|
var LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
1756
|
+
function safeToken(value) {
|
|
1757
|
+
const text = typeof value === "string" ? value : String(value);
|
|
1758
|
+
return /^[A-Za-z0-9_.:/+-]{1,64}$/.test(text) ? text : "(unprintable)";
|
|
1759
|
+
}
|
|
1756
1760
|
var ANSI2 = /\u001B\[[0-9;]*m/g;
|
|
1757
1761
|
var HEAD = /^(\S+) (DEBUG|INFO|WARN|ERROR) {1,2}(.*)$/;
|
|
1758
1762
|
var FIELDS = / {2}(?=[a-zA-Z]+=)/;
|
|
@@ -17873,6 +17877,9 @@ function codecAdapter(id, capabilities2, codec2, origins) {
|
|
|
17873
17877
|
};
|
|
17874
17878
|
}
|
|
17875
17879
|
|
|
17880
|
+
// packages/providers/src/body.ts
|
|
17881
|
+
import { createHash } from "crypto";
|
|
17882
|
+
|
|
17876
17883
|
// packages/providers/src/headers.ts
|
|
17877
17884
|
var SAFE = /^[\x20-\x7E]{1,200}$/;
|
|
17878
17885
|
function env(name, fallback) {
|
|
@@ -17928,14 +17935,14 @@ function mergeHeaders(base, overrides) {
|
|
|
17928
17935
|
|
|
17929
17936
|
// packages/providers/src/anthropic/profile.ts
|
|
17930
17937
|
var host = stainlessHost(process.platform, process.arch);
|
|
17931
|
-
var ANTHROPIC_CLI_VERSION = env("OMNI_ANTHROPIC_CLI_VERSION", "2.1.
|
|
17938
|
+
var ANTHROPIC_CLI_VERSION = env("OMNI_ANTHROPIC_CLI_VERSION", "2.1.258");
|
|
17932
17939
|
var anthropicProfile = {
|
|
17933
17940
|
headers: [
|
|
17934
17941
|
["User-Agent", env("OMNI_UA_ANTHROPIC", `claude-cli/${ANTHROPIC_CLI_VERSION} (external, cli)`)],
|
|
17935
17942
|
["x-app", "cli"],
|
|
17936
17943
|
["anthropic-dangerous-direct-browser-access", "true"],
|
|
17937
17944
|
["X-Stainless-Lang", "js"],
|
|
17938
|
-
["X-Stainless-Package-Version", env("OMNI_ANTHROPIC_STAINLESS_PACKAGE_VERSION", "0.
|
|
17945
|
+
["X-Stainless-Package-Version", env("OMNI_ANTHROPIC_STAINLESS_PACKAGE_VERSION", "0.112.1")],
|
|
17939
17946
|
["X-Stainless-OS", envOrNull("OMNI_ANTHROPIC_STAINLESS_OS") ?? host.os],
|
|
17940
17947
|
["X-Stainless-Arch", envOrNull("OMNI_ANTHROPIC_STAINLESS_ARCH") ?? host.arch],
|
|
17941
17948
|
["X-Stainless-Runtime", "node"],
|
|
@@ -18177,19 +18184,18 @@ function orderFields(obj, order) {
|
|
|
18177
18184
|
}
|
|
18178
18185
|
return out;
|
|
18179
18186
|
}
|
|
18180
|
-
var BUILD_REVISION = envOr("OMNI_ANTHROPIC_BUILD_REVISION", "250");
|
|
18181
|
-
var CLI_VERSION = envOr("OMNI_ANTHROPIC_CLI_VERSION", "2.1.219");
|
|
18182
18187
|
var CCH_PLACEHOLDER = "00000";
|
|
18183
18188
|
var CCH_SEED = 0x6e52736ac806831en;
|
|
18184
18189
|
var CCH_MASK = 0xfffffn;
|
|
18190
|
+
var CCV_SALT = "59cf53e54c78";
|
|
18185
18191
|
var BILLING_PREFIX = "x-anthropic-billing-header:";
|
|
18186
18192
|
var AGENT_PREAMBLE = "You are a Claude agent, built on Anthropic's Claude Agent SDK.";
|
|
18187
|
-
function
|
|
18188
|
-
const
|
|
18189
|
-
return
|
|
18193
|
+
function ccVersionSuffix(firstUserText) {
|
|
18194
|
+
const picked = [4, 7, 20].map((i) => firstUserText[i] ?? "0").join("");
|
|
18195
|
+
return createHash("sha256").update(`${CCV_SALT}${picked}${ANTHROPIC_CLI_VERSION}`).digest("hex").slice(0, 3);
|
|
18190
18196
|
}
|
|
18191
|
-
function billingBlock() {
|
|
18192
|
-
return `${BILLING_PREFIX} cc_version=${
|
|
18197
|
+
function billingBlock(firstUserText) {
|
|
18198
|
+
return `${BILLING_PREFIX} cc_version=${ANTHROPIC_CLI_VERSION}.${ccVersionSuffix(firstUserText)}; ` + `cc_entrypoint=cli; cch=${CCH_PLACEHOLDER};`;
|
|
18193
18199
|
}
|
|
18194
18200
|
var BANNED_SUBSTRINGS = [
|
|
18195
18201
|
"github.com/anomalyco/opencode",
|
|
@@ -18207,7 +18213,7 @@ var REWRITES = [
|
|
|
18207
18213
|
"Environment context you are running in:"
|
|
18208
18214
|
]
|
|
18209
18215
|
];
|
|
18210
|
-
function applyAnthropicSystem(system) {
|
|
18216
|
+
function applyAnthropicSystem(system, firstUserText) {
|
|
18211
18217
|
const kept = [];
|
|
18212
18218
|
for (const block of system) {
|
|
18213
18219
|
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(`
|
|
@@ -18224,17 +18230,26 @@ function applyAnthropicSystem(system) {
|
|
|
18224
18230
|
});
|
|
18225
18231
|
}
|
|
18226
18232
|
}
|
|
18227
|
-
return [
|
|
18233
|
+
return [
|
|
18234
|
+
{ type: "text", text: billingBlock(firstUserText) },
|
|
18235
|
+
{ type: "text", text: AGENT_PREAMBLE },
|
|
18236
|
+
...kept
|
|
18237
|
+
];
|
|
18228
18238
|
}
|
|
18229
18239
|
function computeCch(body) {
|
|
18230
18240
|
const digest = Bun.hash.xxHash64(Buffer.from(body, "utf8"), CCH_SEED);
|
|
18231
18241
|
return (digest & CCH_MASK).toString(16).padStart(5, "0");
|
|
18232
18242
|
}
|
|
18243
|
+
var BILLING_ANCHOR = `"system":[{"type":"text","text":"${BILLING_PREFIX}`;
|
|
18233
18244
|
function signAnthropicBody(json2) {
|
|
18234
18245
|
const needle = `cch=${CCH_PLACEHOLDER};`;
|
|
18235
|
-
|
|
18246
|
+
const anchor = json2.indexOf(BILLING_ANCHOR);
|
|
18247
|
+
if (anchor < 0)
|
|
18236
18248
|
return json2;
|
|
18237
|
-
|
|
18249
|
+
const at = json2.indexOf(needle, anchor);
|
|
18250
|
+
if (at < 0)
|
|
18251
|
+
return json2;
|
|
18252
|
+
return `${json2.slice(0, at)}cch=${computeCch(json2)};${json2.slice(at + needle.length)}`;
|
|
18238
18253
|
}
|
|
18239
18254
|
|
|
18240
18255
|
// packages/providers/src/catalog.ts
|
|
@@ -19197,9 +19212,11 @@ var anthropicCodec = {
|
|
|
19197
19212
|
cloak,
|
|
19198
19213
|
autoCache: input.autoCacheEnabled === true
|
|
19199
19214
|
});
|
|
19215
|
+
const firstUser = input.request.messages.find((m) => m.role === "user");
|
|
19216
|
+
const firstText = firstUser?.content.find((b) => b.type === "text");
|
|
19200
19217
|
const withSystem = {
|
|
19201
19218
|
...body,
|
|
19202
|
-
system: applyAnthropicSystem(body.system ?? []),
|
|
19219
|
+
system: applyAnthropicSystem(body.system ?? [], firstText?.text ?? ""),
|
|
19203
19220
|
stream: true
|
|
19204
19221
|
};
|
|
19205
19222
|
const protocol = [
|
|
@@ -20642,10 +20659,10 @@ function toCustomResponsesWire(req, model) {
|
|
|
20642
20659
|
note2("custom:context-1m-dropped");
|
|
20643
20660
|
for (const message of req.messages) {
|
|
20644
20661
|
const parts = [];
|
|
20645
|
-
const
|
|
20646
|
-
if (
|
|
20647
|
-
note2("custom:system-turn-
|
|
20648
|
-
const role =
|
|
20662
|
+
const asDeveloper = message.role === "system";
|
|
20663
|
+
if (asDeveloper)
|
|
20664
|
+
note2("custom:system-turn-as-developer");
|
|
20665
|
+
const role = asDeveloper ? "developer" : message.role;
|
|
20649
20666
|
const flush = () => {
|
|
20650
20667
|
if (parts.length === 0)
|
|
20651
20668
|
return;
|
|
@@ -20657,9 +20674,7 @@ function toCustomResponsesWire(req, model) {
|
|
|
20657
20674
|
case "text":
|
|
20658
20675
|
parts.push({
|
|
20659
20676
|
type: role === "assistant" ? "output_text" : "input_text",
|
|
20660
|
-
text:
|
|
20661
|
-
${block.text}
|
|
20662
|
-
</system-reminder>` : block.text
|
|
20677
|
+
text: block.text
|
|
20663
20678
|
});
|
|
20664
20679
|
break;
|
|
20665
20680
|
case "image":
|
|
@@ -20737,7 +20752,7 @@ function metadata(data, fail) {
|
|
|
20737
20752
|
function endpointUrl(origin, basePath, protocol) {
|
|
20738
20753
|
const suffix = protocol === "chat_completions" ? "chat/completions" : "responses";
|
|
20739
20754
|
const base = `${origin}${basePath}`.replace(/\/+$/, "");
|
|
20740
|
-
return
|
|
20755
|
+
return /\/v\d+$/i.test(base) ? `${base}/${suffix}` : `${base}/v1/${suffix}`;
|
|
20741
20756
|
}
|
|
20742
20757
|
function protocolOf(state, fail) {
|
|
20743
20758
|
if (state !== null && typeof state === "object") {
|
|
@@ -20778,7 +20793,7 @@ var customCodec = {
|
|
|
20778
20793
|
// packages/providers/src/custom/index.ts
|
|
20779
20794
|
var customAdapter = codecAdapter("custom", customDescriptor.capabilities, customCodec);
|
|
20780
20795
|
// packages/providers/src/grok/codec.ts
|
|
20781
|
-
import { createHash as
|
|
20796
|
+
import { createHash as createHash3 } from "crypto";
|
|
20782
20797
|
|
|
20783
20798
|
// packages/providers/src/grok/decode.ts
|
|
20784
20799
|
var ERROR_CODE = {
|
|
@@ -20977,7 +20992,7 @@ async function* decodeGrokResponses(messages) {
|
|
|
20977
20992
|
}
|
|
20978
20993
|
|
|
20979
20994
|
// packages/providers/src/grok/wire.ts
|
|
20980
|
-
import { createHash } from "crypto";
|
|
20995
|
+
import { createHash as createHash2 } from "crypto";
|
|
20981
20996
|
var MAX_TOOLS = 200;
|
|
20982
20997
|
function encodeToolChoice2(c) {
|
|
20983
20998
|
switch (c.type) {
|
|
@@ -20993,7 +21008,7 @@ function encodeToolChoice2(c) {
|
|
|
20993
21008
|
}
|
|
20994
21009
|
function promptCacheKey(instructions, firstInput) {
|
|
20995
21010
|
const stable = JSON.stringify({ instructions, firstInput });
|
|
20996
|
-
return
|
|
21011
|
+
return createHash2("sha256").update(stable).digest("hex").slice(0, 32);
|
|
20997
21012
|
}
|
|
20998
21013
|
function toGrokWire(req, model) {
|
|
20999
21014
|
const degradations = [];
|
|
@@ -21006,10 +21021,10 @@ function toGrokWire(req, model) {
|
|
|
21006
21021
|
note2("grok:context-1m-dropped");
|
|
21007
21022
|
for (const message of req.messages) {
|
|
21008
21023
|
const parts = [];
|
|
21009
|
-
const
|
|
21010
|
-
if (
|
|
21011
|
-
note2("grok:system-turn-
|
|
21012
|
-
const role =
|
|
21024
|
+
const asDeveloper = message.role === "system";
|
|
21025
|
+
if (asDeveloper)
|
|
21026
|
+
note2("grok:system-turn-as-developer");
|
|
21027
|
+
const role = asDeveloper ? "developer" : message.role;
|
|
21013
21028
|
const flush = () => {
|
|
21014
21029
|
if (parts.length === 0)
|
|
21015
21030
|
return;
|
|
@@ -21021,9 +21036,7 @@ function toGrokWire(req, model) {
|
|
|
21021
21036
|
case "text":
|
|
21022
21037
|
parts.push({
|
|
21023
21038
|
type: role === "assistant" ? "output_text" : "input_text",
|
|
21024
|
-
text:
|
|
21025
|
-
${block.text}
|
|
21026
|
-
</system-reminder>` : block.text
|
|
21039
|
+
text: block.text
|
|
21027
21040
|
});
|
|
21028
21041
|
break;
|
|
21029
21042
|
case "image":
|
|
@@ -21106,7 +21119,7 @@ var PROXY_URL = "https://cli-chat-proxy.grok.com/v1/responses";
|
|
|
21106
21119
|
var API_URL = "https://api.x.ai/v1/responses";
|
|
21107
21120
|
var CONV_NAMESPACE = "omni-grok-conv";
|
|
21108
21121
|
function derivedUuid(value) {
|
|
21109
|
-
const h =
|
|
21122
|
+
const h = createHash3("sha256").update(`${CONV_NAMESPACE}:${value}`).digest("hex");
|
|
21110
21123
|
const variant = (Number.parseInt(h[16], 16) & 3 | 8).toString(16);
|
|
21111
21124
|
return [
|
|
21112
21125
|
h.slice(0, 8),
|
|
@@ -21815,6 +21828,7 @@ var ERROR_CODE2 = {
|
|
|
21815
21828
|
content_policy_violation: "CONTENT_FILTER"
|
|
21816
21829
|
};
|
|
21817
21830
|
var KNOWN_EVENTS3 = new Set([
|
|
21831
|
+
"keepalive",
|
|
21818
21832
|
"response.created",
|
|
21819
21833
|
"response.queued",
|
|
21820
21834
|
"response.in_progress",
|
|
@@ -21848,7 +21862,8 @@ function json7(data) {
|
|
|
21848
21862
|
return null;
|
|
21849
21863
|
}
|
|
21850
21864
|
}
|
|
21851
|
-
async function* decodeResponses(messages) {
|
|
21865
|
+
async function* decodeResponses(messages, options = {}) {
|
|
21866
|
+
const nativeReasoning = options.nativeReasoning === true;
|
|
21852
21867
|
const indices = new Map;
|
|
21853
21868
|
let next = 0;
|
|
21854
21869
|
const irIndex = (outputIndex, contentIndex = 0) => {
|
|
@@ -21893,7 +21908,7 @@ async function* decodeResponses(messages) {
|
|
|
21893
21908
|
yield {
|
|
21894
21909
|
type: "blockStart",
|
|
21895
21910
|
index: irIndex(d.output_index ?? 0),
|
|
21896
|
-
block: { type: "thinking" }
|
|
21911
|
+
block: nativeReasoning ? { type: "providerNative", provider: "openai", blockType: "reasoning", data: {} } : { type: "thinking" }
|
|
21897
21912
|
};
|
|
21898
21913
|
} else if (item.type === "function_call") {
|
|
21899
21914
|
sawToolCall = true;
|
|
@@ -21926,7 +21941,12 @@ async function* decodeResponses(messages) {
|
|
|
21926
21941
|
yield {
|
|
21927
21942
|
type: "blockDelta",
|
|
21928
21943
|
index: irIndex(d.output_index ?? 0),
|
|
21929
|
-
delta:
|
|
21944
|
+
delta: nativeReasoning ? {
|
|
21945
|
+
type: "providerNative",
|
|
21946
|
+
provider: "openai",
|
|
21947
|
+
deltaType: "reasoning_summary_text.delta",
|
|
21948
|
+
data: { text: String(d.delta ?? "") }
|
|
21949
|
+
} : { type: "thinking", text: String(d.delta ?? "") }
|
|
21930
21950
|
};
|
|
21931
21951
|
break;
|
|
21932
21952
|
case "response.function_call_arguments.delta":
|
|
@@ -21942,6 +21962,20 @@ async function* decodeResponses(messages) {
|
|
|
21942
21962
|
case "response.output_item.done": {
|
|
21943
21963
|
const outputIndex = d.output_index ?? 0;
|
|
21944
21964
|
if (ownsBlock.delete(outputIndex)) {
|
|
21965
|
+
const item = d.item ?? {};
|
|
21966
|
+
if (nativeReasoning && item.type === "reasoning") {
|
|
21967
|
+
yield {
|
|
21968
|
+
type: "blockDelta",
|
|
21969
|
+
index: irIndex(outputIndex),
|
|
21970
|
+
delta: {
|
|
21971
|
+
type: "providerNative",
|
|
21972
|
+
provider: "openai",
|
|
21973
|
+
deltaType: "response.output_item.done",
|
|
21974
|
+
fold: "merge",
|
|
21975
|
+
data: item
|
|
21976
|
+
}
|
|
21977
|
+
};
|
|
21978
|
+
}
|
|
21945
21979
|
yield { type: "blockEnd", index: irIndex(outputIndex) };
|
|
21946
21980
|
}
|
|
21947
21981
|
break;
|
|
@@ -22001,7 +22035,7 @@ async function* decodeResponses(messages) {
|
|
|
22001
22035
|
}
|
|
22002
22036
|
|
|
22003
22037
|
// packages/providers/src/openai/wire.ts
|
|
22004
|
-
import { createHash as
|
|
22038
|
+
import { createHash as createHash4 } from "crypto";
|
|
22005
22039
|
function suppliedKey(req) {
|
|
22006
22040
|
const vendor = req.vendor?.openai;
|
|
22007
22041
|
for (const name of ["prompt_cache_key", "session_id"]) {
|
|
@@ -22013,7 +22047,24 @@ function suppliedKey(req) {
|
|
|
22013
22047
|
}
|
|
22014
22048
|
function cacheKey(req, instructions, firstInput) {
|
|
22015
22049
|
const stable = req.conversationId !== undefined && req.conversationId.length > 0 ? JSON.stringify({ conversation: req.conversationId }) : JSON.stringify({ instructions, firstInput: firstInput ?? null });
|
|
22016
|
-
return
|
|
22050
|
+
return createHash4("sha256").update(stable).digest("hex").slice(0, 32);
|
|
22051
|
+
}
|
|
22052
|
+
function repairOrphanedCalls(input) {
|
|
22053
|
+
const answered = new Set;
|
|
22054
|
+
for (const item of input) {
|
|
22055
|
+
const record2 = item;
|
|
22056
|
+
if (record2.type === "function_call_output" && typeof record2.call_id === "string") {
|
|
22057
|
+
answered.add(record2.call_id);
|
|
22058
|
+
}
|
|
22059
|
+
}
|
|
22060
|
+
for (let i = input.length - 1;i >= 0; i--) {
|
|
22061
|
+
const record2 = input[i];
|
|
22062
|
+
if (record2.type !== "function_call" || typeof record2.call_id !== "string")
|
|
22063
|
+
continue;
|
|
22064
|
+
if (answered.has(record2.call_id))
|
|
22065
|
+
continue;
|
|
22066
|
+
input.splice(i + 1, 0, { type: "function_call_output", call_id: record2.call_id, output: "" });
|
|
22067
|
+
}
|
|
22017
22068
|
}
|
|
22018
22069
|
function encodeToolChoice5(c) {
|
|
22019
22070
|
switch (c.type) {
|
|
@@ -22038,10 +22089,10 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
|
|
|
22038
22089
|
note2("openai:context-1m-dropped");
|
|
22039
22090
|
for (const message of req.messages) {
|
|
22040
22091
|
const parts = [];
|
|
22041
|
-
const
|
|
22042
|
-
if (
|
|
22043
|
-
note2("openai:system-turn-
|
|
22044
|
-
const role =
|
|
22092
|
+
const asDeveloper = message.role === "system";
|
|
22093
|
+
if (asDeveloper)
|
|
22094
|
+
note2("openai:system-turn-as-developer");
|
|
22095
|
+
const role = asDeveloper ? "developer" : message.role;
|
|
22045
22096
|
const flush = () => {
|
|
22046
22097
|
if (parts.length === 0)
|
|
22047
22098
|
return;
|
|
@@ -22053,9 +22104,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
|
|
|
22053
22104
|
case "text":
|
|
22054
22105
|
parts.push({
|
|
22055
22106
|
type: role === "assistant" ? "output_text" : "input_text",
|
|
22056
|
-
text:
|
|
22057
|
-
${block.text}
|
|
22058
|
-
</system-reminder>` : block.text
|
|
22107
|
+
text: block.text
|
|
22059
22108
|
});
|
|
22060
22109
|
break;
|
|
22061
22110
|
case "image":
|
|
@@ -22087,12 +22136,19 @@ ${block.text}
|
|
|
22087
22136
|
});
|
|
22088
22137
|
break;
|
|
22089
22138
|
case "providerNative":
|
|
22139
|
+
if (block.provider === "openai") {
|
|
22140
|
+
flush();
|
|
22141
|
+
const { id: _id, ...rest } = block.data;
|
|
22142
|
+
input.push({ type: block.blockType, ...rest });
|
|
22143
|
+
break;
|
|
22144
|
+
}
|
|
22090
22145
|
note2("openai:anthropic-native-block-dropped");
|
|
22091
22146
|
break;
|
|
22092
22147
|
}
|
|
22093
22148
|
}
|
|
22094
22149
|
flush();
|
|
22095
22150
|
}
|
|
22151
|
+
repairOrphanedCalls(input);
|
|
22096
22152
|
const body = { model, input, stream: req.stream, store: false };
|
|
22097
22153
|
const instructions = systemText(req.system, "openai", note2);
|
|
22098
22154
|
if (instructions !== undefined && instructions.length > 0)
|
|
@@ -22156,7 +22212,10 @@ var openaiCodec = {
|
|
|
22156
22212
|
throw input.fail("AUTH", "openai credential has no token");
|
|
22157
22213
|
}
|
|
22158
22214
|
const headers = orderHeaders(mergeHeaders(openaiProfile.headers, protocol), openaiProfile.order);
|
|
22215
|
+
const include = body.include;
|
|
22216
|
+
const nativeReasoning = Array.isArray(include) && include.includes("reasoning.encrypted_content");
|
|
22159
22217
|
return {
|
|
22218
|
+
decodeState: { nativeReasoning },
|
|
22160
22219
|
request: {
|
|
22161
22220
|
url: oauth ? OAUTH_URL2 : API_URL3,
|
|
22162
22221
|
method: "POST",
|
|
@@ -22166,8 +22225,9 @@ var openaiCodec = {
|
|
|
22166
22225
|
degradations
|
|
22167
22226
|
};
|
|
22168
22227
|
},
|
|
22169
|
-
decode({ body }) {
|
|
22170
|
-
|
|
22228
|
+
decode({ body, decodeState }) {
|
|
22229
|
+
const state = decodeState;
|
|
22230
|
+
return decodeResponses(parseSse(body), { nativeReasoning: state?.nativeReasoning === true });
|
|
22171
22231
|
}
|
|
22172
22232
|
};
|
|
22173
22233
|
|
|
@@ -22344,8 +22404,10 @@ function parseOrThrow(schema, body2) {
|
|
|
22344
22404
|
if (result.success)
|
|
22345
22405
|
return result.data;
|
|
22346
22406
|
const issue2 = result.error.issues[0];
|
|
22347
|
-
const
|
|
22348
|
-
|
|
22407
|
+
const segments = issue2?.path ?? [];
|
|
22408
|
+
const path = segments.length === 0 ? "(root)" : segments.map((s) => safeToken(String(s))).join(".");
|
|
22409
|
+
const detail = issue2 === undefined ? "invalid request" : issue2.code === "unrecognized_keys" ? `unrecognized key "${safeToken(issue2.keys[0])}"` : issue2.message;
|
|
22410
|
+
throw new GatewayError("BAD_REQUEST", `${path}: ${detail}`);
|
|
22349
22411
|
}
|
|
22350
22412
|
function optionalNumber(value, fallback) {
|
|
22351
22413
|
if (value === undefined)
|
|
@@ -22705,10 +22767,13 @@ function bestPositive(values2) {
|
|
|
22705
22767
|
return positive.length > 0 ? Math.min(...positive) : null;
|
|
22706
22768
|
}
|
|
22707
22769
|
var EXPECTED_OUTPUT_TOKENS = 1000;
|
|
22708
|
-
function
|
|
22770
|
+
function estimateTokens(request2) {
|
|
22709
22771
|
const cachedTok = estimateCachedInputTokens(request2);
|
|
22710
22772
|
const freshTok = Math.max(0, estimateInputTokens(request2) - cachedTok);
|
|
22711
22773
|
const outTok = Math.min(request2.maxTokens ?? EXPECTED_OUTPUT_TOKENS, EXPECTED_OUTPUT_TOKENS);
|
|
22774
|
+
return { cachedTok, freshTok, outTok };
|
|
22775
|
+
}
|
|
22776
|
+
function requestCost(target, { cachedTok, freshTok, outTok }) {
|
|
22712
22777
|
return freshTok * target.costPerMTok.input + cachedTok * cacheReadRate(target.costPerMTok) + outTok * target.costPerMTok.output;
|
|
22713
22778
|
}
|
|
22714
22779
|
function healthScore(h) {
|
|
@@ -22721,7 +22786,8 @@ function score(pairs, input) {
|
|
|
22721
22786
|
const tiers = pairs.map((p) => p.target.tier);
|
|
22722
22787
|
const minTier = Math.min(...tiers);
|
|
22723
22788
|
const maxTier = Math.max(...tiers);
|
|
22724
|
-
const
|
|
22789
|
+
const tokens2 = estimateTokens(input.request);
|
|
22790
|
+
const costs = pairs.map((p) => requestCost(p.target, tokens2));
|
|
22725
22791
|
const bestCost = bestPositive(costs);
|
|
22726
22792
|
const bestLatency = bestPositive(pairs.flatMap((p) => {
|
|
22727
22793
|
const h = snapshot.health.get(healthKey(p.credential.id, p.target.model));
|
|
@@ -23403,16 +23469,16 @@ async function createKey(store, input) {
|
|
|
23403
23469
|
}
|
|
23404
23470
|
async function setKeyLimits(store, id, input, now = Date.now()) {
|
|
23405
23471
|
const body2 = parseOrThrow(keyLimitsSchema, input);
|
|
23406
|
-
const key =
|
|
23407
|
-
if (key ===
|
|
23472
|
+
const key = await store.keys.get(id);
|
|
23473
|
+
if (key === null)
|
|
23408
23474
|
throw new GatewayError("BAD_REQUEST", "no such api key");
|
|
23409
23475
|
await store.keys.setLimits(id, body2.limits);
|
|
23410
23476
|
return toSummary(store, { ...key, limits: body2.limits }, now);
|
|
23411
23477
|
}
|
|
23412
23478
|
async function setKeyModels(store, id, input, now = Date.now()) {
|
|
23413
23479
|
const body2 = parseOrThrow(keyModelsSchema, input);
|
|
23414
|
-
const key =
|
|
23415
|
-
if (key ===
|
|
23480
|
+
const key = await store.keys.get(id);
|
|
23481
|
+
if (key === null)
|
|
23416
23482
|
throw new GatewayError("BAD_REQUEST", "no such api key");
|
|
23417
23483
|
await store.keys.setModelAllowlist(id, body2.modelAllowlist);
|
|
23418
23484
|
return toSummary(store, { ...key, modelAllowlist: body2.modelAllowlist }, now);
|
|
@@ -27062,7 +27128,7 @@ function createServiceDeps(input) {
|
|
|
27062
27128
|
}
|
|
27063
27129
|
|
|
27064
27130
|
// apps/cli/src/version.ts
|
|
27065
|
-
var VERSION = "0.7.
|
|
27131
|
+
var VERSION = "0.7.3";
|
|
27066
27132
|
|
|
27067
27133
|
// apps/cli/src/commands/service.ts
|
|
27068
27134
|
function gatewayArgv(root) {
|