@openclaw/ai 2026.8.1-beta.2 → 2026.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{anthropic-B6dLpq5L.mjs → anthropic-Djj7L1rx.mjs} +49 -39
- package/dist/{anthropic-compaction-replay-8lJNKXOE.mjs → anthropic-compaction-replay-CY4tkD4V.mjs} +42 -44
- package/dist/{anthropic-payload-policy-CiEuQS72.d.mts → anthropic-payload-policy-i_5_inWe.d.mts} +4 -2
- package/dist/{api-registry-k3zTz0cV.d.mts → api-registry-C9-wZd_W.d.mts} +2 -1
- package/dist/{azure-openai-responses-mxIOtUnn.mjs → azure-openai-responses-Bj3czHNa.mjs} +4 -4
- package/dist/{number-coercion-H9qHik3g.mjs → base64-CEFBpSkN.mjs} +73 -1
- package/dist/diagnostics.d.mts +2 -3
- package/dist/diagnostics.mjs +1 -1
- package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-bktO00EJ.mjs} +2 -15
- package/dist/event-stream-C988TSLe.d.mts +1 -0
- package/dist/{event-stream-BP6AWT8j.d.mts → event-stream-UhnxHuqt.d.mts} +1 -2
- package/dist/event-stream.d.mts +2 -1
- package/dist/{google-C7h2QzDX.mjs → google-0Ca6TYbw.mjs} +4 -4
- package/dist/{google-shared-B0Qr9OR7.mjs → google-shared-DVfL9COU.mjs} +22 -8
- package/dist/{google-vertex-Bhc3TjDl.mjs → google-vertex-5dAMxprN.mjs} +4 -4
- package/dist/{host-DTqNc7ad.mjs → host-D51fmkH6.mjs} +40 -33
- package/dist/{host-vWgMMhiJ.d.mts → host-DoPJJ1KD.d.mts} +7 -7
- package/dist/index-N3zr6__t.d.mts +105 -0
- package/dist/index.d.mts +9 -10
- package/dist/index.mjs +2 -3
- package/dist/internal/anthropic.d.mts +57 -49
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
- package/dist/internal/openai-responses-payload-policy.mjs +2 -3
- package/dist/internal/openai.d.mts +65 -63
- package/dist/internal/openai.mjs +10 -8
- package/dist/internal/retry-after.d.mts +2 -3
- package/dist/internal/runtime.d.mts +53 -40
- package/dist/internal/runtime.mjs +10 -9
- package/dist/internal/shared.d.mts +37 -23
- package/dist/internal/shared.mjs +4 -4
- package/dist/{json-parse-CDnesDM_.mjs → json-parse-BuAJEbdW.mjs} +18 -2
- package/dist/{headers-DdOQtGuU.mjs → llm-request-activity-BjtkplhG.mjs} +1 -9
- package/dist/{mistral-CEWoQI_g.mjs → mistral-BCnrI-kV.mjs} +64 -53
- package/dist/{openai-chatgpt-responses-CrPmqERt.mjs → openai-chatgpt-responses-CGBGWSqr.mjs} +45 -20
- package/dist/{openai-completions-BPnt4Sml.mjs → openai-completions-BaTuwID7.mjs} +63 -258
- package/dist/{openai-completions-compat-Dt3dcawL.d.mts → openai-completions-compat-DB7FFq7k.d.mts} +3 -3
- package/dist/openai-completions-stream-Bpns6uNc.mjs +1622 -0
- package/dist/{openai-responses-DhIKtOup.mjs → openai-responses-1GBcQujk.mjs} +8 -6
- package/dist/openai-responses-compaction-window-DwydGZI8.mjs +686 -0
- package/dist/{openai-responses-contracts-XpZJxrRG.d.mts → openai-responses-contracts-DgaR3t5T.d.mts} +14 -5
- package/dist/{openai-responses-payload-policy-BSs371VM.d.mts → openai-responses-payload-policy-rLRPsSmB.d.mts} +2 -0
- package/dist/{openai-responses-prompt-observer-internal-DgNTYnRY.mjs → openai-responses-prompt-observer-internal-_nhGTn2b.mjs} +3 -3
- package/dist/{openai-responses-shared-DXIt3iY5.mjs → openai-responses-shared-zPmKnhF5.mjs} +345 -1553
- package/dist/openai-stop-reason-Drnn_6Qj.mjs +28 -0
- package/dist/openai-tool-schema-Dgl4H2MU.mjs +1695 -0
- package/dist/{provider-error-BUwEnjXq.mjs → provider-error-jZP5NMTZ.mjs} +3 -82
- package/dist/{provider-options-B96RdNpH.d.mts → provider-options-HvA_slFa.d.mts} +23 -4
- package/dist/provider-transcript-transform-C01bQ5a3.mjs +32 -0
- package/dist/provider-types.d.mts +18 -17
- package/dist/providers.d.mts +5 -6
- package/dist/providers.mjs +9 -9
- package/dist/{reasoning-tag-text-partitioner-rnPwX2pg.mjs → reasoning-tag-text-partitioner-CwzKb0bA.mjs} +4 -1
- package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
- package/dist/{sanitize-unicode-BYqrYtC_.mjs → sanitize-unicode-DCkltN94.mjs} +1 -2
- package/dist/{simple-options-D58D5Kvw.mjs → simple-options-DKx86yX9.mjs} +42 -4
- package/dist/{anthropic-JsNA5KCu.mjs → src-Bu3FiFAG.mjs} +1 -1
- package/dist/{stream-first-event-timeout-MK28puvq.mjs → stream-first-event-timeout-DcNjoFQE.mjs} +1 -1
- package/dist/{streaming-byte-guard-BrbkbwUu.mjs → streaming-byte-guard-CC-HMn_u.mjs} +5 -6
- package/dist/string-normalization--fwJ4S2q.mjs +16 -0
- package/dist/{tool-schema-json-projection-q5d7QX5c.mjs → tool-schema-json-projection-qvTEs5Am.mjs} +17 -8
- package/dist/transport-stream-shared-CT5ycdzn.mjs +342 -0
- package/dist/transport-stream-shared-NjwWNaRY.d.mts +138 -0
- package/dist/{transport-utils-DJqkxbhC.mjs → transport-utils-BHx9z8Cl.mjs} +9 -9
- package/dist/transports.d.mts +140 -169
- package/dist/transports.mjs +269 -1262
- package/dist/types-DtGu2d3C.d.mts +1 -0
- package/dist/{types-BHNrPS1l.d.mts → types-h38Azne1.d.mts} +53 -17
- package/dist/types.d.mts +6 -5
- package/dist/types.mjs +1 -2
- package/dist/utf16-slice-qz3nsy87.mjs +84 -0
- package/dist/{validation-DT9SrFn3.d.mts → validation-C68lP2uy.d.mts} +1 -2
- package/dist/validation.d.mts +1 -1
- package/package.json +6 -6
- package/dist/anthropic-SrGtwsJu.d.mts +0 -100
- package/dist/index-BVVgDSdq.d.mts +0 -1
- package/dist/openai-responses-contracts-CyfIkQi5.mjs +0 -253
- package/dist/openai-responses-payload-policy-BDxV-W0c.mjs +0 -206
- package/dist/openai-stop-reason-BkFkqqK0.mjs +0 -563
- package/dist/openai-tool-projection-CY04OcvQ.mjs +0 -338
- package/dist/provider-transcript-transform-ePx-Bbfr.mjs +0 -155
- package/dist/record-coerce-DdXsgUd_.mjs +0 -23
- package/dist/src-D2H6yKkH.mjs +0 -2
- package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
- package/dist/string-coerce-fsri9iCu.mjs +0 -34
- package/dist/types-BVVgDSdq.d.mts +0 -1
- package/dist/utf16-slice-CvGodqok.mjs +0 -29
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import { n as applyProviderReportedUsageCost, r as calculateCost } from "./sanitize-unicode-BYqrYtC_.mjs";
|
|
2
|
-
import { n as getAiTransportHost } from "./host-DTqNc7ad.mjs";
|
|
3
|
-
import { a as isRecord } from "./record-coerce-DdXsgUd_.mjs";
|
|
4
|
-
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
|
|
5
|
-
import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-q5d7QX5c.mjs";
|
|
6
|
-
import { t as headersToRecord } from "./headers-DdOQtGuU.mjs";
|
|
7
|
-
import { f as transportAbortError } from "./provider-transcript-transform-ePx-Bbfr.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 parseOpenAICompletionsUsage(rawUsage, model, options) {
|
|
28
|
-
const cacheRead = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
|
|
29
|
-
const cacheWrite = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
|
|
30
|
-
const input = Math.max(0, (rawUsage.prompt_tokens || 0) - cacheRead - cacheWrite);
|
|
31
|
-
const output = rawUsage.completion_tokens || 0;
|
|
32
|
-
const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
|
|
33
|
-
const usage = {
|
|
34
|
-
input,
|
|
35
|
-
output,
|
|
36
|
-
cacheRead,
|
|
37
|
-
cacheWrite,
|
|
38
|
-
...options?.includeReasoningTokens !== false && typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) ? { reasoningTokens } : {},
|
|
39
|
-
totalTokens: input + output + cacheRead + cacheWrite,
|
|
40
|
-
cost: {
|
|
41
|
-
input: 0,
|
|
42
|
-
output: 0,
|
|
43
|
-
cacheRead: 0,
|
|
44
|
-
cacheWrite: 0,
|
|
45
|
-
total: 0
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
calculateCost(model, usage);
|
|
49
|
-
applyProviderReportedUsageCost(usage, rawUsage.cost);
|
|
50
|
-
return usage;
|
|
51
|
-
}
|
|
52
|
-
function createOpenAIResponseHook(onResponse, response, model) {
|
|
53
|
-
return onResponse ? () => onResponse({
|
|
54
|
-
status: response.status,
|
|
55
|
-
headers: headersToRecord(response.headers)
|
|
56
|
-
}, model) : void 0;
|
|
57
|
-
}
|
|
58
|
-
function throwIfModelStreamAborted(signal) {
|
|
59
|
-
if (signal?.aborted) throw transportAbortError(signal);
|
|
60
|
-
}
|
|
61
|
-
/** Measure one UTF-8 append without double-counting a surrogate pair split across chunks. */
|
|
62
|
-
function measureUtf8AppendBytes(bufferEndsWithHighSurrogate, chunk) {
|
|
63
|
-
let bytes = Buffer.byteLength(chunk, "utf8");
|
|
64
|
-
if (!chunk) return {
|
|
65
|
-
bytes,
|
|
66
|
-
endsWithHighSurrogate: bufferEndsWithHighSurrogate
|
|
67
|
-
};
|
|
68
|
-
const nextCodeUnit = chunk.charCodeAt(0);
|
|
69
|
-
if (bufferEndsWithHighSurrogate && nextCodeUnit >= 56320 && nextCodeUnit <= 57343) bytes -= 2;
|
|
70
|
-
const finalCodeUnit = chunk.charCodeAt(chunk.length - 1);
|
|
71
|
-
return {
|
|
72
|
-
bytes,
|
|
73
|
-
endsWithHighSurrogate: finalCodeUnit >= 55296 && finalCodeUnit <= 56319
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
function createModelStreamCooperativeScheduler(signal) {
|
|
77
|
-
let lastYieldedAt = Date.now();
|
|
78
|
-
let eventsSinceYield = 0;
|
|
79
|
-
return { async afterEvent() {
|
|
80
|
-
throwIfModelStreamAborted(signal);
|
|
81
|
-
eventsSinceYield += 1;
|
|
82
|
-
const now = Date.now();
|
|
83
|
-
if (eventsSinceYield < MODEL_STREAM_COOPERATIVE_YIELD_MAX_EVENTS && now - lastYieldedAt < MODEL_STREAM_COOPERATIVE_YIELD_INTERVAL_MS) return;
|
|
84
|
-
eventsSinceYield = 0;
|
|
85
|
-
lastYieldedAt = now;
|
|
86
|
-
await new Promise((resolve) => {
|
|
87
|
-
setTimeout(resolve, 0);
|
|
88
|
-
});
|
|
89
|
-
throwIfModelStreamAborted(signal);
|
|
90
|
-
} };
|
|
91
|
-
}
|
|
92
|
-
function resolvePromptCacheKey(options, cacheRetention) {
|
|
93
|
-
if (cacheRetention === "none") return;
|
|
94
|
-
return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
|
|
95
|
-
}
|
|
96
|
-
function isOpenAICompletionsThinkingEnabled(effort) {
|
|
97
|
-
const normalized = effort.trim().toLowerCase();
|
|
98
|
-
return normalized !== "off" && normalized !== "none";
|
|
99
|
-
}
|
|
100
|
-
function readOpenAICompletionsContentDeltas(content, topLevelRefusal, mirroredThinking = []) {
|
|
101
|
-
let deltas = readOpenAICompletionsContentPartDeltas(content);
|
|
102
|
-
if (mirroredThinking.length > 0) {
|
|
103
|
-
const structuredThinking = deltas.filter((delta) => delta.kind === "thinking").map((delta) => delta.text);
|
|
104
|
-
const mirrorsCombinedThinking = structuredThinking.length > 1 && mirroredThinking.includes(structuredThinking.join(""));
|
|
105
|
-
deltas = deltas.filter((delta) => delta.kind !== "thinking" || !mirrorsCombinedThinking && !mirroredThinking.includes(delta.text));
|
|
106
|
-
}
|
|
107
|
-
if (typeof topLevelRefusal !== "string" || !topLevelRefusal) return deltas;
|
|
108
|
-
const structuredRefusals = deltas.filter((delta) => delta.kind === "text" && delta.source === "refusal").map((delta) => delta.text);
|
|
109
|
-
if (structuredRefusals.some((refusal) => refusal === topLevelRefusal) || structuredRefusals.length > 1 && structuredRefusals.join("") === topLevelRefusal) return deltas;
|
|
110
|
-
return [...deltas, {
|
|
111
|
-
kind: "text",
|
|
112
|
-
text: topLevelRefusal,
|
|
113
|
-
source: "refusal"
|
|
114
|
-
}];
|
|
115
|
-
}
|
|
116
|
-
function readOpenAICompletionsContentPartDeltas(content) {
|
|
117
|
-
if (typeof content === "string") return content ? [{
|
|
118
|
-
kind: "text",
|
|
119
|
-
text: content
|
|
120
|
-
}] : [];
|
|
121
|
-
if (Array.isArray(content)) return content.flatMap(readOpenAICompletionsContentPartDeltas);
|
|
122
|
-
if (!content || typeof content !== "object") return [];
|
|
123
|
-
const record = content;
|
|
124
|
-
const type = typeof record.type === "string" ? record.type.toLowerCase() : "";
|
|
125
|
-
const extractText = (value) => {
|
|
126
|
-
if (typeof value === "string") return value;
|
|
127
|
-
if (Array.isArray(value)) return value.map(extractText).join("");
|
|
128
|
-
if (value && typeof value === "object") {
|
|
129
|
-
const nested = value;
|
|
130
|
-
return extractText(nested.text ?? nested.content ?? nested.thinking ?? nested.refusal);
|
|
131
|
-
}
|
|
132
|
-
return "";
|
|
133
|
-
};
|
|
134
|
-
const text = extractText(record.text ?? record.content ?? record.thinking ?? record.refusal);
|
|
135
|
-
if (!text) return [];
|
|
136
|
-
if (type.includes("thinking") || type.includes("reasoning")) return [{
|
|
137
|
-
kind: "thinking",
|
|
138
|
-
text
|
|
139
|
-
}];
|
|
140
|
-
if (type === "refusal") return [{
|
|
141
|
-
kind: "text",
|
|
142
|
-
text,
|
|
143
|
-
source: "refusal"
|
|
144
|
-
}];
|
|
145
|
-
if (["text", "output_text"].includes(type) || type.endsWith(".output_text")) return [{
|
|
146
|
-
kind: "text",
|
|
147
|
-
text
|
|
148
|
-
}];
|
|
149
|
-
return [];
|
|
150
|
-
}
|
|
151
|
-
//#endregion
|
|
152
|
-
//#region packages/ai/src/providers/openai-tool-projection.ts
|
|
153
|
-
function unreadableToolDiagnostic(toolIndex) {
|
|
154
|
-
return {
|
|
155
|
-
toolIndex,
|
|
156
|
-
violations: [`tool[${toolIndex}] is unreadable`]
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
/** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
|
|
160
|
-
function projectOpenAITools(tools) {
|
|
161
|
-
let inputToolCount;
|
|
162
|
-
try {
|
|
163
|
-
inputToolCount = tools.length;
|
|
164
|
-
} catch {
|
|
165
|
-
return {
|
|
166
|
-
inputToolCount: 0,
|
|
167
|
-
tools: [],
|
|
168
|
-
diagnostics: [unreadableToolDiagnostic(0)]
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
const projectedTools = [];
|
|
172
|
-
const diagnostics = [];
|
|
173
|
-
for (let toolIndex = 0; toolIndex < inputToolCount; toolIndex += 1) {
|
|
174
|
-
let tool;
|
|
175
|
-
try {
|
|
176
|
-
const candidate = tools[toolIndex];
|
|
177
|
-
if (!candidate) {
|
|
178
|
-
diagnostics.push(unreadableToolDiagnostic(toolIndex));
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
tool = candidate;
|
|
182
|
-
} catch {
|
|
183
|
-
diagnostics.push(unreadableToolDiagnostic(toolIndex));
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
let name;
|
|
187
|
-
try {
|
|
188
|
-
name = tool.name;
|
|
189
|
-
} catch {
|
|
190
|
-
diagnostics.push({
|
|
191
|
-
toolIndex,
|
|
192
|
-
violations: [`tool[${toolIndex}].name is unreadable`]
|
|
193
|
-
});
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
if (typeof name !== "string" || !name) {
|
|
197
|
-
diagnostics.push({
|
|
198
|
-
toolIndex,
|
|
199
|
-
violations: [`tool[${toolIndex}].name is empty`]
|
|
200
|
-
});
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
let parameters;
|
|
204
|
-
try {
|
|
205
|
-
parameters = tool.parameters;
|
|
206
|
-
} catch {
|
|
207
|
-
diagnostics.push({
|
|
208
|
-
toolIndex,
|
|
209
|
-
toolName: name,
|
|
210
|
-
violations: [`${name}.parameters is unreadable`]
|
|
211
|
-
});
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
const schemaProjection = projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
|
|
215
|
-
if (!isRecord(schemaProjection.schema) || schemaProjection.violations.length > 0) {
|
|
216
|
-
diagnostics.push({
|
|
217
|
-
toolIndex,
|
|
218
|
-
toolName: name,
|
|
219
|
-
violations: schemaProjection.violations.length > 0 ? schemaProjection.violations : [`${name}.parameters must be a JSON object schema`]
|
|
220
|
-
});
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
let descriptionValue;
|
|
224
|
-
try {
|
|
225
|
-
descriptionValue = tool.description;
|
|
226
|
-
} catch {}
|
|
227
|
-
const description = typeof descriptionValue === "string" ? descriptionValue : void 0;
|
|
228
|
-
projectedTools.push({
|
|
229
|
-
toolIndex,
|
|
230
|
-
name,
|
|
231
|
-
...description !== void 0 ? { description } : {},
|
|
232
|
-
parameters: schemaProjection.schema
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
return {
|
|
236
|
-
inputToolCount,
|
|
237
|
-
tools: projectedTools,
|
|
238
|
-
diagnostics
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
function requireProjectedFunction(name, projection, choiceLabel) {
|
|
242
|
-
if (!projection.tools.some((tool) => tool.name === name)) throw new Error(`${choiceLabel} requested unavailable tool "${name}" after schema conversion`);
|
|
243
|
-
}
|
|
244
|
-
/** Keeps Responses tool choices aligned with surviving function schemas. */
|
|
245
|
-
function reconcileOpenAIResponsesToolChoice(choice, projection) {
|
|
246
|
-
if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
|
|
247
|
-
if (choice === "required") {
|
|
248
|
-
if (projection.tools.length === 0) throw new Error("OpenAI Responses tool_choice requires a tool, but no tools survived schema conversion");
|
|
249
|
-
return choice;
|
|
250
|
-
}
|
|
251
|
-
if (choice === "none" || !isRecord(choice)) return choice;
|
|
252
|
-
const choiceType = choice.type;
|
|
253
|
-
if (choiceType === "function") {
|
|
254
|
-
const functionName = choice.name;
|
|
255
|
-
if (typeof functionName !== "string") return choice;
|
|
256
|
-
requireProjectedFunction(functionName, projection, "OpenAI Responses tool_choice");
|
|
257
|
-
return {
|
|
258
|
-
type: "function",
|
|
259
|
-
name: functionName
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
if (choiceType !== "allowed_tools") return choice;
|
|
263
|
-
const mode = choice.mode;
|
|
264
|
-
const tools = choice.tools;
|
|
265
|
-
if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
|
|
266
|
-
const normalizedAllowedTools = [];
|
|
267
|
-
for (const tool of tools) {
|
|
268
|
-
if (!isRecord(tool) || tool.type !== "function") {
|
|
269
|
-
normalizedAllowedTools.push(tool);
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
const functionName = tool.name;
|
|
273
|
-
if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
|
|
274
|
-
type: "function",
|
|
275
|
-
name: functionName
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
if (normalizedAllowedTools.length === 0) {
|
|
279
|
-
if (mode === "auto") return "none";
|
|
280
|
-
throw new Error("OpenAI Responses tool_choice requires a tool, but no allowed tools survived schema conversion");
|
|
281
|
-
}
|
|
282
|
-
return {
|
|
283
|
-
type: "allowed_tools",
|
|
284
|
-
mode,
|
|
285
|
-
tools: normalizedAllowedTools
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
/** Keeps Chat Completions tool choices aligned with surviving function schemas. */
|
|
289
|
-
function reconcileOpenAICompletionsToolChoice(choice, projection) {
|
|
290
|
-
if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
|
|
291
|
-
if (choice === "required") {
|
|
292
|
-
if (projection.tools.length === 0) throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no tools survived schema conversion");
|
|
293
|
-
return choice;
|
|
294
|
-
}
|
|
295
|
-
if (choice === "none" || !isRecord(choice)) return choice;
|
|
296
|
-
const choiceType = choice.type;
|
|
297
|
-
if (choiceType === "custom") throw new Error("OpenAI Chat Completions custom tool_choice is unsupported because this adapter emits function tools only");
|
|
298
|
-
if (choiceType === "function") {
|
|
299
|
-
const functionChoice = choice.function;
|
|
300
|
-
if (!isRecord(functionChoice)) return choice;
|
|
301
|
-
const functionName = functionChoice.name;
|
|
302
|
-
if (typeof functionName !== "string") return choice;
|
|
303
|
-
requireProjectedFunction(functionName, projection, "OpenAI Chat Completions tool_choice");
|
|
304
|
-
return {
|
|
305
|
-
type: "function",
|
|
306
|
-
function: { name: functionName }
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
if (choiceType !== "allowed_tools") return choice;
|
|
310
|
-
const allowedConfig = choice.allowed_tools;
|
|
311
|
-
if (!isRecord(allowedConfig)) return choice;
|
|
312
|
-
const mode = allowedConfig.mode;
|
|
313
|
-
const tools = allowedConfig.tools;
|
|
314
|
-
if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
|
|
315
|
-
const normalizedAllowedTools = [];
|
|
316
|
-
for (const tool of tools) {
|
|
317
|
-
if (!isRecord(tool) || tool.type !== "function") continue;
|
|
318
|
-
const functionChoice = tool.function;
|
|
319
|
-
const functionName = isRecord(functionChoice) ? functionChoice.name : void 0;
|
|
320
|
-
if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
|
|
321
|
-
type: "function",
|
|
322
|
-
function: { name: functionName }
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
if (normalizedAllowedTools.length === 0) {
|
|
326
|
-
if (mode === "auto") return "none";
|
|
327
|
-
throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no allowed tools survived schema conversion");
|
|
328
|
-
}
|
|
329
|
-
return {
|
|
330
|
-
type: "allowed_tools",
|
|
331
|
-
allowed_tools: {
|
|
332
|
-
mode,
|
|
333
|
-
tools: normalizedAllowedTools
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
//#endregion
|
|
338
|
-
export { createModelStreamCooperativeScheduler as a, log as c, readOpenAICompletionsContentDeltas as d, resolvePromptCacheKey as f, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as i, measureUtf8AppendBytes as l, reconcileOpenAICompletionsToolChoice as n, createOpenAIResponseHook as o, throwIfModelStreamAborted as p, reconcileOpenAIResponsesToolChoice as r, isOpenAICompletionsThinkingEnabled as s, projectOpenAITools as t, parseOpenAICompletionsUsage as u };
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { r as createAssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
|
|
2
|
-
import { t as sanitizeSurrogates } from "./sanitize-unicode-BYqrYtC_.mjs";
|
|
3
|
-
import { i as transformMessages } from "./host-DTqNc7ad.mjs";
|
|
4
|
-
import { i as asOptionalRecord, t as asNonArrayRecord } from "./record-coerce-DdXsgUd_.mjs";
|
|
5
|
-
import { n as projectProviderError } from "./provider-error-BUwEnjXq.mjs";
|
|
6
|
-
//#region packages/ai/src/transports/transport-stream-shared.ts
|
|
7
|
-
const EMPTY_TOOL_RESULT_TEXT = "(no output)";
|
|
8
|
-
function sanitizeTransportPayloadText(text) {
|
|
9
|
-
if (typeof text !== "string") return "";
|
|
10
|
-
return sanitizeSurrogates(text);
|
|
11
|
-
}
|
|
12
|
-
function sanitizeNonEmptyTransportPayloadText(text, fallback = EMPTY_TOOL_RESULT_TEXT) {
|
|
13
|
-
const sanitized = sanitizeTransportPayloadText(text);
|
|
14
|
-
return sanitized.trim().length > 0 ? sanitized : fallback;
|
|
15
|
-
}
|
|
16
|
-
function coerceTransportToolCallArguments(argumentsValue) {
|
|
17
|
-
const argumentsRecord = asOptionalRecord(argumentsValue);
|
|
18
|
-
if (argumentsRecord) return argumentsRecord;
|
|
19
|
-
if (typeof argumentsValue === "string") try {
|
|
20
|
-
return asNonArrayRecord(JSON.parse(argumentsValue));
|
|
21
|
-
} catch {}
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
function mergeTransportHeaders(...headerSources) {
|
|
25
|
-
const merged = {};
|
|
26
|
-
for (const headers of headerSources) if (headers) Object.assign(merged, headers);
|
|
27
|
-
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
28
|
-
}
|
|
29
|
-
function mergeTransportMetadata(payload, metadata) {
|
|
30
|
-
if (!metadata || Object.keys(metadata).length === 0) return payload;
|
|
31
|
-
const existingMetadata = asOptionalRecord(payload.metadata);
|
|
32
|
-
return {
|
|
33
|
-
...payload,
|
|
34
|
-
metadata: {
|
|
35
|
-
...existingMetadata,
|
|
36
|
-
...metadata
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
function createEmptyTransportUsage() {
|
|
41
|
-
return {
|
|
42
|
-
input: 0,
|
|
43
|
-
output: 0,
|
|
44
|
-
cacheRead: 0,
|
|
45
|
-
cacheWrite: 0,
|
|
46
|
-
totalTokens: 0,
|
|
47
|
-
cost: {
|
|
48
|
-
input: 0,
|
|
49
|
-
output: 0,
|
|
50
|
-
cacheRead: 0,
|
|
51
|
-
cacheWrite: 0,
|
|
52
|
-
total: 0
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
function createWritableTransportEventStream() {
|
|
57
|
-
const eventStream = createAssistantMessageEventStream();
|
|
58
|
-
return {
|
|
59
|
-
eventStream,
|
|
60
|
-
stream: eventStream
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Abort error to surface for an aborted `signal`.
|
|
65
|
-
*
|
|
66
|
-
* Rethrows the caller's abort reason only when it carries a `code`, so that code
|
|
67
|
-
* survives into `errorCode` on the persisted assistant message and consumers can
|
|
68
|
-
* recognize an abort's origin without matching error text. A default
|
|
69
|
-
* `abort()` reason is an uncoded DOMException that carries nothing the synthetic
|
|
70
|
-
* error does not, so it keeps the "Request was aborted" text every transport
|
|
71
|
-
* already emits rather than churning it.
|
|
72
|
-
*/
|
|
73
|
-
function transportAbortError(signal) {
|
|
74
|
-
const reason = signal?.reason;
|
|
75
|
-
return reason instanceof Error && typeof reason.code === "string" ? reason : /* @__PURE__ */ new Error("Request was aborted");
|
|
76
|
-
}
|
|
77
|
-
/** Run a provider-response hook before start/body consumption inside the first-event deadline. */
|
|
78
|
-
function withProviderResponseHook(params) {
|
|
79
|
-
return { async *[Symbol.asyncIterator]() {
|
|
80
|
-
let onAbort;
|
|
81
|
-
try {
|
|
82
|
-
if (params.signal.aborted) throw transportAbortError(params.signal);
|
|
83
|
-
if (params.hook) await Promise.race([Promise.resolve().then(params.hook), new Promise((_resolve, reject) => {
|
|
84
|
-
onAbort = () => reject(transportAbortError(params.signal));
|
|
85
|
-
params.signal.addEventListener("abort", onAbort, { once: true });
|
|
86
|
-
})]);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
params.abort(error instanceof Error ? error : new Error(String(error)));
|
|
89
|
-
throw error;
|
|
90
|
-
} finally {
|
|
91
|
-
if (onAbort) params.signal.removeEventListener("abort", onAbort);
|
|
92
|
-
}
|
|
93
|
-
if (params.signal.aborted) throw transportAbortError(params.signal);
|
|
94
|
-
params.onReady?.();
|
|
95
|
-
if (params.stream) yield* params.stream;
|
|
96
|
-
} };
|
|
97
|
-
}
|
|
98
|
-
function finalizeTransportStream(params) {
|
|
99
|
-
const { stream, output, signal } = params;
|
|
100
|
-
if (signal?.aborted) throw transportAbortError(signal);
|
|
101
|
-
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
|
|
102
|
-
stream.push({
|
|
103
|
-
type: "done",
|
|
104
|
-
reason: output.stopReason,
|
|
105
|
-
message: output
|
|
106
|
-
});
|
|
107
|
-
stream.end();
|
|
108
|
-
}
|
|
109
|
-
/** @deprecated Use projectProviderError. v2026.7.2-beta.5 compatibility; remove after 2026.10. */
|
|
110
|
-
function assignTransportErrorDetails(output, error, signal) {
|
|
111
|
-
Object.assign(output, projectProviderError(error, signal));
|
|
112
|
-
}
|
|
113
|
-
function failTransportStream(params) {
|
|
114
|
-
const { stream, output, signal, error, cleanup } = params;
|
|
115
|
-
cleanup?.();
|
|
116
|
-
assignTransportErrorDetails(output, error, signal);
|
|
117
|
-
stream.push({
|
|
118
|
-
type: "error",
|
|
119
|
-
reason: output.stopReason,
|
|
120
|
-
error: output
|
|
121
|
-
});
|
|
122
|
-
stream.end();
|
|
123
|
-
}
|
|
124
|
-
//#endregion
|
|
125
|
-
//#region packages/ai/src/provider-transcript-transform.ts
|
|
126
|
-
const IMAGE_OMISSION = "(image omitted: model does not support images)";
|
|
127
|
-
const VIDEO_OMISSION = "(video omitted: provider does not support video input)";
|
|
128
|
-
function projectUserMediaForTransport(content, supportsImages, supportsVideo) {
|
|
129
|
-
const result = [];
|
|
130
|
-
for (const block of content) {
|
|
131
|
-
if (block.type === "text" || block.type === "image" && supportsImages || block.type === "video" && supportsVideo) {
|
|
132
|
-
result.push(block);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
const text = block.type === "video" ? VIDEO_OMISSION : IMAGE_OMISSION;
|
|
136
|
-
const previous = result.at(-1);
|
|
137
|
-
if (block.data.trim() && !(previous?.type === "text" && previous.text === text)) result.push({
|
|
138
|
-
type: "text",
|
|
139
|
-
text
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
return result;
|
|
143
|
-
}
|
|
144
|
-
function transformProviderMessages(messages, model, normalizeToolCallId) {
|
|
145
|
-
const target = {
|
|
146
|
-
...model,
|
|
147
|
-
input: model.input.filter((type) => type !== "video")
|
|
148
|
-
};
|
|
149
|
-
return transformMessages(messages.map((message) => {
|
|
150
|
-
if (message.role !== "user" || !Array.isArray(message.content)) return message;
|
|
151
|
-
return Object.assign({}, message, { content: projectUserMediaForTransport(message.content, model.input.includes("image"), model.api === "openai-completions" && model.input.includes("video")) });
|
|
152
|
-
}), target, normalizeToolCallId);
|
|
153
|
-
}
|
|
154
|
-
//#endregion
|
|
155
|
-
export { createWritableTransportEventStream as a, mergeTransportHeaders as c, sanitizeTransportPayloadText as d, transportAbortError as f, createEmptyTransportUsage as i, mergeTransportMetadata as l, assignTransportErrorDetails as n, failTransportStream as o, withProviderResponseHook as p, coerceTransportToolCallArguments as r, finalizeTransportStream as s, transformProviderMessages as t, sanitizeNonEmptyTransportPayloadText as u };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
//#region packages/normalization-core/src/record-coerce.ts
|
|
2
|
-
/** Type guard for non-array object records at browser-safe boundaries. */
|
|
3
|
-
function isRecord(value) {
|
|
4
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
|
-
}
|
|
6
|
-
/** Returns a non-array record or undefined. */
|
|
7
|
-
function asOptionalRecord(value) {
|
|
8
|
-
return isRecord(value) ? value : void 0;
|
|
9
|
-
}
|
|
10
|
-
/** Returns a non-array record or a fresh ordinary empty record. */
|
|
11
|
-
function asNonArrayRecord(value) {
|
|
12
|
-
return asOptionalRecord(value) ?? {};
|
|
13
|
-
}
|
|
14
|
-
/** Returns a non-array record or null. */
|
|
15
|
-
function asNullableRecord(value) {
|
|
16
|
-
return isRecord(value) ? value : null;
|
|
17
|
-
}
|
|
18
|
-
/** Returns any object-backed record, including arrays, or undefined. */
|
|
19
|
-
function asOptionalObjectRecord(value) {
|
|
20
|
-
return value && typeof value === "object" ? value : void 0;
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
|
-
export { isRecord as a, asOptionalRecord as i, asNullableRecord as n, asOptionalObjectRecord as r, asNonArrayRecord as t };
|
package/dist/src-D2H6yKkH.mjs
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//#region packages/ai/src/utils/stream-first-event-timeout.d.ts
|
|
2
|
-
type StreamStage = "responses" | "completions";
|
|
3
|
-
type FirstStreamEventTimeoutContext = {
|
|
4
|
-
provider?: string;
|
|
5
|
-
api?: string;
|
|
6
|
-
model?: string;
|
|
7
|
-
timeoutMs: number;
|
|
8
|
-
stage?: StreamStage;
|
|
9
|
-
hint?: string;
|
|
10
|
-
abort?: (reason: Error) => void;
|
|
11
|
-
onTimeout?: (reason: Error) => void;
|
|
12
|
-
};
|
|
13
|
-
type FirstStreamEventInternalOptions = {
|
|
14
|
-
firstEventTimeoutMs?: number;
|
|
15
|
-
abortFirstEventStream?: (reason: Error) => void;
|
|
16
|
-
onFirstEventTimeout?: (reason: Error) => void;
|
|
17
|
-
};
|
|
18
|
-
type FirstStreamEventAbortController = {
|
|
19
|
-
signal: AbortSignal;
|
|
20
|
-
abort: (reason: Error) => void;
|
|
21
|
-
dispose: () => void;
|
|
22
|
-
};
|
|
23
|
-
declare function getFirstStreamEventTimeoutMs(options: unknown): number | undefined;
|
|
24
|
-
declare function getFirstStreamEventTimeoutHandler(options: unknown): ((reason: Error) => void) | undefined;
|
|
25
|
-
declare function createFirstStreamEventTimeoutError(context: FirstStreamEventTimeoutContext): Error;
|
|
26
|
-
declare function createFirstStreamEventAbortController(parentSignal?: AbortSignal): FirstStreamEventAbortController;
|
|
27
|
-
declare function withFirstStreamEventTimeout<T>(stream: AsyncIterable<T>, context: FirstStreamEventTimeoutContext): AsyncIterable<T>;
|
|
28
|
-
//#endregion
|
|
29
|
-
export { createFirstStreamEventTimeoutError as a, withFirstStreamEventTimeout as c, createFirstStreamEventAbortController as i, FirstStreamEventInternalOptions as n, getFirstStreamEventTimeoutHandler as o, FirstStreamEventTimeoutContext as r, getFirstStreamEventTimeoutMs as s, FirstStreamEventAbortController as t };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
//#region packages/normalization-core/src/string-coerce.ts
|
|
2
|
-
/** Reads a value only when it is already a string, preserving whitespace. */
|
|
3
|
-
function readStringValue(value) {
|
|
4
|
-
return typeof value === "string" ? value : void 0;
|
|
5
|
-
}
|
|
6
|
-
/** Trims string input and returns null for non-strings or empty strings. */
|
|
7
|
-
function normalizeNullableString(value) {
|
|
8
|
-
if (typeof value !== "string") return null;
|
|
9
|
-
const trimmed = value.trim();
|
|
10
|
-
return trimmed ? trimmed : null;
|
|
11
|
-
}
|
|
12
|
-
/** Trims string input and returns undefined for non-strings or empty strings. */
|
|
13
|
-
function normalizeOptionalString(value) {
|
|
14
|
-
return normalizeNullableString(value) ?? void 0;
|
|
15
|
-
}
|
|
16
|
-
/** Stringifies primitive ids/flags before applying optional string normalization. */
|
|
17
|
-
function normalizeStringifiedOptionalString(value) {
|
|
18
|
-
if (typeof value === "string") return normalizeOptionalString(value);
|
|
19
|
-
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return normalizeOptionalString(String(value));
|
|
20
|
-
}
|
|
21
|
-
/** Lowercases a normalized optional string. */
|
|
22
|
-
function normalizeOptionalLowercaseString(value) {
|
|
23
|
-
return normalizeOptionalString(value)?.toLowerCase();
|
|
24
|
-
}
|
|
25
|
-
/** Lowercases a normalized string or returns an empty string when absent. */
|
|
26
|
-
function normalizeLowercaseStringOrEmpty(value) {
|
|
27
|
-
return normalizeOptionalLowercaseString(value) ?? "";
|
|
28
|
-
}
|
|
29
|
-
/** Type guard for strings that remain non-empty after trimming. */
|
|
30
|
-
function hasNonEmptyString(value) {
|
|
31
|
-
return normalizeOptionalString(value) !== void 0;
|
|
32
|
-
}
|
|
33
|
-
//#endregion
|
|
34
|
-
export { normalizeOptionalString as a, normalizeOptionalLowercaseString as i, normalizeLowercaseStringOrEmpty as n, normalizeStringifiedOptionalString as o, normalizeNullableString as r, readStringValue as s, hasNonEmptyString as t };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//#region packages/normalization-core/src/utf16-slice.ts
|
|
2
|
-
function isHighSurrogate(codeUnit) {
|
|
3
|
-
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
4
|
-
}
|
|
5
|
-
function isLowSurrogate(codeUnit) {
|
|
6
|
-
return codeUnit >= 56320 && codeUnit <= 57343;
|
|
7
|
-
}
|
|
8
|
-
/** Slices a UTF-16 string without returning dangling surrogate halves at either edge. */
|
|
9
|
-
function sliceUtf16Safe(input, start, end) {
|
|
10
|
-
const len = input.length;
|
|
11
|
-
let from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
|
|
12
|
-
let to = end === void 0 ? len : end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
|
|
13
|
-
if (to <= from) return "";
|
|
14
|
-
if (from > 0 && from < len) {
|
|
15
|
-
if (isLowSurrogate(input.charCodeAt(from)) && isHighSurrogate(input.charCodeAt(from - 1))) from += 1;
|
|
16
|
-
}
|
|
17
|
-
if (to > 0 && to < len) {
|
|
18
|
-
if (isHighSurrogate(input.charCodeAt(to - 1)) && isLowSurrogate(input.charCodeAt(to))) to -= 1;
|
|
19
|
-
}
|
|
20
|
-
return input.slice(from, to);
|
|
21
|
-
}
|
|
22
|
-
/** Truncates a UTF-16 string without cutting a surrogate pair in half. */
|
|
23
|
-
function truncateUtf16Safe(input, maxLen) {
|
|
24
|
-
const limit = Math.max(0, Math.floor(maxLen));
|
|
25
|
-
if (input.length <= limit) return input;
|
|
26
|
-
return sliceUtf16Safe(input, 0, limit);
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
export { truncateUtf16Safe as t };
|