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.
Files changed (48) hide show
  1. package/README.md +6 -4
  2. package/bin/omni.js +122 -56
  3. package/gateway.js +832 -93
  4. package/package.json +1 -1
  5. package/public/assets/{Chip-BWxO0uV7.js → Chip-BOyBT5TP.js} +1 -1
  6. package/public/assets/{CopyValue-DIR5A6PG.js → CopyValue-DRHHQlN_.js} +3 -3
  7. package/public/assets/{Field-DI5YTYOX.js → Field-DK5zaBVA.js} +1 -1
  8. package/public/assets/Lamp-ZlMzNs5N.js +25 -0
  9. package/public/assets/{Panel-BCpZVY4U.js → Panel-CYQvfI3L.js} +19 -19
  10. package/public/assets/Rack-D798XvPQ.js +466 -0
  11. package/public/assets/{Readout-B0TZE8aA.js → Readout-D6-aurU8.js} +1 -1
  12. package/public/assets/{RequestTable-D4z82uxG.js → RequestTable-CEBhwDs7.js} +2 -2
  13. package/public/assets/{SummaryDeck-CzozuXOu.js → SummaryDeck-DBCSHihY.js} +2 -2
  14. package/public/assets/{Toggle-ByxBCMfb.js → Toggle-CdCCoDEo.js} +1 -1
  15. package/public/assets/{TokenBreakdown-BMEiZhRX.js → TokenBreakdown-DDI9uTPW.js} +1 -1
  16. package/public/assets/{WindowChart-nxC4SCRC.js → WindowChart-C-Y6U3WF.js} +2 -2
  17. package/public/assets/_app-BWNEo1e-.js +1 -0
  18. package/public/assets/_app.accounts-CLLLwN77.js +59 -0
  19. package/public/assets/{_app.console-D6lrTxJt.js → _app.console-Dr9qxU7J.js} +3 -3
  20. package/public/assets/{_app.database-Y3lFDxoP.js → _app.database-D0W0pcxC.js} +4 -4
  21. package/public/assets/{_app.index-DUFa7RRT.js → _app.index-CyxnfhVX.js} +8 -8
  22. package/public/assets/{_app.keys-DRfXCzMJ.js → _app.keys-D9qmw9Tj.js} +11 -11
  23. package/public/assets/{_app.logs-BQT3kFZr.js → _app.logs-DtXUZETW.js} +4 -4
  24. package/public/assets/{_app.models-CDpbIYHW.js → _app.models-CNxwXyFl.js} +11 -11
  25. package/public/assets/{_app.plugins._pluginId-jaswB8Z5.js → _app.plugins._pluginId-87Ox_hkW.js} +1 -1
  26. package/public/assets/_app.plugins._pluginId-CZWipH1n.js +2 -0
  27. package/public/assets/_app.settings-DjiMSl1Y.js +88 -0
  28. package/public/assets/{_app.usage-BaT54Vee.js → _app.usage-CZz9raYR.js} +6 -6
  29. package/public/assets/{chevron-right-0adI8395.js → chevron-right-CPoaXYHw.js} +1 -1
  30. package/public/assets/client-CZnyYbay.js +39 -0
  31. package/public/assets/{index-BRrBGt1i.js → index-DNSPtYpM.js} +3 -3
  32. package/public/assets/{login-BSWCo_Fz.js → login-BtlMmyKj.js} +3 -3
  33. package/public/assets/login-dV42ZQIA.js +2 -0
  34. package/public/assets/plus-_zo43Lvf.js +1 -0
  35. package/public/assets/{preload-helper-CD37DT-E.js → preload-helper-4wSmu2-E.js} +1 -1
  36. package/public/assets/{shared-dShKzjig.js → shared-OJcoRCqT.js} +1 -1
  37. package/public/assets/{stream-BD4FhzLn.js → stream-CEb81tzM.js} +1 -1
  38. package/public/assets/{trash-2-DrDlpCqO.js → trash-2-BjpqTubo.js} +1 -1
  39. package/public/index.html +8 -8
  40. package/public/assets/Lamp-DN2EKL4m.js +0 -25
  41. package/public/assets/Rack-B03tpeW-.js +0 -466
  42. package/public/assets/_app-D9B6OIjd.js +0 -1
  43. package/public/assets/_app.accounts-BiRGhH3s.js +0 -59
  44. package/public/assets/_app.plugins._pluginId-CtEAGvad.js +0 -2
  45. package/public/assets/_app.settings-CG63splg.js +0 -58
  46. package/public/assets/client-_6YMm6vh.js +0 -39
  47. package/public/assets/login-C7v-Fr28.js +0 -2
  48. 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 both dialects.** `POST /v1/messages` (Anthropic) and
25
- `POST /v1/chat/completions` (OpenAI), including streaming, translated to
26
- whichever provider actually serves the request.
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.219");
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.94.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 envOr(name, fallback) {
18188
- const raw = Bun.env[name];
18189
- return typeof raw === "string" && /^[\x20-\x7E]{1,200}$/.test(raw) ? raw : fallback;
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=${CLI_VERSION}.${BUILD_REVISION}; ` + `cc_entrypoint=cli; cch=${CCH_PLACEHOLDER};`;
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 [{ type: "text", text: billingBlock() }, { type: "text", text: AGENT_PREAMBLE }, ...kept];
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
- if (!json2.includes(needle))
18246
+ const anchor = json2.indexOf(BILLING_ANCHOR);
18247
+ if (anchor < 0)
18236
18248
  return json2;
18237
- return json2.replace(needle, `cch=${computeCch(json2)};`);
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 inlined = message.role === "system";
20646
- if (inlined)
20647
- note2("custom:system-turn-inlined");
20648
- const role = inlined ? "user" : message.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: inlined ? `<system-reminder>
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 base.endsWith("/v1") ? `${base}/${suffix}` : `${base}/v1/${suffix}`;
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 createHash2 } from "crypto";
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 createHash("sha256").update(stable).digest("hex").slice(0, 32);
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 inlined = message.role === "system";
21010
- if (inlined)
21011
- note2("grok:system-turn-inlined");
21012
- const role = inlined ? "user" : message.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: inlined ? `<system-reminder>
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 = createHash2("sha256").update(`${CONV_NAMESPACE}:${value}`).digest("hex");
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: { type: "thinking", text: String(d.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 createHash3 } from "crypto";
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 createHash3("sha256").update(stable).digest("hex").slice(0, 32);
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 inlined = message.role === "system";
22042
- if (inlined)
22043
- note2("openai:system-turn-inlined");
22044
- const role = inlined ? "user" : message.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: inlined ? `<system-reminder>
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
- return decodeResponses(parseSse(body));
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 path = issue2?.path.join(".") ?? "(root)";
22348
- throw new GatewayError("BAD_REQUEST", `${path}: ${issue2?.message ?? "invalid request"}`);
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 requestCost(target, request2) {
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 costs = pairs.map((p) => requestCost(p.target, input.request));
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 = (await store.keys.list()).find((entry) => entry.id === id);
23407
- if (key === undefined)
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 = (await store.keys.list()).find((entry) => entry.id === id);
23415
- if (key === undefined)
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.1";
27131
+ var VERSION = "0.7.3";
27066
27132
 
27067
27133
  // apps/cli/src/commands/service.ts
27068
27134
  function gatewayArgv(root) {