omnigateway 0.7.1 → 0.7.2

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 +79 -30
  3. package/gateway.js +782 -64
  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]+=)/;
@@ -20642,10 +20646,10 @@ function toCustomResponsesWire(req, model) {
20642
20646
  note2("custom:context-1m-dropped");
20643
20647
  for (const message of req.messages) {
20644
20648
  const parts = [];
20645
- const inlined = message.role === "system";
20646
- if (inlined)
20647
- note2("custom:system-turn-inlined");
20648
- const role = inlined ? "user" : message.role;
20649
+ const asDeveloper = message.role === "system";
20650
+ if (asDeveloper)
20651
+ note2("custom:system-turn-as-developer");
20652
+ const role = asDeveloper ? "developer" : message.role;
20649
20653
  const flush = () => {
20650
20654
  if (parts.length === 0)
20651
20655
  return;
@@ -20657,9 +20661,7 @@ function toCustomResponsesWire(req, model) {
20657
20661
  case "text":
20658
20662
  parts.push({
20659
20663
  type: role === "assistant" ? "output_text" : "input_text",
20660
- text: inlined ? `<system-reminder>
20661
- ${block.text}
20662
- </system-reminder>` : block.text
20664
+ text: block.text
20663
20665
  });
20664
20666
  break;
20665
20667
  case "image":
@@ -20737,7 +20739,7 @@ function metadata(data, fail) {
20737
20739
  function endpointUrl(origin, basePath, protocol) {
20738
20740
  const suffix = protocol === "chat_completions" ? "chat/completions" : "responses";
20739
20741
  const base = `${origin}${basePath}`.replace(/\/+$/, "");
20740
- return base.endsWith("/v1") ? `${base}/${suffix}` : `${base}/v1/${suffix}`;
20742
+ return /\/v\d+$/i.test(base) ? `${base}/${suffix}` : `${base}/v1/${suffix}`;
20741
20743
  }
20742
20744
  function protocolOf(state, fail) {
20743
20745
  if (state !== null && typeof state === "object") {
@@ -21006,10 +21008,10 @@ function toGrokWire(req, model) {
21006
21008
  note2("grok:context-1m-dropped");
21007
21009
  for (const message of req.messages) {
21008
21010
  const parts = [];
21009
- const inlined = message.role === "system";
21010
- if (inlined)
21011
- note2("grok:system-turn-inlined");
21012
- const role = inlined ? "user" : message.role;
21011
+ const asDeveloper = message.role === "system";
21012
+ if (asDeveloper)
21013
+ note2("grok:system-turn-as-developer");
21014
+ const role = asDeveloper ? "developer" : message.role;
21013
21015
  const flush = () => {
21014
21016
  if (parts.length === 0)
21015
21017
  return;
@@ -21021,9 +21023,7 @@ function toGrokWire(req, model) {
21021
21023
  case "text":
21022
21024
  parts.push({
21023
21025
  type: role === "assistant" ? "output_text" : "input_text",
21024
- text: inlined ? `<system-reminder>
21025
- ${block.text}
21026
- </system-reminder>` : block.text
21026
+ text: block.text
21027
21027
  });
21028
21028
  break;
21029
21029
  case "image":
@@ -21815,6 +21815,7 @@ var ERROR_CODE2 = {
21815
21815
  content_policy_violation: "CONTENT_FILTER"
21816
21816
  };
21817
21817
  var KNOWN_EVENTS3 = new Set([
21818
+ "keepalive",
21818
21819
  "response.created",
21819
21820
  "response.queued",
21820
21821
  "response.in_progress",
@@ -21848,7 +21849,8 @@ function json7(data) {
21848
21849
  return null;
21849
21850
  }
21850
21851
  }
21851
- async function* decodeResponses(messages) {
21852
+ async function* decodeResponses(messages, options = {}) {
21853
+ const nativeReasoning = options.nativeReasoning === true;
21852
21854
  const indices = new Map;
21853
21855
  let next = 0;
21854
21856
  const irIndex = (outputIndex, contentIndex = 0) => {
@@ -21893,7 +21895,7 @@ async function* decodeResponses(messages) {
21893
21895
  yield {
21894
21896
  type: "blockStart",
21895
21897
  index: irIndex(d.output_index ?? 0),
21896
- block: { type: "thinking" }
21898
+ block: nativeReasoning ? { type: "providerNative", provider: "openai", blockType: "reasoning", data: {} } : { type: "thinking" }
21897
21899
  };
21898
21900
  } else if (item.type === "function_call") {
21899
21901
  sawToolCall = true;
@@ -21926,7 +21928,12 @@ async function* decodeResponses(messages) {
21926
21928
  yield {
21927
21929
  type: "blockDelta",
21928
21930
  index: irIndex(d.output_index ?? 0),
21929
- delta: { type: "thinking", text: String(d.delta ?? "") }
21931
+ delta: nativeReasoning ? {
21932
+ type: "providerNative",
21933
+ provider: "openai",
21934
+ deltaType: "reasoning_summary_text.delta",
21935
+ data: { text: String(d.delta ?? "") }
21936
+ } : { type: "thinking", text: String(d.delta ?? "") }
21930
21937
  };
21931
21938
  break;
21932
21939
  case "response.function_call_arguments.delta":
@@ -21942,6 +21949,20 @@ async function* decodeResponses(messages) {
21942
21949
  case "response.output_item.done": {
21943
21950
  const outputIndex = d.output_index ?? 0;
21944
21951
  if (ownsBlock.delete(outputIndex)) {
21952
+ const item = d.item ?? {};
21953
+ if (nativeReasoning && item.type === "reasoning") {
21954
+ yield {
21955
+ type: "blockDelta",
21956
+ index: irIndex(outputIndex),
21957
+ delta: {
21958
+ type: "providerNative",
21959
+ provider: "openai",
21960
+ deltaType: "response.output_item.done",
21961
+ fold: "merge",
21962
+ data: item
21963
+ }
21964
+ };
21965
+ }
21945
21966
  yield { type: "blockEnd", index: irIndex(outputIndex) };
21946
21967
  }
21947
21968
  break;
@@ -22015,6 +22036,23 @@ function cacheKey(req, instructions, firstInput) {
22015
22036
  const stable = req.conversationId !== undefined && req.conversationId.length > 0 ? JSON.stringify({ conversation: req.conversationId }) : JSON.stringify({ instructions, firstInput: firstInput ?? null });
22016
22037
  return createHash3("sha256").update(stable).digest("hex").slice(0, 32);
22017
22038
  }
22039
+ function repairOrphanedCalls(input) {
22040
+ const answered = new Set;
22041
+ for (const item of input) {
22042
+ const record2 = item;
22043
+ if (record2.type === "function_call_output" && typeof record2.call_id === "string") {
22044
+ answered.add(record2.call_id);
22045
+ }
22046
+ }
22047
+ for (let i = input.length - 1;i >= 0; i--) {
22048
+ const record2 = input[i];
22049
+ if (record2.type !== "function_call" || typeof record2.call_id !== "string")
22050
+ continue;
22051
+ if (answered.has(record2.call_id))
22052
+ continue;
22053
+ input.splice(i + 1, 0, { type: "function_call_output", call_id: record2.call_id, output: "" });
22054
+ }
22055
+ }
22018
22056
  function encodeToolChoice5(c) {
22019
22057
  switch (c.type) {
22020
22058
  case "auto":
@@ -22038,10 +22076,10 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
22038
22076
  note2("openai:context-1m-dropped");
22039
22077
  for (const message of req.messages) {
22040
22078
  const parts = [];
22041
- const inlined = message.role === "system";
22042
- if (inlined)
22043
- note2("openai:system-turn-inlined");
22044
- const role = inlined ? "user" : message.role;
22079
+ const asDeveloper = message.role === "system";
22080
+ if (asDeveloper)
22081
+ note2("openai:system-turn-as-developer");
22082
+ const role = asDeveloper ? "developer" : message.role;
22045
22083
  const flush = () => {
22046
22084
  if (parts.length === 0)
22047
22085
  return;
@@ -22053,9 +22091,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
22053
22091
  case "text":
22054
22092
  parts.push({
22055
22093
  type: role === "assistant" ? "output_text" : "input_text",
22056
- text: inlined ? `<system-reminder>
22057
- ${block.text}
22058
- </system-reminder>` : block.text
22094
+ text: block.text
22059
22095
  });
22060
22096
  break;
22061
22097
  case "image":
@@ -22087,12 +22123,19 @@ ${block.text}
22087
22123
  });
22088
22124
  break;
22089
22125
  case "providerNative":
22126
+ if (block.provider === "openai") {
22127
+ flush();
22128
+ const { id: _id, ...rest } = block.data;
22129
+ input.push({ type: block.blockType, ...rest });
22130
+ break;
22131
+ }
22090
22132
  note2("openai:anthropic-native-block-dropped");
22091
22133
  break;
22092
22134
  }
22093
22135
  }
22094
22136
  flush();
22095
22137
  }
22138
+ repairOrphanedCalls(input);
22096
22139
  const body = { model, input, stream: req.stream, store: false };
22097
22140
  const instructions = systemText(req.system, "openai", note2);
22098
22141
  if (instructions !== undefined && instructions.length > 0)
@@ -22156,7 +22199,10 @@ var openaiCodec = {
22156
22199
  throw input.fail("AUTH", "openai credential has no token");
22157
22200
  }
22158
22201
  const headers = orderHeaders(mergeHeaders(openaiProfile.headers, protocol), openaiProfile.order);
22202
+ const include = body.include;
22203
+ const nativeReasoning = Array.isArray(include) && include.includes("reasoning.encrypted_content");
22159
22204
  return {
22205
+ decodeState: { nativeReasoning },
22160
22206
  request: {
22161
22207
  url: oauth ? OAUTH_URL2 : API_URL3,
22162
22208
  method: "POST",
@@ -22166,8 +22212,9 @@ var openaiCodec = {
22166
22212
  degradations
22167
22213
  };
22168
22214
  },
22169
- decode({ body }) {
22170
- return decodeResponses(parseSse(body));
22215
+ decode({ body, decodeState }) {
22216
+ const state = decodeState;
22217
+ return decodeResponses(parseSse(body), { nativeReasoning: state?.nativeReasoning === true });
22171
22218
  }
22172
22219
  };
22173
22220
 
@@ -22344,8 +22391,10 @@ function parseOrThrow(schema, body2) {
22344
22391
  if (result.success)
22345
22392
  return result.data;
22346
22393
  const issue2 = result.error.issues[0];
22347
- const path = issue2?.path.join(".") ?? "(root)";
22348
- throw new GatewayError("BAD_REQUEST", `${path}: ${issue2?.message ?? "invalid request"}`);
22394
+ const segments = issue2?.path ?? [];
22395
+ const path = segments.length === 0 ? "(root)" : segments.map((s) => safeToken(String(s))).join(".");
22396
+ const detail = issue2 === undefined ? "invalid request" : issue2.code === "unrecognized_keys" ? `unrecognized key "${safeToken(issue2.keys[0])}"` : issue2.message;
22397
+ throw new GatewayError("BAD_REQUEST", `${path}: ${detail}`);
22349
22398
  }
22350
22399
  function optionalNumber(value, fallback) {
22351
22400
  if (value === undefined)
@@ -27062,7 +27111,7 @@ function createServiceDeps(input) {
27062
27111
  }
27063
27112
 
27064
27113
  // apps/cli/src/version.ts
27065
- var VERSION = "0.7.1";
27114
+ var VERSION = "0.7.2";
27066
27115
 
27067
27116
  // apps/cli/src/commands/service.ts
27068
27117
  function gatewayArgv(root) {