@openclaw/ai 2026.10.5 → 2026.10.10-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +11 -0
  2. package/dist/{anthropic-DIIiiz99.mjs → anthropic-D6spfBri.mjs} +16 -18
  3. package/dist/{anthropic-payload-policy-DGblkHL5.d.mts → anthropic-payload-policy-Cr8xjazC.d.mts} +6 -3
  4. package/dist/{anthropic-stream-reducer-DfMVFm-r.mjs → anthropic-stream-reducer-CzPXOaLM.mjs} +55 -227
  5. package/dist/anthropic-tool-projection-BdAS3rtJ.mjs +165 -0
  6. package/dist/anthropic-tool-projection-DKH-aEWU.d.mts +51 -0
  7. package/dist/{api-registry-BhXXYdRA.d.mts → api-registry-gDt0faai.d.mts} +2 -2
  8. package/dist/{assistant-output-BuhRpLeD.mjs → assistant-output-6iFA1nbC.mjs} +2 -2
  9. package/dist/{azure-openai-responses-DGQnXRMs.mjs → azure-openai-responses-0TqHwnlD.mjs} +8 -8
  10. package/dist/{cloudflare-5qSGvIUH.mjs → cloudflare-Dttf8jKq.mjs} +1 -1
  11. package/dist/{credential-redaction-BHxruEH6.d.mts → credential-redaction-XvsPf7Yi.d.mts} +1 -0
  12. package/dist/{diagnostics-tQasYct1.mjs → diagnostics-Cv7cW3pS.mjs} +3 -3
  13. package/dist/diagnostics.d.mts +6 -6
  14. package/dist/diagnostics.mjs +2 -2
  15. package/dist/{env-api-keys-CrxwdylR.mjs → env-api-keys-Xd8dm_aV.mjs} +10 -34
  16. package/dist/event-stream-CDpFza-M.d.mts +1 -0
  17. package/dist/{event-stream-BcqWLo_u.d.mts → event-stream-CzpE1g_o.d.mts} +1 -1
  18. package/dist/event-stream.d.mts +2 -2
  19. package/dist/{github-copilot-request-facts-DEE6gcB9.mjs → github-copilot-request-facts-F-EmvkpW.mjs} +1 -1
  20. package/dist/{google-interactions-zIz70M2e.mjs → google-interactions-DVQ7AaSF.mjs} +29 -50
  21. package/dist/{google-messages-CNbUJK5E.mjs → google-messages-DfpHVTaD.mjs} +15 -5
  22. package/dist/{google-provider-stream-Cn0XF1MG.mjs → google-provider-stream-DJ8ANfsS.mjs} +6 -6
  23. package/dist/{google-shared-BPnWP4tT.mjs → google-shared-VTcCJLW3.mjs} +21 -29
  24. package/dist/{google-vertex-XQ7OQtaM.mjs → google-vertex-Bkfizj7M.mjs} +3 -3
  25. package/dist/{google-BlbTC1Xp.mjs → google-zWpkDSeN.mjs} +4 -4
  26. package/dist/{host-Bf3NjYNj.mjs → host-B2gk-d1H.mjs} +5 -11
  27. package/dist/{host-CTDz7LXD.d.mts → host-jJOffdlW.d.mts} +4 -6
  28. package/dist/{host-policy-BzZluO6_.mjs → host-policy-mpqGhbeM.mjs} +1 -1
  29. package/dist/{index-BYDvopUB.d.mts → index-DSprYWaz.d.mts} +7 -5
  30. package/dist/index.d.mts +7 -7
  31. package/dist/index.mjs +6 -6
  32. package/dist/internal/anthropic.d.mts +7 -53
  33. package/dist/internal/anthropic.mjs +6 -5
  34. package/dist/internal/google-model-family.mjs +1 -1
  35. package/dist/internal/openai-completions-compat.d.mts +1 -1
  36. package/dist/internal/openai-completions-compat.mjs +1 -1
  37. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  38. package/dist/internal/openai-responses-payload-policy.mjs +3 -3
  39. package/dist/internal/openai.d.mts +17 -26
  40. package/dist/internal/openai.mjs +10 -10
  41. package/dist/internal/retry-after.d.mts +1 -1
  42. package/dist/internal/retry-after.mjs +80 -55
  43. package/dist/internal/runtime.d.mts +9 -31
  44. package/dist/internal/runtime.mjs +10 -116
  45. package/dist/internal/shared.d.mts +9 -7
  46. package/dist/internal/shared.mjs +8 -6
  47. package/dist/internal/tool-schema.d.mts +83 -5
  48. package/dist/internal/tool-schema.mjs +4 -3
  49. package/dist/{mistral-dCDCR5ur.mjs → mistral-CATJrwne.mjs} +32 -35
  50. package/dist/model-request-body-BD5vy4rP.d.mts +17 -0
  51. package/dist/{number-coercion-C3hztWoY.mjs → number-coercion-37gmNkuA.mjs} +1 -1
  52. package/dist/{openai-chatgpt-responses-D8-q7cgy.mjs → openai-chatgpt-responses-CtdnpWwe.mjs} +95 -63
  53. package/dist/{openai-completions-CMN24pza.mjs → openai-completions-B6sET3oI.mjs} +10 -8
  54. package/dist/{openai-completions-compat-i-nLZxFy.d.mts → openai-completions-compat-1gsjP-KO.d.mts} +6 -3
  55. package/dist/{openai-completions-compat-CYX18uDk.mjs → openai-completions-compat-CFhQ3UVU.mjs} +7 -2
  56. package/dist/{openai-completions-transport-DuXQOxrH.mjs → openai-completions-transport-DviPEqw3.mjs} +369 -237
  57. package/dist/{openai-prompt-cache-r93BJhjm.mjs → openai-prompt-cache-DJ_P143P.mjs} +1 -1
  58. package/dist/{openai-prompt-cache-DIPMrMFy.d.mts → openai-prompt-cache-DgjD-UL5.d.mts} +2 -2
  59. package/dist/{openai-responses-BMxoJdTC.mjs → openai-responses-BXsJK-mD.mjs} +13 -15
  60. package/dist/{openai-responses-compaction-replay-B2FE4Nw8.d.mts → openai-responses-compaction-replay-Cvnl_nCq.d.mts} +5 -5
  61. package/dist/{openai-responses-contracts-DlKMMTxK.mjs → openai-responses-contracts-Bx-16mnf.mjs} +45 -6
  62. package/dist/{openai-responses-contracts-DKqMJ1Ct.d.mts → openai-responses-contracts-CQ4_AWjL.d.mts} +20 -8
  63. package/dist/{openai-responses-endpoint-CinGh4VZ.mjs → openai-responses-endpoint-D4v-eeYy.mjs} +55 -22
  64. package/dist/{openai-responses-payload-policy-C7GsA1y0.d.mts → openai-responses-payload-policy-BzM52TTH.d.mts} +9 -3
  65. package/dist/openai-responses-request-lifecycle-CTdAb2v1.mjs +246 -0
  66. package/dist/{openai-responses-shared-afo9-s16.mjs → openai-responses-shared-Bv_1NtH9.mjs} +284 -173
  67. package/dist/{openai-responses-terminal-usage-BygjiAdi.d.mts → openai-responses-terminal-usage-CpVjkqn-.d.mts} +2 -2
  68. package/dist/{openai-tool-schema-DDPXsvJP.mjs → openai-tool-schema-Buv0GXFb.mjs} +170 -237
  69. package/dist/overflow-DJHXTNBQ.mjs +117 -0
  70. package/dist/{positive-integer-CqWjqSi9.mjs → positive-integer-Bb4Evc7L.mjs} +1 -1
  71. package/dist/prompt-cache-stability-D_MeCQFI.mjs +32 -0
  72. package/dist/{provider-error-xumb1V3F.d.mts → provider-error-CnaWYTRY.d.mts} +1 -0
  73. package/dist/{provider-error-CF9GWCs2.mjs → provider-error-qtZD2inE.mjs} +75 -13
  74. package/dist/{provider-options-CVrXZBtA.d.mts → provider-options-DeYeaflL.d.mts} +52 -6
  75. package/dist/{transport-utils-34BQoXq3.mjs → provider-replay-context-J6CfU3m1.mjs} +28 -5
  76. package/dist/{provider-transport-turn-state-BYrELw8H.mjs → provider-transport-turn-state-Jxppzuc2.mjs} +5 -5
  77. package/dist/{provider-types-CHtRx0dI.d.mts → provider-types-ODq57rG_.d.mts} +3 -3
  78. package/dist/provider-types.d.mts +6 -6
  79. package/dist/providers.d.mts +2 -2
  80. package/dist/providers.mjs +11 -11
  81. package/dist/{reasoning-tag-text-partitioner-CpOy9-IQ.mjs → reasoning-tag-text-partitioner-DzlRubwU.mjs} +134 -47
  82. package/dist/{required-api-key-CFJvcFy_.mjs → required-api-key-D088S4Cd.mjs} +1 -1
  83. package/dist/{retry-after-CdCURCVg.d.mts → retry-after-sw-XX8aC.d.mts} +1 -1
  84. package/dist/sanitize-unicode-CRGuMONI.mjs +8 -0
  85. package/dist/sanitize-unicode-ZqVLLEKC.d.mts +27 -0
  86. package/dist/{session-resources-D1wgDQ8C.mjs → session-resources-vKvGIE3J.mjs} +1 -10
  87. package/dist/{simple-options-BAu4B54D.mjs → simple-options-BYgC6kse.mjs} +68 -79
  88. package/dist/{src-C44MKrW5.mjs → src-CyA0zJnt.mjs} +6 -2
  89. package/dist/{stream-Dd8DwRFL.mjs → stream-DLBirT0e.mjs} +8 -47
  90. package/dist/{stream-first-event-timeout-Dc42hKv6.mjs → stream-first-event-timeout-D_TfJHRJ.mjs} +1 -1
  91. package/dist/{string-coerce-CtgOVOSv.mjs → string-coerce-Cj8sqWHx.mjs} +26 -1
  92. package/dist/tool-schema-json-projection-B0hHDV7N.mjs +492 -0
  93. package/dist/{transport-stream-shared-BmpzDtdQ.d.mts → transport-stream-shared-8ru8eX4s.d.mts} +5 -5
  94. package/dist/{transport-stream-shared-CWGOuLcA.mjs → transport-stream-shared-CzQlAzJH.mjs} +27 -75
  95. package/dist/transports.d.mts +33 -28
  96. package/dist/transports.mjs +42 -48
  97. package/dist/{types-CQc6JNG4.mjs → types-BXd0kI8-.mjs} +1 -1
  98. package/dist/types-CBJthzJX.d.mts +1 -0
  99. package/dist/{types-Bd2T86VJ.d.mts → types-CVYzKrMl.d.mts} +20 -3
  100. package/dist/types.d.mts +6 -6
  101. package/dist/types.mjs +4 -4
  102. package/dist/{validation-ZX_sPVV0.mjs → validation-9FSkE8T-.mjs} +22 -3
  103. package/dist/{validation-DdGB1yy3.d.mts → validation-BQ5u20Ru.d.mts} +1 -1
  104. package/dist/validation.d.mts +1 -1
  105. package/dist/validation.mjs +1 -1
  106. package/package.json +3 -3
  107. package/dist/assistant-text-phase-mvdMcrY-.mjs +0 -50
  108. package/dist/event-stream-6UNs-AhN.d.mts +0 -1
  109. package/dist/expect-lbe3Hgrh.mjs +0 -8
  110. package/dist/json-schema-Bp07Qui3.mjs +0 -22
  111. package/dist/openai-responses-request-lifecycle-NSIJo9jY.mjs +0 -67
  112. package/dist/openai-tool-projection-793cE3QX.d.mts +0 -37
  113. package/dist/openai-tool-schema-a5ysBBga.d.mts +0 -32
  114. package/dist/rolldown-runtime-BhDjJH2R.mjs +0 -15
  115. package/dist/sanitize-unicode-CjDG6jJx.d.mts +0 -5
  116. package/dist/string-normalization-I3ux50s9.mjs +0 -28
  117. package/dist/text-signature-CUXnvk_c.mjs +0 -34
  118. package/dist/tool-schema-json-projection-B8sG1I9v.mjs +0 -180
  119. package/dist/types-Kdfw_04V.d.mts +0 -1
@@ -1,5 +1,5 @@
1
- import { $ as StopReason, a as AssistantMessage, pt as Usage } from "./types-Bd2T86VJ.mjs";
2
- import "./types-Kdfw_04V.mjs";
1
+ import { $ as StopReason, a as AssistantMessage, pt as Usage } from "./types-CVYzKrMl.mjs";
2
+ import "./types-CBJthzJX.mjs";
3
3
  import OpenAI from "openai";
4
4
  //#region packages/ai/src/providers/openai-responses-terminal-usage.d.ts
5
5
  /** A known output ceiling can resume sampling after admitted tools have settled. */
@@ -1,8 +1,43 @@
1
1
  import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
2
- import { t as parseLocalSchemaRefPointer } from "./json-schema-Bp07Qui3.mjs";
3
- import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-CtgOVOSv.mjs";
4
- import { i as uniqueValues, t as normalizeStringEntries } from "./string-normalization-I3ux50s9.mjs";
5
- import { a as SCHEMA_NESTED_KEYS, c as walkSchemaArray, i as SCHEMA_MAP_KEYS$1, l as walkSchemaValue, o as SCHEMA_OBJECT_KEYS$1, r as SCHEMA_ARRAY_KEYS$1, s as evaluateSchemaWalk } from "./tool-schema-json-projection-B8sG1I9v.mjs";
2
+ import { r as parseLocalSchemaRefPointer } from "./validation-9FSkE8T-.mjs";
3
+ import { r as normalizeLowercaseStringOrEmpty } from "./string-coerce-Cj8sqWHx.mjs";
4
+ import { N as uniqueValues, j as normalizeStringEntries } from "./openai-responses-contracts-Bx-16mnf.mjs";
5
+ import { S as walkSchemaValue, _ as SCHEMA_MAP_KEYS, a as SCHEMA_LITERAL_KEYS, b as evaluateSchemaWalk, c as inlineLocalToolSchemaRefs, d as inheritToolSchemaTruncation, f as reportToolSchemaTruncation, g as SCHEMA_ARRAY_KEYS, h as wasToolSchemaTruncated, i as publishRuntimeToolInputSchema, l as setOwnSchemaProperty, m as truncateToolSchemaDepth, o as canPreserveRootSchemaRefs, s as copySchemaMeta$1, t as getPublishedRuntimeToolInputSchema, v as SCHEMA_NESTED_KEYS, x as walkSchemaArray, y as SCHEMA_OBJECT_KEYS } from "./tool-schema-json-projection-B0hHDV7N.mjs";
6
+ //#region packages/ai/src/providers/openai-function-tool.ts
7
+ const preparedTools = /* @__PURE__ */ new WeakMap();
8
+ const MAX_DESCRIPTOR_VARIANTS = 8;
9
+ /** Reuse wire descriptors only when their parameter owner published immutable JSON. */
10
+ function prepareOpenAIFunctionTool(name, description, parameters, strict) {
11
+ const published = getPublishedRuntimeToolInputSchema(parameters);
12
+ const variants = published ? preparedTools.get(parameters) : void 0;
13
+ const cached = variants?.find(({ responses }) => responses.name === name && responses.description === description && responses.strict === strict);
14
+ if (cached) return cached;
15
+ const descriptor = {
16
+ name,
17
+ description,
18
+ parameters,
19
+ ...strict !== void 0 ? { strict } : {}
20
+ };
21
+ const result = {
22
+ responses: {
23
+ type: "function",
24
+ ...descriptor
25
+ },
26
+ completions: {
27
+ type: "function",
28
+ function: descriptor
29
+ }
30
+ };
31
+ if (published) {
32
+ Object.freeze(descriptor);
33
+ Object.freeze(result.responses);
34
+ Object.freeze(result.completions);
35
+ Object.freeze(result);
36
+ preparedTools.set(parameters, [result, ...variants ?? []].slice(0, MAX_DESCRIPTOR_VARIANTS));
37
+ }
38
+ return result;
39
+ }
40
+ //#endregion
6
41
  //#region packages/ai/src/providers/clean-for-gemini.ts
7
42
  const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
8
43
  "~optional",
@@ -33,7 +68,7 @@ const SCHEMA_META_KEYS = [
33
68
  "title",
34
69
  "default"
35
70
  ];
36
- function copySchemaMeta$1(from, to) {
71
+ function copySchemaMeta(from, to) {
37
72
  for (const key of SCHEMA_META_KEYS) if (key in from && from[key] !== void 0) to[key] = from[key];
38
73
  return to;
39
74
  }
@@ -72,7 +107,7 @@ function isNullSchema(variant) {
72
107
  const typeValue = variant.type;
73
108
  return typeValue === "null" || Array.isArray(typeValue) && typeValue.length === 1 && typeValue[0] === "null";
74
109
  }
75
- function extendSchemaDefs$1(defs, schema) {
110
+ function extendSchemaDefs(defs, schema) {
76
111
  const defsEntry = isRecord(schema.$defs) ? schema.$defs : void 0;
77
112
  const legacyDefsEntry = isRecord(schema.definitions) ? schema.definitions : void 0;
78
113
  if (!defsEntry && !legacyDefsEntry) return defs;
@@ -80,7 +115,7 @@ function extendSchemaDefs$1(defs, schema) {
80
115
  for (const entry of [defsEntry, legacyDefsEntry]) for (const [key, value] of Object.entries(entry ?? {})) next.set(key, value);
81
116
  return next;
82
117
  }
83
- function tryResolveLocalRef$1(ref, defs) {
118
+ function tryResolveLocalRef(ref, defs) {
84
119
  if (!defs) return;
85
120
  const tokens = parseLocalSchemaRefPointer(ref);
86
121
  const [table, name] = tokens ?? [];
@@ -94,13 +129,13 @@ function simplifyUnionVariants(params) {
94
129
  const flattened = tryFlattenLiteralAnyOf(nonNullVariants);
95
130
  if (flattened) return {
96
131
  kind: "simplified",
97
- value: copySchemaMeta$1(obj, flattened)
132
+ value: copySchemaMeta(obj, flattened)
98
133
  };
99
134
  if (stripped && nonNullVariants.length === 1) {
100
135
  const lone = nonNullVariants[0];
101
136
  return {
102
137
  kind: "simplified",
103
- value: isRecord(lone) ? copySchemaMeta$1(obj, { ...lone }) : lone
138
+ value: isRecord(lone) ? copySchemaMeta(obj, { ...lone }) : lone
104
139
  };
105
140
  }
106
141
  return {
@@ -120,22 +155,26 @@ function sanitizeRequiredFields(schema) {
120
155
  else delete schema.required;
121
156
  return schema;
122
157
  }
123
- function* cleanSchemaForGeminiWithDefs(schema, defs, refStack, ancestors) {
158
+ function* cleanSchemaForGeminiWithDefs(schema, defs, refStack, ancestors, budget, depth = 0) {
159
+ if (depth > 128) {
160
+ budget.truncated = true;
161
+ return {};
162
+ }
124
163
  return yield walkSchemaValue(schema, ancestors, function* (obj) {
125
- const nextDefs = extendSchemaDefs$1(defs, obj);
126
- const visit = (value) => cleanSchemaForGeminiWithDefs(value, nextDefs, refStack, ancestors);
164
+ const nextDefs = extendSchemaDefs(defs, obj);
165
+ const visit = (value) => cleanSchemaForGeminiWithDefs(value, nextDefs, refStack, ancestors, budget, depth + 1);
127
166
  const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
128
167
  if (refValue) {
129
168
  if (refStack?.has(refValue)) return {};
130
- const resolved = tryResolveLocalRef$1(refValue, nextDefs);
169
+ const resolved = tryResolveLocalRef(refValue, nextDefs);
131
170
  if (resolved) {
132
171
  const nextRefStack = new Set(refStack);
133
172
  nextRefStack.add(refValue);
134
- const cleaned = yield cleanSchemaForGeminiWithDefs(resolved, nextDefs, nextRefStack, /* @__PURE__ */ new Set());
173
+ const cleaned = yield cleanSchemaForGeminiWithDefs(resolved, nextDefs, nextRefStack, /* @__PURE__ */ new Set(), budget, depth + 1);
135
174
  if (!cleaned || typeof cleaned !== "object" || Array.isArray(cleaned)) return cleaned;
136
- return copySchemaMeta$1(obj, { ...cleaned });
175
+ return copySchemaMeta(obj, { ...cleaned });
137
176
  }
138
- return copySchemaMeta$1(obj, {});
177
+ return copySchemaMeta(obj, {});
139
178
  }
140
179
  const unions = {};
141
180
  for (const key of ["anyOf", "oneOf"]) {
@@ -201,202 +240,29 @@ function flattenUnionFallback(obj, variants) {
201
240
  const types = new Set(objects.map((v) => v.type).filter(Boolean));
202
241
  const first = objects[0];
203
242
  const type = types.size === 1 ? Array.from(types)[0] : first?.type;
204
- return copySchemaMeta$1(obj, objects.length === 1 ? { ...first } : type ? { type } : {});
205
- }
206
- function cleanSchemaForGemini(schema) {
207
- return evaluateSchemaWalk(cleanSchemaForGeminiWithDefs(schema, void 0, void 0, /* @__PURE__ */ new Set()));
208
- }
209
- //#endregion
210
- //#region packages/ai/src/providers/tool-schema-refs.ts
211
- function setOwnSchemaProperty(target, key, value) {
212
- Object.defineProperty(target, key, {
213
- value,
214
- enumerable: true,
215
- configurable: true,
216
- writable: true
217
- });
218
- }
219
- function copySchemaMeta(from, to) {
220
- for (const key of [
221
- "title",
222
- "description",
223
- "default"
224
- ]) if (key in from && from[key] !== void 0) to[key] = from[key];
225
- }
226
- function extendSchemaDefs(defs, schema) {
227
- const defsEntry = isRecord(schema.$defs) ? schema.$defs : void 0;
228
- const legacyDefsEntry = isRecord(schema.definitions) ? schema.definitions : void 0;
229
- if (!defsEntry && !legacyDefsEntry) return defs;
230
- const next = {
231
- $defs: new Map(defs?.$defs),
232
- definitions: new Map(defs?.definitions)
233
- };
234
- if (defsEntry) for (const [key, value] of Object.entries(defsEntry)) next.$defs.set(key, value);
235
- if (legacyDefsEntry) for (const [key, value] of Object.entries(legacyDefsEntry)) next.definitions.set(key, value);
236
- return next;
237
- }
238
- function resolveJsonPointerPath(value, tokens) {
239
- let current = value;
240
- for (const key of tokens) {
241
- if (!current || typeof current !== "object") return;
242
- if (Array.isArray(current)) {
243
- const index = /^(?:0|[1-9]\d*)$/.test(key) ? Number(key) : -1;
244
- if (index < 0 || index >= current.length) return;
245
- current = current[index];
246
- continue;
247
- }
248
- if (!isRecord(current) || !Object.hasOwn(current, key)) return;
249
- current = current[key];
250
- }
251
- return current;
252
- }
253
- const SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
254
- "$defs",
255
- "definitions",
256
- "dependentSchemas",
257
- "patternProperties",
258
- "properties"
259
- ]);
260
- const SCHEMA_OBJECT_KEYS = /* @__PURE__ */ new Set([
261
- "additionalProperties",
262
- "contains",
263
- "else",
264
- "if",
265
- "items",
266
- "not",
267
- "propertyNames",
268
- "then"
269
- ]);
270
- const SCHEMA_ARRAY_KEYS = /* @__PURE__ */ new Set([
271
- "allOf",
272
- "anyOf",
273
- "items",
274
- "oneOf",
275
- "prefixItems"
276
- ]);
277
- const SCHEMA_LITERAL_KEYS = /* @__PURE__ */ new Set([
278
- "const",
279
- "default",
280
- "enum",
281
- "examples"
282
- ]);
283
- function tryResolveLocalRef(ref, defs, rootDocument) {
284
- const tokens = parseLocalSchemaRefPointer(ref);
285
- if (!tokens) return;
286
- const [table, name, ...remainingPath] = tokens;
287
- if (defs && name && (table === "$defs" || table === "definitions")) {
288
- const resolved = (table === "$defs" ? defs.$defs : defs.definitions).get(name);
289
- if (resolved !== void 0) return resolveJsonPointerPath(resolved, remainingPath);
290
- }
291
- return resolveJsonPointerPath(rootDocument, tokens);
292
- }
293
- function inlineLocalSchemaRefsWithDefs(schema, defs, refStack, state, rootDocument) {
294
- if (Array.isArray(schema)) return schema.map((entry) => inlineLocalSchemaRefsWithDefs(entry, defs, refStack, state, rootDocument));
295
- if (!isRecord(schema)) return schema;
296
- const obj = schema;
297
- const nextDefs = extendSchemaDefs(defs, obj);
298
- const refValue = typeof obj.$ref === "string" ? obj.$ref : void 0;
299
- if (refValue) {
300
- if (refStack?.has(refValue)) return {};
301
- const resolved = tryResolveLocalRef(refValue, nextDefs, rootDocument);
302
- if (resolved === void 0) {
303
- if (refValue.startsWith("#/") || parseLocalSchemaRefPointer(refValue)) state.unresolvedLocalRefs = true;
304
- return { ...obj };
305
- }
306
- const nextRefStack = new Set(refStack);
307
- nextRefStack.add(refValue);
308
- const inlined = inlineLocalSchemaRefsWithDefs(resolved, nextDefs, nextRefStack, state, rootDocument);
309
- if (!isRecord(inlined)) return inlined;
310
- const result = { ...inlined };
311
- copySchemaMeta(obj, result);
312
- if (obj.nullable === true) result.nullable = true;
313
- return result;
314
- }
315
- const result = {};
316
- for (const [key, value] of Object.entries(obj)) {
317
- if (key === "$defs" || key === "definitions" || key === "components") continue;
318
- let next = value;
319
- if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
320
- const entries = Object.entries(value);
321
- for (const entry of entries) entry[1] = inlineLocalSchemaRefsWithDefs(entry[1], nextDefs, refStack, state, rootDocument);
322
- next = Object.fromEntries(entries);
323
- } else if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) next = inlineLocalSchemaRefsWithDefs(value, nextDefs, refStack, state, rootDocument);
324
- else if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) next = value.map((entry) => inlineLocalSchemaRefsWithDefs(entry, nextDefs, refStack, state, rootDocument));
325
- setOwnSchemaProperty(result, key, next);
326
- }
327
- if (state.unresolvedLocalRefs) {
328
- for (const key of [
329
- "$defs",
330
- "definitions",
331
- "components"
332
- ]) if (key in obj) result[key] = obj[key];
333
- }
334
- return result;
335
- }
336
- /** Inline local $ref pointers so providers receive self-contained tool schemas. */
337
- function inlineLocalToolSchemaRefs(schema) {
338
- if (!schema || typeof schema !== "object") return schema;
339
- const schemaRecord = schema;
340
- return inlineLocalSchemaRefsWithDefs(schema, Array.isArray(schema) ? extendSchemaDefs(void 0, schemaRecord) : void 0, void 0, { unresolvedLocalRefs: false }, schema);
243
+ return copySchemaMeta(obj, objects.length === 1 ? { ...first } : type ? { type } : {});
341
244
  }
342
- /** Keep compact root definitions. Fall back for scopes or refs we must rewrite. */
343
- function canPreserveRootSchemaRefs(schema) {
344
- if (!isRecord(schema) || schema.type !== "object" || !isRecord(schema.properties) || ["$defs", "definitions"].some((key) => key in schema && !isRecord(schema[key])) || [
345
- "anyOf",
346
- "oneOf",
347
- "allOf"
348
- ].some((key) => Array.isArray(schema[key])) || "$ref" in schema) return false;
349
- let hasRefs = false;
350
- const ancestors = /* @__PURE__ */ new Set();
351
- function visit(node, inDefinitions = false) {
352
- if (!isRecord(node)) return true;
353
- if (ancestors.has(node) || "$id" in node || "id" in node || "components" in node || node !== schema && ("$defs" in node || "definitions" in node)) return false;
354
- if ("$ref" in node) {
355
- if (typeof node.$ref !== "string" || !/^#\/(\$defs|definitions)\/[^/]+$/.test(node.$ref) || node.nullable === true || tryResolveLocalRef(node.$ref, void 0, schema) === void 0) return false;
356
- hasRefs ||= !inDefinitions;
357
- }
358
- ancestors.add(node);
359
- try {
360
- for (const [key, value] of Object.entries(node)) if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
361
- const childInDefinitions = inDefinitions || key === "$defs" || key === "definitions";
362
- if (!Object.values(value).every((entry) => visit(entry, childInDefinitions))) return false;
363
- } else if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) {
364
- if (!value.every((entry) => visit(entry, inDefinitions))) return false;
365
- } else if (SCHEMA_OBJECT_KEYS.has(key) && !visit(value, inDefinitions)) return false;
366
- return true;
367
- } finally {
368
- ancestors.delete(node);
369
- }
370
- }
371
- return visit(schema) && hasRefs;
245
+ function cleanSchemaForGemini(schema, toolName) {
246
+ const budget = { truncated: false };
247
+ const boundedSchema = truncateToolSchemaDepth(schema, toolName);
248
+ const normalized = evaluateSchemaWalk(cleanSchemaForGeminiWithDefs(boundedSchema, void 0, void 0, /* @__PURE__ */ new Set(), budget));
249
+ if (budget.truncated) reportToolSchemaTruncation(schema, toolName);
250
+ return inheritToolSchemaTruncation(boundedSchema, normalized, budget.truncated);
372
251
  }
373
252
  //#endregion
374
253
  //#region packages/ai/src/providers/clean-for-llamacpp-gbnf.ts
375
254
  /** llama.cpp rejects grammar repetitions whose expanded rule count reaches 2000. */
376
255
  const LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD = 2e3;
377
- const SCHEMA_CHILD_KEYS = /* @__PURE__ */ new Set([
378
- "additionalItems",
379
- "additionalProperties",
380
- "allOf",
381
- "anyOf",
382
- "contains",
383
- "else",
384
- "if",
385
- "items",
386
- "not",
387
- "oneOf",
388
- "prefixItems",
389
- "propertyNames",
390
- "then",
391
- "unevaluatedItems",
392
- "unevaluatedProperties"
393
- ]);
394
256
  /** Removes JSON Schema constraints that llama.cpp cannot compile into GBNF. */
395
- function cleanSchemaForLlamacppGbnf(schema) {
257
+ function cleanSchemaForLlamacppGbnf(schema, toolName) {
258
+ const bounded = truncateToolSchemaDepth(schema, toolName);
259
+ return inheritToolSchemaTruncation(bounded, cleanSchema(bounded));
260
+ }
261
+ function cleanSchema(schema) {
396
262
  if (Array.isArray(schema)) {
397
263
  let changed = false;
398
264
  const entries = schema.map((entry) => {
399
- const next = cleanSchemaForLlamacppGbnf(entry);
265
+ const next = cleanSchema(entry);
400
266
  changed ||= next !== entry;
401
267
  return next;
402
268
  });
@@ -418,12 +284,12 @@ function cleanSchemaForLlamacppGbnf(schema) {
418
284
  if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
419
285
  let mapChanged = false;
420
286
  next = Object.fromEntries(Object.entries(value).map(([childKey, childValue]) => {
421
- const cleanedChild = cleanSchemaForLlamacppGbnf(childValue);
287
+ const cleanedChild = cleanSchema(childValue);
422
288
  mapChanged ||= cleanedChild !== childValue;
423
289
  return [childKey, cleanedChild];
424
290
  }));
425
291
  if (!mapChanged) next = value;
426
- } else if (SCHEMA_CHILD_KEYS.has(key)) next = cleanSchemaForLlamacppGbnf(value);
292
+ } else if (key !== "contentSchema" && SCHEMA_NESTED_KEYS.has(key)) next = cleanSchema(value);
427
293
  cleaned[key] = next;
428
294
  changed ||= next !== value;
429
295
  }
@@ -438,12 +304,12 @@ function collectSchemaViolations(node, path, violations) {
438
304
  if ("pattern" in node) violations.push(`${path}.pattern`);
439
305
  if (typeof node.maxLength === "number" && node.maxLength >= 2e3) violations.push(`${path}.maxLength`);
440
306
  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);
441
- else if (SCHEMA_CHILD_KEYS.has(key)) collectSchemaViolations(value, `${path}.${key}`, violations);
307
+ else if (key !== "contentSchema" && SCHEMA_NESTED_KEYS.has(key)) collectSchemaViolations(value, `${path}.${key}`, violations);
442
308
  }
443
309
  /** Reports schema paths that llama.cpp cannot compile into GBNF. */
444
310
  function findLlamacppGbnfSchemaViolations(schema, path) {
445
311
  const violations = [];
446
- collectSchemaViolations(schema, path, violations);
312
+ collectSchemaViolations(truncateToolSchemaDepth(schema), path, violations);
447
313
  return violations;
448
314
  }
449
315
  //#endregion
@@ -454,12 +320,12 @@ function* stripSchemaKeywords(schema, unsupportedKeywords, ancestors) {
454
320
  const cleaned = {};
455
321
  for (const [key, value] of Object.entries(obj)) {
456
322
  if (unsupportedKeywords.has(key)) continue;
457
- if (SCHEMA_MAP_KEYS$1.has(key) && value && typeof value === "object" && !Array.isArray(value)) {
323
+ if (SCHEMA_MAP_KEYS.has(key) && value && typeof value === "object" && !Array.isArray(value)) {
458
324
  const entries = Object.entries(value);
459
325
  for (const entry of entries) entry[1] = yield visit(entry[1]);
460
326
  cleaned[key] = Object.fromEntries(entries);
461
- } else if (SCHEMA_ARRAY_KEYS$1.has(key) && Array.isArray(value)) cleaned[key] = yield walkSchemaArray(value, visit);
462
- else if (SCHEMA_OBJECT_KEYS$1.has(key) && value && typeof value === "object") cleaned[key] = yield visit(value);
327
+ } else if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) cleaned[key] = yield walkSchemaArray(value, visit);
328
+ else if (SCHEMA_OBJECT_KEYS.has(key) && value && typeof value === "object") cleaned[key] = yield visit(value);
463
329
  else cleaned[key] = value;
464
330
  }
465
331
  return cleaned;
@@ -467,7 +333,8 @@ function* stripSchemaKeywords(schema, unsupportedKeywords, ancestors) {
467
333
  }
468
334
  /** Remove schema keywords unsupported by a target provider/tool surface. */
469
335
  function stripUnsupportedSchemaKeywords(schema, unsupportedKeywords) {
470
- return evaluateSchemaWalk(stripSchemaKeywords(schema, unsupportedKeywords, /* @__PURE__ */ new Set()));
336
+ const bounded = truncateToolSchemaDepth(schema);
337
+ return inheritToolSchemaTruncation(bounded, evaluateSchemaWalk(stripSchemaKeywords(bounded, unsupportedKeywords, /* @__PURE__ */ new Set())));
471
338
  }
472
339
  //#endregion
473
340
  //#region packages/ai/src/providers/tool-schema-normalization-cache.ts
@@ -505,19 +372,25 @@ function createToolSchemaNormalizationCache(maxEntries) {
505
372
  return {
506
373
  get(source, key) {
507
374
  const prepared = preparedSchemas?.get(source);
508
- if (!prepared) return directCache.get(source, key);
375
+ if (!prepared) return inheritToolSchemaTruncation(source, directCache.get(source, key));
509
376
  const entry = preparedCache.get(prepared.source, key);
510
- return entry?.inputJson === prepared.inputJson ? JSON.parse(entry.outputJson) : void 0;
377
+ return entry?.inputJson === prepared.inputJson && entry.inputTruncated === wasToolSchemaTruncated(source) ? inheritToolSchemaTruncation(source, JSON.parse(entry.outputJson), entry.truncated) : void 0;
511
378
  },
512
379
  remember(source, key, value) {
380
+ const result = inheritToolSchemaTruncation(source, value);
513
381
  const prepared = preparedSchemas?.get(source);
514
- if (!prepared) return directCache.remember(source, key, value);
515
- const outputJson = JSON.stringify(value);
382
+ if (!prepared) {
383
+ const published = getPublishedRuntimeToolInputSchema(source) ? publishRuntimeToolInputSchema(result) : void 0;
384
+ return directCache.remember(source, key, published?.violations.length === 0 ? published.schema : result);
385
+ }
386
+ const outputJson = JSON.stringify(result);
516
387
  if (outputJson !== void 0) preparedCache.remember(prepared.source, key, {
517
388
  inputJson: prepared.inputJson,
518
- outputJson
389
+ inputTruncated: wasToolSchemaTruncated(source),
390
+ outputJson,
391
+ truncated: wasToolSchemaTruncated(result)
519
392
  });
520
- return value;
393
+ return result;
521
394
  }
522
395
  };
523
396
  }
@@ -545,12 +418,36 @@ const OPENAI_NULLABLE_ANNOTATION_KEYS = /* @__PURE__ */ new Set([
545
418
  "format",
546
419
  "title"
547
420
  ]);
548
- function normalizeToolSchema(schema, profile, depth = 0) {
421
+ function inferUnionBranchType(schema) {
422
+ const types = /* @__PURE__ */ new Set();
423
+ const values = "const" in schema ? [schema.const] : schema.enum;
424
+ if (Array.isArray(values)) for (const value of values) types.add(value === null ? "null" : Array.isArray(value) ? "array" : typeof value);
425
+ for (const [type, keywords] of [
426
+ ["number", [
427
+ "minimum",
428
+ "maximum",
429
+ "exclusiveMinimum",
430
+ "exclusiveMaximum",
431
+ "multipleOf"
432
+ ]],
433
+ ["string", [
434
+ "minLength",
435
+ "maxLength",
436
+ "pattern",
437
+ "format"
438
+ ]],
439
+ ["object", ["properties", "required"]],
440
+ ["array", ["items"]]
441
+ ]) if (keywords.some((key) => key in schema)) types.add(type);
442
+ return types.size === 1 ? types.values().next().value : void 0;
443
+ }
444
+ function normalizeToolSchemaRecursive(schema, profile, depth = 0, inferBranchType = false) {
445
+ const mapProfile = profile === "strict-map" ? "strict" : profile === "compat-map" ? "compat" : profile === "openapi-map" ? "openapi" : profile === "moonshot-map" ? "moonshot" : void 0;
549
446
  if (Array.isArray(schema)) {
550
- if (profile === "compat-map" || profile === "openapi-map") return schema;
447
+ if (mapProfile) return schema;
551
448
  let changed = false;
552
449
  const normalized = schema.map((entry) => {
553
- const next = normalizeToolSchema(entry, profile, profile === "strict" ? depth : 1);
450
+ const next = normalizeToolSchemaRecursive(entry, profile, profile === "strict" ? depth : 1, inferBranchType);
554
451
  changed ||= next !== entry;
555
452
  return next;
556
453
  });
@@ -578,10 +475,10 @@ function normalizeToolSchema(schema, profile, depth = 0) {
578
475
  continue;
579
476
  }
580
477
  let next = value;
581
- if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) next = normalizeToolSchema(value, "openapi-map", 1);
582
- else if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) next = normalizeToolSchema(value, profile, 1);
478
+ if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) next = normalizeToolSchemaRecursive(value, "openapi-map", 1);
479
+ else if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) next = normalizeToolSchemaRecursive(value, profile, 1);
583
480
  else if (SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) {
584
- const nextEntries = value.map((entry) => normalizeToolSchema(entry, profile, 1));
481
+ const nextEntries = value.map((entry) => normalizeToolSchemaRecursive(entry, profile, 1));
585
482
  changed ||= nextEntries.some((entry, index) => entry !== value[index]);
586
483
  entries.push([key, nextEntries]);
587
484
  continue;
@@ -591,15 +488,27 @@ function normalizeToolSchema(schema, profile, depth = 0) {
591
488
  continue;
592
489
  }
593
490
  let next = value;
594
- if (profile === "strict") next = normalizeToolSchema(value, profile, key === "properties" ? depth : depth + 1);
595
- else if (profile === "compat-map" || profile === "openapi-map") next = normalizeToolSchema(value, profile === "compat-map" ? "compat" : "openapi", 1);
596
- else if (SCHEMA_MAP_KEYS$1.has(key)) next = normalizeToolSchema(value, "compat-map", 1);
597
- else if (SCHEMA_NESTED_KEYS.has(key)) next = normalizeToolSchema(value, "compat", 1);
491
+ if (profile === "strict") {
492
+ if (SCHEMA_MAP_KEYS.has(key)) next = normalizeToolSchemaRecursive(value, "strict-map", depth);
493
+ else if (SCHEMA_NESTED_KEYS.has(key)) next = normalizeToolSchemaRecursive(value, profile, depth + 1);
494
+ } else if (mapProfile) next = normalizeToolSchemaRecursive(value, mapProfile, profile === "strict-map" ? depth + 1 : 1);
495
+ else if (SCHEMA_MAP_KEYS.has(key)) next = normalizeToolSchemaRecursive(value, profile === "moonshot" ? "moonshot-map" : "compat-map", 1);
496
+ else if (SCHEMA_NESTED_KEYS.has(key)) next = normalizeToolSchemaRecursive(value, profile === "moonshot" ? "moonshot" : "compat", 1, profile === "moonshot" && (key === "anyOf" || key === "oneOf"));
598
497
  changed ||= next !== value;
599
498
  entries.push([key, next]);
600
499
  }
601
500
  const normalized = Object.fromEntries(entries);
602
- if (profile === "compat-map" || profile === "openapi-map") return changed ? normalized : schema;
501
+ if (mapProfile) return changed ? normalized : schema;
502
+ if (profile === "moonshot") {
503
+ if (inferBranchType && !("type" in normalized)) {
504
+ const type = inferUnionBranchType(normalized);
505
+ if (type) {
506
+ normalized.type = type;
507
+ changed = true;
508
+ }
509
+ }
510
+ return changed ? normalized : schema;
511
+ }
603
512
  if (profile === "openapi") {
604
513
  if (nullable) {
605
514
  if ([
@@ -609,7 +518,7 @@ function normalizeToolSchema(schema, profile, depth = 0) {
609
518
  ].some(Array.isArray)) {
610
519
  if (Array.isArray(normalized.anyOf) && normalized.anyOf.some(isNullSchemaLike) || Array.isArray(normalized.oneOf) && normalized.oneOf.some(isNullSchemaLike)) return normalized;
611
520
  const wrapped = { anyOf: [normalized, { type: "null" }] };
612
- copySchemaMeta(normalized, wrapped);
521
+ copySchemaMeta$1(normalized, wrapped);
613
522
  return wrapped;
614
523
  }
615
524
  const type = normalized.type;
@@ -651,6 +560,10 @@ function normalizeToolSchema(schema, profile, depth = 0) {
651
560
  }
652
561
  return changed ? normalized : schema;
653
562
  }
563
+ function normalizeToolSchema(schema, profile) {
564
+ const bounded = truncateToolSchemaDepth(schema);
565
+ return inheritToolSchemaTruncation(bounded, normalizeToolSchemaRecursive(bounded, profile));
566
+ }
654
567
  //#endregion
655
568
  //#region packages/ai/src/providers/agent-tools-parameter-schema.ts
656
569
  /**
@@ -783,6 +696,9 @@ function normalizeArraySchemaItems(schema, mode) {
783
696
  }
784
697
  /** Return a provider-compatible JSON schema for a model-facing tool. */
785
698
  function normalizeToolParameterSchema(schema, options) {
699
+ const published = getPublishedRuntimeToolInputSchema(schema);
700
+ const boundedSchema = published ? schema : truncateToolSchemaDepth(schema, options?.toolName);
701
+ if (published && wasToolSchemaTruncated(schema)) reportToolSchemaTruncation(schema, options?.toolName);
786
702
  const normalizedProvider = normalizeLowercaseStringOrEmpty(options?.modelProvider);
787
703
  const normalizedModelId = normalizeLowercaseStringOrEmpty(options?.modelId);
788
704
  const normalizedToolSchemaProfile = normalizeLowercaseStringOrEmpty(options?.modelCompat?.toolSchemaProfile);
@@ -798,9 +714,11 @@ function normalizeToolParameterSchema(schema, options) {
798
714
  ]) : "";
799
715
  if (source) {
800
716
  const cached = toolParameterSchemaCache.get(source, cacheKey);
801
- if (cached) return cached;
717
+ if (cached) {
718
+ if (wasToolSchemaTruncated(cached)) reportToolSchemaTruncation(source, options?.toolName);
719
+ return cached;
720
+ }
802
721
  }
803
- const rememberResult = (normalized) => source ? toolParameterSchemaCache.remember(source, cacheKey, normalized) : normalized;
804
722
  const isGeminiProvider = normalizedProvider.includes("google") || normalizedProvider.includes("gemini") || isGeminiModelId(normalizedModelId) || normalizedToolSchemaProfile === "gemini";
805
723
  const isAnthropicProvider = normalizedProvider.includes("anthropic");
806
724
  const isLlamacppGbnfProfile = normalizedToolSchemaProfile === "llamacpp";
@@ -808,7 +726,11 @@ function normalizeToolParameterSchema(schema, options) {
808
726
  "$ref",
809
727
  "$defs",
810
728
  "definitions"
811
- ].some((key) => unsupportedToolSchemaKeywords.has(key)) && canPreserveRootSchemaRefs(schema) ? schema : inlineLocalToolSchemaRefs(schema), "openapi");
729
+ ].some((key) => unsupportedToolSchemaKeywords.has(key)) && canPreserveRootSchemaRefs(boundedSchema) ? boundedSchema : inlineLocalToolSchemaRefs(boundedSchema, options?.toolName), "openapi");
730
+ const rememberResult = (normalized) => {
731
+ const result = inheritToolSchemaTruncation(inlinedSchema, normalized);
732
+ return source ? toolParameterSchemaCache.remember(source, cacheKey, result) : result;
733
+ };
812
734
  const schemaRecord = inlinedSchema && typeof inlinedSchema === "object" ? inlinedSchema : void 0;
813
735
  if (!schemaRecord) return rememberResult(inlinedSchema);
814
736
  function applyProviderCleaning(s) {
@@ -897,9 +819,13 @@ function hasRegexLookaround(pattern) {
897
819
  }
898
820
  /** Finds schema paths that violate OpenAI strict tool-schema requirements. */
899
821
  function findOpenAIStrictSchemaViolations(schema, path, options) {
822
+ const bounded = truncateToolSchemaDepth(schema);
823
+ return wasToolSchemaTruncated(bounded) ? [`${path}.depth`] : collectStrictSchemaViolations(bounded, path, options);
824
+ }
825
+ function collectStrictSchemaViolations(schema, path, options) {
900
826
  if (Array.isArray(schema)) {
901
827
  if (options?.requireObjectRoot) return [`${path}.type`];
902
- return schema.flatMap((item, index) => findOpenAIStrictSchemaViolations(item, `${path}[${index}]`));
828
+ return schema.flatMap((item, index) => collectStrictSchemaViolations(item, `${path}[${index}]`));
903
829
  }
904
830
  if (!schema || typeof schema !== "object") return options?.requireObjectRoot ? [`${path}.type`] : [];
905
831
  const record = schema;
@@ -921,20 +847,21 @@ function findOpenAIStrictSchemaViolations(schema, path, options) {
921
847
  for (const key of Object.keys(properties)) if (!requiredSet.has(key)) violations.push(`${path}.required.${key}`);
922
848
  }
923
849
  }
924
- for (const key of SCHEMA_MAP_KEYS$1) {
850
+ for (const key of SCHEMA_MAP_KEYS) {
925
851
  const schemaMap = record[key];
926
852
  if (!isRecord(schemaMap)) continue;
927
- for (const [entryKey, value] of Object.entries(schemaMap)) violations.push(...findOpenAIStrictSchemaViolations(value, `${path}.${key}.${entryKey}`));
853
+ for (const [entryKey, value] of Object.entries(schemaMap)) violations.push(...collectStrictSchemaViolations(value, `${path}.${key}.${entryKey}`));
928
854
  }
929
855
  for (const key of SCHEMA_NESTED_KEYS) {
930
856
  const value = record[key];
931
- if (value && typeof value === "object") violations.push(...findOpenAIStrictSchemaViolations(value, `${path}.${key}`));
857
+ if (value && typeof value === "object") violations.push(...collectStrictSchemaViolations(value, `${path}.${key}`));
932
858
  }
933
859
  return violations;
934
860
  }
935
861
  //#endregion
936
862
  //#region packages/ai/src/providers/openai-tool-schema.ts
937
863
  const strictOpenAISchemaCache = createToolSchemaNormalizationCache(8);
864
+ const publishedStrictCompatibility = /* @__PURE__ */ new WeakMap();
938
865
  function resolveToolSchemaModelCompat(compat) {
939
866
  if (!compat) return;
940
867
  const unsupportedToolSchemaKeywords = Array.isArray(compat.unsupportedToolSchemaKeywords) ? compat.unsupportedToolSchemaKeywords.filter((keyword) => typeof keyword === "string") : [];
@@ -968,7 +895,13 @@ function normalizeOpenAIStrictToolParameters(schema, strict, modelCompat) {
968
895
  }
969
896
  /** Returns whether a schema already satisfies OpenAI strict tool-schema constraints. */
970
897
  function isStrictOpenAIJsonSchemaCompatible(schema) {
971
- return findOpenAIStrictSchemaViolations(normalizeStrictOpenAIJsonSchema(schema), "parameters").length === 0;
898
+ const publishedSchema = getPublishedRuntimeToolInputSchema(schema)?.projection.schema;
899
+ const source = publishedSchema && typeof publishedSchema === "object" ? publishedSchema : void 0;
900
+ const cached = source ? publishedStrictCompatibility.get(source) : void 0;
901
+ if (cached !== void 0) return cached;
902
+ const compatible = findOpenAIStrictSchemaViolations(normalizeStrictOpenAIJsonSchema(schema), "parameters").length === 0;
903
+ if (source) publishedStrictCompatibility.set(source, compatible);
904
+ return compatible;
972
905
  }
973
906
  /** Returns strict-schema diagnostics for an already materialized OpenAI tool projection. */
974
907
  function findOpenAIStrictToolProjectionDiagnostics(projection) {
@@ -991,4 +924,4 @@ function resolveOpenAIProjectedToolsStrictToolFlag(projection, strict) {
991
924
  return projection.tools.every((tool) => isStrictOpenAIJsonSchemaCompatible(tool.parameters));
992
925
  }
993
926
  //#endregion
994
- export { GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as _, resolveOpenAIProjectedToolsStrictToolFlag as a, extractToolSchemaModelCompat as c, shouldOmitEmptyArrayItems as d, withPreparedToolSchemaNormalization as f, findLlamacppGbnfSchemaViolations as g, cleanSchemaForLlamacppGbnf as h, normalizeStrictOpenAIJsonSchema as i, normalizeToolParameterSchema as l, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as m, isStrictOpenAIJsonSchemaCompatible as n, findOpenAIStrictSchemaViolations as o, stripUnsupportedSchemaKeywords as p, normalizeOpenAIStrictToolParameters as r, normalizeOpenAIStrictCompatSchema as s, findOpenAIStrictToolProjectionDiagnostics as t, resolveUnsupportedToolSchemaKeywords as u, cleanSchemaForGemini as v };
927
+ export { findLlamacppGbnfSchemaViolations as _, resolveOpenAIProjectedToolsStrictToolFlag as a, prepareOpenAIFunctionTool as b, extractToolSchemaModelCompat as c, shouldOmitEmptyArrayItems as d, normalizeToolSchema as f, cleanSchemaForLlamacppGbnf as g, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as h, normalizeStrictOpenAIJsonSchema as i, normalizeToolParameterSchema as l, stripUnsupportedSchemaKeywords as m, isStrictOpenAIJsonSchemaCompatible as n, findOpenAIStrictSchemaViolations as o, withPreparedToolSchemaNormalization as p, normalizeOpenAIStrictToolParameters as r, normalizeOpenAIStrictCompatSchema as s, findOpenAIStrictToolProjectionDiagnostics as t, resolveUnsupportedToolSchemaKeywords as u, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as v, cleanSchemaForGemini as y };