@openclaw/ai 2026.9.2 → 2026.9.4
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 +3 -2
- package/dist/anthropic-C4Qu4H0Z.mjs +377 -0
- package/dist/{anthropic-payload-policy-d46X2pR0.d.mts → anthropic-payload-policy-BZ8umAbk.d.mts} +16 -6
- package/dist/{anthropic-compaction-replay-DB2FGLQc.mjs → anthropic-stream-reducer-CILWF7JD.mjs} +931 -184
- package/dist/{api-registry-DWtPjzyn.d.mts → api-registry-ByUwIR0e.d.mts} +2 -2
- package/dist/assistant-output-tLt4H-iQ.mjs +16 -0
- package/dist/assistant-text-phase-C20rxWwP.mjs +55 -0
- package/dist/{azure-openai-responses-C5bZRfAP.mjs → azure-openai-responses-BAlqlKKc.mjs} +5 -5
- package/dist/{base64-CEFBpSkN.mjs → base64-D-su8YVo.mjs} +1 -27
- package/dist/{diagnostics-DfFyKeX_.mjs → diagnostics-QuErwCIl.mjs} +96 -21
- package/dist/diagnostics.d.mts +3 -1
- package/dist/diagnostics.mjs +3 -3
- package/dist/{event-stream-BhT5T1Ay.d.mts → event-stream-Bt5Y4Pav.d.mts} +11 -3
- package/dist/event-stream-C3WGFsum.d.mts +1 -0
- package/dist/{event-stream-BgDvQeum.mjs → event-stream-D8PARQfL.mjs} +45 -1
- package/dist/event-stream.d.mts +2 -2
- package/dist/event-stream.mjs +1 -1
- package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-B37TB3rB.mjs} +3 -10
- package/dist/github-copilot-request-facts-BTEBMeOv.mjs +16 -0
- package/dist/{google-4qeuE8iX.mjs → google-DPBAOaOW.mjs} +10 -10
- package/dist/google-messages-6JkpHrhJ.mjs +448 -0
- package/dist/google-shared-BvBeW9aq.mjs +185 -0
- package/dist/{google-vertex-O9BcnB6X.mjs → google-vertex-k-TMCAYD.mjs} +7 -6
- package/dist/{host-DjzGmdZ2.d.mts → host-4atIX-2V.d.mts} +5 -3
- package/dist/{host-CEvLw30U.mjs → host-B8YfDGd4.mjs} +181 -41
- package/dist/host-policy-Zcg_cNz8.mjs +37 -0
- package/dist/{index-FnHM2FcI.d.mts → index-DdD3qerf.d.mts} +4 -4
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +7 -6
- package/dist/internal/anthropic.d.mts +7 -7
- package/dist/internal/anthropic.mjs +4 -4
- package/dist/internal/google-model-family.d.mts +5 -0
- package/dist/internal/google-model-family.mjs +15 -0
- package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
- package/dist/internal/openai-responses-payload-policy.mjs +3 -2
- package/dist/internal/openai.d.mts +8 -103
- package/dist/internal/openai.mjs +9 -10
- package/dist/internal/retry-after.d.mts +2 -4
- package/dist/internal/retry-after.mjs +57 -8
- package/dist/internal/runtime.d.mts +43 -7
- package/dist/internal/runtime.mjs +6 -7
- package/dist/internal/shared.d.mts +43 -3
- package/dist/internal/shared.mjs +5 -4
- package/dist/internal/tool-schema.d.mts +63 -0
- package/dist/internal/tool-schema.mjs +3 -0
- package/dist/{mistral-Tb6oalqH.mjs → mistral-CxUZ1jUb.mjs} +10 -37
- package/dist/model-transport-url-DKocrEsb.d.mts +28 -0
- package/dist/{openai-chatgpt-responses-yUXjPNfu.mjs → openai-chatgpt-responses-CgO6kZfo.mjs} +50 -41
- package/dist/{openai-completions-compat-CpjYUArk.d.mts → openai-completions-compat-eHgh5UPE.d.mts} +26 -4
- package/dist/{openai-completions-stream-BsrBe3Gg.mjs → openai-completions-stream-Da2vvl-S.mjs} +654 -453
- package/dist/openai-completions-yJuk7eis.mjs +187 -0
- package/dist/openai-prompt-cache-B4eYo2-I.d.mts +16 -0
- package/dist/openai-prompt-cache-Bds-n_9Q.mjs +220 -0
- package/dist/openai-provider-client-S2gCrM2Z.mjs +24 -0
- package/dist/{openai-responses-CCL41ALM.mjs → openai-responses-DaYwH05E.mjs} +14 -29
- package/dist/{openai-responses-compaction-window-BMVHFOtq.mjs → openai-responses-compaction-window-CIhBAkkq.mjs} +6 -246
- package/dist/{openai-responses-contracts-rF5DDRNS.d.mts → openai-responses-contracts-BjBAqAg_.d.mts} +5 -38
- package/dist/openai-responses-contracts-DDOHA62Y.mjs +245 -0
- package/dist/{openai-responses-prompt-observer-internal-D0bhBfgL.mjs → openai-responses-prompt-observer-internal-f8J7wpsk.mjs} +3 -3
- package/dist/{openai-responses-shared-Bmma_3Qc.mjs → openai-responses-shared-B8RdBPCv.mjs} +47 -118
- package/dist/openai-tool-projection-793cE3QX.d.mts +37 -0
- package/dist/{openai-tool-schema-_pTAJqKF.mjs → openai-tool-schema-CzjyYXun.mjs} +38 -556
- package/dist/openai-tool-schema-ynZBgqW-.d.mts +38 -0
- package/dist/openai-transport-params-9aPuV5YY.mjs +675 -0
- package/dist/positive-integer-41zhOdcV.mjs +8 -0
- package/dist/{provider-error-9TraxGvt.mjs → provider-error-BA-v_tKd.mjs} +70 -11
- package/dist/{provider-options-Bcc_p-TU.d.mts → provider-options-Ceqv1OKk.d.mts} +4 -39
- package/dist/{provider-replay-context-BuSUaAk5.mjs → provider-replay-context-CJ_YvcEW.mjs} +1 -1
- package/dist/{provider-transcript-transform-BaMbI1hr.mjs → provider-transcript-transform-V5YzU9zh.mjs} +1 -1
- package/dist/provider-transport-turn-state-D5EXOFL2.mjs +42 -0
- package/dist/provider-types-CVjKjsuq.d.mts +29 -0
- package/dist/provider-types.d.mts +6 -31
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +11 -11
- package/dist/{reasoning-tag-text-partitioner-DLCNXki6.mjs → reasoning-tag-text-partitioner-BcR5pztD.mjs} +19 -19
- package/dist/record-coerce-DwRYMj3t.mjs +32 -0
- package/dist/retry-after-CdCURCVg.d.mts +15 -0
- package/dist/session-affinity-Bcunsn4I.mjs +23 -0
- package/dist/{simple-options-BjHCCh4v.mjs → simple-options-BQbb4yQL.mjs} +24 -5
- package/dist/src-DDmEryvj.mjs +2 -0
- package/dist/{stream-first-event-timeout-DcNjoFQE.mjs → stream-first-event-timeout-2hfrquuz.mjs} +1 -1
- package/dist/string-coerce-fsri9iCu.mjs +34 -0
- package/dist/{string-normalization--fwJ4S2q.mjs → string-normalization-CmLIasuf.mjs} +1 -1
- package/dist/{tool-schema-json-projection-mJhXDcyz.mjs → tool-schema-json-projection-ClptDdAO.mjs} +2 -38
- package/dist/{transport-stream-shared-xnaqxmbP.d.mts → transport-stream-shared-DNvmoWnv.d.mts} +20 -36
- package/dist/{transport-stream-shared-CZqMhfIw.mjs → transport-stream-shared-zHll9BxO.mjs} +225 -13
- package/dist/transport-utils-zrYjICLZ.mjs +118 -0
- package/dist/transports.d.mts +137 -193
- package/dist/transports.mjs +204 -1334
- package/dist/types-DlfwzH3T.d.mts +1 -0
- package/dist/types-LFWwv0cF.mjs +8 -0
- package/dist/{types-CJ1-Ht7A.d.mts → types-Ntv5z2g2.d.mts} +74 -57
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +6 -5
- package/dist/{src-2qBGKg8O.mjs → usage-cost-BNWbbXav.mjs} +0 -1
- package/dist/utf16-slice-CvGodqok.mjs +29 -0
- package/dist/{validation-AKZBDGQd.d.mts → validation-B0t_G2H6.d.mts} +1 -1
- package/dist/{validation-CJZtym2g.mjs → validation-BDzVDnTs.mjs} +9 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +13 -3
- package/dist/anthropic-BDdqdVLK.mjs +0 -886
- package/dist/event-stream-zctLx0yr.d.mts +0 -1
- package/dist/google-shared-CWeG8RIl.mjs +0 -636
- package/dist/google-thinking-level-C-V3tecN.mjs +0 -9
- package/dist/hash-CHgqbJmD.mjs +0 -16
- package/dist/json-parse-BuAJEbdW.mjs +0 -146
- package/dist/openai-completions-BIUV3RDT.mjs +0 -403
- package/dist/openai-prompt-cache-CGnVB74a.mjs +0 -21
- package/dist/openai-prompt-cache-CNoIfHYC.d.mts +0 -16
- package/dist/sanitize-unicode-D6xUvZaS.mjs +0 -83
- package/dist/transport-utils-7il795_9.mjs +0 -138
- package/dist/types-3Lnm-QSJ.d.mts +0 -1
- package/dist/types-BDdaOVi2.mjs +0 -6
- package/dist/utf16-slice-qz3nsy87.mjs +0 -84
|
@@ -1,433 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { r as uniqueValues, t as normalizeStringEntries } from "./string-normalization--fwJ4S2q.mjs";
|
|
5
|
-
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-CGnVB74a.mjs";
|
|
6
|
-
import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-mJhXDcyz.mjs";
|
|
7
|
-
import { C as headersToRecord, _ as transportAbortError, f as notifyProviderHttpResponse } from "./transport-stream-shared-CZqMhfIw.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
|
|
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
|
-
|
|
1065
|
-
const entries = schema.map((entry) =>
|
|
1066
|
-
|
|
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
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
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 (
|
|
1090
|
-
|
|
1091
|
-
|
|
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
|
-
|
|
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 [
|
|
@@ -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
|
-
|
|
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);
|
|
@@ -1682,4 +1164,4 @@ function resolveOpenAIProjectedToolsStrictToolFlag(projection, strict) {
|
|
|
1682
1164
|
return projection.tools.every((tool) => isStrictOpenAIJsonSchemaCompatible(tool.parameters));
|
|
1683
1165
|
}
|
|
1684
1166
|
//#endregion
|
|
1685
|
-
export {
|
|
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 };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { n as OpenAIToolProjection } from "./openai-tool-projection-793cE3QX.mjs";
|
|
2
|
+
import { TSchema } from "typebox";
|
|
3
|
+
//#region packages/ai/src/providers/openai-tool-schema-compat.d.ts
|
|
4
|
+
/** Repairs recoverable OpenAI tool-schema shapes before canonical normalization. */
|
|
5
|
+
declare function normalizeOpenAIStrictCompatSchema(schema: unknown): TSchema;
|
|
6
|
+
/** Finds schema paths that violate OpenAI strict tool-schema requirements. */
|
|
7
|
+
declare function findOpenAIStrictSchemaViolations(schema: unknown, path: string, options?: {
|
|
8
|
+
requireObjectRoot?: boolean;
|
|
9
|
+
}): string[];
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region packages/ai/src/providers/openai-tool-schema.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* OpenAI strict-tool-schema normalization and diagnostics.
|
|
14
|
+
*
|
|
15
|
+
* Strict schemas need all object properties required and `additionalProperties: false`; model
|
|
16
|
+
* compatibility settings can also remove unsupported schema constructs before strict checks run.
|
|
17
|
+
*/
|
|
18
|
+
type ToolSchemaCompatInput = {
|
|
19
|
+
unsupportedToolSchemaKeywords?: unknown;
|
|
20
|
+
omitEmptyArrayItems?: unknown;
|
|
21
|
+
};
|
|
22
|
+
/** Normalizes a tool parameter schema into the OpenAI strict JSON-schema subset. */
|
|
23
|
+
declare function normalizeStrictOpenAIJsonSchema(schema: unknown, modelCompat?: ToolSchemaCompatInput | null): unknown;
|
|
24
|
+
/** Normalizes tool parameters using strict OpenAI rules only when strict mode is active. */
|
|
25
|
+
declare function normalizeOpenAIStrictToolParameters<T>(schema: T, strict: boolean, modelCompat?: ToolSchemaCompatInput | null): T;
|
|
26
|
+
/** Returns whether a schema already satisfies OpenAI strict tool-schema constraints. */
|
|
27
|
+
declare function isStrictOpenAIJsonSchemaCompatible(schema: unknown): boolean;
|
|
28
|
+
type OpenAIStrictToolSchemaDiagnostic = {
|
|
29
|
+
toolIndex: number;
|
|
30
|
+
toolName?: string;
|
|
31
|
+
violations: string[];
|
|
32
|
+
};
|
|
33
|
+
/** Returns strict-schema diagnostics for an already materialized OpenAI tool projection. */
|
|
34
|
+
declare function findOpenAIStrictToolProjectionDiagnostics(projection: OpenAIToolProjection): OpenAIStrictToolSchemaDiagnostic[];
|
|
35
|
+
/** Resolves strict mode for the projected tools that will be emitted in the request payload. */
|
|
36
|
+
declare function resolveOpenAIProjectedToolsStrictToolFlag(projection: OpenAIToolProjection, strict: boolean | null | undefined): boolean | undefined;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { resolveOpenAIProjectedToolsStrictToolFlag as a, normalizeStrictOpenAIJsonSchema as i, isStrictOpenAIJsonSchemaCompatible as n, findOpenAIStrictSchemaViolations as o, normalizeOpenAIStrictToolParameters as r, normalizeOpenAIStrictCompatSchema as s, findOpenAIStrictToolProjectionDiagnostics as t };
|