@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.
- package/README.md +11 -0
- package/dist/{anthropic-DIIiiz99.mjs → anthropic-D6spfBri.mjs} +16 -18
- package/dist/{anthropic-payload-policy-DGblkHL5.d.mts → anthropic-payload-policy-Cr8xjazC.d.mts} +6 -3
- package/dist/{anthropic-stream-reducer-DfMVFm-r.mjs → anthropic-stream-reducer-CzPXOaLM.mjs} +55 -227
- package/dist/anthropic-tool-projection-BdAS3rtJ.mjs +165 -0
- package/dist/anthropic-tool-projection-DKH-aEWU.d.mts +51 -0
- package/dist/{api-registry-BhXXYdRA.d.mts → api-registry-gDt0faai.d.mts} +2 -2
- package/dist/{assistant-output-BuhRpLeD.mjs → assistant-output-6iFA1nbC.mjs} +2 -2
- package/dist/{azure-openai-responses-DGQnXRMs.mjs → azure-openai-responses-0TqHwnlD.mjs} +8 -8
- package/dist/{cloudflare-5qSGvIUH.mjs → cloudflare-Dttf8jKq.mjs} +1 -1
- package/dist/{credential-redaction-BHxruEH6.d.mts → credential-redaction-XvsPf7Yi.d.mts} +1 -0
- package/dist/{diagnostics-tQasYct1.mjs → diagnostics-Cv7cW3pS.mjs} +3 -3
- package/dist/diagnostics.d.mts +6 -6
- package/dist/diagnostics.mjs +2 -2
- package/dist/{env-api-keys-CrxwdylR.mjs → env-api-keys-Xd8dm_aV.mjs} +10 -34
- package/dist/event-stream-CDpFza-M.d.mts +1 -0
- package/dist/{event-stream-BcqWLo_u.d.mts → event-stream-CzpE1g_o.d.mts} +1 -1
- package/dist/event-stream.d.mts +2 -2
- package/dist/{github-copilot-request-facts-DEE6gcB9.mjs → github-copilot-request-facts-F-EmvkpW.mjs} +1 -1
- package/dist/{google-interactions-zIz70M2e.mjs → google-interactions-DVQ7AaSF.mjs} +29 -50
- package/dist/{google-messages-CNbUJK5E.mjs → google-messages-DfpHVTaD.mjs} +15 -5
- package/dist/{google-provider-stream-Cn0XF1MG.mjs → google-provider-stream-DJ8ANfsS.mjs} +6 -6
- package/dist/{google-shared-BPnWP4tT.mjs → google-shared-VTcCJLW3.mjs} +21 -29
- package/dist/{google-vertex-XQ7OQtaM.mjs → google-vertex-Bkfizj7M.mjs} +3 -3
- package/dist/{google-BlbTC1Xp.mjs → google-zWpkDSeN.mjs} +4 -4
- package/dist/{host-Bf3NjYNj.mjs → host-B2gk-d1H.mjs} +5 -11
- package/dist/{host-CTDz7LXD.d.mts → host-jJOffdlW.d.mts} +4 -6
- package/dist/{host-policy-BzZluO6_.mjs → host-policy-mpqGhbeM.mjs} +1 -1
- package/dist/{index-BYDvopUB.d.mts → index-DSprYWaz.d.mts} +7 -5
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +6 -6
- package/dist/internal/anthropic.d.mts +7 -53
- package/dist/internal/anthropic.mjs +6 -5
- package/dist/internal/google-model-family.mjs +1 -1
- 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 +3 -3
- package/dist/internal/openai-responses-payload-policy.mjs +3 -3
- package/dist/internal/openai.d.mts +17 -26
- package/dist/internal/openai.mjs +10 -10
- package/dist/internal/retry-after.d.mts +1 -1
- package/dist/internal/retry-after.mjs +80 -55
- package/dist/internal/runtime.d.mts +9 -31
- package/dist/internal/runtime.mjs +10 -116
- package/dist/internal/shared.d.mts +9 -7
- package/dist/internal/shared.mjs +8 -6
- package/dist/internal/tool-schema.d.mts +83 -5
- package/dist/internal/tool-schema.mjs +4 -3
- package/dist/{mistral-dCDCR5ur.mjs → mistral-CATJrwne.mjs} +32 -35
- package/dist/model-request-body-BD5vy4rP.d.mts +17 -0
- package/dist/{number-coercion-C3hztWoY.mjs → number-coercion-37gmNkuA.mjs} +1 -1
- package/dist/{openai-chatgpt-responses-D8-q7cgy.mjs → openai-chatgpt-responses-CtdnpWwe.mjs} +95 -63
- package/dist/{openai-completions-CMN24pza.mjs → openai-completions-B6sET3oI.mjs} +10 -8
- package/dist/{openai-completions-compat-i-nLZxFy.d.mts → openai-completions-compat-1gsjP-KO.d.mts} +6 -3
- package/dist/{openai-completions-compat-CYX18uDk.mjs → openai-completions-compat-CFhQ3UVU.mjs} +7 -2
- package/dist/{openai-completions-transport-DuXQOxrH.mjs → openai-completions-transport-DviPEqw3.mjs} +369 -237
- package/dist/{openai-prompt-cache-r93BJhjm.mjs → openai-prompt-cache-DJ_P143P.mjs} +1 -1
- package/dist/{openai-prompt-cache-DIPMrMFy.d.mts → openai-prompt-cache-DgjD-UL5.d.mts} +2 -2
- package/dist/{openai-responses-BMxoJdTC.mjs → openai-responses-BXsJK-mD.mjs} +13 -15
- package/dist/{openai-responses-compaction-replay-B2FE4Nw8.d.mts → openai-responses-compaction-replay-Cvnl_nCq.d.mts} +5 -5
- package/dist/{openai-responses-contracts-DlKMMTxK.mjs → openai-responses-contracts-Bx-16mnf.mjs} +45 -6
- package/dist/{openai-responses-contracts-DKqMJ1Ct.d.mts → openai-responses-contracts-CQ4_AWjL.d.mts} +20 -8
- package/dist/{openai-responses-endpoint-CinGh4VZ.mjs → openai-responses-endpoint-D4v-eeYy.mjs} +55 -22
- package/dist/{openai-responses-payload-policy-C7GsA1y0.d.mts → openai-responses-payload-policy-BzM52TTH.d.mts} +9 -3
- package/dist/openai-responses-request-lifecycle-CTdAb2v1.mjs +246 -0
- package/dist/{openai-responses-shared-afo9-s16.mjs → openai-responses-shared-Bv_1NtH9.mjs} +284 -173
- package/dist/{openai-responses-terminal-usage-BygjiAdi.d.mts → openai-responses-terminal-usage-CpVjkqn-.d.mts} +2 -2
- package/dist/{openai-tool-schema-DDPXsvJP.mjs → openai-tool-schema-Buv0GXFb.mjs} +170 -237
- package/dist/overflow-DJHXTNBQ.mjs +117 -0
- package/dist/{positive-integer-CqWjqSi9.mjs → positive-integer-Bb4Evc7L.mjs} +1 -1
- package/dist/prompt-cache-stability-D_MeCQFI.mjs +32 -0
- package/dist/{provider-error-xumb1V3F.d.mts → provider-error-CnaWYTRY.d.mts} +1 -0
- package/dist/{provider-error-CF9GWCs2.mjs → provider-error-qtZD2inE.mjs} +75 -13
- package/dist/{provider-options-CVrXZBtA.d.mts → provider-options-DeYeaflL.d.mts} +52 -6
- package/dist/{transport-utils-34BQoXq3.mjs → provider-replay-context-J6CfU3m1.mjs} +28 -5
- package/dist/{provider-transport-turn-state-BYrELw8H.mjs → provider-transport-turn-state-Jxppzuc2.mjs} +5 -5
- package/dist/{provider-types-CHtRx0dI.d.mts → provider-types-ODq57rG_.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -6
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +11 -11
- package/dist/{reasoning-tag-text-partitioner-CpOy9-IQ.mjs → reasoning-tag-text-partitioner-DzlRubwU.mjs} +134 -47
- package/dist/{required-api-key-CFJvcFy_.mjs → required-api-key-D088S4Cd.mjs} +1 -1
- package/dist/{retry-after-CdCURCVg.d.mts → retry-after-sw-XX8aC.d.mts} +1 -1
- package/dist/sanitize-unicode-CRGuMONI.mjs +8 -0
- package/dist/sanitize-unicode-ZqVLLEKC.d.mts +27 -0
- package/dist/{session-resources-D1wgDQ8C.mjs → session-resources-vKvGIE3J.mjs} +1 -10
- package/dist/{simple-options-BAu4B54D.mjs → simple-options-BYgC6kse.mjs} +68 -79
- package/dist/{src-C44MKrW5.mjs → src-CyA0zJnt.mjs} +6 -2
- package/dist/{stream-Dd8DwRFL.mjs → stream-DLBirT0e.mjs} +8 -47
- package/dist/{stream-first-event-timeout-Dc42hKv6.mjs → stream-first-event-timeout-D_TfJHRJ.mjs} +1 -1
- package/dist/{string-coerce-CtgOVOSv.mjs → string-coerce-Cj8sqWHx.mjs} +26 -1
- package/dist/tool-schema-json-projection-B0hHDV7N.mjs +492 -0
- package/dist/{transport-stream-shared-BmpzDtdQ.d.mts → transport-stream-shared-8ru8eX4s.d.mts} +5 -5
- package/dist/{transport-stream-shared-CWGOuLcA.mjs → transport-stream-shared-CzQlAzJH.mjs} +27 -75
- package/dist/transports.d.mts +33 -28
- package/dist/transports.mjs +42 -48
- package/dist/{types-CQc6JNG4.mjs → types-BXd0kI8-.mjs} +1 -1
- package/dist/types-CBJthzJX.d.mts +1 -0
- package/dist/{types-Bd2T86VJ.d.mts → types-CVYzKrMl.d.mts} +20 -3
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +4 -4
- package/dist/{validation-ZX_sPVV0.mjs → validation-9FSkE8T-.mjs} +22 -3
- package/dist/{validation-DdGB1yy3.d.mts → validation-BQ5u20Ru.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +3 -3
- package/dist/assistant-text-phase-mvdMcrY-.mjs +0 -50
- package/dist/event-stream-6UNs-AhN.d.mts +0 -1
- package/dist/expect-lbe3Hgrh.mjs +0 -8
- package/dist/json-schema-Bp07Qui3.mjs +0 -22
- package/dist/openai-responses-request-lifecycle-NSIJo9jY.mjs +0 -67
- package/dist/openai-tool-projection-793cE3QX.d.mts +0 -37
- package/dist/openai-tool-schema-a5ysBBga.d.mts +0 -32
- package/dist/rolldown-runtime-BhDjJH2R.mjs +0 -15
- package/dist/sanitize-unicode-CjDG6jJx.d.mts +0 -5
- package/dist/string-normalization-I3ux50s9.mjs +0 -28
- package/dist/text-signature-CUXnvk_c.mjs +0 -34
- package/dist/tool-schema-json-projection-B8sG1I9v.mjs +0 -180
- 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-
|
|
2
|
-
import "./types-
|
|
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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { a as
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
175
|
+
return copySchemaMeta(obj, { ...cleaned });
|
|
137
176
|
}
|
|
138
|
-
return copySchemaMeta
|
|
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
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
|
462
|
-
else if (SCHEMA_OBJECT_KEYS
|
|
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
|
-
|
|
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)
|
|
515
|
-
|
|
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
|
-
|
|
389
|
+
inputTruncated: wasToolSchemaTruncated(source),
|
|
390
|
+
outputJson,
|
|
391
|
+
truncated: wasToolSchemaTruncated(result)
|
|
519
392
|
});
|
|
520
|
-
return
|
|
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
|
|
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 (
|
|
447
|
+
if (mapProfile) return schema;
|
|
551
448
|
let changed = false;
|
|
552
449
|
const normalized = schema.map((entry) => {
|
|
553
|
-
const next =
|
|
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 =
|
|
582
|
-
else if (SCHEMA_OBJECT_KEYS.has(key) && isRecord(value)) next =
|
|
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) =>
|
|
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")
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
else if (
|
|
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 (
|
|
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)
|
|
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(
|
|
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) =>
|
|
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
|
|
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(...
|
|
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(...
|
|
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
|
-
|
|
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 {
|
|
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 };
|