@openclaw/ai 2026.9.6 → 2026.9.8

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 (99) hide show
  1. package/dist/{anthropic-DZQ_7gD1.mjs → anthropic-CTXJlfnS.mjs} +37 -66
  2. package/dist/{anthropic-payload-policy-DyfwikYJ.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +7 -5
  3. package/dist/{anthropic-stream-reducer-D6ZI1wwj.mjs → anthropic-stream-reducer-DrsBCsFY.mjs} +192 -261
  4. package/dist/{api-registry-C2T3lTV7.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-DS86GYzq.mjs → azure-openai-responses-BBxv4QVI.mjs} +22 -33
  6. package/dist/{base64-CPmadnUf.mjs → base64-C1PsYcRQ.mjs} +15 -9
  7. package/dist/{diagnostics-CH8j2wIG.mjs → diagnostics-CJaB6g8J.mjs} +3 -3
  8. package/dist/diagnostics.d.mts +4 -4
  9. package/dist/diagnostics.mjs +2 -2
  10. package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
  11. package/dist/event-stream-CMQfX_yr.d.mts +1 -0
  12. package/dist/{event-stream-CjnIZZst.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
  13. package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
  14. package/dist/event-stream.d.mts +2 -2
  15. package/dist/event-stream.mjs +1 -1
  16. package/dist/{google-BZJFjhuC.mjs → google-B3HEK0Ag.mjs} +8 -11
  17. package/dist/google-interactions-vMlEfPAA.mjs +574 -0
  18. package/dist/{google-messages-DB7GKkDk.mjs → google-messages-Dz2dAnGo.mjs} +35 -71
  19. package/dist/{google-shared-Bok4I6zB.mjs → google-shared-B58i3c8H.mjs} +43 -47
  20. package/dist/{google-vertex-3eVNR2qW.mjs → google-vertex-DYFXzEbh.mjs} +16 -30
  21. package/dist/{host-yTvBrYM2.mjs → host-DwBmNMCC.mjs} +29 -188
  22. package/dist/{host-policy-DZO3oPPk.mjs → host-policy-wK-ay_RK.mjs} +2 -14
  23. package/dist/{host-DH-Z-LDb.d.mts → host-rxlNaBwm.d.mts} +9 -3
  24. package/dist/{index-C25RT6bP.d.mts → index-D6KsSE74.d.mts} +28 -8
  25. package/dist/index.d.mts +7 -7
  26. package/dist/index.mjs +6 -6
  27. package/dist/internal/anthropic.d.mts +8 -7
  28. package/dist/internal/anthropic.mjs +5 -5
  29. package/dist/internal/openai-completions-compat.d.mts +1 -1
  30. package/dist/internal/openai-completions-compat.mjs +1 -1
  31. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  32. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  33. package/dist/internal/openai.d.mts +31 -8
  34. package/dist/internal/openai.mjs +13 -13
  35. package/dist/internal/runtime.d.mts +31 -70
  36. package/dist/internal/runtime.mjs +10 -65
  37. package/dist/internal/shared.d.mts +14 -12
  38. package/dist/internal/shared.mjs +5 -4
  39. package/dist/internal/tool-schema.d.mts +1 -1
  40. package/dist/internal/tool-schema.mjs +2 -2
  41. package/dist/{mistral-C_13dVBn.mjs → mistral-7wDWcjfF.mjs} +46 -93
  42. package/dist/{openai-chatgpt-responses-sTxPl4zM.mjs → openai-chatgpt-responses-Bc7NZrQR.mjs} +26 -30
  43. package/dist/{openai-completions-BO6D_hrB.mjs → openai-completions-CHnwIV-W.mjs} +14 -12
  44. package/dist/{openai-completions-compat-CUollwl6.mjs → openai-completions-compat-BJf57ZxN.mjs} +3 -5
  45. package/dist/{openai-completions-compat-DfJG1wSO.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
  46. package/dist/{openai-completions-stream-BpuJ0ZOA.mjs → openai-completions-stream-dju_5F3P.mjs} +101 -173
  47. package/dist/{openai-prompt-cache-CjV_2IRI.mjs → openai-prompt-cache-BTMs80_O.mjs} +1 -1
  48. package/dist/{openai-prompt-cache-C4RHdN4n.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
  49. package/dist/{openai-provider-client-BP8J1aeg.mjs → openai-provider-client-G8Otsq2Q.mjs} +2 -2
  50. package/dist/{openai-reasoning-effort-ash8dPrd.mjs → openai-reasoning-effort-C_0p3psG.mjs} +5 -4
  51. package/dist/{openai-responses-BJ_IEoMU.mjs → openai-responses-DbPe3-Py.mjs} +12 -11
  52. package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
  53. package/dist/{openai-responses-compaction-window-BiNCT0bS.mjs → openai-responses-compaction-window-CYGCjAQz.mjs} +5 -5
  54. package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
  55. package/dist/{openai-responses-contracts-B1ENJFpI.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
  56. package/dist/{openai-responses-prompt-observer-internal-DPHWgbBH.mjs → openai-responses-prompt-observer-internal-BX3QTNSv.mjs} +12 -12
  57. package/dist/{openai-responses-request-lifecycle-DFuyO1pQ.mjs → openai-responses-request-lifecycle-Fsag-IGZ.mjs} +1 -1
  58. package/dist/{openai-responses-shared-DvSqtJ6_.mjs → openai-responses-shared-CIEHiKx7.mjs} +312 -122
  59. package/dist/{openai-responses-terminal-usage-BNFbvY9f.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
  60. package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
  61. package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
  62. package/dist/{openai-tool-schema-D4BMcj2D.mjs → openai-tool-schema-vsl-cE-n.mjs} +243 -383
  63. package/dist/{openai-transport-params-DZKOTSfH.mjs → openai-transport-params-DyFJ4cgR.mjs} +60 -105
  64. package/dist/{positive-integer-BiUxrd71.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
  65. package/dist/{provider-error-CRhW7lkJ.mjs → provider-error-CwT_j2v0.mjs} +43 -4
  66. package/dist/{provider-options-DZYq53lj.d.mts → provider-options-Df7ov0K1.d.mts} +2 -2
  67. package/dist/{provider-replay-context-DPr3w20a.mjs → provider-replay-context-Bs5aWE1d.mjs} +1 -1
  68. package/dist/{provider-transcript-transform-BTocjCRs.mjs → provider-transcript-transform-DjA5Fk2P.mjs} +17 -2
  69. package/dist/{provider-transport-turn-state-lrXEFkYr.mjs → provider-transport-turn-state-Dw7OtYUs.mjs} +1 -1
  70. package/dist/{provider-types-w1rEqrGP.d.mts → provider-types-d4XnoZMd.d.mts} +3 -3
  71. package/dist/provider-types.d.mts +6 -6
  72. package/dist/providers.d.mts +2 -2
  73. package/dist/providers.mjs +15 -11
  74. package/dist/{reasoning-tag-text-partitioner-Di38crhI.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +47 -71
  75. package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
  76. package/dist/simple-options-BkDPMuxw.mjs +349 -0
  77. package/dist/{src-DwGYYyZp.mjs → src-H4aXcFuX.mjs} +43 -25
  78. package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
  79. package/dist/{stream-first-event-timeout-BeptfRL6.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
  80. package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
  81. package/dist/{transport-stream-shared-B5RioB_Q.mjs → transport-stream-shared-BU5pwY6W.mjs} +62 -28
  82. package/dist/{transport-stream-shared-B7Z9oCYg.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +12 -6
  83. package/dist/{transport-utils-03Qi0CN2.mjs → transport-utils-CqXzku3R.mjs} +3 -4
  84. package/dist/transports.d.mts +36 -32
  85. package/dist/transports.mjs +160 -216
  86. package/dist/types-CB-_vNyI.d.mts +1 -0
  87. package/dist/{types-qZFbaDbK.d.mts → types-CLLR3eB4.d.mts} +3 -1
  88. package/dist/types.d.mts +6 -6
  89. package/dist/types.mjs +4 -4
  90. package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
  91. package/dist/{validation-DhQhmt6t.d.mts → validation-Cat2wQsc.d.mts} +1 -1
  92. package/dist/validation.d.mts +1 -1
  93. package/dist/validation.mjs +1 -1
  94. package/package.json +5 -5
  95. package/dist/assistant-output-DM1JBNs1.mjs +0 -16
  96. package/dist/event-stream-C0nsgbj2.d.mts +0 -1
  97. package/dist/simple-options-np1XPuhm.mjs +0 -175
  98. package/dist/types-DTvddOfm.d.mts +0 -1
  99. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,32 +1,7 @@
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
- //#region packages/ai/src/providers/schema-walk.ts
5
- /** Resume child schema walks on a heap stack, never through recursive yield delegation. */
6
- function evaluateSchemaWalk(walk) {
7
- const parents = [];
8
- let current = walk;
9
- let value;
10
- try {
11
- while (true) {
12
- const step = current.next(value);
13
- if (!step.done) {
14
- parents.push(current);
15
- current = step.value;
16
- value = void 0;
17
- continue;
18
- }
19
- value = step.value;
20
- const parent = parents.pop();
21
- if (!parent) return value;
22
- current = parent;
23
- }
24
- } finally {
25
- let parent;
26
- while (parent = parents.pop()) parent.return(void 0);
27
- }
28
- }
29
- //#endregion
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";
30
5
  //#region packages/ai/src/providers/clean-for-gemini.ts
31
6
  const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
32
7
  "~optional",
@@ -98,7 +73,7 @@ function tryFlattenLiteralAnyOf(variants) {
98
73
  return null;
99
74
  }
100
75
  function isNullSchema(variant) {
101
- if (!variant || typeof variant !== "object" || Array.isArray(variant)) return false;
76
+ if (!isRecord(variant)) return false;
102
77
  const record = variant;
103
78
  if ("const" in record && record.const === null) return true;
104
79
  if (Array.isArray(record.enum) && record.enum.length === 1) return record.enum[0] === null;
@@ -107,20 +82,9 @@ function isNullSchema(variant) {
107
82
  if (Array.isArray(typeValue) && typeValue.length === 1 && typeValue[0] === "null") return true;
108
83
  return false;
109
84
  }
110
- function stripNullVariants(variants) {
111
- if (variants.length === 0) return {
112
- variants,
113
- stripped: false
114
- };
115
- const nonNull = variants.filter((variant) => !isNullSchema(variant));
116
- return {
117
- variants: nonNull,
118
- stripped: nonNull.length !== variants.length
119
- };
120
- }
121
85
  function extendSchemaDefs$1(defs, schema) {
122
- const defsEntry = schema.$defs && typeof schema.$defs === "object" && !Array.isArray(schema.$defs) ? schema.$defs : void 0;
123
- 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;
124
88
  if (!defsEntry && !legacyDefsEntry) return defs;
125
89
  const next = defs ? new Map(defs) : /* @__PURE__ */ new Map();
126
90
  if (defsEntry) for (const [key, value] of Object.entries(defsEntry)) next.set(key, value);
@@ -140,7 +104,8 @@ function tryResolveLocalRef$1(ref, defs) {
140
104
  }
141
105
  function simplifyUnionVariants(params) {
142
106
  const { obj, variants } = params;
143
- const { variants: nonNullVariants, stripped } = stripNullVariants(variants);
107
+ const nonNullVariants = variants.filter((variant) => !isNullSchema(variant));
108
+ const stripped = nonNullVariants.length !== variants.length;
144
109
  const flattened = tryFlattenLiteralAnyOf(nonNullVariants);
145
110
  if (flattened) {
146
111
  const result = {
@@ -175,7 +140,7 @@ function simplifyUnionVariants(params) {
175
140
  }
176
141
  function sanitizeRequiredFields(schema) {
177
142
  if (!Array.isArray(schema.required)) return schema;
178
- if (!schema.properties || typeof schema.properties !== "object" || Array.isArray(schema.properties)) {
143
+ if (!isRecord(schema.properties)) {
179
144
  if (schema.type === "object") delete schema.required;
180
145
  return schema;
181
146
  }
@@ -252,13 +217,8 @@ function* cleanSchemaForGeminiWithDefs(schema, defs, refStack, ancestors) {
252
217
  const cleaned = {};
253
218
  for (const [key, value] of Object.entries(obj)) {
254
219
  if (GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS.has(key)) continue;
255
- if (key === "const") {
256
- const enumValues = cleanGeminiEnumValues([value]);
257
- if (enumValues) cleaned.enum = enumValues;
258
- continue;
259
- }
260
- if (key === "enum") {
261
- const enumValues = cleanGeminiEnumValues(value);
220
+ if (key === "const" || key === "enum") {
221
+ const enumValues = cleanGeminiEnumValues(key === "const" ? [value] : value);
262
222
  if (enumValues) cleaned.enum = enumValues;
263
223
  continue;
264
224
  }
@@ -290,12 +250,8 @@ function* cleanSchemaForGeminiWithDefs(schema, defs, refStack, ancestors) {
290
250
  cleaned[key] = result;
291
251
  } else cleaned[key] = value;
292
252
  }
293
- if (cleaned.anyOf && Array.isArray(cleaned.anyOf)) {
294
- const flattened = flattenUnionFallback(cleaned, cleaned.anyOf);
295
- if (flattened) return sanitizeRequiredFields(flattened);
296
- }
297
- if (cleaned.oneOf && Array.isArray(cleaned.oneOf)) {
298
- const flattened = flattenUnionFallback(cleaned, cleaned.oneOf);
253
+ for (const variants of [cleaned.anyOf, cleaned.oneOf]) if (Array.isArray(variants)) {
254
+ const flattened = flattenUnionFallback(cleaned, variants);
299
255
  if (flattened) return sanitizeRequiredFields(flattened);
300
256
  }
301
257
  return sanitizeRequiredFields(cleaned);
@@ -312,23 +268,9 @@ function flattenUnionFallback(obj, variants) {
312
268
  const objects = variants.filter((v) => Boolean(v) && typeof v === "object");
313
269
  if (objects.length === 0) return;
314
270
  const types = new Set(objects.map((v) => v.type).filter(Boolean));
315
- if (objects.length === 1) {
316
- const merged = { ...objects[0] };
317
- copySchemaMeta$1(obj, merged);
318
- return merged;
319
- }
320
- if (types.size === 1) {
321
- const merged = { type: Array.from(types)[0] };
322
- copySchemaMeta$1(obj, merged);
323
- return merged;
324
- }
325
271
  const first = objects[0];
326
- if (first?.type) {
327
- const merged = { type: first.type };
328
- copySchemaMeta$1(obj, merged);
329
- return merged;
330
- }
331
- const merged = {};
272
+ const type = types.size === 1 ? Array.from(types)[0] : first?.type;
273
+ const merged = objects.length === 1 ? { ...first } : type ? { type } : {};
332
274
  copySchemaMeta$1(obj, merged);
333
275
  return merged;
334
276
  }
@@ -336,16 +278,182 @@ function cleanSchemaForGemini(schema) {
336
278
  return evaluateSchemaWalk(cleanSchemaForGeminiWithDefs(schema, void 0, void 0, /* @__PURE__ */ new Set()));
337
279
  }
338
280
  //#endregion
339
- //#region packages/ai/src/providers/clean-for-llamacpp-gbnf.ts
340
- /** llama.cpp rejects grammar repetitions whose expanded rule count reaches 2000. */
341
- const LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD = 2e3;
342
- 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([
343
336
  "$defs",
344
337
  "definitions",
345
338
  "dependentSchemas",
346
339
  "patternProperties",
347
340
  "properties"
348
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;
349
457
  const SCHEMA_CHILD_KEYS = /* @__PURE__ */ new Set([
350
458
  "additionalItems",
351
459
  "additionalProperties",
@@ -363,20 +471,21 @@ const SCHEMA_CHILD_KEYS = /* @__PURE__ */ new Set([
363
471
  "unevaluatedItems",
364
472
  "unevaluatedProperties"
365
473
  ]);
366
- function cleanSchemaNode(node) {
367
- 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)) {
368
477
  let changed = false;
369
- const entries = node.map((entry) => {
370
- const next = cleanSchemaNode(entry);
478
+ const entries = schema.map((entry) => {
479
+ const next = cleanSchemaForLlamacppGbnf(entry);
371
480
  changed ||= next !== entry;
372
481
  return next;
373
482
  });
374
- return changed ? entries : node;
483
+ return changed ? entries : schema;
375
484
  }
376
- if (!isRecord(node)) return node;
485
+ if (!isRecord(schema)) return schema;
377
486
  let changed = false;
378
487
  const cleaned = {};
379
- for (const [key, value] of Object.entries(node)) {
488
+ for (const [key, value] of Object.entries(schema)) {
380
489
  if (key === "pattern") {
381
490
  changed = true;
382
491
  continue;
@@ -386,19 +495,19 @@ function cleanSchemaNode(node) {
386
495
  continue;
387
496
  }
388
497
  let next = value;
389
- if (SCHEMA_MAP_KEYS$2.has(key) && isRecord(value)) {
498
+ if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
390
499
  let mapChanged = false;
391
500
  next = Object.fromEntries(Object.entries(value).map(([childKey, childValue]) => {
392
- const cleanedChild = cleanSchemaNode(childValue);
501
+ const cleanedChild = cleanSchemaForLlamacppGbnf(childValue);
393
502
  mapChanged ||= cleanedChild !== childValue;
394
503
  return [childKey, cleanedChild];
395
504
  }));
396
505
  if (!mapChanged) next = value;
397
- } else if (SCHEMA_CHILD_KEYS.has(key)) next = cleanSchemaNode(value);
506
+ } else if (SCHEMA_CHILD_KEYS.has(key)) next = cleanSchemaForLlamacppGbnf(value);
398
507
  cleaned[key] = next;
399
508
  changed ||= next !== value;
400
509
  }
401
- return changed ? cleaned : node;
510
+ return changed ? cleaned : schema;
402
511
  }
403
512
  function collectSchemaViolations(node, path, violations) {
404
513
  if (Array.isArray(node)) {
@@ -408,13 +517,9 @@ function collectSchemaViolations(node, path, violations) {
408
517
  if (!isRecord(node)) return;
409
518
  if ("pattern" in node) violations.push(`${path}.pattern`);
410
519
  if (typeof node.maxLength === "number" && node.maxLength >= 2e3) violations.push(`${path}.maxLength`);
411
- 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);
412
521
  else if (SCHEMA_CHILD_KEYS.has(key)) collectSchemaViolations(value, `${path}.${key}`, violations);
413
522
  }
414
- /** Removes JSON Schema constraints that llama.cpp cannot compile into GBNF. */
415
- function cleanSchemaForLlamacppGbnf(schema) {
416
- return cleanSchemaNode(schema);
417
- }
418
523
  /** Reports schema paths that llama.cpp cannot compile into GBNF. */
419
524
  function findLlamacppGbnfSchemaViolations(schema, path) {
420
525
  const violations = [];
@@ -423,38 +528,8 @@ function findLlamacppGbnfSchemaViolations(schema, path) {
423
528
  }
424
529
  //#endregion
425
530
  //#region packages/ai/src/providers/schema-keyword-strip.ts
426
- const SCHEMA_MAP_KEYS$1 = /* @__PURE__ */ new Set([
427
- "$defs",
428
- "definitions",
429
- "dependentSchemas",
430
- "dependencies",
431
- "patternProperties",
432
- "properties"
433
- ]);
434
- /** Containers whose value is a single nested schema. */
435
- const SCHEMA_OBJECT_KEYS$1 = /* @__PURE__ */ new Set([
436
- "additionalItems",
437
- "additionalProperties",
438
- "contains",
439
- "contentSchema",
440
- "else",
441
- "if",
442
- "items",
443
- "not",
444
- "propertyNames",
445
- "then",
446
- "unevaluatedItems",
447
- "unevaluatedProperties"
448
- ]);
449
- /** Containers whose value is a list of nested schemas. */
450
- const SCHEMA_ARRAY_KEYS$1 = /* @__PURE__ */ new Set([
451
- "allOf",
452
- "anyOf",
453
- "items",
454
- "oneOf",
455
- "prefixItems"
456
- ]);
457
- function* stripSchemaArray(schemas, unsupportedKeywords, ancestors, result) {
531
+ function* stripSchemaArray(schemas, unsupportedKeywords, ancestors) {
532
+ const result = [];
458
533
  result.length = schemas.length;
459
534
  for (let index = 0; index < result.length; index += 1) if (index in schemas) result[index] = yield stripSchemaKeywords(schemas[index], unsupportedKeywords, ancestors);
460
535
  return result;
@@ -464,11 +539,7 @@ function* stripSchemaKeywords(schema, unsupportedKeywords, ancestors) {
464
539
  if (ancestors.has(schema)) throw new TypeError("Tool schema contains a circular reference.");
465
540
  ancestors.add(schema);
466
541
  try {
467
- if (Array.isArray(schema)) {
468
- const result = [];
469
- yield stripSchemaArray(schema, unsupportedKeywords, ancestors, result);
470
- return result;
471
- }
542
+ if (Array.isArray(schema)) return yield stripSchemaArray(schema, unsupportedKeywords, ancestors);
472
543
  const obj = schema;
473
544
  const cleaned = {};
474
545
  for (const [key, value] of Object.entries(obj)) {
@@ -477,11 +548,8 @@ function* stripSchemaKeywords(schema, unsupportedKeywords, ancestors) {
477
548
  const entries = Object.entries(value);
478
549
  for (const entry of entries) entry[1] = yield stripSchemaKeywords(entry[1], unsupportedKeywords, ancestors);
479
550
  cleaned[key] = Object.fromEntries(entries);
480
- } else if (SCHEMA_ARRAY_KEYS$1.has(key) && Array.isArray(value)) {
481
- const result = [];
482
- yield stripSchemaArray(value, unsupportedKeywords, ancestors, result);
483
- cleaned[key] = result;
484
- } else if (SCHEMA_OBJECT_KEYS$1.has(key) && value && typeof value === "object") cleaned[key] = yield stripSchemaKeywords(value, unsupportedKeywords, ancestors);
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);
485
553
  else cleaned[key] = value;
486
554
  }
487
555
  return cleaned;
@@ -625,37 +693,6 @@ function mergePropertySchemas(existing, incoming) {
625
693
  }
626
694
  return existing;
627
695
  }
628
- function setOwnSchemaProperty(target, key, value) {
629
- Object.defineProperty(target, key, {
630
- value,
631
- enumerable: true,
632
- configurable: true,
633
- writable: true
634
- });
635
- }
636
- function hasTopLevelArrayKeyword(schemaRecord, key) {
637
- return Array.isArray(schemaRecord[key]);
638
- }
639
- function getFlattenableVariantKey(schemaRecord) {
640
- if (hasTopLevelArrayKeyword(schemaRecord, "anyOf")) return "anyOf";
641
- if (hasTopLevelArrayKeyword(schemaRecord, "oneOf")) return "oneOf";
642
- return null;
643
- }
644
- function getTopLevelConditionalKey(schemaRecord) {
645
- return getFlattenableVariantKey(schemaRecord) ?? (hasTopLevelArrayKeyword(schemaRecord, "allOf") ? "allOf" : null);
646
- }
647
- function hasTopLevelObjectSchema(schemaRecord, conditionalKey) {
648
- return schemaRecord.type === "object" && isRecord(schemaRecord.properties) && conditionalKey === null;
649
- }
650
- function isObjectLikeSchemaMissingType(schemaRecord, conditionalKey) {
651
- return !("type" in schemaRecord) && (isRecord(schemaRecord.properties) || Array.isArray(schemaRecord.required)) && conditionalKey === null;
652
- }
653
- function isTypedObjectSchemaMissingValidProperties(schemaRecord, conditionalKey) {
654
- return schemaRecord.type === "object" && !isRecord(schemaRecord.properties) && conditionalKey === null;
655
- }
656
- function isTrulyEmptySchema(schemaRecord) {
657
- return Object.keys(schemaRecord).length === 0;
658
- }
659
696
  function normalizeArraySchemaItems(schema, mode) {
660
697
  if (Array.isArray(schema)) {
661
698
  if (mode === "add") return schema;
@@ -677,7 +714,7 @@ function normalizeArraySchemaItems(schema, mode) {
677
714
  return entries.some((entry, index) => entry !== value[index]) ? entries : value;
678
715
  };
679
716
  for (const [key, value] of Object.entries(normalized)) {
680
- if (mode !== "add" && key === "items" && allowsArray && isRecord(value) && isTrulyEmptySchema(value)) {
717
+ if (mode !== "add" && key === "items" && allowsArray && isRecord(value) && Object.keys(value).length === 0) {
681
718
  delete normalized.items;
682
719
  changed = true;
683
720
  continue;
@@ -698,150 +735,6 @@ function normalizeArraySchemaItems(schema, mode) {
698
735
  }
699
736
  return changed ? normalized : schema;
700
737
  }
701
- function copySchemaMeta(from, to) {
702
- for (const key of [
703
- "title",
704
- "description",
705
- "default"
706
- ]) if (key in from && from[key] !== void 0) to[key] = from[key];
707
- }
708
- function extendSchemaDefs(defs, schema) {
709
- const defsEntry = schema.$defs && typeof schema.$defs === "object" && !Array.isArray(schema.$defs) ? schema.$defs : void 0;
710
- const legacyDefsEntry = schema.definitions && typeof schema.definitions === "object" && !Array.isArray(schema.definitions) ? schema.definitions : void 0;
711
- if (!defsEntry && !legacyDefsEntry) return defs;
712
- const next = defs ? {
713
- $defs: new Map(defs.$defs),
714
- definitions: new Map(defs.definitions)
715
- } : {
716
- $defs: /* @__PURE__ */ new Map(),
717
- definitions: /* @__PURE__ */ new Map()
718
- };
719
- if (defsEntry) for (const [key, value] of Object.entries(defsEntry)) next.$defs.set(key, value);
720
- if (legacyDefsEntry) for (const [key, value] of Object.entries(legacyDefsEntry)) next.definitions.set(key, value);
721
- return next;
722
- }
723
- function decodeJsonPointerSegment(segment) {
724
- return segment.replaceAll("~1", "/").replaceAll("~0", "~");
725
- }
726
- function resolveJsonPointerPath(value, segments) {
727
- let current = value;
728
- for (const segment of segments) {
729
- if (!current || typeof current !== "object") return;
730
- const key = decodeJsonPointerSegment(segment);
731
- if (Array.isArray(current)) {
732
- const index = /^(?:0|[1-9]\d*)$/.test(key) ? Number(key) : -1;
733
- if (index < 0 || index >= current.length) return;
734
- current = current[index];
735
- continue;
736
- }
737
- const record = current;
738
- if (!Object.hasOwn(record, key)) return;
739
- current = record[key];
740
- }
741
- return current;
742
- }
743
- function resolveLocalJsonPointer(rootDocument, ref) {
744
- if (!ref.startsWith("#/")) return;
745
- return resolveJsonPointerPath(rootDocument, ref.slice(2).split("/"));
746
- }
747
- const SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
748
- "$defs",
749
- "definitions",
750
- "dependentSchemas",
751
- "patternProperties",
752
- "properties"
753
- ]);
754
- const SCHEMA_OBJECT_KEYS = /* @__PURE__ */ new Set([
755
- "additionalProperties",
756
- "contains",
757
- "else",
758
- "if",
759
- "items",
760
- "not",
761
- "propertyNames",
762
- "then"
763
- ]);
764
- const SCHEMA_ARRAY_KEYS = /* @__PURE__ */ new Set([
765
- "allOf",
766
- "anyOf",
767
- "items",
768
- "oneOf",
769
- "prefixItems"
770
- ]);
771
- const SCHEMA_LITERAL_KEYS = /* @__PURE__ */ new Set([
772
- "const",
773
- "default",
774
- "enum",
775
- "examples"
776
- ]);
777
- function tryResolveLocalRef(ref, defs, rootDocument) {
778
- const match = ref.match(/^#\/(\$defs|definitions)\/([^/]+)(?:\/(.*))?$/);
779
- if (match && defs) {
780
- const namespace = match[1] === "$defs" ? defs.$defs : defs.definitions;
781
- const name = decodeJsonPointerSegment(match[2] ?? "");
782
- const resolved = name ? namespace.get(name) : void 0;
783
- if (resolved !== void 0) return resolveJsonPointerPath(resolved, match[3] ? match[3].split("/") : []);
784
- }
785
- return resolveLocalJsonPointer(rootDocument, ref);
786
- }
787
- function inlineLocalSchemaRefsWithDefs(schema, defs, refStack, state, rootDocument) {
788
- if (!schema || typeof schema !== "object") return schema;
789
- if (Array.isArray(schema)) return schema.map((entry) => inlineLocalSchemaRefsWithDefs(entry, defs, refStack, state, rootDocument));
790
- const obj = schema;
791
- const nextDefs = extendSchemaDefs(defs, obj);
792
- const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
793
- if (refValue) {
794
- if (refStack?.has(refValue)) return {};
795
- const resolved = tryResolveLocalRef(refValue, nextDefs, rootDocument);
796
- if (resolved === void 0) {
797
- if (refValue.startsWith("#/")) state.unresolvedLocalRefs = true;
798
- return { ...obj };
799
- }
800
- const nextRefStack = refStack ? new Set(refStack) : /* @__PURE__ */ new Set();
801
- nextRefStack.add(refValue);
802
- const inlined = inlineLocalSchemaRefsWithDefs(resolved, nextDefs, nextRefStack, state, rootDocument);
803
- if (!inlined || typeof inlined !== "object" || Array.isArray(inlined)) return inlined;
804
- const result = { ...inlined };
805
- copySchemaMeta(obj, result);
806
- if (obj.nullable === true) result.nullable = true;
807
- return result;
808
- }
809
- const result = {};
810
- for (const [key, value] of Object.entries(obj)) {
811
- if (key === "$defs" || key === "definitions" || key === "components") continue;
812
- if (SCHEMA_LITERAL_KEYS.has(key)) {
813
- setOwnSchemaProperty(result, key, value);
814
- continue;
815
- }
816
- if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
817
- const entries = Object.entries(value);
818
- for (const entry of entries) entry[1] = inlineLocalSchemaRefsWithDefs(entry[1], nextDefs, refStack, state, rootDocument);
819
- setOwnSchemaProperty(result, key, Object.fromEntries(entries));
820
- continue;
821
- }
822
- if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) {
823
- setOwnSchemaProperty(result, key, inlineLocalSchemaRefsWithDefs(value, nextDefs, refStack, state, rootDocument));
824
- continue;
825
- }
826
- if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) {
827
- setOwnSchemaProperty(result, key, value.map((entry) => inlineLocalSchemaRefsWithDefs(entry, nextDefs, refStack, state, rootDocument)));
828
- continue;
829
- }
830
- setOwnSchemaProperty(result, key, value);
831
- }
832
- if (state.unresolvedLocalRefs) {
833
- if ("$defs" in obj) result.$defs = obj.$defs;
834
- if ("definitions" in obj) result.definitions = obj.definitions;
835
- if ("components" in obj) result.components = obj.components;
836
- }
837
- return result;
838
- }
839
- /** Inline local $ref pointers so providers receive self-contained tool schemas. */
840
- function inlineLocalToolSchemaRefs(schema) {
841
- if (!schema || typeof schema !== "object") return schema;
842
- const schemaRecord = schema;
843
- return inlineLocalSchemaRefsWithDefs(schema, Array.isArray(schema) ? extendSchemaDefs(void 0, schemaRecord) : void 0, void 0, { unresolvedLocalRefs: false }, schema);
844
- }
845
738
  const OPENAPI_SCHEMA_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
846
739
  "discriminator",
847
740
  "externalDocs",
@@ -936,9 +829,6 @@ function normalizeOpenApiSchemaKeywords(schema) {
936
829
  return changed || nullable ? normalized ?? schema : schema;
937
830
  }
938
831
  function normalizeToolParameterSchemaUncached(schema, options) {
939
- const inlinedSchema = normalizeOpenApiSchemaKeywords(inlineLocalToolSchemaRefs(schema));
940
- const schemaRecord = inlinedSchema && typeof inlinedSchema === "object" ? inlinedSchema : void 0;
941
- if (!schemaRecord) return inlinedSchema;
942
832
  const normalizedProvider = normalizeLowercaseStringOrEmpty(options?.modelProvider);
943
833
  const normalizedModelId = normalizeLowercaseStringOrEmpty(options?.modelId);
944
834
  const normalizedToolSchemaProfile = normalizeLowercaseStringOrEmpty(options?.modelCompat?.toolSchemaProfile);
@@ -947,36 +837,37 @@ function normalizeToolParameterSchemaUncached(schema, options) {
947
837
  const unsupportedToolSchemaKeywords = resolveUnsupportedToolSchemaKeywords(options?.modelCompat);
948
838
  const omitEmptyArrayItems = shouldOmitEmptyArrayItems(options?.modelCompat);
949
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;
950
847
  function applyProviderCleaning(s) {
951
848
  let arrayItemsCompatibleSchema = normalizeArraySchemaItems(s, omitEmptyArrayItems ? "normalize" : "add");
952
849
  if (isLlamacppGbnfProfile) arrayItemsCompatibleSchema = cleanSchemaForLlamacppGbnf(arrayItemsCompatibleSchema);
953
- if (isGeminiProvider && !isAnthropicProvider) {
954
- const geminiCompatibleSchema = cleanSchemaForGemini(arrayItemsCompatibleSchema);
955
- return unsupportedToolSchemaKeywords.size > 0 ? stripUnsupportedSchemaKeywords(geminiCompatibleSchema, unsupportedToolSchemaKeywords) : geminiCompatibleSchema;
956
- }
957
- if (unsupportedToolSchemaKeywords.size > 0) return stripUnsupportedSchemaKeywords(arrayItemsCompatibleSchema, unsupportedToolSchemaKeywords);
850
+ if (isGeminiProvider && !isAnthropicProvider) arrayItemsCompatibleSchema = cleanSchemaForGemini(arrayItemsCompatibleSchema);
851
+ if (unsupportedToolSchemaKeywords.size > 0) arrayItemsCompatibleSchema = stripUnsupportedSchemaKeywords(arrayItemsCompatibleSchema, unsupportedToolSchemaKeywords);
958
852
  return arrayItemsCompatibleSchema;
959
853
  }
960
- const conditionalKey = getTopLevelConditionalKey(schemaRecord);
961
- const flattenableVariantKey = getFlattenableVariantKey(schemaRecord);
962
- if (hasTopLevelObjectSchema(schemaRecord, conditionalKey)) return applyProviderCleaning(schemaRecord);
963
- if (isObjectLikeSchemaMissingType(schemaRecord, conditionalKey)) return applyProviderCleaning({
964
- ...schemaRecord,
965
- type: "object",
966
- properties: isRecord(schemaRecord.properties) ? schemaRecord.properties : {}
967
- });
968
- if (isTypedObjectSchemaMissingValidProperties(schemaRecord, conditionalKey)) return applyProviderCleaning({
969
- ...schemaRecord,
970
- properties: {}
971
- });
972
- if (!flattenableVariantKey) {
973
- if (isTrulyEmptySchema(schemaRecord)) return applyProviderCleaning({
974
- 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,
975
859
  properties: {}
976
860
  });
977
- if (conditionalKey === "allOf") return applyProviderCleaning(inlinedSchema);
978
- 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
+ });
979
866
  }
867
+ if (!flattenableVariantKey) return applyProviderCleaning(Object.keys(schemaRecord).length === 0 ? {
868
+ type: "object",
869
+ properties: {}
870
+ } : inlinedSchema);
980
871
  const variants = schemaRecord[flattenableVariantKey];
981
872
  const mergedProperties = isRecord(schemaRecord.properties) ? { ...schemaRecord.properties } : {};
982
873
  const requiredCounts = /* @__PURE__ */ new Map();
@@ -995,11 +886,10 @@ function normalizeToolParameterSchemaUncached(schema, options) {
995
886
  }
996
887
  const baseRequired = Array.isArray(schemaRecord.required) ? schemaRecord.required.filter((key) => typeof key === "string") : void 0;
997
888
  const mergedRequired = baseRequired && baseRequired.length > 0 ? baseRequired : objectVariants > 0 ? Array.from(requiredCounts.entries()).filter(([, count]) => count === objectVariants).map(([key]) => key) : void 0;
998
- const nextSchema = { ...schemaRecord };
999
889
  return applyProviderCleaning({
1000
890
  type: "object",
1001
- ...typeof nextSchema.title === "string" ? { title: nextSchema.title } : {},
1002
- ...typeof nextSchema.description === "string" ? { description: nextSchema.description } : {},
891
+ ...typeof schemaRecord.title === "string" ? { title: schemaRecord.title } : {},
892
+ ...typeof schemaRecord.description === "string" ? { description: schemaRecord.description } : {},
1003
893
  properties: Object.keys(mergedProperties).length > 0 ? mergedProperties : schemaRecord.properties ?? {},
1004
894
  ...mergedRequired && mergedRequired.length > 0 ? { required: mergedRequired } : {},
1005
895
  additionalProperties: "additionalProperties" in schemaRecord ? schemaRecord.additionalProperties : true
@@ -1015,14 +905,6 @@ function normalizeToolParameterSchema(schema, options) {
1015
905
  }
1016
906
  //#endregion
1017
907
  //#region packages/ai/src/providers/openai-tool-schema-compat.ts
1018
- const OPENAI_STRICT_COMPAT_SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
1019
- "$defs",
1020
- "definitions",
1021
- "dependentSchemas",
1022
- "dependencies",
1023
- "patternProperties",
1024
- "properties"
1025
- ]);
1026
908
  const OPENAI_NULLABLE_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
1027
909
  "default",
1028
910
  "description",
@@ -1030,39 +912,22 @@ const OPENAI_NULLABLE_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
1030
912
  "format",
1031
913
  "title"
1032
914
  ]);
1033
- const OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS = /* @__PURE__ */ new Set([
1034
- "additionalItems",
1035
- "additionalProperties",
1036
- "allOf",
1037
- "anyOf",
1038
- "contains",
1039
- "contentSchema",
1040
- "else",
1041
- "if",
1042
- "items",
1043
- "not",
1044
- "oneOf",
1045
- "prefixItems",
1046
- "propertyNames",
1047
- "then",
1048
- "unevaluatedItems",
1049
- "unevaluatedProperties"
1050
- ]);
915
+ const OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS = new Set([...SCHEMA_OBJECT_KEYS$1, ...SCHEMA_ARRAY_KEYS$1].toSorted());
1051
916
  function normalizeOpenAIStrictCompatSchemaMap(schema) {
1052
- if (!schema || typeof schema !== "object" || Array.isArray(schema)) return schema;
917
+ if (!isRecord(schema)) return schema;
1053
918
  let changed = false;
1054
919
  const normalized = Object.fromEntries(Object.entries(schema).map(([key, value]) => {
1055
- const next = normalizeOpenAIStrictCompatSchemaRecursive(value, { promoteEmptyObject: false });
920
+ const next = normalizeOpenAIStrictCompatSchemaRecursive(value);
1056
921
  changed ||= next !== value;
1057
922
  return [key, next];
1058
923
  }));
1059
924
  return changed ? normalized : schema;
1060
925
  }
1061
- function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
926
+ function normalizeOpenAIStrictCompatSchemaRecursive(schema, promoteEmptyObject = false) {
1062
927
  if (Array.isArray(schema)) {
1063
928
  let changed = false;
1064
929
  const normalized = schema.map((entry) => {
1065
- const next = normalizeOpenAIStrictCompatSchemaRecursive(entry, { promoteEmptyObject: false });
930
+ const next = normalizeOpenAIStrictCompatSchemaRecursive(entry);
1066
931
  changed ||= next !== entry;
1067
932
  return next;
1068
933
  });
@@ -1078,13 +943,13 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1078
943
  changed = true;
1079
944
  return [];
1080
945
  }
1081
- 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;
1082
947
  changed ||= next !== value;
1083
948
  return [[key, next]];
1084
949
  });
1085
950
  const normalized = Object.fromEntries(entries);
1086
951
  if (Object.keys(normalized).length === 0) {
1087
- if (!options.promoteEmptyObject) return schema;
952
+ if (!promoteEmptyObject) return schema;
1088
953
  return {
1089
954
  type: "object",
1090
955
  properties: {},
@@ -1102,7 +967,7 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1102
967
  normalized.properties = {};
1103
968
  changed = true;
1104
969
  }
1105
- 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;
1106
971
  if (normalized.type === "object" && !Array.isArray(normalized.required) && hasEmptyProperties) {
1107
972
  normalized.required = [];
1108
973
  changed = true;
@@ -1115,7 +980,7 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1115
980
  }
1116
981
  /** Repairs recoverable OpenAI tool-schema shapes before canonical normalization. */
1117
982
  function normalizeOpenAIStrictCompatSchema(schema) {
1118
- return normalizeOpenAIStrictCompatSchemaRecursive(schema, { promoteEmptyObject: true });
983
+ return normalizeOpenAIStrictCompatSchemaRecursive(schema, true);
1119
984
  }
1120
985
  /** Finds schema paths that violate OpenAI strict tool-schema requirements. */
1121
986
  function findOpenAIStrictSchemaViolations(schema, path, options) {
@@ -1132,7 +997,7 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1132
997
  "allOf"
1133
998
  ]) if (key in record) violations.push(`${path}.${key}`);
1134
999
  if (Array.isArray(record.type)) violations.push(`${path}.type`);
1135
- 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;
1136
1001
  if (record.type === "object") {
1137
1002
  if (record.additionalProperties !== false) violations.push(`${path}.additionalProperties`);
1138
1003
  const required = Array.isArray(record.required) ? record.required.filter((entry) => typeof entry === "string") : void 0;
@@ -1142,9 +1007,9 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1142
1007
  for (const key of Object.keys(properties)) if (!requiredSet.has(key)) violations.push(`${path}.required.${key}`);
1143
1008
  }
1144
1009
  }
1145
- for (const key of OPENAI_STRICT_COMPAT_SCHEMA_MAP_KEYS) {
1010
+ for (const key of SCHEMA_MAP_KEYS$1) {
1146
1011
  const schemaMap = record[key];
1147
- if (!schemaMap || typeof schemaMap !== "object" || Array.isArray(schemaMap)) continue;
1012
+ if (!isRecord(schemaMap)) continue;
1148
1013
  for (const [entryKey, value] of Object.entries(schemaMap)) violations.push(...findOpenAIStrictSchemaViolations(value, `${path}.${key}.${entryKey}`));
1149
1014
  }
1150
1015
  for (const key of OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS) {
@@ -1155,11 +1020,6 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
1155
1020
  }
1156
1021
  //#endregion
1157
1022
  //#region packages/ai/src/providers/openai-tool-schema.ts
1158
- /**
1159
- * OpenAI strict JSON-schema normalization for tool inventories and request payloads.
1160
- *
1161
- * Caches normalized object inputs by provider compatibility so repeated inventory builds preserve identity.
1162
- */
1163
1023
  const strictOpenAISchemaCache = createToolSchemaNormalizationCache(8);
1164
1024
  function resolveToolSchemaModelCompat(compat) {
1165
1025
  if (!compat) return;
@@ -1202,7 +1062,7 @@ function normalizeStrictOpenAIJsonSchemaRecursive(schema, depth) {
1202
1062
  return [key, next];
1203
1063
  }));
1204
1064
  if (normalized.type === "object") {
1205
- 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;
1206
1066
  if (properties && Object.keys(properties).length === 0 && !Array.isArray(normalized.required)) {
1207
1067
  normalized.required = [];
1208
1068
  changed = true;
@@ -1247,14 +1107,14 @@ function isStrictOpenAIJsonSchemaCompatibleRecursive(schema) {
1247
1107
  if (Array.isArray(record.type)) return false;
1248
1108
  if (record.type === "object" && record.additionalProperties !== false) return false;
1249
1109
  if (record.type === "object") {
1250
- const properties = record.properties && typeof record.properties === "object" && !Array.isArray(record.properties) ? record.properties : {};
1110
+ const properties = isRecord(record.properties) ? record.properties : {};
1251
1111
  const required = Array.isArray(record.required) ? record.required.filter((entry) => typeof entry === "string") : void 0;
1252
1112
  if (!required) return false;
1253
1113
  const requiredSet = new Set(required);
1254
1114
  if (Object.keys(properties).some((key) => !requiredSet.has(key))) return false;
1255
1115
  }
1256
1116
  return Object.entries(record).every(([key, entry]) => {
1257
- 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);
1258
1118
  return isStrictOpenAIJsonSchemaCompatibleRecursive(entry);
1259
1119
  });
1260
1120
  }