@openclaw/ai 2026.9.5 → 2026.9.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 (102) hide show
  1. package/dist/{anthropic-COtDvgtt.mjs → anthropic-Cw2pgccz.mjs} +59 -88
  2. package/dist/{anthropic-payload-policy-5Erq1Nzy.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +8 -6
  3. package/dist/{anthropic-stream-reducer-BvdYYWL8.mjs → anthropic-stream-reducer-D9MCkl8Z.mjs} +194 -247
  4. package/dist/{api-registry-Ba2Cv-ut.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-YrgnD583.mjs → azure-openai-responses-BwT3-X8P.mjs} +22 -33
  6. package/dist/{base64-BQOzsvUH.mjs → base64-C1PsYcRQ.mjs} +22 -16
  7. package/dist/{diagnostics-Dm4bisWG.mjs → diagnostics-CJaB6g8J.mjs} +55 -10
  8. package/dist/{diagnostics-CPeq9F7y.mjs → diagnostics-DzrF1h4J.mjs} +18 -1
  9. package/dist/diagnostics.d.mts +11 -5
  10. package/dist/diagnostics.mjs +4 -4
  11. package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
  12. package/dist/event-stream-CMQfX_yr.d.mts +1 -0
  13. package/dist/{event-stream-CCoa-qSI.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
  14. package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
  15. package/dist/event-stream.d.mts +2 -2
  16. package/dist/event-stream.mjs +1 -1
  17. package/dist/{google-BuhpRO9r.mjs → google-BfapkS_K.mjs} +8 -11
  18. package/dist/google-interactions-DW3iXzjc.mjs +574 -0
  19. package/dist/{google-messages-CyWnYlh0.mjs → google-messages-CtjVtVot.mjs} +35 -71
  20. package/dist/{google-shared-BT5ZeNer.mjs → google-shared-Y2YfotEu.mjs} +43 -47
  21. package/dist/{google-vertex-C7EplRvt.mjs → google-vertex-Dov4kBWu.mjs} +16 -30
  22. package/dist/{host-B4MeUNBc.mjs → host-CHi3X87F.mjs} +64 -189
  23. package/dist/{host-policy-DUnXSx0I.mjs → host-policy-BOAwRg_M.mjs} +2 -14
  24. package/dist/{host-FZ1RA_qD.d.mts → host-rxlNaBwm.d.mts} +9 -3
  25. package/dist/{index-DaF2QbwS.d.mts → index-D6KsSE74.d.mts} +57 -9
  26. package/dist/index.d.mts +7 -7
  27. package/dist/index.mjs +7 -7
  28. package/dist/internal/anthropic.d.mts +13 -8
  29. package/dist/internal/anthropic.mjs +5 -5
  30. package/dist/internal/openai-completions-compat.d.mts +1 -1
  31. package/dist/internal/openai-completions-compat.mjs +1 -1
  32. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  33. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  34. package/dist/internal/openai.d.mts +46 -9
  35. package/dist/internal/openai.mjs +13 -12
  36. package/dist/internal/runtime.d.mts +31 -70
  37. package/dist/internal/runtime.mjs +11 -66
  38. package/dist/internal/shared.d.mts +16 -13
  39. package/dist/internal/shared.mjs +6 -5
  40. package/dist/internal/tool-schema.d.mts +2 -2
  41. package/dist/internal/tool-schema.mjs +2 -2
  42. package/dist/{mistral-moA-mbwl.mjs → mistral-RS6mboC-.mjs} +46 -93
  43. package/dist/{model-transport-url-DKocrEsb.d.mts → model-transport-url-C5f59L3Y.d.mts} +1 -1
  44. package/dist/{openai-chatgpt-responses-DWID3EFO.mjs → openai-chatgpt-responses-CYbidtrn.mjs} +118 -99
  45. package/dist/{openai-completions-DJ1Vm-CD.mjs → openai-completions-D14ihPYk.mjs} +14 -12
  46. package/dist/{openai-completions-compat-CkwdxTZx.mjs → openai-completions-compat-BOVWBZDn.mjs} +3 -5
  47. package/dist/{openai-completions-compat-JE7gqxb9.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
  48. package/dist/{openai-completions-stream-Bu98b0Hv.mjs → openai-completions-stream-CDCuw3DP.mjs} +124 -183
  49. package/dist/{openai-prompt-cache-CJ_xEevu.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
  50. package/dist/{openai-prompt-cache-1wfaIszn.mjs → openai-prompt-cache-D2V7MqR7.mjs} +1 -1
  51. package/dist/{openai-provider-client-DPo0Hmak.mjs → openai-provider-client-CwfsGBbA.mjs} +2 -2
  52. package/dist/{openai-reasoning-effort-NlFZmfEu.mjs → openai-reasoning-effort-ConhwkeX.mjs} +14 -5
  53. package/dist/{openai-responses-BejZzQCP.mjs → openai-responses-CKCBEc2W.mjs} +12 -11
  54. package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
  55. package/dist/{openai-responses-compaction-window-D6P5oZP5.mjs → openai-responses-compaction-window-UNK1GDpy.mjs} +5 -5
  56. package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
  57. package/dist/{openai-responses-contracts-Dflvrfa8.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
  58. package/dist/{openai-responses-prompt-observer-internal-C15_-OwV.mjs → openai-responses-prompt-observer-internal-iAqLb4tk.mjs} +16 -13
  59. package/dist/openai-responses-request-lifecycle-Fsag-IGZ.mjs +36 -0
  60. package/dist/{openai-responses-shared-CwsziD_m.mjs → openai-responses-shared-DL4ulQn7.mjs} +838 -577
  61. package/dist/{openai-responses-terminal-usage-Dl3J6zrf.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
  62. package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
  63. package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
  64. package/dist/{openai-tool-schema-BO8rwyAD.mjs → openai-tool-schema-vsl-cE-n.mjs} +365 -429
  65. package/dist/{openai-transport-params-DQeuAvBl.mjs → openai-transport-params-BwlpzX-2.mjs} +61 -106
  66. package/dist/{positive-integer-DtjCkbue.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
  67. package/dist/{provider-error-DDqw9Qda.mjs → provider-error-CwT_j2v0.mjs} +82 -10
  68. package/dist/{provider-error-CzNw4BWX.d.mts → provider-error-xumb1V3F.d.mts} +3 -1
  69. package/dist/{provider-options-DprLsWh9.d.mts → provider-options-Df7ov0K1.d.mts} +6 -4
  70. package/dist/{provider-replay-context-CnUSOwhr.mjs → provider-replay-context-DsyI5jOP.mjs} +1 -1
  71. package/dist/{provider-transcript-transform-BsRAhuWJ.mjs → provider-transcript-transform-JbFbHV8h.mjs} +17 -2
  72. package/dist/{provider-transport-turn-state-CkGToCD2.mjs → provider-transport-turn-state-BheUi_hl.mjs} +1 -1
  73. package/dist/{provider-types-CAKRC7N5.d.mts → provider-types-d4XnoZMd.d.mts} +3 -3
  74. package/dist/provider-types.d.mts +6 -6
  75. package/dist/providers.d.mts +2 -2
  76. package/dist/providers.mjs +15 -11
  77. package/dist/{reasoning-tag-text-partitioner-Dy9IO8Dc.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +193 -98
  78. package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
  79. package/dist/simple-options-CGAkCwtM.mjs +349 -0
  80. package/dist/{src-DeKjbE8I.mjs → src-H4aXcFuX.mjs} +53 -26
  81. package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
  82. package/dist/{stream-first-event-timeout-C9ZadkJW.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
  83. package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
  84. package/dist/{transport-stream-shared-D-6FQSHm.mjs → transport-stream-shared-Dh5qKJ8e.mjs} +63 -37
  85. package/dist/{transport-stream-shared-BbUkFaHi.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +13 -7
  86. package/dist/{transport-utils-1cyq5Y7x.mjs → transport-utils-C-4bf2Ok.mjs} +3 -4
  87. package/dist/transports.d.mts +37 -33
  88. package/dist/transports.mjs +208 -239
  89. package/dist/types-CB-_vNyI.d.mts +1 -0
  90. package/dist/{types-4_uVs5WH.d.mts → types-CLLR3eB4.d.mts} +5 -1
  91. package/dist/types.d.mts +6 -6
  92. package/dist/types.mjs +5 -5
  93. package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
  94. package/dist/{validation-Ctzu2DhF.d.mts → validation-Cat2wQsc.d.mts} +1 -1
  95. package/dist/validation.d.mts +1 -1
  96. package/dist/validation.mjs +1 -1
  97. package/package.json +6 -6
  98. package/dist/assistant-output-BsEkB-vU.mjs +0 -16
  99. package/dist/event-stream-DmSCpi1T.d.mts +0 -1
  100. package/dist/simple-options-C6cFWj_f.mjs +0 -175
  101. package/dist/types-DkJfb4W3.d.mts +0 -1
  102. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,8 +1,10 @@
1
+ import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
1
2
  import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
2
- import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
3
3
  import { i as uniqueValues, t as normalizeStringEntries } from "./string-normalization-J9ZiLfGO.mjs";
4
+ import { a as SCHEMA_OBJECT_KEYS$1, i as SCHEMA_MAP_KEYS$1, o as evaluateSchemaWalk, r as SCHEMA_ARRAY_KEYS$1 } from "./tool-schema-json-projection-Ct8SeBeJ.mjs";
4
5
  //#region packages/ai/src/providers/clean-for-gemini.ts
5
6
  const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
7
+ "~optional",
6
8
  "patternProperties",
7
9
  "additionalProperties",
8
10
  "$schema",
@@ -71,7 +73,7 @@ function tryFlattenLiteralAnyOf(variants) {
71
73
  return null;
72
74
  }
73
75
  function isNullSchema(variant) {
74
- if (!variant || typeof variant !== "object" || Array.isArray(variant)) return false;
76
+ if (!isRecord(variant)) return false;
75
77
  const record = variant;
76
78
  if ("const" in record && record.const === null) return true;
77
79
  if (Array.isArray(record.enum) && record.enum.length === 1) return record.enum[0] === null;
@@ -80,20 +82,9 @@ function isNullSchema(variant) {
80
82
  if (Array.isArray(typeValue) && typeValue.length === 1 && typeValue[0] === "null") return true;
81
83
  return false;
82
84
  }
83
- function stripNullVariants(variants) {
84
- if (variants.length === 0) return {
85
- variants,
86
- stripped: false
87
- };
88
- const nonNull = variants.filter((variant) => !isNullSchema(variant));
89
- return {
90
- variants: nonNull,
91
- stripped: nonNull.length !== variants.length
92
- };
93
- }
94
85
  function extendSchemaDefs$1(defs, schema) {
95
- const defsEntry = schema.$defs && typeof schema.$defs === "object" && !Array.isArray(schema.$defs) ? schema.$defs : void 0;
96
- const legacyDefsEntry = schema.definitions && typeof schema.definitions === "object" && !Array.isArray(schema.definitions) ? schema.definitions : void 0;
86
+ const defsEntry = isRecord(schema.$defs) ? schema.$defs : void 0;
87
+ const legacyDefsEntry = isRecord(schema.definitions) ? schema.definitions : void 0;
97
88
  if (!defsEntry && !legacyDefsEntry) return defs;
98
89
  const next = defs ? new Map(defs) : /* @__PURE__ */ new Map();
99
90
  if (defsEntry) for (const [key, value] of Object.entries(defsEntry)) next.set(key, value);
@@ -113,7 +104,8 @@ function tryResolveLocalRef$1(ref, defs) {
113
104
  }
114
105
  function simplifyUnionVariants(params) {
115
106
  const { obj, variants } = params;
116
- const { variants: nonNullVariants, stripped } = stripNullVariants(variants);
107
+ const nonNullVariants = variants.filter((variant) => !isNullSchema(variant));
108
+ const stripped = nonNullVariants.length !== variants.length;
117
109
  const flattened = tryFlattenLiteralAnyOf(nonNullVariants);
118
110
  if (flattened) {
119
111
  const result = {
@@ -148,7 +140,7 @@ function simplifyUnionVariants(params) {
148
140
  }
149
141
  function sanitizeRequiredFields(schema) {
150
142
  if (!Array.isArray(schema.required)) return schema;
151
- if (!schema.properties || typeof schema.properties !== "object" || Array.isArray(schema.properties)) {
143
+ if (!isRecord(schema.properties)) {
152
144
  if (schema.type === "object") delete schema.required;
153
145
  return schema;
154
146
  }
@@ -158,89 +150,114 @@ function sanitizeRequiredFields(schema) {
158
150
  else delete schema.required;
159
151
  return schema;
160
152
  }
161
- function cleanSchemaForGeminiWithDefs(schema, defs, refStack) {
153
+ function* cleanSchemaArray(schemas, defs, refStack, ancestors, result) {
154
+ result.length = schemas.length;
155
+ for (let index = 0; index < result.length; index += 1) if (index in schemas) result[index] = yield cleanSchemaForGeminiWithDefs(schemas[index], defs, refStack, ancestors);
156
+ return result;
157
+ }
158
+ function* cleanSchemaForGeminiWithDefs(schema, defs, refStack, ancestors) {
162
159
  if (!schema || typeof schema !== "object") return schema;
163
- if (Array.isArray(schema)) return schema.map((item) => cleanSchemaForGeminiWithDefs(item, defs, refStack));
164
- const obj = schema;
165
- const nextDefs = extendSchemaDefs$1(defs, obj);
166
- const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
167
- if (refValue) {
168
- if (refStack?.has(refValue)) return {};
169
- const resolved = tryResolveLocalRef$1(refValue, nextDefs);
170
- if (resolved) {
171
- const nextRefStack = refStack ? new Set(refStack) : /* @__PURE__ */ new Set();
172
- nextRefStack.add(refValue);
173
- const cleaned = cleanSchemaForGeminiWithDefs(resolved, nextDefs, nextRefStack);
174
- if (!cleaned || typeof cleaned !== "object" || Array.isArray(cleaned)) return cleaned;
175
- const result = { ...cleaned };
160
+ if (ancestors.has(schema)) throw new TypeError("Tool schema contains a circular reference.");
161
+ ancestors.add(schema);
162
+ try {
163
+ if (Array.isArray(schema)) {
164
+ const result = [];
165
+ yield cleanSchemaArray(schema, defs, refStack, ancestors, result);
166
+ return result;
167
+ }
168
+ const obj = schema;
169
+ const nextDefs = extendSchemaDefs$1(defs, obj);
170
+ const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
171
+ if (refValue) {
172
+ if (refStack?.has(refValue)) return {};
173
+ const resolved = tryResolveLocalRef$1(refValue, nextDefs);
174
+ if (resolved) {
175
+ const nextRefStack = refStack ? new Set(refStack) : /* @__PURE__ */ new Set();
176
+ nextRefStack.add(refValue);
177
+ const cleaned = yield cleanSchemaForGeminiWithDefs(resolved, nextDefs, nextRefStack, /* @__PURE__ */ new Set());
178
+ if (!cleaned || typeof cleaned !== "object" || Array.isArray(cleaned)) return cleaned;
179
+ const result = { ...cleaned };
180
+ copySchemaMeta$1(obj, result);
181
+ return result;
182
+ }
183
+ const result = {};
176
184
  copySchemaMeta$1(obj, result);
177
185
  return result;
178
186
  }
179
- const result = {};
180
- copySchemaMeta$1(obj, result);
181
- return result;
182
- }
183
- const hasAnyOf = "anyOf" in obj && Array.isArray(obj.anyOf);
184
- const hasOneOf = "oneOf" in obj && Array.isArray(obj.oneOf);
185
- let cleanedAnyOf = hasAnyOf ? obj.anyOf.map((variant) => cleanSchemaForGeminiWithDefs(variant, nextDefs, refStack)) : void 0;
186
- let cleanedOneOf = hasOneOf ? obj.oneOf.map((variant) => cleanSchemaForGeminiWithDefs(variant, nextDefs, refStack)) : void 0;
187
- if (hasAnyOf) {
188
- const simplified = simplifyUnionVariants({
189
- obj,
190
- variants: cleanedAnyOf ?? []
191
- });
192
- if (simplified.kind === "simplified") return simplified.value;
193
- cleanedAnyOf = simplified.value;
194
- }
195
- if (hasOneOf) {
196
- const simplified = simplifyUnionVariants({
197
- obj,
198
- variants: cleanedOneOf ?? []
199
- });
200
- if (simplified.kind === "simplified") return simplified.value;
201
- cleanedOneOf = simplified.value;
202
- }
203
- const cleaned = {};
204
- for (const [key, value] of Object.entries(obj)) {
205
- if (GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS.has(key)) continue;
206
- if (key === "const") {
207
- const enumValues = cleanGeminiEnumValues([value]);
208
- if (enumValues) cleaned.enum = enumValues;
209
- continue;
187
+ const hasAnyOf = "anyOf" in obj && Array.isArray(obj.anyOf);
188
+ const hasOneOf = "oneOf" in obj && Array.isArray(obj.oneOf);
189
+ let cleanedAnyOf;
190
+ if (hasAnyOf) {
191
+ const variants = obj.anyOf;
192
+ cleanedAnyOf = [];
193
+ yield cleanSchemaArray(variants, nextDefs, refStack, ancestors, cleanedAnyOf);
210
194
  }
211
- if (key === "enum") {
212
- const enumValues = cleanGeminiEnumValues(value);
213
- if (enumValues) cleaned.enum = enumValues;
214
- continue;
195
+ let cleanedOneOf;
196
+ if (hasOneOf) {
197
+ const variants = obj.oneOf;
198
+ cleanedOneOf = [];
199
+ yield cleanSchemaArray(variants, nextDefs, refStack, ancestors, cleanedOneOf);
215
200
  }
216
- if (key === "required" && Array.isArray(value) && value.length === 0) continue;
217
- if (key === "type" && (hasAnyOf || hasOneOf)) continue;
218
- if (key === "type" && Array.isArray(value) && value.every((entry) => typeof entry === "string")) {
219
- const types = value.filter((entry) => entry !== "null");
220
- cleaned.type = types.length === 1 ? types[0] : types;
221
- continue;
201
+ if (hasAnyOf) {
202
+ const simplified = simplifyUnionVariants({
203
+ obj,
204
+ variants: cleanedAnyOf ?? []
205
+ });
206
+ if (simplified.kind === "simplified") return simplified.value;
207
+ cleanedAnyOf = simplified.value;
222
208
  }
223
- if (key === "properties") {
224
- if (value && typeof value === "object" && !Array.isArray(value)) cleaned[key] = Object.fromEntries(Object.entries(value).map(([k, v]) => [k, cleanSchemaForGeminiWithDefs(v, nextDefs, refStack)]));
225
- else cleaned[key] = {};
226
- } else if (key === "items" && value) {
227
- if (Array.isArray(value)) cleaned[key] = value.map((entry) => cleanSchemaForGeminiWithDefs(entry, nextDefs, refStack));
228
- else if (typeof value === "object") cleaned[key] = cleanSchemaForGeminiWithDefs(value, nextDefs, refStack);
229
- else cleaned[key] = value;
230
- } else if (key === "anyOf" && Array.isArray(value)) cleaned[key] = cleanedAnyOf ?? value.map((variant) => cleanSchemaForGeminiWithDefs(variant, nextDefs, refStack));
231
- else if (key === "oneOf" && Array.isArray(value)) cleaned[key] = cleanedOneOf ?? value.map((variant) => cleanSchemaForGeminiWithDefs(variant, nextDefs, refStack));
232
- else if (key === "allOf" && Array.isArray(value)) cleaned[key] = value.map((variant) => cleanSchemaForGeminiWithDefs(variant, nextDefs, refStack));
233
- else cleaned[key] = value;
234
- }
235
- if (cleaned.anyOf && Array.isArray(cleaned.anyOf)) {
236
- const flattened = flattenUnionFallback(cleaned, cleaned.anyOf);
237
- if (flattened) return sanitizeRequiredFields(flattened);
238
- }
239
- if (cleaned.oneOf && Array.isArray(cleaned.oneOf)) {
240
- const flattened = flattenUnionFallback(cleaned, cleaned.oneOf);
241
- if (flattened) return sanitizeRequiredFields(flattened);
209
+ if (hasOneOf) {
210
+ const simplified = simplifyUnionVariants({
211
+ obj,
212
+ variants: cleanedOneOf ?? []
213
+ });
214
+ if (simplified.kind === "simplified") return simplified.value;
215
+ cleanedOneOf = simplified.value;
216
+ }
217
+ const cleaned = {};
218
+ for (const [key, value] of Object.entries(obj)) {
219
+ if (GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS.has(key)) continue;
220
+ if (key === "const" || key === "enum") {
221
+ const enumValues = cleanGeminiEnumValues(key === "const" ? [value] : value);
222
+ if (enumValues) cleaned.enum = enumValues;
223
+ continue;
224
+ }
225
+ if (key === "required" && Array.isArray(value) && value.length === 0) continue;
226
+ if (key === "type" && (hasAnyOf || hasOneOf)) continue;
227
+ if (key === "type" && Array.isArray(value) && value.every((entry) => typeof entry === "string")) {
228
+ const types = value.filter((entry) => entry !== "null");
229
+ cleaned.type = types.length === 1 ? types[0] : types;
230
+ continue;
231
+ }
232
+ if (key === "properties") {
233
+ if (value && typeof value === "object" && !Array.isArray(value)) {
234
+ const entries = Object.entries(value);
235
+ for (const entry of entries) entry[1] = yield cleanSchemaForGeminiWithDefs(entry[1], nextDefs, refStack, ancestors);
236
+ cleaned[key] = Object.fromEntries(entries);
237
+ } else cleaned[key] = {};
238
+ } else if (key === "items" && value) {
239
+ if (Array.isArray(value)) {
240
+ const result = [];
241
+ yield cleanSchemaArray(value, nextDefs, refStack, ancestors, result);
242
+ cleaned[key] = result;
243
+ } else if (typeof value === "object") cleaned[key] = yield cleanSchemaForGeminiWithDefs(value, nextDefs, refStack, ancestors);
244
+ else cleaned[key] = value;
245
+ } else if (key === "anyOf" && Array.isArray(value)) cleaned[key] = cleanedAnyOf;
246
+ else if (key === "oneOf" && Array.isArray(value)) cleaned[key] = cleanedOneOf;
247
+ else if (key === "allOf" && Array.isArray(value)) {
248
+ const result = [];
249
+ yield cleanSchemaArray(value, nextDefs, refStack, ancestors, result);
250
+ cleaned[key] = result;
251
+ } else cleaned[key] = value;
252
+ }
253
+ for (const variants of [cleaned.anyOf, cleaned.oneOf]) if (Array.isArray(variants)) {
254
+ const flattened = flattenUnionFallback(cleaned, variants);
255
+ if (flattened) return sanitizeRequiredFields(flattened);
256
+ }
257
+ return sanitizeRequiredFields(cleaned);
258
+ } finally {
259
+ ancestors.delete(schema);
242
260
  }
243
- return sanitizeRequiredFields(cleaned);
244
261
  }
245
262
  /**
246
263
  * Last-resort flattening for anyOf/oneOf arrays that could not be simplified
@@ -251,40 +268,192 @@ function flattenUnionFallback(obj, variants) {
251
268
  const objects = variants.filter((v) => Boolean(v) && typeof v === "object");
252
269
  if (objects.length === 0) return;
253
270
  const types = new Set(objects.map((v) => v.type).filter(Boolean));
254
- if (objects.length === 1) {
255
- const merged = { ...objects[0] };
256
- copySchemaMeta$1(obj, merged);
257
- return merged;
258
- }
259
- if (types.size === 1) {
260
- const merged = { type: Array.from(types)[0] };
261
- copySchemaMeta$1(obj, merged);
262
- return merged;
263
- }
264
271
  const first = objects[0];
265
- if (first?.type) {
266
- const merged = { type: first.type };
267
- copySchemaMeta$1(obj, merged);
268
- return merged;
269
- }
270
- const merged = {};
272
+ const type = types.size === 1 ? Array.from(types)[0] : first?.type;
273
+ const merged = objects.length === 1 ? { ...first } : type ? { type } : {};
271
274
  copySchemaMeta$1(obj, merged);
272
275
  return merged;
273
276
  }
274
277
  function cleanSchemaForGemini(schema) {
275
- return cleanSchemaForGeminiWithDefs(schema, void 0, void 0);
278
+ return evaluateSchemaWalk(cleanSchemaForGeminiWithDefs(schema, void 0, void 0, /* @__PURE__ */ new Set()));
276
279
  }
277
280
  //#endregion
278
- //#region packages/ai/src/providers/clean-for-llamacpp-gbnf.ts
279
- /** llama.cpp rejects grammar repetitions whose expanded rule count reaches 2000. */
280
- const LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD = 2e3;
281
- const SCHEMA_MAP_KEYS$2 = /* @__PURE__ */ new Set([
281
+ //#region packages/ai/src/providers/tool-schema-refs.ts
282
+ function setOwnSchemaProperty(target, key, value) {
283
+ Object.defineProperty(target, key, {
284
+ value,
285
+ enumerable: true,
286
+ configurable: true,
287
+ writable: true
288
+ });
289
+ }
290
+ function copySchemaMeta(from, to) {
291
+ for (const key of [
292
+ "title",
293
+ "description",
294
+ "default"
295
+ ]) if (key in from && from[key] !== void 0) to[key] = from[key];
296
+ }
297
+ function extendSchemaDefs(defs, schema) {
298
+ const defsEntry = isRecord(schema.$defs) ? schema.$defs : void 0;
299
+ const legacyDefsEntry = isRecord(schema.definitions) ? schema.definitions : void 0;
300
+ if (!defsEntry && !legacyDefsEntry) return defs;
301
+ const next = defs ? {
302
+ $defs: new Map(defs.$defs),
303
+ definitions: new Map(defs.definitions)
304
+ } : {
305
+ $defs: /* @__PURE__ */ new Map(),
306
+ definitions: /* @__PURE__ */ new Map()
307
+ };
308
+ if (defsEntry) for (const [key, value] of Object.entries(defsEntry)) next.$defs.set(key, value);
309
+ if (legacyDefsEntry) for (const [key, value] of Object.entries(legacyDefsEntry)) next.definitions.set(key, value);
310
+ return next;
311
+ }
312
+ function decodeJsonPointerSegment(segment) {
313
+ return segment.replaceAll("~1", "/").replaceAll("~0", "~");
314
+ }
315
+ function resolveJsonPointerPath(value, segments) {
316
+ let current = value;
317
+ for (const segment of segments) {
318
+ if (!current || typeof current !== "object") return;
319
+ const key = decodeJsonPointerSegment(segment);
320
+ if (Array.isArray(current)) {
321
+ const index = /^(?:0|[1-9]\d*)$/.test(key) ? Number(key) : -1;
322
+ if (index < 0 || index >= current.length) return;
323
+ current = current[index];
324
+ continue;
325
+ }
326
+ if (!isRecord(current) || !Object.hasOwn(current, key)) return;
327
+ current = current[key];
328
+ }
329
+ return current;
330
+ }
331
+ function resolveLocalJsonPointer(rootDocument, ref) {
332
+ if (!ref.startsWith("#/")) return;
333
+ return resolveJsonPointerPath(rootDocument, ref.slice(2).split("/"));
334
+ }
335
+ const SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
282
336
  "$defs",
283
337
  "definitions",
284
338
  "dependentSchemas",
285
339
  "patternProperties",
286
340
  "properties"
287
341
  ]);
342
+ const SCHEMA_OBJECT_KEYS = /* @__PURE__ */ new Set([
343
+ "additionalProperties",
344
+ "contains",
345
+ "else",
346
+ "if",
347
+ "items",
348
+ "not",
349
+ "propertyNames",
350
+ "then"
351
+ ]);
352
+ const SCHEMA_ARRAY_KEYS = /* @__PURE__ */ new Set([
353
+ "allOf",
354
+ "anyOf",
355
+ "items",
356
+ "oneOf",
357
+ "prefixItems"
358
+ ]);
359
+ const SCHEMA_LITERAL_KEYS = /* @__PURE__ */ new Set([
360
+ "const",
361
+ "default",
362
+ "enum",
363
+ "examples"
364
+ ]);
365
+ function tryResolveLocalRef(ref, defs, rootDocument) {
366
+ const match = ref.match(/^#\/(\$defs|definitions)\/([^/]+)(?:\/(.*))?$/);
367
+ if (match && defs) {
368
+ const namespace = match[1] === "$defs" ? defs.$defs : defs.definitions;
369
+ const name = decodeJsonPointerSegment(match[2] ?? "");
370
+ const resolved = name ? namespace.get(name) : void 0;
371
+ if (resolved !== void 0) return resolveJsonPointerPath(resolved, match[3] ? match[3].split("/") : []);
372
+ }
373
+ return resolveLocalJsonPointer(rootDocument, ref);
374
+ }
375
+ function inlineLocalSchemaRefsWithDefs(schema, defs, refStack, state, rootDocument) {
376
+ if (Array.isArray(schema)) return schema.map((entry) => inlineLocalSchemaRefsWithDefs(entry, defs, refStack, state, rootDocument));
377
+ if (!isRecord(schema)) return schema;
378
+ const obj = schema;
379
+ const nextDefs = extendSchemaDefs(defs, obj);
380
+ const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
381
+ if (refValue) {
382
+ if (refStack?.has(refValue)) return {};
383
+ const resolved = tryResolveLocalRef(refValue, nextDefs, rootDocument);
384
+ if (resolved === void 0) {
385
+ if (refValue.startsWith("#/")) state.unresolvedLocalRefs = true;
386
+ return { ...obj };
387
+ }
388
+ const nextRefStack = refStack ? new Set(refStack) : /* @__PURE__ */ new Set();
389
+ nextRefStack.add(refValue);
390
+ const inlined = inlineLocalSchemaRefsWithDefs(resolved, nextDefs, nextRefStack, state, rootDocument);
391
+ if (!isRecord(inlined)) return inlined;
392
+ const result = { ...inlined };
393
+ copySchemaMeta(obj, result);
394
+ if (obj.nullable === true) result.nullable = true;
395
+ return result;
396
+ }
397
+ const result = {};
398
+ for (const [key, value] of Object.entries(obj)) {
399
+ if (key === "$defs" || key === "definitions" || key === "components") continue;
400
+ let next = value;
401
+ if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
402
+ const entries = Object.entries(value);
403
+ for (const entry of entries) entry[1] = inlineLocalSchemaRefsWithDefs(entry[1], nextDefs, refStack, state, rootDocument);
404
+ next = Object.fromEntries(entries);
405
+ } else if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) next = inlineLocalSchemaRefsWithDefs(value, nextDefs, refStack, state, rootDocument);
406
+ else if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) next = value.map((entry) => inlineLocalSchemaRefsWithDefs(entry, nextDefs, refStack, state, rootDocument));
407
+ setOwnSchemaProperty(result, key, next);
408
+ }
409
+ if (state.unresolvedLocalRefs) {
410
+ if ("$defs" in obj) result.$defs = obj.$defs;
411
+ if ("definitions" in obj) result.definitions = obj.definitions;
412
+ if ("components" in obj) result.components = obj.components;
413
+ }
414
+ return result;
415
+ }
416
+ /** Inline local $ref pointers so providers receive self-contained tool schemas. */
417
+ function inlineLocalToolSchemaRefs(schema) {
418
+ if (!schema || typeof schema !== "object") return schema;
419
+ const schemaRecord = schema;
420
+ return inlineLocalSchemaRefsWithDefs(schema, Array.isArray(schema) ? extendSchemaDefs(void 0, schemaRecord) : void 0, void 0, { unresolvedLocalRefs: false }, schema);
421
+ }
422
+ /** Keep compact root definitions. Fall back for scopes or refs we must rewrite. */
423
+ function canPreserveRootSchemaRefs(schema) {
424
+ if (!isRecord(schema) || schema.type !== "object" || !isRecord(schema.properties) || ["$defs", "definitions"].some((key) => key in schema && !isRecord(schema[key])) || [
425
+ "anyOf",
426
+ "oneOf",
427
+ "allOf"
428
+ ].some((key) => Array.isArray(schema[key])) || "$ref" in schema) return false;
429
+ let hasRefs = false;
430
+ const ancestors = /* @__PURE__ */ new Set();
431
+ function visit(node, inDefinitions = false) {
432
+ if (!isRecord(node)) return true;
433
+ if (ancestors.has(node) || "$id" in node || "id" in node || "components" in node || node !== schema && ("$defs" in node || "definitions" in node)) return false;
434
+ if ("$ref" in node) {
435
+ if (typeof node.$ref !== "string" || !/^#\/(\$defs|definitions)\/[^/]+$/.test(node.$ref) || node.nullable === true || resolveLocalJsonPointer(schema, node.$ref) === void 0) return false;
436
+ hasRefs ||= !inDefinitions;
437
+ }
438
+ ancestors.add(node);
439
+ try {
440
+ for (const [key, value] of Object.entries(node)) if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
441
+ const childInDefinitions = inDefinitions || key === "$defs" || key === "definitions";
442
+ if (!Object.values(value).every((entry) => visit(entry, childInDefinitions))) return false;
443
+ } else if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) {
444
+ if (!value.every((entry) => visit(entry, inDefinitions))) return false;
445
+ } else if (SCHEMA_OBJECT_KEYS.has(key) && !visit(value, inDefinitions)) return false;
446
+ return true;
447
+ } finally {
448
+ ancestors.delete(node);
449
+ }
450
+ }
451
+ return visit(schema) && hasRefs;
452
+ }
453
+ //#endregion
454
+ //#region packages/ai/src/providers/clean-for-llamacpp-gbnf.ts
455
+ /** llama.cpp rejects grammar repetitions whose expanded rule count reaches 2000. */
456
+ const LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD = 2e3;
288
457
  const SCHEMA_CHILD_KEYS = /* @__PURE__ */ new Set([
289
458
  "additionalItems",
290
459
  "additionalProperties",
@@ -302,20 +471,21 @@ const SCHEMA_CHILD_KEYS = /* @__PURE__ */ new Set([
302
471
  "unevaluatedItems",
303
472
  "unevaluatedProperties"
304
473
  ]);
305
- function cleanSchemaNode(node) {
306
- if (Array.isArray(node)) {
474
+ /** Removes JSON Schema constraints that llama.cpp cannot compile into GBNF. */
475
+ function cleanSchemaForLlamacppGbnf(schema) {
476
+ if (Array.isArray(schema)) {
307
477
  let changed = false;
308
- const entries = node.map((entry) => {
309
- const next = cleanSchemaNode(entry);
478
+ const entries = schema.map((entry) => {
479
+ const next = cleanSchemaForLlamacppGbnf(entry);
310
480
  changed ||= next !== entry;
311
481
  return next;
312
482
  });
313
- return changed ? entries : node;
483
+ return changed ? entries : schema;
314
484
  }
315
- if (!isRecord(node)) return node;
485
+ if (!isRecord(schema)) return schema;
316
486
  let changed = false;
317
487
  const cleaned = {};
318
- for (const [key, value] of Object.entries(node)) {
488
+ for (const [key, value] of Object.entries(schema)) {
319
489
  if (key === "pattern") {
320
490
  changed = true;
321
491
  continue;
@@ -325,19 +495,19 @@ function cleanSchemaNode(node) {
325
495
  continue;
326
496
  }
327
497
  let next = value;
328
- if (SCHEMA_MAP_KEYS$2.has(key) && isRecord(value)) {
498
+ if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
329
499
  let mapChanged = false;
330
500
  next = Object.fromEntries(Object.entries(value).map(([childKey, childValue]) => {
331
- const cleanedChild = cleanSchemaNode(childValue);
501
+ const cleanedChild = cleanSchemaForLlamacppGbnf(childValue);
332
502
  mapChanged ||= cleanedChild !== childValue;
333
503
  return [childKey, cleanedChild];
334
504
  }));
335
505
  if (!mapChanged) next = value;
336
- } else if (SCHEMA_CHILD_KEYS.has(key)) next = cleanSchemaNode(value);
506
+ } else if (SCHEMA_CHILD_KEYS.has(key)) next = cleanSchemaForLlamacppGbnf(value);
337
507
  cleaned[key] = next;
338
508
  changed ||= next !== value;
339
509
  }
340
- return changed ? cleaned : node;
510
+ return changed ? cleaned : schema;
341
511
  }
342
512
  function collectSchemaViolations(node, path, violations) {
343
513
  if (Array.isArray(node)) {
@@ -347,13 +517,9 @@ function collectSchemaViolations(node, path, violations) {
347
517
  if (!isRecord(node)) return;
348
518
  if ("pattern" in node) violations.push(`${path}.pattern`);
349
519
  if (typeof node.maxLength === "number" && node.maxLength >= 2e3) violations.push(`${path}.maxLength`);
350
- for (const [key, value] of Object.entries(node)) if (SCHEMA_MAP_KEYS$2.has(key) && isRecord(value)) for (const [childKey, childValue] of Object.entries(value)) collectSchemaViolations(childValue, `${path}.${key}.${childKey}`, violations);
520
+ for (const [key, value] of Object.entries(node)) if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) for (const [childKey, childValue] of Object.entries(value)) collectSchemaViolations(childValue, `${path}.${key}.${childKey}`, violations);
351
521
  else if (SCHEMA_CHILD_KEYS.has(key)) collectSchemaViolations(value, `${path}.${key}`, violations);
352
522
  }
353
- /** Removes JSON Schema constraints that llama.cpp cannot compile into GBNF. */
354
- function cleanSchemaForLlamacppGbnf(schema) {
355
- return cleanSchemaNode(schema);
356
- }
357
523
  /** Reports schema paths that llama.cpp cannot compile into GBNF. */
358
524
  function findLlamacppGbnfSchemaViolations(schema, path) {
359
525
  const violations = [];
@@ -362,60 +528,38 @@ function findLlamacppGbnfSchemaViolations(schema, path) {
362
528
  }
363
529
  //#endregion
364
530
  //#region packages/ai/src/providers/schema-keyword-strip.ts
365
- const SCHEMA_MAP_KEYS$1 = /* @__PURE__ */ new Set([
366
- "$defs",
367
- "definitions",
368
- "dependentSchemas",
369
- "dependencies",
370
- "patternProperties",
371
- "properties"
372
- ]);
373
- /** Containers whose value is a single nested schema. */
374
- const SCHEMA_OBJECT_KEYS$1 = /* @__PURE__ */ new Set([
375
- "additionalItems",
376
- "additionalProperties",
377
- "contains",
378
- "contentSchema",
379
- "else",
380
- "if",
381
- "items",
382
- "not",
383
- "propertyNames",
384
- "then",
385
- "unevaluatedItems",
386
- "unevaluatedProperties"
387
- ]);
388
- /** Containers whose value is a list of nested schemas. */
389
- const SCHEMA_ARRAY_KEYS$1 = /* @__PURE__ */ new Set([
390
- "allOf",
391
- "anyOf",
392
- "items",
393
- "oneOf",
394
- "prefixItems"
395
- ]);
396
- /** Recursively remove schema keywords unsupported by a target provider/tool surface. */
397
- function stripUnsupportedSchemaKeywords(schema, unsupportedKeywords) {
531
+ function* stripSchemaArray(schemas, unsupportedKeywords, ancestors) {
532
+ const result = [];
533
+ result.length = schemas.length;
534
+ for (let index = 0; index < result.length; index += 1) if (index in schemas) result[index] = yield stripSchemaKeywords(schemas[index], unsupportedKeywords, ancestors);
535
+ return result;
536
+ }
537
+ function* stripSchemaKeywords(schema, unsupportedKeywords, ancestors) {
398
538
  if (!schema || typeof schema !== "object") return schema;
399
- if (Array.isArray(schema)) return schema.map((entry) => stripUnsupportedSchemaKeywords(entry, unsupportedKeywords));
400
- const obj = schema;
401
- const cleaned = {};
402
- for (const [key, value] of Object.entries(obj)) {
403
- if (unsupportedKeywords.has(key)) continue;
404
- if (SCHEMA_MAP_KEYS$1.has(key) && value && typeof value === "object" && !Array.isArray(value)) {
405
- cleaned[key] = Object.fromEntries(Object.entries(value).map(([childKey, childValue]) => [childKey, stripUnsupportedSchemaKeywords(childValue, unsupportedKeywords)]));
406
- continue;
407
- }
408
- if (SCHEMA_ARRAY_KEYS$1.has(key) && Array.isArray(value)) {
409
- cleaned[key] = value.map((entry) => stripUnsupportedSchemaKeywords(entry, unsupportedKeywords));
410
- continue;
411
- }
412
- if (SCHEMA_OBJECT_KEYS$1.has(key) && value && typeof value === "object") {
413
- cleaned[key] = stripUnsupportedSchemaKeywords(value, unsupportedKeywords);
414
- continue;
539
+ if (ancestors.has(schema)) throw new TypeError("Tool schema contains a circular reference.");
540
+ ancestors.add(schema);
541
+ try {
542
+ if (Array.isArray(schema)) return yield stripSchemaArray(schema, unsupportedKeywords, ancestors);
543
+ const obj = schema;
544
+ const cleaned = {};
545
+ for (const [key, value] of Object.entries(obj)) {
546
+ if (unsupportedKeywords.has(key)) continue;
547
+ if (SCHEMA_MAP_KEYS$1.has(key) && value && typeof value === "object" && !Array.isArray(value)) {
548
+ const entries = Object.entries(value);
549
+ for (const entry of entries) entry[1] = yield stripSchemaKeywords(entry[1], unsupportedKeywords, ancestors);
550
+ cleaned[key] = Object.fromEntries(entries);
551
+ } else if (SCHEMA_ARRAY_KEYS$1.has(key) && Array.isArray(value)) cleaned[key] = yield stripSchemaArray(value, unsupportedKeywords, ancestors);
552
+ else if (SCHEMA_OBJECT_KEYS$1.has(key) && value && typeof value === "object") cleaned[key] = yield stripSchemaKeywords(value, unsupportedKeywords, ancestors);
553
+ else cleaned[key] = value;
415
554
  }
416
- cleaned[key] = value;
555
+ return cleaned;
556
+ } finally {
557
+ ancestors.delete(schema);
417
558
  }
418
- return cleaned;
559
+ }
560
+ /** Remove schema keywords unsupported by a target provider/tool surface. */
561
+ function stripUnsupportedSchemaKeywords(schema, unsupportedKeywords) {
562
+ return evaluateSchemaWalk(stripSchemaKeywords(schema, unsupportedKeywords, /* @__PURE__ */ new Set()));
419
563
  }
420
564
  //#endregion
421
565
  //#region packages/ai/src/providers/tool-schema-normalization-cache.ts
@@ -549,37 +693,6 @@ function mergePropertySchemas(existing, incoming) {
549
693
  }
550
694
  return existing;
551
695
  }
552
- function setOwnSchemaProperty(target, key, value) {
553
- Object.defineProperty(target, key, {
554
- value,
555
- enumerable: true,
556
- configurable: true,
557
- writable: true
558
- });
559
- }
560
- function hasTopLevelArrayKeyword(schemaRecord, key) {
561
- return Array.isArray(schemaRecord[key]);
562
- }
563
- function getFlattenableVariantKey(schemaRecord) {
564
- if (hasTopLevelArrayKeyword(schemaRecord, "anyOf")) return "anyOf";
565
- if (hasTopLevelArrayKeyword(schemaRecord, "oneOf")) return "oneOf";
566
- return null;
567
- }
568
- function getTopLevelConditionalKey(schemaRecord) {
569
- return getFlattenableVariantKey(schemaRecord) ?? (hasTopLevelArrayKeyword(schemaRecord, "allOf") ? "allOf" : null);
570
- }
571
- function hasTopLevelObjectSchema(schemaRecord, conditionalKey) {
572
- return schemaRecord.type === "object" && isRecord(schemaRecord.properties) && conditionalKey === null;
573
- }
574
- function isObjectLikeSchemaMissingType(schemaRecord, conditionalKey) {
575
- return !("type" in schemaRecord) && (isRecord(schemaRecord.properties) || Array.isArray(schemaRecord.required)) && conditionalKey === null;
576
- }
577
- function isTypedObjectSchemaMissingValidProperties(schemaRecord, conditionalKey) {
578
- return schemaRecord.type === "object" && !isRecord(schemaRecord.properties) && conditionalKey === null;
579
- }
580
- function isTrulyEmptySchema(schemaRecord) {
581
- return Object.keys(schemaRecord).length === 0;
582
- }
583
696
  function normalizeArraySchemaItems(schema, mode) {
584
697
  if (Array.isArray(schema)) {
585
698
  if (mode === "add") return schema;
@@ -601,7 +714,7 @@ function normalizeArraySchemaItems(schema, mode) {
601
714
  return entries.some((entry, index) => entry !== value[index]) ? entries : value;
602
715
  };
603
716
  for (const [key, value] of Object.entries(normalized)) {
604
- if (mode !== "add" && key === "items" && allowsArray && isRecord(value) && isTrulyEmptySchema(value)) {
717
+ if (mode !== "add" && key === "items" && allowsArray && isRecord(value) && Object.keys(value).length === 0) {
605
718
  delete normalized.items;
606
719
  changed = true;
607
720
  continue;
@@ -622,150 +735,6 @@ function normalizeArraySchemaItems(schema, mode) {
622
735
  }
623
736
  return changed ? normalized : schema;
624
737
  }
625
- function copySchemaMeta(from, to) {
626
- for (const key of [
627
- "title",
628
- "description",
629
- "default"
630
- ]) if (key in from && from[key] !== void 0) to[key] = from[key];
631
- }
632
- function extendSchemaDefs(defs, schema) {
633
- const defsEntry = schema.$defs && typeof schema.$defs === "object" && !Array.isArray(schema.$defs) ? schema.$defs : void 0;
634
- const legacyDefsEntry = schema.definitions && typeof schema.definitions === "object" && !Array.isArray(schema.definitions) ? schema.definitions : void 0;
635
- if (!defsEntry && !legacyDefsEntry) return defs;
636
- const next = defs ? {
637
- $defs: new Map(defs.$defs),
638
- definitions: new Map(defs.definitions)
639
- } : {
640
- $defs: /* @__PURE__ */ new Map(),
641
- definitions: /* @__PURE__ */ new Map()
642
- };
643
- if (defsEntry) for (const [key, value] of Object.entries(defsEntry)) next.$defs.set(key, value);
644
- if (legacyDefsEntry) for (const [key, value] of Object.entries(legacyDefsEntry)) next.definitions.set(key, value);
645
- return next;
646
- }
647
- function decodeJsonPointerSegment(segment) {
648
- return segment.replaceAll("~1", "/").replaceAll("~0", "~");
649
- }
650
- function resolveJsonPointerPath(value, segments) {
651
- let current = value;
652
- for (const segment of segments) {
653
- if (!current || typeof current !== "object") return;
654
- const key = decodeJsonPointerSegment(segment);
655
- if (Array.isArray(current)) {
656
- const index = /^(?:0|[1-9]\d*)$/.test(key) ? Number(key) : -1;
657
- if (index < 0 || index >= current.length) return;
658
- current = current[index];
659
- continue;
660
- }
661
- const record = current;
662
- if (!Object.hasOwn(record, key)) return;
663
- current = record[key];
664
- }
665
- return current;
666
- }
667
- function resolveLocalJsonPointer(rootDocument, ref) {
668
- if (!ref.startsWith("#/")) return;
669
- return resolveJsonPointerPath(rootDocument, ref.slice(2).split("/"));
670
- }
671
- const SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
672
- "$defs",
673
- "definitions",
674
- "dependentSchemas",
675
- "patternProperties",
676
- "properties"
677
- ]);
678
- const SCHEMA_OBJECT_KEYS = /* @__PURE__ */ new Set([
679
- "additionalProperties",
680
- "contains",
681
- "else",
682
- "if",
683
- "items",
684
- "not",
685
- "propertyNames",
686
- "then"
687
- ]);
688
- const SCHEMA_ARRAY_KEYS = /* @__PURE__ */ new Set([
689
- "allOf",
690
- "anyOf",
691
- "items",
692
- "oneOf",
693
- "prefixItems"
694
- ]);
695
- const SCHEMA_LITERAL_KEYS = /* @__PURE__ */ new Set([
696
- "const",
697
- "default",
698
- "enum",
699
- "examples"
700
- ]);
701
- function tryResolveLocalRef(ref, defs, rootDocument) {
702
- const match = ref.match(/^#\/(\$defs|definitions)\/([^/]+)(?:\/(.*))?$/);
703
- if (match && defs) {
704
- const namespace = match[1] === "$defs" ? defs.$defs : defs.definitions;
705
- const name = decodeJsonPointerSegment(match[2] ?? "");
706
- const resolved = name ? namespace.get(name) : void 0;
707
- if (resolved !== void 0) return resolveJsonPointerPath(resolved, match[3] ? match[3].split("/") : []);
708
- }
709
- return resolveLocalJsonPointer(rootDocument, ref);
710
- }
711
- function inlineLocalSchemaRefsWithDefs(schema, defs, refStack, state, rootDocument) {
712
- if (!schema || typeof schema !== "object") return schema;
713
- if (Array.isArray(schema)) return schema.map((entry) => inlineLocalSchemaRefsWithDefs(entry, defs, refStack, state, rootDocument));
714
- const obj = schema;
715
- const nextDefs = extendSchemaDefs(defs, obj);
716
- const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
717
- if (refValue) {
718
- if (refStack?.has(refValue)) return {};
719
- const resolved = tryResolveLocalRef(refValue, nextDefs, rootDocument);
720
- if (resolved === void 0) {
721
- if (refValue.startsWith("#/")) state.unresolvedLocalRefs = true;
722
- return { ...obj };
723
- }
724
- const nextRefStack = refStack ? new Set(refStack) : /* @__PURE__ */ new Set();
725
- nextRefStack.add(refValue);
726
- const inlined = inlineLocalSchemaRefsWithDefs(resolved, nextDefs, nextRefStack, state, rootDocument);
727
- if (!inlined || typeof inlined !== "object" || Array.isArray(inlined)) return inlined;
728
- const result = { ...inlined };
729
- copySchemaMeta(obj, result);
730
- if (obj.nullable === true) result.nullable = true;
731
- return result;
732
- }
733
- const result = {};
734
- for (const [key, value] of Object.entries(obj)) {
735
- if (key === "$defs" || key === "definitions" || key === "components") continue;
736
- if (SCHEMA_LITERAL_KEYS.has(key)) {
737
- setOwnSchemaProperty(result, key, value);
738
- continue;
739
- }
740
- if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
741
- const entries = Object.entries(value);
742
- for (const entry of entries) entry[1] = inlineLocalSchemaRefsWithDefs(entry[1], nextDefs, refStack, state, rootDocument);
743
- setOwnSchemaProperty(result, key, Object.fromEntries(entries));
744
- continue;
745
- }
746
- if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) {
747
- setOwnSchemaProperty(result, key, inlineLocalSchemaRefsWithDefs(value, nextDefs, refStack, state, rootDocument));
748
- continue;
749
- }
750
- if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) {
751
- setOwnSchemaProperty(result, key, value.map((entry) => inlineLocalSchemaRefsWithDefs(entry, nextDefs, refStack, state, rootDocument)));
752
- continue;
753
- }
754
- setOwnSchemaProperty(result, key, value);
755
- }
756
- if (state.unresolvedLocalRefs) {
757
- if ("$defs" in obj) result.$defs = obj.$defs;
758
- if ("definitions" in obj) result.definitions = obj.definitions;
759
- if ("components" in obj) result.components = obj.components;
760
- }
761
- return result;
762
- }
763
- /** Inline local $ref pointers so providers receive self-contained tool schemas. */
764
- function inlineLocalToolSchemaRefs(schema) {
765
- if (!schema || typeof schema !== "object") return schema;
766
- const schemaRecord = schema;
767
- return inlineLocalSchemaRefsWithDefs(schema, Array.isArray(schema) ? extendSchemaDefs(void 0, schemaRecord) : void 0, void 0, { unresolvedLocalRefs: false }, schema);
768
- }
769
738
  const OPENAPI_SCHEMA_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
770
739
  "discriminator",
771
740
  "externalDocs",
@@ -860,9 +829,6 @@ function normalizeOpenApiSchemaKeywords(schema) {
860
829
  return changed || nullable ? normalized ?? schema : schema;
861
830
  }
862
831
  function normalizeToolParameterSchemaUncached(schema, options) {
863
- const inlinedSchema = normalizeOpenApiSchemaKeywords(inlineLocalToolSchemaRefs(schema));
864
- const schemaRecord = inlinedSchema && typeof inlinedSchema === "object" ? inlinedSchema : void 0;
865
- if (!schemaRecord) return inlinedSchema;
866
832
  const normalizedProvider = normalizeLowercaseStringOrEmpty(options?.modelProvider);
867
833
  const normalizedModelId = normalizeLowercaseStringOrEmpty(options?.modelId);
868
834
  const normalizedToolSchemaProfile = normalizeLowercaseStringOrEmpty(options?.modelCompat?.toolSchemaProfile);
@@ -871,36 +837,37 @@ function normalizeToolParameterSchemaUncached(schema, options) {
871
837
  const unsupportedToolSchemaKeywords = resolveUnsupportedToolSchemaKeywords(options?.modelCompat);
872
838
  const omitEmptyArrayItems = shouldOmitEmptyArrayItems(options?.modelCompat);
873
839
  const isLlamacppGbnfProfile = normalizedToolSchemaProfile === "llamacpp";
840
+ const inlinedSchema = normalizeOpenApiSchemaKeywords(normalizedProvider === "openai" && !isGeminiProvider && !isLlamacppGbnfProfile && ![
841
+ "$ref",
842
+ "$defs",
843
+ "definitions"
844
+ ].some((key) => unsupportedToolSchemaKeywords.has(key)) && canPreserveRootSchemaRefs(schema) ? schema : inlineLocalToolSchemaRefs(schema));
845
+ const schemaRecord = inlinedSchema && typeof inlinedSchema === "object" ? inlinedSchema : void 0;
846
+ if (!schemaRecord) return inlinedSchema;
874
847
  function applyProviderCleaning(s) {
875
848
  let arrayItemsCompatibleSchema = normalizeArraySchemaItems(s, omitEmptyArrayItems ? "normalize" : "add");
876
849
  if (isLlamacppGbnfProfile) arrayItemsCompatibleSchema = cleanSchemaForLlamacppGbnf(arrayItemsCompatibleSchema);
877
- if (isGeminiProvider && !isAnthropicProvider) {
878
- const geminiCompatibleSchema = cleanSchemaForGemini(arrayItemsCompatibleSchema);
879
- return unsupportedToolSchemaKeywords.size > 0 ? stripUnsupportedSchemaKeywords(geminiCompatibleSchema, unsupportedToolSchemaKeywords) : geminiCompatibleSchema;
880
- }
881
- if (unsupportedToolSchemaKeywords.size > 0) return stripUnsupportedSchemaKeywords(arrayItemsCompatibleSchema, unsupportedToolSchemaKeywords);
850
+ if (isGeminiProvider && !isAnthropicProvider) arrayItemsCompatibleSchema = cleanSchemaForGemini(arrayItemsCompatibleSchema);
851
+ if (unsupportedToolSchemaKeywords.size > 0) arrayItemsCompatibleSchema = stripUnsupportedSchemaKeywords(arrayItemsCompatibleSchema, unsupportedToolSchemaKeywords);
882
852
  return arrayItemsCompatibleSchema;
883
853
  }
884
- const conditionalKey = getTopLevelConditionalKey(schemaRecord);
885
- const flattenableVariantKey = getFlattenableVariantKey(schemaRecord);
886
- if (hasTopLevelObjectSchema(schemaRecord, conditionalKey)) return applyProviderCleaning(schemaRecord);
887
- if (isObjectLikeSchemaMissingType(schemaRecord, conditionalKey)) return applyProviderCleaning({
888
- ...schemaRecord,
889
- type: "object",
890
- properties: isRecord(schemaRecord.properties) ? schemaRecord.properties : {}
891
- });
892
- if (isTypedObjectSchemaMissingValidProperties(schemaRecord, conditionalKey)) return applyProviderCleaning({
893
- ...schemaRecord,
894
- properties: {}
895
- });
896
- if (!flattenableVariantKey) {
897
- if (isTrulyEmptySchema(schemaRecord)) return applyProviderCleaning({
898
- type: "object",
854
+ const flattenableVariantKey = Array.isArray(schemaRecord.anyOf) ? "anyOf" : Array.isArray(schemaRecord.oneOf) ? "oneOf" : void 0;
855
+ if (!flattenableVariantKey && !Array.isArray(schemaRecord.allOf)) {
856
+ const hasProperties = isRecord(schemaRecord.properties);
857
+ if (schemaRecord.type === "object") return applyProviderCleaning(hasProperties ? schemaRecord : {
858
+ ...schemaRecord,
899
859
  properties: {}
900
860
  });
901
- if (conditionalKey === "allOf") return applyProviderCleaning(inlinedSchema);
902
- return applyProviderCleaning(inlinedSchema);
861
+ if (!("type" in schemaRecord) && (hasProperties || Array.isArray(schemaRecord.required))) return applyProviderCleaning({
862
+ ...schemaRecord,
863
+ type: "object",
864
+ properties: hasProperties ? schemaRecord.properties : {}
865
+ });
903
866
  }
867
+ if (!flattenableVariantKey) return applyProviderCleaning(Object.keys(schemaRecord).length === 0 ? {
868
+ type: "object",
869
+ properties: {}
870
+ } : inlinedSchema);
904
871
  const variants = schemaRecord[flattenableVariantKey];
905
872
  const mergedProperties = isRecord(schemaRecord.properties) ? { ...schemaRecord.properties } : {};
906
873
  const requiredCounts = /* @__PURE__ */ new Map();
@@ -919,11 +886,10 @@ function normalizeToolParameterSchemaUncached(schema, options) {
919
886
  }
920
887
  const baseRequired = Array.isArray(schemaRecord.required) ? schemaRecord.required.filter((key) => typeof key === "string") : void 0;
921
888
  const mergedRequired = baseRequired && baseRequired.length > 0 ? baseRequired : objectVariants > 0 ? Array.from(requiredCounts.entries()).filter(([, count]) => count === objectVariants).map(([key]) => key) : void 0;
922
- const nextSchema = { ...schemaRecord };
923
889
  return applyProviderCleaning({
924
890
  type: "object",
925
- ...typeof nextSchema.title === "string" ? { title: nextSchema.title } : {},
926
- ...typeof nextSchema.description === "string" ? { description: nextSchema.description } : {},
891
+ ...typeof schemaRecord.title === "string" ? { title: schemaRecord.title } : {},
892
+ ...typeof schemaRecord.description === "string" ? { description: schemaRecord.description } : {},
927
893
  properties: Object.keys(mergedProperties).length > 0 ? mergedProperties : schemaRecord.properties ?? {},
928
894
  ...mergedRequired && mergedRequired.length > 0 ? { required: mergedRequired } : {},
929
895
  additionalProperties: "additionalProperties" in schemaRecord ? schemaRecord.additionalProperties : true
@@ -939,14 +905,6 @@ function normalizeToolParameterSchema(schema, options) {
939
905
  }
940
906
  //#endregion
941
907
  //#region packages/ai/src/providers/openai-tool-schema-compat.ts
942
- const OPENAI_STRICT_COMPAT_SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
943
- "$defs",
944
- "definitions",
945
- "dependentSchemas",
946
- "dependencies",
947
- "patternProperties",
948
- "properties"
949
- ]);
950
908
  const OPENAI_NULLABLE_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
951
909
  "default",
952
910
  "description",
@@ -954,39 +912,22 @@ const OPENAI_NULLABLE_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
954
912
  "format",
955
913
  "title"
956
914
  ]);
957
- const OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS = /* @__PURE__ */ new Set([
958
- "additionalItems",
959
- "additionalProperties",
960
- "allOf",
961
- "anyOf",
962
- "contains",
963
- "contentSchema",
964
- "else",
965
- "if",
966
- "items",
967
- "not",
968
- "oneOf",
969
- "prefixItems",
970
- "propertyNames",
971
- "then",
972
- "unevaluatedItems",
973
- "unevaluatedProperties"
974
- ]);
915
+ const OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS = new Set([...SCHEMA_OBJECT_KEYS$1, ...SCHEMA_ARRAY_KEYS$1].toSorted());
975
916
  function normalizeOpenAIStrictCompatSchemaMap(schema) {
976
- if (!schema || typeof schema !== "object" || Array.isArray(schema)) return schema;
917
+ if (!isRecord(schema)) return schema;
977
918
  let changed = false;
978
919
  const normalized = Object.fromEntries(Object.entries(schema).map(([key, value]) => {
979
- const next = normalizeOpenAIStrictCompatSchemaRecursive(value, { promoteEmptyObject: false });
920
+ const next = normalizeOpenAIStrictCompatSchemaRecursive(value);
980
921
  changed ||= next !== value;
981
922
  return [key, next];
982
923
  }));
983
924
  return changed ? normalized : schema;
984
925
  }
985
- function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
926
+ function normalizeOpenAIStrictCompatSchemaRecursive(schema, promoteEmptyObject = false) {
986
927
  if (Array.isArray(schema)) {
987
928
  let changed = false;
988
929
  const normalized = schema.map((entry) => {
989
- const next = normalizeOpenAIStrictCompatSchemaRecursive(entry, { promoteEmptyObject: false });
930
+ const next = normalizeOpenAIStrictCompatSchemaRecursive(entry);
990
931
  changed ||= next !== entry;
991
932
  return next;
992
933
  });
@@ -1002,13 +943,13 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1002
943
  changed = true;
1003
944
  return [];
1004
945
  }
1005
- const next = OPENAI_STRICT_COMPAT_SCHEMA_MAP_KEYS.has(key) ? normalizeOpenAIStrictCompatSchemaMap(value) : OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS.has(key) ? normalizeOpenAIStrictCompatSchemaRecursive(value, { promoteEmptyObject: false }) : value;
946
+ const next = SCHEMA_MAP_KEYS$1.has(key) ? normalizeOpenAIStrictCompatSchemaMap(value) : OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS.has(key) ? normalizeOpenAIStrictCompatSchemaRecursive(value) : value;
1006
947
  changed ||= next !== value;
1007
948
  return [[key, next]];
1008
949
  });
1009
950
  const normalized = Object.fromEntries(entries);
1010
951
  if (Object.keys(normalized).length === 0) {
1011
- if (!options.promoteEmptyObject) return schema;
952
+ if (!promoteEmptyObject) return schema;
1012
953
  return {
1013
954
  type: "object",
1014
955
  properties: {},
@@ -1026,7 +967,7 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1026
967
  normalized.properties = {};
1027
968
  changed = true;
1028
969
  }
1029
- const hasEmptyProperties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) && Object.keys(normalized.properties).length === 0;
970
+ const hasEmptyProperties = isRecord(normalized.properties) && Object.keys(normalized.properties).length === 0;
1030
971
  if (normalized.type === "object" && !Array.isArray(normalized.required) && hasEmptyProperties) {
1031
972
  normalized.required = [];
1032
973
  changed = true;
@@ -1039,7 +980,7 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1039
980
  }
1040
981
  /** Repairs recoverable OpenAI tool-schema shapes before canonical normalization. */
1041
982
  function normalizeOpenAIStrictCompatSchema(schema) {
1042
- return normalizeOpenAIStrictCompatSchemaRecursive(schema, { promoteEmptyObject: true });
983
+ return normalizeOpenAIStrictCompatSchemaRecursive(schema, true);
1043
984
  }
1044
985
  /** Finds schema paths that violate OpenAI strict tool-schema requirements. */
1045
986
  function findOpenAIStrictSchemaViolations(schema, path, options) {
@@ -1056,7 +997,7 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1056
997
  "allOf"
1057
998
  ]) if (key in record) violations.push(`${path}.${key}`);
1058
999
  if (Array.isArray(record.type)) violations.push(`${path}.type`);
1059
- const properties = record.properties && typeof record.properties === "object" && !Array.isArray(record.properties) ? record.properties : void 0;
1000
+ const properties = isRecord(record.properties) ? record.properties : void 0;
1060
1001
  if (record.type === "object") {
1061
1002
  if (record.additionalProperties !== false) violations.push(`${path}.additionalProperties`);
1062
1003
  const required = Array.isArray(record.required) ? record.required.filter((entry) => typeof entry === "string") : void 0;
@@ -1066,9 +1007,9 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1066
1007
  for (const key of Object.keys(properties)) if (!requiredSet.has(key)) violations.push(`${path}.required.${key}`);
1067
1008
  }
1068
1009
  }
1069
- for (const key of OPENAI_STRICT_COMPAT_SCHEMA_MAP_KEYS) {
1010
+ for (const key of SCHEMA_MAP_KEYS$1) {
1070
1011
  const schemaMap = record[key];
1071
- if (!schemaMap || typeof schemaMap !== "object" || Array.isArray(schemaMap)) continue;
1012
+ if (!isRecord(schemaMap)) continue;
1072
1013
  for (const [entryKey, value] of Object.entries(schemaMap)) violations.push(...findOpenAIStrictSchemaViolations(value, `${path}.${key}.${entryKey}`));
1073
1014
  }
1074
1015
  for (const key of OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS) {
@@ -1079,11 +1020,6 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1079
1020
  }
1080
1021
  //#endregion
1081
1022
  //#region packages/ai/src/providers/openai-tool-schema.ts
1082
- /**
1083
- * OpenAI strict JSON-schema normalization for tool inventories and request payloads.
1084
- *
1085
- * Caches normalized object inputs by provider compatibility so repeated inventory builds preserve identity.
1086
- */
1087
1023
  const strictOpenAISchemaCache = createToolSchemaNormalizationCache(8);
1088
1024
  function resolveToolSchemaModelCompat(compat) {
1089
1025
  if (!compat) return;
@@ -1126,7 +1062,7 @@ function normalizeStrictOpenAIJsonSchemaRecursive(schema, depth) {
1126
1062
  return [key, next];
1127
1063
  }));
1128
1064
  if (normalized.type === "object") {
1129
- const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : void 0;
1065
+ const properties = isRecord(normalized.properties) ? normalized.properties : void 0;
1130
1066
  if (properties && Object.keys(properties).length === 0 && !Array.isArray(normalized.required)) {
1131
1067
  normalized.required = [];
1132
1068
  changed = true;
@@ -1171,14 +1107,14 @@ function isStrictOpenAIJsonSchemaCompatibleRecursive(schema) {
1171
1107
  if (Array.isArray(record.type)) return false;
1172
1108
  if (record.type === "object" && record.additionalProperties !== false) return false;
1173
1109
  if (record.type === "object") {
1174
- const properties = record.properties && typeof record.properties === "object" && !Array.isArray(record.properties) ? record.properties : {};
1110
+ const properties = isRecord(record.properties) ? record.properties : {};
1175
1111
  const required = Array.isArray(record.required) ? record.required.filter((entry) => typeof entry === "string") : void 0;
1176
1112
  if (!required) return false;
1177
1113
  const requiredSet = new Set(required);
1178
1114
  if (Object.keys(properties).some((key) => !requiredSet.has(key))) return false;
1179
1115
  }
1180
1116
  return Object.entries(record).every(([key, entry]) => {
1181
- if (key === "properties" && entry && typeof entry === "object" && !Array.isArray(entry)) return Object.values(entry).every((value) => isStrictOpenAIJsonSchemaCompatibleRecursive(value));
1117
+ if (key === "properties" && isRecord(entry)) return Object.values(entry).every(isStrictOpenAIJsonSchemaCompatibleRecursive);
1182
1118
  return isStrictOpenAIJsonSchemaCompatibleRecursive(entry);
1183
1119
  });
1184
1120
  }