@openclaw/ai 2026.9.1 → 2026.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +3 -2
  2. package/dist/anthropic-CZy5U0NY.mjs +376 -0
  3. package/dist/anthropic-payload-policy-wuRCb6MH.d.mts +85 -0
  4. package/dist/anthropic-stream-reducer-B_yo_7pf.mjs +1669 -0
  5. package/dist/{api-registry-Cs6HGNqY.d.mts → api-registry-CB1-1oQ2.d.mts} +2 -2
  6. package/dist/assistant-output-iqnlJCV2.mjs +16 -0
  7. package/dist/assistant-text-phase-C20rxWwP.mjs +55 -0
  8. package/dist/{azure-openai-responses-CN4Fy5zV.mjs → azure-openai-responses-Crpa40QR.mjs} +5 -5
  9. package/dist/{base64-CEFBpSkN.mjs → base64-D-su8YVo.mjs} +1 -27
  10. package/dist/{diagnostics-KhXK-QJI.mjs → diagnostics-dV98PqIy.mjs} +96 -21
  11. package/dist/diagnostics.d.mts +3 -1
  12. package/dist/diagnostics.mjs +3 -3
  13. package/dist/{event-stream-vK_7r3bj.d.mts → event-stream-C1Z2piyk.d.mts} +11 -3
  14. package/dist/{event-stream-uSMZJ3FA.mjs → event-stream-D8PARQfL.mjs} +48 -10
  15. package/dist/event-stream-I_GlBsuZ.d.mts +1 -0
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/event-stream.mjs +1 -1
  18. package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-B37TB3rB.mjs} +3 -10
  19. package/dist/github-copilot-request-facts-BTEBMeOv.mjs +16 -0
  20. package/dist/{google-CC-nrwXg.mjs → google-BDPriaVe.mjs} +10 -10
  21. package/dist/google-messages-CVn9eFpF.mjs +449 -0
  22. package/dist/google-shared-BedY23XS.mjs +185 -0
  23. package/dist/{google-vertex-DCr0pyzQ.mjs → google-vertex-DMz8XQCn.mjs} +7 -6
  24. package/dist/{host-BIaiBURL.mjs → host-CWuF-sS3.mjs} +84 -34
  25. package/dist/{host-BztR4tQj.d.mts → host-DK3wmS3e.d.mts} +3 -3
  26. package/dist/host-policy-CAopLRKA.mjs +37 -0
  27. package/dist/{index-AfaxKT8w.d.mts → index-CQ6LTHw8.d.mts} +11 -5
  28. package/dist/index.d.mts +7 -7
  29. package/dist/index.mjs +5 -5
  30. package/dist/internal/anthropic.d.mts +14 -11
  31. package/dist/internal/anthropic.mjs +5 -5
  32. package/dist/internal/google-model-family.d.mts +5 -0
  33. package/dist/internal/google-model-family.mjs +15 -0
  34. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  35. package/dist/internal/openai-responses-payload-policy.mjs +1 -1
  36. package/dist/internal/openai.d.mts +8 -103
  37. package/dist/internal/openai.mjs +10 -10
  38. package/dist/internal/retry-after.d.mts +2 -4
  39. package/dist/internal/retry-after.mjs +57 -8
  40. package/dist/internal/runtime.d.mts +7 -6
  41. package/dist/internal/runtime.mjs +8 -7
  42. package/dist/internal/shared.d.mts +14 -3
  43. package/dist/internal/shared.mjs +6 -4
  44. package/dist/internal/tool-schema.d.mts +63 -0
  45. package/dist/internal/tool-schema.mjs +3 -0
  46. package/dist/{json-parse-BuAJEbdW.mjs → json-parse-Dw_hnxsA.mjs} +1 -1
  47. package/dist/{mistral-B7etBd_H.mjs → mistral--m-Jm6VZ.mjs} +16 -38
  48. package/dist/model-transport-url-DKocrEsb.d.mts +28 -0
  49. package/dist/{openai-chatgpt-responses-BAJ4gq3i.mjs → openai-chatgpt-responses-nDZccFW-.mjs} +62 -54
  50. package/dist/openai-completions-KuoZyx0d.mjs +187 -0
  51. package/dist/{openai-completions-compat-4IjSBpr6.d.mts → openai-completions-compat-CXn3T1we.d.mts} +26 -4
  52. package/dist/{openai-completions-stream-DZjwK8vp.mjs → openai-completions-stream-BQk3SkLD.mjs} +621 -451
  53. package/dist/openai-prompt-cache-BI0rkM-5.mjs +220 -0
  54. package/dist/openai-prompt-cache-rrutvqxq.d.mts +16 -0
  55. package/dist/openai-provider-client-ha_WxTyj.mjs +24 -0
  56. package/dist/openai-reasoning-effort-BK7FbcLT.mjs +167 -0
  57. package/dist/{openai-responses-BEUlxfDu.mjs → openai-responses-D99dOzKI.mjs} +14 -32
  58. package/dist/{openai-responses-compaction-window-DO7yV7az.mjs → openai-responses-compaction-window-D5jbzCi3.mjs} +7 -159
  59. package/dist/{openai-responses-contracts-bPzSN_Ba.d.mts → openai-responses-contracts-B55afwRo.d.mts} +12 -4
  60. package/dist/{openai-responses-prompt-observer-internal-C7x4IK7r.mjs → openai-responses-prompt-observer-internal-tApyTLVu.mjs} +3 -3
  61. package/dist/{openai-responses-shared-DiAdpNAM.mjs → openai-responses-shared-ZyQEzS5i.mjs} +217 -212
  62. package/dist/openai-tool-projection-793cE3QX.d.mts +37 -0
  63. package/dist/{openai-tool-schema-BMiHFH36.mjs → openai-tool-schema-CzjyYXun.mjs} +53 -583
  64. package/dist/openai-tool-schema-ynZBgqW-.d.mts +38 -0
  65. package/dist/openai-transport-params-DNasp2fU.mjs +674 -0
  66. package/dist/{provider-error-B6EGq6gg.mjs → provider-error-C6TbKiey.mjs} +29 -13
  67. package/dist/{provider-options-CxFPtvh7.d.mts → provider-options-BXr9Ec83.d.mts} +19 -42
  68. package/dist/provider-replay-context-BuSUaAk5.mjs +21 -0
  69. package/dist/{provider-transcript-transform-WvJmFUAf.mjs → provider-transcript-transform-pPmUIwKt.mjs} +1 -1
  70. package/dist/provider-types-CAV0Og3m.d.mts +29 -0
  71. package/dist/provider-types.d.mts +6 -31
  72. package/dist/providers.d.mts +2 -2
  73. package/dist/providers.mjs +11 -11
  74. package/dist/{reasoning-tag-text-partitioner-C-4uedDb.mjs → reasoning-tag-text-partitioner-BQBi4B9d.mjs} +90 -35
  75. package/dist/record-coerce-DwRYMj3t.mjs +32 -0
  76. package/dist/retry-after-CdCURCVg.d.mts +15 -0
  77. package/dist/{sanitize-unicode-S6binQG-.mjs → sanitize-unicode-Bb-v9meu.mjs} +1 -1
  78. package/dist/session-affinity-CCH7eYdB.mjs +20 -0
  79. package/dist/{simple-options-0PLDyJ-d.mjs → simple-options-tcKOqnpF.mjs} +3 -3
  80. package/dist/{src-C8U7lkoa.mjs → src-B2Q_6G8V.mjs} +10 -2
  81. package/dist/{stream-first-event-timeout-DcNjoFQE.mjs → stream-first-event-timeout-2hfrquuz.mjs} +1 -1
  82. package/dist/string-coerce-fsri9iCu.mjs +34 -0
  83. package/dist/{string-normalization--fwJ4S2q.mjs → string-normalization-CmLIasuf.mjs} +1 -1
  84. package/dist/{tool-schema-json-projection-BtZiml7r.mjs → tool-schema-json-projection-ClptDdAO.mjs} +2 -38
  85. package/dist/{transport-stream-shared-CytPVLIg.mjs → transport-stream-shared-Cu3ZPhNW.mjs} +5 -5
  86. package/dist/{transport-stream-shared-BrvFTkoO.d.mts → transport-stream-shared-DOxpGJ-H.d.mts} +4 -4
  87. package/dist/transport-utils-CCooe-cr.mjs +121 -0
  88. package/dist/transports.d.mts +114 -41
  89. package/dist/transports.mjs +796 -1596
  90. package/dist/types-BADKjDBI.d.mts +1 -0
  91. package/dist/{types-DbrhszyQ.d.mts → types-Dy1q0CSu.d.mts} +101 -64
  92. package/dist/types.d.mts +6 -6
  93. package/dist/types.mjs +4 -4
  94. package/dist/utf16-slice-CvGodqok.mjs +29 -0
  95. package/dist/{validation-CJZtym2g.mjs → validation-BDzVDnTs.mjs} +9 -1
  96. package/dist/{validation-BOwtcl9X.d.mts → validation-CaFUZN9B.d.mts} +1 -1
  97. package/dist/validation.d.mts +1 -1
  98. package/dist/validation.mjs +1 -1
  99. package/package.json +14 -4
  100. package/dist/anthropic-compaction-replay-OMJZ0uyo.mjs +0 -838
  101. package/dist/anthropic-hk7F7ptG.mjs +0 -883
  102. package/dist/anthropic-payload-policy-DBT1itQ-.d.mts +0 -51
  103. package/dist/event-stream-DeDhbCc5.d.mts +0 -1
  104. package/dist/google-shared-CjPY0hZM.mjs +0 -634
  105. package/dist/google-thinking-level-C-V3tecN.mjs +0 -9
  106. package/dist/openai-completions-D0QZ0AyB.mjs +0 -403
  107. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
  108. package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
  109. package/dist/transport-utils-CtuS1Upe.mjs +0 -138
  110. package/dist/types-B5EFUmXs.d.mts +0 -1
  111. package/dist/utf16-slice-qz3nsy87.mjs +0 -84
@@ -1,433 +1,6 @@
1
- import { c as normalizeLowercaseStringOrEmpty, o as isRecord } from "./utf16-slice-qz3nsy87.mjs";
2
- import { n as applyProviderReportedUsageCost, r as calculateCost } from "./sanitize-unicode-S6binQG-.mjs";
3
- import { n as getAiTransportHost } from "./host-BIaiBURL.mjs";
4
- import { r as uniqueValues, t as normalizeStringEntries } from "./string-normalization--fwJ4S2q.mjs";
5
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
6
- import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BtZiml7r.mjs";
7
- import { C as headersToRecord, _ as transportAbortError, f as notifyProviderHttpResponse } from "./transport-stream-shared-CytPVLIg.mjs";
8
- //#region packages/ai/src/transports/openai-transport-shared.ts
9
- /** Shared options, usage shape, cache identity, ordering, and stream scheduling for OpenAI APIs. */
10
- const MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS = 12;
11
- const MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS = 64;
12
- const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
13
- const log = {
14
- debug(message, data) {
15
- getAiTransportHost().logDebug("openai-transport", () => ({
16
- message,
17
- data
18
- }));
19
- },
20
- info(message, data) {
21
- getAiTransportHost().logInfo("openai-transport", message, data);
22
- },
23
- warn(message, data) {
24
- getAiTransportHost().logWarn("openai-transport", message, data);
25
- }
26
- };
27
- function resolveOpenAIClientBaseUrl(model, baseUrl = model.baseUrl) {
28
- if (baseUrl?.trim()) return baseUrl;
29
- if (model.provider.trim().toLowerCase() === "openai") return;
30
- throw new Error(`Provider "${model.provider}" requires an explicit base URL before using an OpenAI-compatible API. Reload provider metadata or configure an endpoint.`);
31
- }
32
- const EMPTY_OPENAI_COMPLETIONS_REASONING_BATCH = {
33
- deltas: [],
34
- mirroredThinking: [],
35
- hasThinking: false,
36
- hasVisibleText: false
37
- };
38
- const OPENAI_COMPLETIONS_REASONING_FIELDS = [
39
- "reasoning_content",
40
- "reasoning",
41
- "reasoning_text"
42
- ];
43
- function appendOpenAICompletionsReasoningDelta(batch, next) {
44
- if (next.kind === "thinking") batch.hasThinking = true;
45
- else batch.hasVisibleText = true;
46
- const previous = batch.deltas[batch.deltas.length - 1];
47
- if (!previous || previous.kind !== next.kind) {
48
- batch.deltas.push(next);
49
- if (next.kind === "thinking") batch.mirroredThinking.push(next.text);
50
- return;
51
- }
52
- if (next.kind === "thinking" && previous.kind === "thinking") {
53
- if (previous.signature !== next.signature) {
54
- batch.deltas.push(next);
55
- batch.mirroredThinking.push(next.text);
56
- return;
57
- }
58
- previous.text += next.text;
59
- batch.mirroredThinking[batch.mirroredThinking.length - 1] += next.text;
60
- return;
61
- }
62
- previous.text += next.text;
63
- }
64
- function createOpenAICompletionsReasoningBatch() {
65
- return {
66
- deltas: [],
67
- mirroredThinking: [],
68
- hasThinking: false,
69
- hasVisibleText: false
70
- };
71
- }
72
- function readOpenAICompletionsReasoningBatch(delta, visibleReasoningDetailTypes) {
73
- let batch;
74
- const reasoningDetails = delta.reasoning_details;
75
- let usedReasoningThinkingDetails = false;
76
- if (Array.isArray(reasoningDetails)) for (const item of reasoningDetails) {
77
- if (!isRecord(item)) continue;
78
- const detail = item;
79
- if (typeof detail.text !== "string" || !detail.text) continue;
80
- if (detail.type === "reasoning.text") {
81
- usedReasoningThinkingDetails = true;
82
- batch ??= createOpenAICompletionsReasoningBatch();
83
- appendOpenAICompletionsReasoningDelta(batch, {
84
- kind: "thinking",
85
- signature: "reasoning_details",
86
- text: detail.text
87
- });
88
- continue;
89
- }
90
- if (typeof detail.type === "string" && visibleReasoningDetailTypes.has(detail.type)) {
91
- batch ??= createOpenAICompletionsReasoningBatch();
92
- appendOpenAICompletionsReasoningDelta(batch, {
93
- kind: "text",
94
- text: detail.text,
95
- source: "reasoning_detail"
96
- });
97
- }
98
- }
99
- if (!usedReasoningThinkingDetails) for (const field of OPENAI_COMPLETIONS_REASONING_FIELDS) {
100
- const value = delta[field];
101
- if (typeof value === "string" && value.length > 0) {
102
- batch ??= createOpenAICompletionsReasoningBatch();
103
- appendOpenAICompletionsReasoningDelta(batch, {
104
- kind: "thinking",
105
- signature: field,
106
- text: value
107
- });
108
- break;
109
- }
110
- }
111
- return batch ?? EMPTY_OPENAI_COMPLETIONS_REASONING_BATCH;
112
- }
113
- function parseOpenAICompletionsUsage(rawUsage, model, options) {
114
- const cacheRead = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
115
- const cacheWrite = rawUsage.prompt_tokens_details?.cache_write_tokens ?? rawUsage.prompt_tokens_details?.cache_creation_input_tokens ?? 0;
116
- const input = Math.max(0, (rawUsage.prompt_tokens || 0) - cacheRead - cacheWrite);
117
- const output = rawUsage.completion_tokens || 0;
118
- const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
119
- const usage = {
120
- input,
121
- output,
122
- cacheRead,
123
- cacheWrite,
124
- ...options?.includeReasoningTokens !== false && typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) ? { reasoningTokens } : {},
125
- totalTokens: input + output + cacheRead + cacheWrite,
126
- cost: {
127
- input: 0,
128
- output: 0,
129
- cacheRead: 0,
130
- cacheWrite: 0,
131
- total: 0
132
- }
133
- };
134
- calculateCost(model, usage);
135
- applyProviderReportedUsageCost(usage, rawUsage.cost);
136
- return usage;
137
- }
138
- function createOpenAIResponseHook(onResponse, response, model) {
139
- return onResponse ? () => onResponse({
140
- status: response.status,
141
- headers: headersToRecord(response.headers)
142
- }, model) : void 0;
143
- }
144
- function createOpenAIProviderAcceptanceHook(options, response, model) {
145
- return () => notifyProviderHttpResponse({
146
- options,
147
- response,
148
- model
149
- });
150
- }
151
- function throwIfModelStreamAborted(signal) {
152
- if (signal?.aborted) throw transportAbortError(signal);
153
- }
154
- /** Measure one UTF-8 append without double-counting a surrogate pair split across chunks. */
155
- function measureUtf8AppendBytes(bufferEndsWithHighSurrogate, chunk) {
156
- let bytes = Buffer.byteLength(chunk, "utf8");
157
- if (!chunk) return {
158
- bytes,
159
- endsWithHighSurrogate: bufferEndsWithHighSurrogate
160
- };
161
- const nextCodeUnit = chunk.charCodeAt(0);
162
- if (bufferEndsWithHighSurrogate && nextCodeUnit >= 56320 && nextCodeUnit <= 57343) bytes -= 2;
163
- const finalCodeUnit = chunk.charCodeAt(chunk.length - 1);
164
- return {
165
- bytes,
166
- endsWithHighSurrogate: finalCodeUnit >= 55296 && finalCodeUnit <= 56319
167
- };
168
- }
169
- function createModelStreamCooperativeScheduler(signal) {
170
- let lastYieldedAt = Date.now();
171
- let eventsSinceYield = 0;
172
- return { async afterEvent() {
173
- throwIfModelStreamAborted(signal);
174
- eventsSinceYield += 1;
175
- const now = Date.now();
176
- if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
177
- eventsSinceYield = 0;
178
- lastYieldedAt = now;
179
- await new Promise((resolve) => {
180
- setTimeout(resolve, 0);
181
- });
182
- throwIfModelStreamAborted(signal);
183
- } };
184
- }
185
- function resolvePromptCacheKey(options, cacheRetention) {
186
- if (cacheRetention === "none") return;
187
- return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
188
- }
189
- function isOpenAICompletionsThinkingEnabled(effort) {
190
- const normalized = effort.trim().toLowerCase();
191
- return normalized !== "off" && normalized !== "none";
192
- }
193
- function readOpenAICompletionsContentDeltas(content, topLevelRefusal, mirroredThinking = []) {
194
- let deltas = readOpenAICompletionsContentPartDeltas(content);
195
- if (mirroredThinking.length > 0) {
196
- const structuredThinking = deltas.filter((delta) => delta.kind === "thinking").map((delta) => delta.text);
197
- const mirrorsCombinedThinking = structuredThinking.length > 1 && mirroredThinking.includes(structuredThinking.join(""));
198
- deltas = deltas.filter((delta) => delta.kind !== "thinking" || !mirrorsCombinedThinking && !mirroredThinking.includes(delta.text));
199
- }
200
- if (typeof topLevelRefusal !== "string" || !topLevelRefusal) return deltas;
201
- const structuredRefusals = deltas.filter((delta) => delta.kind === "text" && delta.source === "refusal").map((delta) => delta.text);
202
- if (structuredRefusals.some((refusal) => refusal === topLevelRefusal) || structuredRefusals.length > 1 && structuredRefusals.join("") === topLevelRefusal) return deltas;
203
- return [...deltas, {
204
- kind: "text",
205
- text: topLevelRefusal,
206
- source: "refusal"
207
- }];
208
- }
209
- function readOpenAICompletionsContentPartDeltas(content) {
210
- if (typeof content === "string") return content ? [{
211
- kind: "text",
212
- text: content
213
- }] : [];
214
- if (Array.isArray(content)) return content.flatMap(readOpenAICompletionsContentPartDeltas);
215
- if (!content || typeof content !== "object") return [];
216
- const record = content;
217
- const type = typeof record.type === "string" ? record.type.toLowerCase() : "";
218
- const extractText = (value) => {
219
- if (typeof value === "string") return value;
220
- if (Array.isArray(value)) return value.map(extractText).join("");
221
- if (value && typeof value === "object") {
222
- const nested = value;
223
- return extractText(nested.text ?? nested.content ?? nested.thinking ?? nested.refusal);
224
- }
225
- return "";
226
- };
227
- const text = extractText(record.text ?? record.content ?? record.thinking ?? record.refusal);
228
- if (!text) return [];
229
- if (type.includes("thinking") || type.includes("reasoning")) return [{
230
- kind: "thinking",
231
- text
232
- }];
233
- if (type === "refusal") return [{
234
- kind: "text",
235
- text,
236
- source: "refusal"
237
- }];
238
- if (["text", "output_text"].includes(type) || type.endsWith(".output_text")) return [{
239
- kind: "text",
240
- text
241
- }];
242
- return [];
243
- }
244
- //#endregion
245
- //#region packages/ai/src/providers/openai-tool-projection.ts
246
- function unreadableToolDiagnostic(toolIndex) {
247
- return {
248
- toolIndex,
249
- violations: [`tool[${toolIndex}] is unreadable`]
250
- };
251
- }
252
- /** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
253
- function projectOpenAITools(tools) {
254
- let inputToolCount;
255
- try {
256
- inputToolCount = tools.length;
257
- } catch {
258
- return {
259
- inputToolCount: 0,
260
- tools: [],
261
- diagnostics: [unreadableToolDiagnostic(0)]
262
- };
263
- }
264
- const projectedTools = [];
265
- const diagnostics = [];
266
- for (let toolIndex = 0; toolIndex < inputToolCount; toolIndex += 1) {
267
- let tool;
268
- try {
269
- const candidate = tools[toolIndex];
270
- if (!candidate) {
271
- diagnostics.push(unreadableToolDiagnostic(toolIndex));
272
- continue;
273
- }
274
- tool = candidate;
275
- } catch {
276
- diagnostics.push(unreadableToolDiagnostic(toolIndex));
277
- continue;
278
- }
279
- let name;
280
- try {
281
- name = tool.name;
282
- } catch {
283
- diagnostics.push({
284
- toolIndex,
285
- violations: [`tool[${toolIndex}].name is unreadable`]
286
- });
287
- continue;
288
- }
289
- if (typeof name !== "string" || !name) {
290
- diagnostics.push({
291
- toolIndex,
292
- violations: [`tool[${toolIndex}].name is empty`]
293
- });
294
- continue;
295
- }
296
- let parameters;
297
- try {
298
- parameters = tool.parameters;
299
- } catch {
300
- diagnostics.push({
301
- toolIndex,
302
- toolName: name,
303
- violations: [`${name}.parameters is unreadable`]
304
- });
305
- continue;
306
- }
307
- const schemaProjection = projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
308
- if (!isRecord(schemaProjection.schema) || schemaProjection.violations.length > 0) {
309
- diagnostics.push({
310
- toolIndex,
311
- toolName: name,
312
- violations: schemaProjection.violations.length > 0 ? schemaProjection.violations : [`${name}.parameters must be a JSON object schema`]
313
- });
314
- continue;
315
- }
316
- let descriptionValue;
317
- try {
318
- descriptionValue = tool.description;
319
- } catch {}
320
- const description = typeof descriptionValue === "string" ? descriptionValue : void 0;
321
- projectedTools.push({
322
- toolIndex,
323
- name,
324
- ...description !== void 0 ? { description } : {},
325
- parameters: schemaProjection.schema
326
- });
327
- }
328
- return {
329
- inputToolCount,
330
- tools: projectedTools,
331
- diagnostics
332
- };
333
- }
334
- function requireProjectedFunction(name, projection, choiceLabel) {
335
- if (!projection.tools.some((tool) => tool.name === name)) throw new Error(`${choiceLabel} requested unavailable tool "${name}" after schema conversion`);
336
- }
337
- /** Keeps Responses tool choices aligned with surviving function schemas. */
338
- function reconcileOpenAIResponsesToolChoice(choice, projection) {
339
- if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
340
- if (choice === "required") {
341
- if (projection.tools.length === 0) throw new Error("OpenAI Responses tool_choice requires a tool, but no tools survived schema conversion");
342
- return choice;
343
- }
344
- if (choice === "none" || !isRecord(choice)) return choice;
345
- const choiceType = choice.type;
346
- if (choiceType === "function") {
347
- const functionName = choice.name;
348
- if (typeof functionName !== "string") return choice;
349
- requireProjectedFunction(functionName, projection, "OpenAI Responses tool_choice");
350
- return {
351
- type: "function",
352
- name: functionName
353
- };
354
- }
355
- if (choiceType !== "allowed_tools") return choice;
356
- const mode = choice.mode;
357
- const tools = choice.tools;
358
- if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
359
- const normalizedAllowedTools = [];
360
- for (const tool of tools) {
361
- if (!isRecord(tool) || tool.type !== "function") {
362
- normalizedAllowedTools.push(tool);
363
- continue;
364
- }
365
- const functionName = tool.name;
366
- if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
367
- type: "function",
368
- name: functionName
369
- });
370
- }
371
- if (normalizedAllowedTools.length === 0) {
372
- if (mode === "auto") return "none";
373
- throw new Error("OpenAI Responses tool_choice requires a tool, but no allowed tools survived schema conversion");
374
- }
375
- return {
376
- type: "allowed_tools",
377
- mode,
378
- tools: normalizedAllowedTools
379
- };
380
- }
381
- /** Keeps Chat Completions tool choices aligned with surviving function schemas. */
382
- function reconcileOpenAICompletionsToolChoice(choice, projection) {
383
- if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
384
- if (choice === "required") {
385
- if (projection.tools.length === 0) throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no tools survived schema conversion");
386
- return choice;
387
- }
388
- if (choice === "none" || !isRecord(choice)) return choice;
389
- const choiceType = choice.type;
390
- if (choiceType === "custom") throw new Error("OpenAI Chat Completions custom tool_choice is unsupported because this adapter emits function tools only");
391
- if (choiceType === "function") {
392
- const functionChoice = choice.function;
393
- if (!isRecord(functionChoice)) return choice;
394
- const functionName = functionChoice.name;
395
- if (typeof functionName !== "string") return choice;
396
- requireProjectedFunction(functionName, projection, "OpenAI Chat Completions tool_choice");
397
- return {
398
- type: "function",
399
- function: { name: functionName }
400
- };
401
- }
402
- if (choiceType !== "allowed_tools") return choice;
403
- const allowedConfig = choice.allowed_tools;
404
- if (!isRecord(allowedConfig)) return choice;
405
- const mode = allowedConfig.mode;
406
- const tools = allowedConfig.tools;
407
- if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
408
- const normalizedAllowedTools = [];
409
- for (const tool of tools) {
410
- if (!isRecord(tool) || tool.type !== "function") continue;
411
- const functionChoice = tool.function;
412
- const functionName = isRecord(functionChoice) ? functionChoice.name : void 0;
413
- if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
414
- type: "function",
415
- function: { name: functionName }
416
- });
417
- }
418
- if (normalizedAllowedTools.length === 0) {
419
- if (mode === "auto") return "none";
420
- throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no allowed tools survived schema conversion");
421
- }
422
- return {
423
- type: "allowed_tools",
424
- allowed_tools: {
425
- mode,
426
- tools: normalizedAllowedTools
427
- }
428
- };
429
- }
430
- //#endregion
1
+ import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
2
+ import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
3
+ import { r as uniqueValues, t as normalizeStringEntries } from "./string-normalization-CmLIasuf.mjs";
431
4
  //#region packages/ai/src/providers/clean-for-gemini.ts
432
5
  const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
433
6
  "patternProperties",
@@ -969,136 +542,46 @@ function isTypedObjectSchemaMissingValidProperties(schemaRecord, conditionalKey)
969
542
  function isTrulyEmptySchema(schemaRecord) {
970
543
  return Object.keys(schemaRecord).length === 0;
971
544
  }
972
- function normalizeArraySchemasMissingItems(schema) {
973
- if (!isRecord(schema)) return schema;
974
- let changed = false;
975
- const nextSchema = { ...schema };
976
- if (nextSchema.type === "array" && nextSchema.items === void 0) {
977
- nextSchema.items = {};
978
- changed = true;
979
- }
980
- const normalizeSchemaValue = (key) => {
981
- if (!(key in nextSchema)) return;
982
- const value = nextSchema[key];
983
- if (Array.isArray(value)) {
984
- const normalized = value.map(normalizeArraySchemasMissingItems);
985
- if (normalized.some((entry, index) => entry !== value[index])) {
986
- nextSchema[key] = normalized;
987
- changed = true;
988
- }
989
- return;
990
- }
991
- const normalized = normalizeArraySchemasMissingItems(value);
992
- if (normalized !== value) {
993
- nextSchema[key] = normalized;
994
- changed = true;
995
- }
996
- };
997
- for (const key of [
998
- "items",
999
- "contains",
1000
- "additionalProperties",
1001
- "propertyNames",
1002
- "not",
1003
- "if",
1004
- "then",
1005
- "else"
1006
- ]) normalizeSchemaValue(key);
1007
- for (const key of [
1008
- "anyOf",
1009
- "oneOf",
1010
- "allOf",
1011
- "prefixItems"
1012
- ]) normalizeSchemaValue(key);
1013
- for (const key of [
1014
- "properties",
1015
- "patternProperties",
1016
- "dependentSchemas",
1017
- "$defs",
1018
- "definitions"
1019
- ]) {
1020
- const value = nextSchema[key];
1021
- if (!isRecord(value)) continue;
1022
- let entriesChanged = false;
1023
- const normalizedEntries = Object.entries(value).map(([entryKey, entryValue]) => {
1024
- const normalizedEntryValue = normalizeArraySchemasMissingItems(entryValue);
1025
- if (normalizedEntryValue !== entryValue) entriesChanged = true;
1026
- return [entryKey, normalizedEntryValue];
1027
- });
1028
- if (entriesChanged) {
1029
- nextSchema[key] = Object.fromEntries(normalizedEntries);
1030
- changed = true;
1031
- }
1032
- }
1033
- return changed ? nextSchema : schema;
1034
- }
1035
- function schemaAllowsArrayType(schema) {
1036
- const type = schema.type;
1037
- return type === "array" || Array.isArray(type) && type.includes("array");
1038
- }
1039
- const ARRAY_ITEMS_SCHEMA_OBJECT_KEYS = /* @__PURE__ */ new Set([
1040
- "additionalProperties",
1041
- "contains",
1042
- "else",
1043
- "if",
1044
- "items",
1045
- "not",
1046
- "propertyNames",
1047
- "then"
1048
- ]);
1049
- const ARRAY_ITEMS_SCHEMA_ARRAY_KEYS = /* @__PURE__ */ new Set([
1050
- "allOf",
1051
- "anyOf",
1052
- "oneOf",
1053
- "prefixItems"
1054
- ]);
1055
- const ARRAY_ITEMS_SCHEMA_MAP_KEYS = /* @__PURE__ */ new Set([
1056
- "$defs",
1057
- "definitions",
1058
- "dependentSchemas",
1059
- "patternProperties",
1060
- "properties"
1061
- ]);
1062
- function stripEmptyArrayItemsFromArraySchemas(schema) {
545
+ function normalizeArraySchemaItems(schema, mode) {
1063
546
  if (Array.isArray(schema)) {
1064
- let changed = false;
1065
- const entries = schema.map((entry) => {
1066
- const next = stripEmptyArrayItemsFromArraySchemas(entry);
1067
- changed ||= next !== entry;
1068
- return next;
1069
- });
1070
- return changed ? entries : schema;
547
+ if (mode === "add") return schema;
548
+ const entries = schema.map((entry) => normalizeArraySchemaItems(entry, "omit"));
549
+ return entries.some((entry, index) => entry !== schema[index]) ? entries : schema;
1071
550
  }
1072
551
  if (!isRecord(schema)) return schema;
1073
- let changed = false;
1074
- const entries = Object.entries(schema).flatMap(([key, value]) => {
1075
- if (key === "items" && schemaAllowsArrayType(schema) && isRecord(value) && isTrulyEmptySchema(value)) {
552
+ const missingItems = mode !== "omit" && schema.type === "array" && schema.items === void 0;
553
+ let changed = missingItems;
554
+ const normalized = { ...schema };
555
+ if (missingItems) {
556
+ if (mode === "add") normalized.items = {};
557
+ else delete normalized.items;
558
+ }
559
+ const allowsArray = schema.type === "array" || Array.isArray(schema.type) && schema.type.includes("array");
560
+ const normalizeValue = (value, valueMode) => {
561
+ if (!Array.isArray(value)) return normalizeArraySchemaItems(value, valueMode);
562
+ const entries = value.map((entry) => normalizeArraySchemaItems(entry, valueMode));
563
+ return entries.some((entry, index) => entry !== value[index]) ? entries : value;
564
+ };
565
+ for (const [key, value] of Object.entries(normalized)) {
566
+ if (mode !== "add" && key === "items" && allowsArray && isRecord(value) && isTrulyEmptySchema(value)) {
567
+ delete normalized.items;
1076
568
  changed = true;
1077
- return [];
1078
- }
1079
- if (ARRAY_ITEMS_SCHEMA_OBJECT_KEYS.has(key)) {
1080
- const next = stripEmptyArrayItemsFromArraySchemas(value);
1081
- changed ||= next !== value;
1082
- return [[key, next]];
569
+ continue;
1083
570
  }
1084
- if (ARRAY_ITEMS_SCHEMA_ARRAY_KEYS.has(key) && Array.isArray(value)) {
1085
- const next = stripEmptyArrayItemsFromArraySchemas(value);
1086
- changed ||= next !== value;
1087
- return [[key, next]];
571
+ let next = value;
572
+ if (SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
573
+ const entries = Object.entries(value).map(([entryKey, entry]) => [entryKey, normalizeArraySchemaItems(entry, mode)]);
574
+ if (entries.some(([entryKey, entry]) => entry !== value[entryKey])) next = Object.fromEntries(entries);
575
+ } else if (SCHEMA_OBJECT_KEYS.has(key) || SCHEMA_ARRAY_KEYS.has(key)) {
576
+ const valueMode = SCHEMA_OBJECT_KEYS.has(key) || Array.isArray(value) ? mode : "add";
577
+ if (valueMode === mode || mode !== "omit") next = normalizeValue(value, valueMode);
1088
578
  }
1089
- if (ARRAY_ITEMS_SCHEMA_MAP_KEYS.has(key) && isRecord(value)) {
1090
- let mapChanged = false;
1091
- const next = Object.fromEntries(Object.entries(value).map(([entryKey, entryValue]) => {
1092
- const entryNext = stripEmptyArrayItemsFromArraySchemas(entryValue);
1093
- mapChanged ||= entryNext !== entryValue;
1094
- return [entryKey, entryNext];
1095
- }));
1096
- changed ||= mapChanged;
1097
- return [[key, mapChanged ? next : value]];
579
+ if (next !== value) {
580
+ setOwnSchemaProperty(normalized, key, next);
581
+ changed = true;
1098
582
  }
1099
- return [[key, value]];
1100
- });
1101
- return changed ? Object.fromEntries(entries) : schema;
583
+ }
584
+ return changed ? normalized : schema;
1102
585
  }
1103
586
  function copySchemaMeta(from, to) {
1104
587
  for (const key of [
@@ -1328,7 +811,7 @@ function normalizeOpenApiSchemaKeywords(schema) {
1328
811
  changed ||= next.some((entry, index) => entry !== value[index]);
1329
812
  continue;
1330
813
  }
1331
- normalized[key] = value;
814
+ setOwnSchemaProperty(normalized, key, value);
1332
815
  }
1333
816
  if (nullable) {
1334
817
  if (hasOpenApiComposition(normalized)) return wrapNullableComposedSchema(normalized);
@@ -1353,8 +836,7 @@ function normalizeToolParameterSchemaUncached(schema, options) {
1353
836
  const omitEmptyArrayItems = shouldOmitEmptyArrayItems(options?.modelCompat);
1354
837
  const isLlamacppGbnfProfile = normalizedToolSchemaProfile === "llamacpp";
1355
838
  function applyProviderCleaning(s) {
1356
- const normalizedSchema = normalizeArraySchemasMissingItems(s);
1357
- let arrayItemsCompatibleSchema = omitEmptyArrayItems ? stripEmptyArrayItemsFromArraySchemas(normalizedSchema) : normalizedSchema;
839
+ let arrayItemsCompatibleSchema = normalizeArraySchemaItems(s, omitEmptyArrayItems ? "normalize" : "add");
1358
840
  if (isLlamacppGbnfProfile) arrayItemsCompatibleSchema = cleanSchemaForLlamacppGbnf(arrayItemsCompatibleSchema);
1359
841
  if (isGeminiProvider && !isAnthropicProvider) {
1360
842
  const geminiCompatibleSchema = cleanSchemaForGemini(arrayItemsCompatibleSchema);
@@ -1392,13 +874,7 @@ function normalizeToolParameterSchemaUncached(schema, options) {
1392
874
  const props = entry.properties;
1393
875
  if (!props || typeof props !== "object") continue;
1394
876
  objectVariants += 1;
1395
- for (const [key, value] of Object.entries(props)) {
1396
- if (!(key in mergedProperties)) {
1397
- mergedProperties[key] = value;
1398
- continue;
1399
- }
1400
- mergedProperties[key] = mergePropertySchemas(mergedProperties[key], value);
1401
- }
877
+ for (const [key, value] of Object.entries(props)) setOwnSchemaProperty(mergedProperties, key, mergePropertySchemas(Object.hasOwn(mergedProperties, key) ? mergedProperties[key] : void 0, value));
1402
878
  const required = Array.isArray(entry.required) ? entry.required : [];
1403
879
  for (const key of required) {
1404
880
  if (typeof key !== "string") continue;
@@ -1463,12 +939,11 @@ const OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS = /* @__PURE__ */ new Set([
1463
939
  function normalizeOpenAIStrictCompatSchemaMap(schema) {
1464
940
  if (!schema || typeof schema !== "object" || Array.isArray(schema)) return schema;
1465
941
  let changed = false;
1466
- const normalized = {};
1467
- for (const [key, value] of Object.entries(schema)) {
942
+ const normalized = Object.fromEntries(Object.entries(schema).map(([key, value]) => {
1468
943
  const next = normalizeOpenAIStrictCompatSchemaRecursive(value, { promoteEmptyObject: false });
1469
- normalized[key] = next;
1470
944
  changed ||= next !== value;
1471
- }
945
+ return [key, next];
946
+ }));
1472
947
  return changed ? normalized : schema;
1473
948
  }
1474
949
  function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
@@ -1485,21 +960,17 @@ function normalizeOpenAIStrictCompatSchemaRecursive(schema, options) {
1485
960
  const record = schema;
1486
961
  let changed = false;
1487
962
  let hadNullType = false;
1488
- const normalized = {};
1489
- for (const [key, value] of Object.entries(record)) {
1490
- if (value === null && OPENAI_NULLABLE_ANNOTATION_KEYS.has(key)) {
963
+ const entries = Object.entries(record).flatMap(([key, value]) => {
964
+ if (value === null && (OPENAI_NULLABLE_ANNOTATION_KEYS.has(key) || key === "type")) {
965
+ hadNullType ||= key === "type";
1491
966
  changed = true;
1492
- continue;
1493
- }
1494
- if (value === null && key === "type") {
1495
- hadNullType = true;
1496
- changed = true;
1497
- continue;
967
+ return [];
1498
968
  }
1499
969
  const next = OPENAI_STRICT_COMPAT_SCHEMA_MAP_KEYS.has(key) ? normalizeOpenAIStrictCompatSchemaMap(value) : OPENAI_STRICT_COMPAT_SCHEMA_NESTED_KEYS.has(key) ? normalizeOpenAIStrictCompatSchemaRecursive(value, { promoteEmptyObject: false }) : value;
1500
- normalized[key] = next;
1501
970
  changed ||= next !== value;
1502
- }
971
+ return [[key, next]];
972
+ });
973
+ const normalized = Object.fromEntries(entries);
1503
974
  if (Object.keys(normalized).length === 0) {
1504
975
  if (!options.promoteEmptyObject) return schema;
1505
976
  return {
@@ -1625,12 +1096,11 @@ function normalizeStrictOpenAIJsonSchemaRecursive(schema, depth) {
1625
1096
  if (!schema || typeof schema !== "object") return schema;
1626
1097
  const record = schema;
1627
1098
  let changed = false;
1628
- const normalized = {};
1629
- for (const [key, value] of Object.entries(record)) {
1099
+ const normalized = Object.fromEntries(Object.entries(record).map(([key, value]) => {
1630
1100
  const next = normalizeStrictOpenAIJsonSchemaRecursive(value, key === "properties" ? depth : depth + 1);
1631
- normalized[key] = next;
1632
1101
  changed ||= next !== value;
1633
- }
1102
+ return [key, next];
1103
+ }));
1634
1104
  if (normalized.type === "object") {
1635
1105
  const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : void 0;
1636
1106
  if (properties && Object.keys(properties).length === 0 && !Array.isArray(normalized.required)) {
@@ -1694,4 +1164,4 @@ function resolveOpenAIProjectedToolsStrictToolFlag(projection, strict) {
1694
1164
  return projection.tools.every((tool) => isStrictOpenAIJsonSchemaCompatible(tool.parameters));
1695
1165
  }
1696
1166
  //#endregion
1697
- export { readOpenAICompletionsReasoningBatch as A, createOpenAIProviderAcceptanceHook as C, measureUtf8AppendBytes as D, log as E, resolvePromptCacheKey as M, throwIfModelStreamAborted as N, parseOpenAICompletionsUsage as O, createModelStreamCooperativeScheduler as S, isOpenAICompletionsThinkingEnabled as T, cleanSchemaForGemini as _, resolveOpenAIProjectedToolsStrictToolFlag as a, reconcileOpenAIResponsesToolChoice as b, extractToolSchemaModelCompat as c, shouldOmitEmptyArrayItems as d, stripUnsupportedSchemaKeywords as f, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as g, findLlamacppGbnfSchemaViolations as h, normalizeStrictOpenAIJsonSchema as i, resolveOpenAIClientBaseUrl as j, readOpenAICompletionsContentDeltas as k, normalizeToolParameterSchema as l, cleanSchemaForLlamacppGbnf as m, isStrictOpenAIJsonSchemaCompatible as n, findOpenAIStrictSchemaViolations as o, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as p, normalizeOpenAIStrictToolParameters as r, normalizeOpenAIStrictCompatSchema as s, findOpenAIStrictToolProjectionDiagnostics as t, resolveUnsupportedToolSchemaKeywords as u, projectOpenAITools as v, createOpenAIResponseHook as w, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as x, reconcileOpenAICompletionsToolChoice as y };
1167
+ export { cleanSchemaForGemini as _, resolveOpenAIProjectedToolsStrictToolFlag as a, extractToolSchemaModelCompat as c, shouldOmitEmptyArrayItems as d, stripUnsupportedSchemaKeywords as f, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as g, findLlamacppGbnfSchemaViolations as h, normalizeStrictOpenAIJsonSchema as i, normalizeToolParameterSchema as l, cleanSchemaForLlamacppGbnf as m, isStrictOpenAIJsonSchemaCompatible as n, findOpenAIStrictSchemaViolations as o, LLAMACPP_GBNF_MAX_REPETITION_THRESHOLD as p, normalizeOpenAIStrictToolParameters as r, normalizeOpenAIStrictCompatSchema as s, findOpenAIStrictToolProjectionDiagnostics as t, resolveUnsupportedToolSchemaKeywords as u };