omnigateway 0.12.6 → 0.12.7

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 (3) hide show
  1. package/bin/omni.js +410 -36
  2. package/gateway.js +423 -49
  3. package/package.json +1 -1
package/bin/omni.js CHANGED
@@ -26769,6 +26769,265 @@ async function* decodeAnthropic(messages, opts = {}) {
26769
26769
  }
26770
26770
  }
26771
26771
 
26772
+ // packages/providers/src/responseFormat.ts
26773
+ var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
26774
+ function readResponseFormatResult(req) {
26775
+ const openai = req.vendor?.openai;
26776
+ const chat = openai?.response_format;
26777
+ if (chat !== undefined) {
26778
+ if (!isRecord(chat) || chat.type !== "json_schema")
26779
+ return { kind: "malformed" };
26780
+ return fromSpec(chat.json_schema);
26781
+ }
26782
+ const responses = openai?.text;
26783
+ if (isRecord(responses) && responses.format !== undefined)
26784
+ return fromSpec(responses.format);
26785
+ if (responses !== undefined)
26786
+ return { kind: "malformed" };
26787
+ const messages = req.vendor?.anthropic?.output_config;
26788
+ if (isRecord(messages) && messages.format !== undefined)
26789
+ return fromSpec(messages.format);
26790
+ if (messages !== undefined)
26791
+ return { kind: "malformed" };
26792
+ return { kind: "absent" };
26793
+ }
26794
+ function readableFormat(spec) {
26795
+ return isRecord(spec) && (spec.type === undefined || spec.type === "json_schema") && isRecord(spec.schema);
26796
+ }
26797
+ function canSerialize(value) {
26798
+ if (typeof value === "bigint")
26799
+ return false;
26800
+ if (typeof value !== "object" || value === null)
26801
+ return true;
26802
+ const seen = new WeakSet;
26803
+ const stack = [value];
26804
+ while (stack.length > 0) {
26805
+ const node2 = stack.pop();
26806
+ if (node2 === undefined)
26807
+ break;
26808
+ if (seen.has(node2))
26809
+ continue;
26810
+ seen.add(node2);
26811
+ if (typeof node2.toJSON === "function") {
26812
+ try {
26813
+ const res = node2.toJSON();
26814
+ if (typeof res === "bigint")
26815
+ return false;
26816
+ } catch {
26817
+ return false;
26818
+ }
26819
+ }
26820
+ const values3 = Array.isArray(node2) ? node2 : Object.values(node2);
26821
+ for (const val of values3) {
26822
+ if (typeof val === "bigint")
26823
+ return false;
26824
+ if (typeof val === "object" && val !== null) {
26825
+ stack.push(val);
26826
+ }
26827
+ }
26828
+ }
26829
+ return true;
26830
+ }
26831
+ function fromSpec(spec) {
26832
+ if (!readableFormat(spec))
26833
+ return { kind: "malformed" };
26834
+ const schema = spec.schema;
26835
+ if (!isRecord(schema))
26836
+ return { kind: "malformed" };
26837
+ if (isCyclic(schema) || tooDeepToSerialize(schema) || !canSerialize(schema)) {
26838
+ return { kind: "tooDeep" };
26839
+ }
26840
+ return {
26841
+ kind: "readable",
26842
+ format: {
26843
+ schema,
26844
+ name: typeof spec.name === "string" && spec.name.length > 0 ? spec.name : "response"
26845
+ }
26846
+ };
26847
+ }
26848
+ function forEachSubschema(nodes, visit2) {
26849
+ for (const node2 of nodes) {
26850
+ for (const [key, value] of Object.entries(node2)) {
26851
+ if (SUBSCHEMA_MAP.includes(key) && isRecord(value)) {
26852
+ for (const member of Object.values(value))
26853
+ if (isRecord(member))
26854
+ visit2(member, node2);
26855
+ } else if (SUBSCHEMA_LIST.includes(key) && Array.isArray(value)) {
26856
+ for (const member of value)
26857
+ if (isRecord(member))
26858
+ visit2(member, node2);
26859
+ } else if (SUBSCHEMA.includes(key) && isRecord(value)) {
26860
+ visit2(value, node2);
26861
+ }
26862
+ }
26863
+ }
26864
+ }
26865
+ function isCyclic(schema) {
26866
+ const onPath = new Set;
26867
+ const done = new WeakSet;
26868
+ const stack = [{ node: schema, entering: true }];
26869
+ while (stack.length > 0) {
26870
+ const frame = stack.pop();
26871
+ if (frame === undefined)
26872
+ break;
26873
+ const node2 = frame.node;
26874
+ if (!frame.entering) {
26875
+ onPath.delete(node2);
26876
+ done.add(node2);
26877
+ continue;
26878
+ }
26879
+ if (onPath.has(node2))
26880
+ return true;
26881
+ if (done.has(node2))
26882
+ continue;
26883
+ onPath.add(node2);
26884
+ stack.push({ node: node2, entering: false });
26885
+ if (Array.isArray(node2)) {
26886
+ for (const item of node2) {
26887
+ if (typeof item === "object" && item !== null) {
26888
+ stack.push({ node: item, entering: true });
26889
+ }
26890
+ }
26891
+ } else {
26892
+ for (const val of Object.values(node2)) {
26893
+ if (typeof val === "object" && val !== null) {
26894
+ stack.push({ node: val, entering: true });
26895
+ }
26896
+ }
26897
+ }
26898
+ }
26899
+ return false;
26900
+ }
26901
+ function tooDeepToSerialize(schema) {
26902
+ let level = [schema];
26903
+ for (let depth = 0;depth < MAX_DEPTH2; depth++) {
26904
+ const next = [];
26905
+ const seenThisLevel = new WeakSet;
26906
+ forEachSubschema(level, (member) => {
26907
+ if (seenThisLevel.has(member))
26908
+ return;
26909
+ seenThisLevel.add(member);
26910
+ next.push(member);
26911
+ });
26912
+ if (next.length === 0)
26913
+ return false;
26914
+ level = next;
26915
+ }
26916
+ return true;
26917
+ }
26918
+ function moveToResponsesText(req, body, provider) {
26919
+ const raw = body.response_format;
26920
+ delete body.response_format;
26921
+ const malformedText = body.text !== undefined && !isRecord(body.text);
26922
+ if (malformedText)
26923
+ delete body.text;
26924
+ const read = readResponseFormatResult(req);
26925
+ const clientText = isRecord(body.text) ? body.text : undefined;
26926
+ const clientFormat = clientText?.format;
26927
+ if (readableFormat(clientFormat) && read.kind === "readable")
26928
+ return;
26929
+ const malformedFormat = clientText !== undefined && clientFormat !== undefined;
26930
+ const text = clientText === undefined ? undefined : { ...clientText };
26931
+ if (text !== undefined)
26932
+ delete text.format;
26933
+ if (malformedFormat)
26934
+ body.text = text;
26935
+ if (read.kind === "readable") {
26936
+ const format = read.format;
26937
+ body.text = {
26938
+ ...text,
26939
+ format: { type: "json_schema", name: format.name, schema: format.schema, strict: true }
26940
+ };
26941
+ return `${provider}:response-format-translated`;
26942
+ }
26943
+ if (isRecord(raw) && raw.type === "json_object") {
26944
+ body.text = { ...text, format: { type: "json_object" } };
26945
+ return `${provider}:response-format-translated`;
26946
+ }
26947
+ if (read.kind === "tooDeep")
26948
+ return `${provider}:response-schema-too-deep`;
26949
+ if (raw !== undefined || malformedText || malformedFormat) {
26950
+ return `${provider}:response-format-dropped`;
26951
+ }
26952
+ return;
26953
+ }
26954
+ function closeObjects(schema, stats) {
26955
+ if (stats !== undefined) {
26956
+ stats.changed = false;
26957
+ stats.truncated = false;
26958
+ }
26959
+ return closeNode(schema, 0, stats ?? { changed: false, truncated: false }, new Map);
26960
+ }
26961
+ var SUBSCHEMA = [
26962
+ "items",
26963
+ "additionalItems",
26964
+ "additionalProperties",
26965
+ "contains",
26966
+ "contentSchema",
26967
+ "if",
26968
+ "then",
26969
+ "else",
26970
+ "not",
26971
+ "propertyNames",
26972
+ "unevaluatedItems",
26973
+ "unevaluatedProperties"
26974
+ ];
26975
+ var SUBSCHEMA_LIST = ["anyOf", "allOf", "oneOf", "prefixItems", "items"];
26976
+ var SUBSCHEMA_MAP = [
26977
+ "properties",
26978
+ "patternProperties",
26979
+ "$defs",
26980
+ "definitions",
26981
+ "dependentSchemas",
26982
+ "dependencies"
26983
+ ];
26984
+ var MAX_DEPTH2 = 64;
26985
+ function closeNode(schema, depth, stats, memo2) {
26986
+ if (depth >= MAX_DEPTH2) {
26987
+ stats.truncated = true;
26988
+ return schema;
26989
+ }
26990
+ let atDepth = memo2.get(depth);
26991
+ if (atDepth === undefined) {
26992
+ atDepth = new WeakMap;
26993
+ memo2.set(depth, atDepth);
26994
+ }
26995
+ const done = atDepth.get(schema);
26996
+ if (done !== undefined)
26997
+ return done;
26998
+ const out = {};
26999
+ atDepth.set(schema, out);
27000
+ for (const [key, value] of Object.entries(schema)) {
27001
+ if (SUBSCHEMA_MAP.includes(key) && isRecord(value)) {
27002
+ const members2 = {};
27003
+ for (const [name, member] of Object.entries(value)) {
27004
+ Object.defineProperty(members2, name, {
27005
+ value: isRecord(member) ? closeNode(member, depth + 1, stats, memo2) : member,
27006
+ writable: true,
27007
+ enumerable: true,
27008
+ configurable: true
27009
+ });
27010
+ }
27011
+ out[key] = members2;
27012
+ continue;
27013
+ }
27014
+ if (SUBSCHEMA.includes(key) && isRecord(value)) {
27015
+ out[key] = closeNode(value, depth + 1, stats, memo2);
27016
+ continue;
27017
+ }
27018
+ if (SUBSCHEMA_LIST.includes(key) && Array.isArray(value)) {
27019
+ out[key] = value.map((arm) => isRecord(arm) ? closeNode(arm, depth + 1, stats, memo2) : arm);
27020
+ continue;
27021
+ }
27022
+ out[key] = value;
27023
+ }
27024
+ if (out.type === "object" && out.additionalProperties !== false) {
27025
+ out.additionalProperties = false;
27026
+ stats.changed = true;
27027
+ }
27028
+ return out;
27029
+ }
27030
+
26772
27031
  // packages/providers/src/system.ts
26773
27032
  function systemTextBlocks(system, provider, note2) {
26774
27033
  if (system === undefined)
@@ -26891,12 +27150,12 @@ function encodeToolChoice(c, cloak) {
26891
27150
  return { type: "tool", name: cloakName(cloak, c.name) };
26892
27151
  }
26893
27152
  }
26894
- function isRecord(value) {
27153
+ function isRecord2(value) {
26895
27154
  return typeof value === "object" && value !== null && !Array.isArray(value);
26896
27155
  }
26897
27156
  function withoutEffort(vendor, note2) {
26898
27157
  const config2 = vendor.output_config;
26899
- if (!isRecord(config2))
27158
+ if (!isRecord2(config2))
26900
27159
  return vendor;
26901
27160
  const entries = Object.entries(config2);
26902
27161
  const kept = entries.filter(([key]) => key !== "effort");
@@ -26910,7 +27169,7 @@ function withoutEffort(vendor, note2) {
26910
27169
  }
26911
27170
  var THINKING_ONLY_EDITS = new Set(["clear_thinking_20251015"]);
26912
27171
  function thinkingIsOff(thinking) {
26913
- if (!isRecord(thinking))
27172
+ if (!isRecord2(thinking))
26914
27173
  return thinking !== undefined;
26915
27174
  return thinking.type !== "adaptive" && thinking.type !== "enabled";
26916
27175
  }
@@ -26918,9 +27177,9 @@ function stripUnsupportedEdits(body, note2) {
26918
27177
  if (!thinkingIsOff(body.thinking))
26919
27178
  return;
26920
27179
  const config2 = body.context_management;
26921
- if (!isRecord(config2) || !Array.isArray(config2.edits))
27180
+ if (!isRecord2(config2) || !Array.isArray(config2.edits))
26922
27181
  return;
26923
- const kept = config2.edits.filter((e) => !(isRecord(e) && THINKING_ONLY_EDITS.has(String(e.type))));
27182
+ const kept = config2.edits.filter((e) => !(isRecord2(e) && THINKING_ONLY_EDITS.has(String(e.type))));
26924
27183
  if (kept.length === config2.edits.length)
26925
27184
  return;
26926
27185
  note2("anthropic:clear-thinking-unsupported");
@@ -26939,11 +27198,11 @@ var CACHEABLE_WIRE_BLOCKS = new Set(["text", "image", "tool_use", "tool_result",
26939
27198
  function lastCacheableHistoryBlock(messages) {
26940
27199
  for (let m = messages.length - 1;m >= 0; m--) {
26941
27200
  const message = messages[m];
26942
- if (!isRecord(message) || !Array.isArray(message.content))
27201
+ if (!isRecord2(message) || !Array.isArray(message.content))
26943
27202
  continue;
26944
27203
  for (let b = message.content.length - 1;b >= 0; b--) {
26945
27204
  const block = message.content[b];
26946
- if (!isRecord(block))
27205
+ if (!isRecord2(block))
26947
27206
  continue;
26948
27207
  if (typeof block.type === "string" && CACHEABLE_WIRE_BLOCKS.has(block.type))
26949
27208
  return block;
@@ -27022,9 +27281,9 @@ function toWire(req, model, opts) {
27022
27281
  };
27023
27282
  if (systemCache.retarget !== undefined) {
27024
27283
  const trailing = body.messages.at(-1);
27025
- if (isRecord(trailing) && Array.isArray(trailing.content)) {
27284
+ if (isRecord2(trailing) && Array.isArray(trailing.content)) {
27026
27285
  for (const block of trailing.content) {
27027
- if (isRecord(block))
27286
+ if (isRecord2(block))
27028
27287
  delete block.cache_control;
27029
27288
  }
27030
27289
  }
@@ -27064,7 +27323,7 @@ function toWire(req, model, opts) {
27064
27323
  };
27065
27324
  if (req.reasoning.effort !== undefined) {
27066
27325
  body.output_config = {
27067
- ...isRecord(body.output_config) ? body.output_config : {},
27326
+ ...isRecord2(body.output_config) ? body.output_config : {},
27068
27327
  effort: req.reasoning.effort
27069
27328
  };
27070
27329
  }
@@ -27077,11 +27336,64 @@ function toWire(req, model, opts) {
27077
27336
  break;
27078
27337
  }
27079
27338
  }
27080
- const vendor = req.vendor?.anthropic ?? {};
27339
+ const native = req.vendor?.anthropic?.output_config;
27340
+ const nativeFormat = isRecord2(native) && readableFormat(native.format);
27341
+ const read = readResponseFormatResult(req);
27342
+ const format = !nativeFormat && read.kind === "readable" ? read.format : undefined;
27343
+ if (format !== undefined) {
27344
+ body.output_config = {
27345
+ ...isRecord2(body.output_config) ? body.output_config : {},
27346
+ format: { type: "json_schema", schema: format.schema }
27347
+ };
27348
+ note2("anthropic:response-format-translated");
27349
+ } else if (!nativeFormat && read.kind === "tooDeep") {
27350
+ note2("anthropic:response-schema-too-deep");
27351
+ }
27352
+ const vendorRaw = req.vendor?.anthropic ?? {};
27353
+ const vendorConfig = vendorRaw.output_config;
27354
+ const encoderConfig = isRecord2(body.output_config) ? body.output_config : undefined;
27355
+ let unreadableFormat = false;
27356
+ let vendor = vendorRaw;
27357
+ if (encoderConfig !== undefined && vendorConfig !== undefined) {
27358
+ if (!isRecord2(vendorConfig)) {
27359
+ const { output_config: _unreadable, ...rest } = vendorRaw;
27360
+ vendor = rest;
27361
+ unreadableFormat = true;
27362
+ } else {
27363
+ const readable = readableFormat(vendorConfig.format);
27364
+ const { format: _unreadable, ...withoutFormat } = vendorConfig;
27365
+ const rest = readable ? vendorConfig : withoutFormat;
27366
+ vendor = { ...vendorRaw, output_config: { ...encoderConfig, ...rest } };
27367
+ unreadableFormat = !readable && vendorConfig.format !== undefined;
27368
+ }
27369
+ }
27081
27370
  Object.assign(body, anthropicReasoningForm(model) === "budget" ? withoutEffort(vendor, note2) : vendor);
27371
+ if (unreadableFormat)
27372
+ note2("anthropic:response-format-dropped");
27373
+ closeOutputConfigSchema(body, note2);
27082
27374
  stripUnsupportedEdits(body, note2);
27083
27375
  return { body, degradations };
27084
27376
  }
27377
+ function closeOutputConfigSchema(body, note2) {
27378
+ const config2 = body.output_config;
27379
+ if (!isRecord2(config2))
27380
+ return;
27381
+ const format = config2.format;
27382
+ if (!isRecord2(format) || !isRecord2(format.schema))
27383
+ return;
27384
+ const stats = { changed: false, truncated: false };
27385
+ const closed = closeObjects(format.schema, stats);
27386
+ if (stats.truncated || !canSerialize(closed)) {
27387
+ const { format: _tooDeep, ...rest } = config2;
27388
+ body.output_config = rest;
27389
+ note2("anthropic:response-schema-too-deep");
27390
+ return;
27391
+ }
27392
+ if (!stats.changed)
27393
+ return;
27394
+ body.output_config = { ...config2, format: { ...format, schema: closed } };
27395
+ note2("anthropic:response-schema-closed");
27396
+ }
27085
27397
 
27086
27398
  // packages/providers/src/anthropic/codec.ts
27087
27399
  var BASE_URL = "https://api.anthropic.com/v1/messages";
@@ -28109,6 +28421,14 @@ function toAntigravityWire(req, model, identity) {
28109
28421
  break;
28110
28422
  }
28111
28423
  }
28424
+ const read = readResponseFormatResult(req);
28425
+ if (read.kind === "readable") {
28426
+ const format = read.format;
28427
+ generationConfig.responseSchema = pruneSchema(format.schema, note2);
28428
+ note2("antigravity:response-format-translated");
28429
+ } else if (read.kind === "tooDeep") {
28430
+ note2("antigravity:response-schema-too-deep");
28431
+ }
28112
28432
  const max = generationConfig.maxOutputTokens;
28113
28433
  if (max !== undefined && max > MAX_OUTPUT_TOKENS) {
28114
28434
  generationConfig.maxOutputTokens = MAX_OUTPUT_TOKENS;
@@ -28608,7 +28928,7 @@ var SCOPES3 = [
28608
28928
  "workspaces:write"
28609
28929
  ].join(" ");
28610
28930
  var TRUSTED_HOST = "x.ai";
28611
- function isRecord2(value) {
28931
+ function isRecord3(value) {
28612
28932
  return typeof value === "object" && value !== null;
28613
28933
  }
28614
28934
  function trustedEndpoint(value, field, fail) {
@@ -28633,7 +28953,7 @@ async function* discover(fail) {
28633
28953
  throw fail("UPSTREAM", `discovery endpoint returned http_${res.status}`);
28634
28954
  }
28635
28955
  const parsed2 = parsed(res.body);
28636
- if (!isRecord2(parsed2)) {
28956
+ if (!isRecord3(parsed2)) {
28637
28957
  throw fail("UPSTREAM", "discovery endpoint returned an unusable response");
28638
28958
  }
28639
28959
  return {
@@ -28642,7 +28962,7 @@ async function* discover(fail) {
28642
28962
  };
28643
28963
  }
28644
28964
  function parseTokenResponse2(value) {
28645
- if (!isRecord2(value) || typeof value.access_token !== "string")
28965
+ if (!isRecord3(value) || typeof value.access_token !== "string")
28646
28966
  return null;
28647
28967
  return {
28648
28968
  accessToken: value.access_token,
@@ -28658,7 +28978,7 @@ function emailFromIdToken(idToken) {
28658
28978
  return null;
28659
28979
  try {
28660
28980
  const json4 = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
28661
- if (!isRecord2(json4))
28981
+ if (!isRecord3(json4))
28662
28982
  return null;
28663
28983
  return typeof json4.email === "string" && json4.email.trim().length > 0 ? json4.email : null;
28664
28984
  } catch {
@@ -28744,11 +29064,11 @@ var PROFILE_URL = "https://api.kilo.ai/api/profile";
28744
29064
  var FALLBACK_VERIFICATION_URL = "https://kilo.ai";
28745
29065
  var DEFAULT_EXPIRES_SECONDS = 300;
28746
29066
  var POLL_INTERVAL_SECONDS = 3;
28747
- function isRecord3(value) {
29067
+ function isRecord4(value) {
28748
29068
  return typeof value === "object" && value !== null;
28749
29069
  }
28750
29070
  function recordFrom(value) {
28751
- return isRecord3(value) ? value : null;
29071
+ return isRecord4(value) ? value : null;
28752
29072
  }
28753
29073
  function stringFrom(value, field) {
28754
29074
  const candidate = value[field];
@@ -28900,11 +29220,11 @@ var TOKEN_URL3 = "https://auth.kimi.com/api/oauth/token";
28900
29220
  var USAGE_URL2 = "https://api.kimi.com/coding/v1/usages";
28901
29221
  var DEFAULT_INTERVAL_SECONDS = 5;
28902
29222
  var PENDING_ERRORS = new Set(["authorization_pending", "slow_down"]);
28903
- function isRecord4(value) {
29223
+ function isRecord5(value) {
28904
29224
  return typeof value === "object" && value !== null;
28905
29225
  }
28906
29226
  function recordFrom2(value) {
28907
- return isRecord4(value) ? value : null;
29227
+ return isRecord5(value) ? value : null;
28908
29228
  }
28909
29229
  function stringFrom2(value, field) {
28910
29230
  const candidate = value[field];
@@ -29095,11 +29415,11 @@ var DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
29095
29415
  var FALLBACK_VERIFICATION_URL2 = "https://auth.meta.com/oauth/device/";
29096
29416
  var DEFAULT_INTERVAL_SECONDS2 = 5;
29097
29417
  var PENDING_ERRORS2 = new Set(["authorization_pending", "slow_down"]);
29098
- function isRecord5(value) {
29418
+ function isRecord6(value) {
29099
29419
  return typeof value === "object" && value !== null;
29100
29420
  }
29101
29421
  function recordFrom3(value) {
29102
- return isRecord5(value) ? value : null;
29422
+ return isRecord6(value) ? value : null;
29103
29423
  }
29104
29424
  function stringFrom3(value, field) {
29105
29425
  const candidate = value[field];
@@ -29280,7 +29600,7 @@ var AUTHORIZE_URL3 = "https://auth.openai.com/oauth/authorize";
29280
29600
  var TOKEN_URL5 = "https://auth.openai.com/oauth/token";
29281
29601
  var SCOPES4 = "openid profile email offline_access";
29282
29602
  var USAGE_URL3 = "https://chatgpt.com/backend-api/wham/usage";
29283
- function isRecord6(value) {
29603
+ function isRecord7(value) {
29284
29604
  return typeof value === "object" && value !== null;
29285
29605
  }
29286
29606
  function nonBlankStringOrNull(value) {
@@ -29297,19 +29617,19 @@ function decodeClaims(idToken) {
29297
29617
  }
29298
29618
  try {
29299
29619
  const json4 = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
29300
- if (!isRecord6(json4))
29620
+ if (!isRecord7(json4))
29301
29621
  return { email: null, accountId: null };
29302
29622
  const auth = json4["https://api.openai.com/auth"];
29303
29623
  return {
29304
29624
  email: typeof json4.email === "string" ? json4.email : null,
29305
- accountId: isRecord6(auth) ? nonBlankStringOrNull(auth.chatgpt_account_id) : null
29625
+ accountId: isRecord7(auth) ? nonBlankStringOrNull(auth.chatgpt_account_id) : null
29306
29626
  };
29307
29627
  } catch {
29308
29628
  return { email: null, accountId: null };
29309
29629
  }
29310
29630
  }
29311
29631
  function parseTokenResponse3(value) {
29312
- if (!isRecord6(value) || typeof value.access_token !== "string")
29632
+ if (!isRecord7(value) || typeof value.access_token !== "string")
29313
29633
  return null;
29314
29634
  return {
29315
29635
  accessToken: value.access_token,
@@ -29894,6 +30214,24 @@ function toCustomChatWire(req, model) {
29894
30214
  else if (req.reasoning?.mode === "budget")
29895
30215
  note2("custom:reasoning-budget-dropped");
29896
30216
  Object.assign(body, req.vendor?.openai ?? {});
30217
+ const droppedText = body.text;
30218
+ delete body.text;
30219
+ const read = readResponseFormatResult(req);
30220
+ const format = read.kind === "readable" ? read.format : undefined;
30221
+ if (format !== undefined) {
30222
+ if (body.response_format === undefined) {
30223
+ body.response_format = {
30224
+ type: "json_schema",
30225
+ json_schema: { name: format.name, schema: format.schema, strict: true }
30226
+ };
30227
+ note2("custom:response-format-translated");
30228
+ }
30229
+ } else if (isRecord(droppedText) && droppedText.format !== undefined) {
30230
+ note2("custom:response-format-dropped");
30231
+ } else if (read.kind === "tooDeep") {
30232
+ delete body.response_format;
30233
+ note2("custom:response-schema-too-deep");
30234
+ }
29897
30235
  return { body, degradations };
29898
30236
  }
29899
30237
  function toCustomResponsesWire(req, model) {
@@ -29985,6 +30323,9 @@ function toCustomResponsesWire(req, model) {
29985
30323
  else if (req.reasoning?.mode === "budget")
29986
30324
  note2("custom:reasoning-budget-dropped");
29987
30325
  Object.assign(body, req.vendor?.openai ?? {});
30326
+ const moved = moveToResponsesText(req, body, "custom");
30327
+ if (moved !== undefined)
30328
+ note2(moved);
29988
30329
  return { body, degradations };
29989
30330
  }
29990
30331
 
@@ -30359,6 +30700,9 @@ function toGrokWire(req, model) {
30359
30700
  }
30360
30701
  }
30361
30702
  Object.assign(body, req.vendor?.grok ?? {});
30703
+ const moved = moveToResponsesText(req, body, "grok");
30704
+ if (moved !== undefined)
30705
+ note2(moved);
30362
30706
  return { body, degradations };
30363
30707
  }
30364
30708
 
@@ -30792,6 +31136,18 @@ function toKiloWire(req, model) {
30792
31136
  }
30793
31137
  }
30794
31138
  Object.assign(body, req.vendor?.kilo ?? {});
31139
+ const read = readResponseFormatResult(req);
31140
+ const format = read.kind === "readable" ? read.format : undefined;
31141
+ if (format !== undefined && body.response_format === undefined) {
31142
+ body.response_format = {
31143
+ type: "json_schema",
31144
+ json_schema: { name: format.name, schema: format.schema, strict: true }
31145
+ };
31146
+ note2("kilo:response-format-translated");
31147
+ } else if (read.kind === "tooDeep") {
31148
+ delete body.response_format;
31149
+ note2("kilo:response-schema-too-deep");
31150
+ }
30795
31151
  return { body, degradations };
30796
31152
  }
30797
31153
 
@@ -31043,6 +31399,18 @@ function toChatWire(req, model, vendor = "kimi") {
31043
31399
  if (req.reasoning !== undefined)
31044
31400
  note2("kimi:reasoning-dropped");
31045
31401
  Object.assign(body, req.vendor?.[vendor] ?? {});
31402
+ const read = readResponseFormatResult(req);
31403
+ const format = read.kind === "readable" ? read.format : undefined;
31404
+ if (format !== undefined && body.response_format === undefined) {
31405
+ body.response_format = {
31406
+ type: "json_schema",
31407
+ json_schema: { name: format.name, schema: format.schema, strict: true }
31408
+ };
31409
+ note2("kimi:response-format-translated");
31410
+ } else if (read.kind === "tooDeep") {
31411
+ delete body.response_format;
31412
+ note2("kimi:response-schema-too-deep");
31413
+ }
31046
31414
  return { body, degradations };
31047
31415
  }
31048
31416
 
@@ -31439,6 +31807,9 @@ function toMuseWire(req, model) {
31439
31807
  }
31440
31808
  const key = suppliedKey(req) ?? cacheKey(req, instructions ?? "", input2[0]);
31441
31809
  Object.assign(body, req.vendor?.openai ?? {});
31810
+ const moved = moveToResponsesText(req, body, "muse");
31811
+ if (moved !== undefined)
31812
+ note2(moved);
31442
31813
  body.prompt_cache_key = key;
31443
31814
  return { body, degradations, cacheKey: key };
31444
31815
  }
@@ -31849,6 +32220,9 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
31849
32220
  }
31850
32221
  const key = suppliedKey2(req) ?? cacheKey2(req, instructions ?? "", input2[0]);
31851
32222
  Object.assign(body, req.vendor?.openai ?? {});
32223
+ const moved = moveToResponsesText(req, body, "openai");
32224
+ if (moved !== undefined)
32225
+ note2(moved);
31852
32226
  body.prompt_cache_key = key;
31853
32227
  return { body, degradations, cacheKey: key };
31854
32228
  }
@@ -34741,7 +35115,7 @@ function createRefresher(deps) {
34741
35115
  }
34742
35116
  // packages/control/src/pluginProviders.ts
34743
35117
  import { join as join5 } from "path";
34744
- function isRecord7(value) {
35118
+ function isRecord8(value) {
34745
35119
  return typeof value === "object" && value !== null && !Array.isArray(value);
34746
35120
  }
34747
35121
  function isNumber(value) {
@@ -34752,7 +35126,7 @@ function checkAt(ok, id, path, expected) {
34752
35126
  throw new Error(`provider ${id} descriptor: ${path} must be ${expected}`);
34753
35127
  }
34754
35128
  function checkLimits(id, path, value) {
34755
- checkAt(isRecord7(value), id, path, "an object");
35129
+ checkAt(isRecord8(value), id, path, "an object");
34756
35130
  const limits = value;
34757
35131
  checkAt(isNumber(limits.contextWindow), id, `${path}.contextWindow`, "a finite number");
34758
35132
  checkAt(isNumber(limits.maxOutputTokens), id, `${path}.maxOutputTokens`, "a finite number");
@@ -34770,19 +35144,19 @@ function checkDescriptor(id, record2) {
34770
35144
  }
34771
35145
  }
34772
35146
  const capabilities2 = record2.capabilities;
34773
- checkAt(isRecord7(capabilities2), id, "capabilities", "an object");
35147
+ checkAt(isRecord8(capabilities2), id, "capabilities", "an object");
34774
35148
  for (const flag of ["tools", "images", "reasoning"]) {
34775
35149
  const value = capabilities2[flag];
34776
35150
  checkAt(typeof value === "boolean", id, `capabilities.${flag}`, "a boolean");
34777
35151
  }
34778
35152
  const write = record2.writeOverInput;
34779
- checkAt(isRecord7(write), id, "writeOverInput", "an object");
35153
+ checkAt(isRecord8(write), id, "writeOverInput", "an object");
34780
35154
  for (const ttl of ["fiveMinute", "oneHour"]) {
34781
35155
  const value = write[ttl];
34782
35156
  checkAt(isNumber(value), id, `writeOverInput.${ttl}`, "a finite number");
34783
35157
  }
34784
35158
  const catalog2 = record2.catalog;
34785
- checkAt(isRecord7(catalog2), id, "catalog", "an object");
35159
+ checkAt(isRecord8(catalog2), id, "catalog", "an object");
34786
35160
  const entry = catalog2;
34787
35161
  checkAt(typeof entry.defaultModel === "string", id, "catalog.defaultModel", "a string");
34788
35162
  checkAt(Array.isArray(entry.authTypes), id, "catalog.authTypes", "an array");
@@ -34793,11 +35167,11 @@ function checkDescriptor(id, record2) {
34793
35167
  checkAt(Array.isArray(entry.models), id, "catalog.models", "an array");
34794
35168
  for (const [index, model] of entry.models.entries()) {
34795
35169
  const at = `catalog.models[${index}]`;
34796
- checkAt(isRecord7(model), id, at, "an object");
35170
+ checkAt(isRecord8(model), id, at, "an object");
34797
35171
  const choice = model;
34798
35172
  checkAt(typeof choice.id === "string", id, `${at}.id`, "a string");
34799
35173
  checkAt(typeof choice.label === "string", id, `${at}.label`, "a string");
34800
- checkAt(isRecord7(choice.pricing), id, `${at}.pricing`, "an object");
35174
+ checkAt(isRecord8(choice.pricing), id, `${at}.pricing`, "an object");
34801
35175
  const pricing = choice.pricing;
34802
35176
  for (const field of ["input", "output", "cacheRead", "cacheWrite5m", "cacheWrite1h"]) {
34803
35177
  checkAt(isNumber(pricing[field]), id, `${at}.pricing.${field}`, "a finite number");
@@ -34813,13 +35187,13 @@ function checkDescriptor(id, record2) {
34813
35187
  checkAt(typeof prefix === "string", id, `modelPrefixes[${index}]`, "a string");
34814
35188
  }
34815
35189
  const presentation = record2.presentation;
34816
- checkAt(isRecord7(presentation), id, "presentation", "an object");
35190
+ checkAt(isRecord8(presentation), id, "presentation", "an object");
34817
35191
  const shown = presentation;
34818
35192
  for (const field of ["label", "tone"]) {
34819
35193
  checkAt(typeof shown[field] === "string", id, `presentation.${field}`, "a string");
34820
35194
  }
34821
35195
  checkAt(isNumber(shown.order), id, "presentation.order", "a finite number");
34822
- checkAt(isRecord7(shown.colour), id, "presentation.colour", "an object");
35196
+ checkAt(isRecord8(shown.colour), id, "presentation.colour", "an object");
34823
35197
  for (const scheme of ["light", "dark"]) {
34824
35198
  const value = shown.colour[scheme];
34825
35199
  checkAt(typeof value === "string", id, `presentation.colour.${scheme}`, "a string");
@@ -34831,7 +35205,7 @@ function checkDescriptor(id, record2) {
34831
35205
  function validateOAuthFlow(id, value) {
34832
35206
  if (value === undefined)
34833
35207
  return;
34834
- if (!isRecord7(value))
35208
+ if (!isRecord8(value))
34835
35209
  throw new Error(`provider ${id} oauth must be an object`);
34836
35210
  const kind = value.kind;
34837
35211
  if (kind !== "pkce" && kind !== "device") {
@@ -37525,7 +37899,7 @@ function createServiceDeps(input2) {
37525
37899
  }
37526
37900
 
37527
37901
  // apps/cli/src/version.ts
37528
- var VERSION = "0.12.6";
37902
+ var VERSION = "0.12.7";
37529
37903
 
37530
37904
  // apps/cli/src/commands/service.ts
37531
37905
  function gatewayArgv(root) {