@openclaw/ai 2026.9.6 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{anthropic-DZQ_7gD1.mjs → anthropic-Cw2pgccz.mjs} +37 -66
- package/dist/{anthropic-payload-policy-DyfwikYJ.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +7 -5
- package/dist/{anthropic-stream-reducer-D6ZI1wwj.mjs → anthropic-stream-reducer-D9MCkl8Z.mjs} +192 -261
- package/dist/{api-registry-C2T3lTV7.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
- package/dist/{azure-openai-responses-DS86GYzq.mjs → azure-openai-responses-BwT3-X8P.mjs} +22 -33
- package/dist/{base64-CPmadnUf.mjs → base64-C1PsYcRQ.mjs} +15 -9
- package/dist/{diagnostics-CH8j2wIG.mjs → diagnostics-CJaB6g8J.mjs} +3 -3
- package/dist/diagnostics.d.mts +4 -4
- package/dist/diagnostics.mjs +2 -2
- package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
- package/dist/event-stream-CMQfX_yr.d.mts +1 -0
- package/dist/{event-stream-CjnIZZst.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
- package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
- package/dist/event-stream.d.mts +2 -2
- package/dist/event-stream.mjs +1 -1
- package/dist/{google-BZJFjhuC.mjs → google-BfapkS_K.mjs} +8 -11
- package/dist/google-interactions-DW3iXzjc.mjs +574 -0
- package/dist/{google-messages-DB7GKkDk.mjs → google-messages-CtjVtVot.mjs} +35 -71
- package/dist/{google-shared-Bok4I6zB.mjs → google-shared-Y2YfotEu.mjs} +43 -47
- package/dist/{google-vertex-3eVNR2qW.mjs → google-vertex-Dov4kBWu.mjs} +16 -30
- package/dist/{host-yTvBrYM2.mjs → host-CHi3X87F.mjs} +29 -188
- package/dist/{host-policy-DZO3oPPk.mjs → host-policy-BOAwRg_M.mjs} +2 -14
- package/dist/{host-DH-Z-LDb.d.mts → host-rxlNaBwm.d.mts} +9 -3
- package/dist/{index-C25RT6bP.d.mts → index-D6KsSE74.d.mts} +28 -8
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +6 -6
- package/dist/internal/anthropic.d.mts +8 -7
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/openai-completions-compat.d.mts +1 -1
- package/dist/internal/openai-completions-compat.mjs +1 -1
- package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
- package/dist/internal/openai-responses-payload-policy.mjs +2 -2
- package/dist/internal/openai.d.mts +31 -8
- package/dist/internal/openai.mjs +13 -13
- package/dist/internal/runtime.d.mts +31 -70
- package/dist/internal/runtime.mjs +10 -65
- package/dist/internal/shared.d.mts +14 -12
- package/dist/internal/shared.mjs +5 -4
- package/dist/internal/tool-schema.d.mts +1 -1
- package/dist/internal/tool-schema.mjs +2 -2
- package/dist/{mistral-C_13dVBn.mjs → mistral-RS6mboC-.mjs} +46 -93
- package/dist/{openai-chatgpt-responses-sTxPl4zM.mjs → openai-chatgpt-responses-CYbidtrn.mjs} +26 -30
- package/dist/{openai-completions-BO6D_hrB.mjs → openai-completions-D14ihPYk.mjs} +14 -12
- package/dist/{openai-completions-compat-CUollwl6.mjs → openai-completions-compat-BOVWBZDn.mjs} +3 -5
- package/dist/{openai-completions-compat-DfJG1wSO.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
- package/dist/{openai-completions-stream-BpuJ0ZOA.mjs → openai-completions-stream-CDCuw3DP.mjs} +101 -173
- package/dist/{openai-prompt-cache-C4RHdN4n.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
- package/dist/{openai-prompt-cache-CjV_2IRI.mjs → openai-prompt-cache-D2V7MqR7.mjs} +1 -1
- package/dist/{openai-provider-client-BP8J1aeg.mjs → openai-provider-client-CwfsGBbA.mjs} +2 -2
- package/dist/{openai-reasoning-effort-ash8dPrd.mjs → openai-reasoning-effort-ConhwkeX.mjs} +2 -1
- package/dist/{openai-responses-BJ_IEoMU.mjs → openai-responses-CKCBEc2W.mjs} +12 -11
- package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
- package/dist/{openai-responses-compaction-window-BiNCT0bS.mjs → openai-responses-compaction-window-UNK1GDpy.mjs} +5 -5
- package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
- package/dist/{openai-responses-contracts-B1ENJFpI.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
- package/dist/{openai-responses-prompt-observer-internal-DPHWgbBH.mjs → openai-responses-prompt-observer-internal-iAqLb4tk.mjs} +12 -12
- package/dist/{openai-responses-request-lifecycle-DFuyO1pQ.mjs → openai-responses-request-lifecycle-Fsag-IGZ.mjs} +1 -1
- package/dist/{openai-responses-shared-DvSqtJ6_.mjs → openai-responses-shared-DL4ulQn7.mjs} +312 -122
- package/dist/{openai-responses-terminal-usage-BNFbvY9f.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
- package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
- package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
- package/dist/{openai-tool-schema-D4BMcj2D.mjs → openai-tool-schema-vsl-cE-n.mjs} +243 -383
- package/dist/{openai-transport-params-DZKOTSfH.mjs → openai-transport-params-BwlpzX-2.mjs} +60 -105
- package/dist/{positive-integer-BiUxrd71.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
- package/dist/{provider-error-CRhW7lkJ.mjs → provider-error-CwT_j2v0.mjs} +43 -4
- package/dist/{provider-options-DZYq53lj.d.mts → provider-options-Df7ov0K1.d.mts} +2 -2
- package/dist/{provider-replay-context-DPr3w20a.mjs → provider-replay-context-DsyI5jOP.mjs} +1 -1
- package/dist/{provider-transcript-transform-BTocjCRs.mjs → provider-transcript-transform-JbFbHV8h.mjs} +17 -2
- package/dist/{provider-transport-turn-state-lrXEFkYr.mjs → provider-transport-turn-state-BheUi_hl.mjs} +1 -1
- package/dist/{provider-types-w1rEqrGP.d.mts → provider-types-d4XnoZMd.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -6
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +15 -11
- package/dist/{reasoning-tag-text-partitioner-Di38crhI.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +47 -71
- package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
- package/dist/simple-options-CGAkCwtM.mjs +349 -0
- package/dist/{src-DwGYYyZp.mjs → src-H4aXcFuX.mjs} +43 -25
- package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
- package/dist/{stream-first-event-timeout-BeptfRL6.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
- package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
- package/dist/{transport-stream-shared-B5RioB_Q.mjs → transport-stream-shared-Dh5qKJ8e.mjs} +62 -28
- package/dist/{transport-stream-shared-B7Z9oCYg.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +12 -6
- package/dist/{transport-utils-03Qi0CN2.mjs → transport-utils-C-4bf2Ok.mjs} +3 -4
- package/dist/transports.d.mts +36 -32
- package/dist/transports.mjs +160 -216
- package/dist/types-CB-_vNyI.d.mts +1 -0
- package/dist/{types-qZFbaDbK.d.mts → types-CLLR3eB4.d.mts} +3 -1
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +4 -4
- package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
- package/dist/{validation-DhQhmt6t.d.mts → validation-Cat2wQsc.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +5 -5
- package/dist/assistant-output-DM1JBNs1.mjs +0 -16
- package/dist/event-stream-C0nsgbj2.d.mts +0 -1
- package/dist/simple-options-np1XPuhm.mjs +0 -175
- package/dist/types-DTvddOfm.d.mts +0 -1
- 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
|
-
|
|
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 (!
|
|
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 =
|
|
123
|
-
const legacyDefsEntry =
|
|
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
|
|
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 (!
|
|
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
|
-
|
|
294
|
-
const flattened = flattenUnionFallback(cleaned,
|
|
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
|
-
|
|
327
|
-
|
|
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/
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
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
|
-
|
|
367
|
-
|
|
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 =
|
|
370
|
-
const next =
|
|
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 :
|
|
483
|
+
return changed ? entries : schema;
|
|
375
484
|
}
|
|
376
|
-
if (!isRecord(
|
|
485
|
+
if (!isRecord(schema)) return schema;
|
|
377
486
|
let changed = false;
|
|
378
487
|
const cleaned = {};
|
|
379
|
-
for (const [key, value] of Object.entries(
|
|
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
|
|
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 =
|
|
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 =
|
|
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 :
|
|
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
|
|
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
|
-
|
|
427
|
-
|
|
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
|
-
|
|
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) &&
|
|
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
|
-
|
|
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
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
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 (
|
|
978
|
-
|
|
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
|
|
1002
|
-
...typeof
|
|
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 =
|
|
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 (!
|
|
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
|
|
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,
|
|
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
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
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,
|
|
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 =
|
|
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
|
|
1010
|
+
for (const key of SCHEMA_MAP_KEYS$1) {
|
|
1146
1011
|
const schemaMap = record[key];
|
|
1147
|
-
if (!
|
|
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 =
|
|
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 =
|
|
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" &&
|
|
1117
|
+
if (key === "properties" && isRecord(entry)) return Object.values(entry).every(isStrictOpenAIJsonSchemaCompatibleRecursive);
|
|
1258
1118
|
return isStrictOpenAIJsonSchemaCompatibleRecursive(entry);
|
|
1259
1119
|
});
|
|
1260
1120
|
}
|