@openclaw/ai 2026.8.1-beta.3 → 2026.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/{anthropic-B8KwTtlb.mjs → anthropic-DTGZ4VMY.mjs} +25 -23
  2. package/dist/{anthropic-compaction-replay-4Zx7-aCr.mjs → anthropic-compaction-replay-CKCDrZJv.mjs} +34 -35
  3. package/dist/{anthropic-payload-policy-CSx7MoKH.d.mts → anthropic-payload-policy-BTzmNC14.d.mts} +3 -2
  4. package/dist/{api-registry-DFxSnFqG.d.mts → api-registry-BbUHEKER.d.mts} +2 -1
  5. package/dist/{azure-openai-responses-Aa4mVcYG.mjs → azure-openai-responses-BmqaDXM1.mjs} +6 -5
  6. package/dist/{number-coercion-H9qHik3g.mjs → base64-CEFBpSkN.mjs} +73 -1
  7. package/dist/diagnostics.d.mts +2 -3
  8. package/dist/diagnostics.mjs +1 -1
  9. package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-bktO00EJ.mjs} +2 -15
  10. package/dist/{event-stream-D91-ohD_.d.mts → event-stream-DcvAPSBe.d.mts} +1 -2
  11. package/dist/event-stream-pXT3FI6X.d.mts +1 -0
  12. package/dist/event-stream.d.mts +2 -1
  13. package/dist/{google-yDRnipeq.mjs → google-CqjVZMwo.mjs} +8 -6
  14. package/dist/{google-shared-M1dl64nz.mjs → google-shared-Bnqni5j3.mjs} +34 -25
  15. package/dist/{google-vertex-DCJHM_a5.mjs → google-vertex-D_WREEJi.mjs} +8 -6
  16. package/dist/{host-DF_yxOsA.mjs → host-BIaiBURL.mjs} +4 -8
  17. package/dist/{host-DJq_FGcz.d.mts → host-DKFUAmCn.d.mts} +3 -3
  18. package/dist/index-CefaUGSS.d.mts +111 -0
  19. package/dist/index.d.mts +9 -10
  20. package/dist/index.mjs +4 -5
  21. package/dist/internal/anthropic.d.mts +51 -49
  22. package/dist/internal/anthropic.mjs +5 -5
  23. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  24. package/dist/internal/openai-responses-payload-policy.mjs +2 -3
  25. package/dist/internal/openai.d.mts +65 -63
  26. package/dist/internal/openai.mjs +10 -9
  27. package/dist/internal/retry-after.d.mts +2 -3
  28. package/dist/internal/runtime.d.mts +51 -40
  29. package/dist/internal/runtime.mjs +9 -9
  30. package/dist/internal/shared.d.mts +25 -25
  31. package/dist/internal/shared.mjs +3 -3
  32. package/dist/{json-parse-CDnesDM_.mjs → json-parse-BuAJEbdW.mjs} +18 -2
  33. package/dist/{mistral-D6hRXI7A.mjs → mistral-C24jVd6f.mjs} +34 -32
  34. package/dist/{openai-chatgpt-responses-C339VIfT.mjs → openai-chatgpt-responses-Czum0oXz.mjs} +38 -20
  35. package/dist/openai-completions-BfFwac6f.mjs +404 -0
  36. package/dist/{openai-completions-compat-B0KTleXp.d.mts → openai-completions-compat-SZhi0Lf4.d.mts} +3 -3
  37. package/dist/openai-completions-stream-DGOvau4J.mjs +1625 -0
  38. package/dist/{openai-responses-BXEcr-Tp.mjs → openai-responses-BAryVEJM.mjs} +11 -7
  39. package/dist/openai-responses-compaction-window-DO7yV7az.mjs +686 -0
  40. package/dist/{openai-responses-contracts-CD75pQ0m.d.mts → openai-responses-contracts-BthRXano.d.mts} +14 -5
  41. package/dist/{openai-responses-payload-policy-CNGFT9zr.d.mts → openai-responses-payload-policy-rLRPsSmB.d.mts} +1 -0
  42. package/dist/{openai-responses-prompt-observer-internal-BG-1AsBI.mjs → openai-responses-prompt-observer-internal--R0kZLOZ.mjs} +3 -2
  43. package/dist/{openai-responses-shared-Cvt5MgEm.mjs → openai-responses-shared-CxgdGBvm.mjs} +332 -1484
  44. package/dist/openai-stop-reason-Drnn_6Qj.mjs +28 -0
  45. package/dist/openai-tool-schema-CSMh5e9O.mjs +1697 -0
  46. package/dist/{provider-error-C8mBRJDl.mjs → provider-error-BI8kIViN.mjs} +14 -88
  47. package/dist/{provider-options-Cc5ZQ6Aa.d.mts → provider-options-DJd_9euj.d.mts} +13 -4
  48. package/dist/{provider-transcript-transform--gtf0ZbR.mjs → provider-transcript-transform-WvJmFUAf.mjs} +1 -1
  49. package/dist/provider-types.d.mts +18 -17
  50. package/dist/providers.d.mts +5 -6
  51. package/dist/providers.mjs +9 -9
  52. package/dist/{reasoning-tag-text-partitioner-5ygO2rZc.mjs → reasoning-tag-text-partitioner-BsUX44Tq.mjs} +30 -20
  53. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  54. package/dist/{sanitize-unicode-BP7HLLZn.mjs → sanitize-unicode-S6binQG-.mjs} +2 -9
  55. package/dist/simple-options-rdOPzr7Z.mjs +155 -0
  56. package/dist/{anthropic-BQXQudmA.mjs → src-C8U7lkoa.mjs} +75 -1
  57. package/dist/{stream-first-event-timeout-MK28puvq.mjs → stream-first-event-timeout-DcNjoFQE.mjs} +1 -1
  58. package/dist/{streaming-byte-guard-BrbkbwUu.mjs → streaming-byte-guard-CC-HMn_u.mjs} +5 -6
  59. package/dist/string-normalization--fwJ4S2q.mjs +16 -0
  60. package/dist/{tool-schema-json-projection-FEr-jOoZ.mjs → tool-schema-json-projection-BtZiml7r.mjs} +22 -32
  61. package/dist/transport-stream-shared-BbG7PThh.d.mts +138 -0
  62. package/dist/{simple-options-oqsXB6U3.mjs → transport-stream-shared-D8nQWCUo.mjs} +10 -118
  63. package/dist/{transport-utils-Bv0FHkd0.mjs → transport-utils-CtuS1Upe.mjs} +10 -10
  64. package/dist/transports.d.mts +130 -189
  65. package/dist/transports.mjs +227 -1249
  66. package/dist/{types-DTAP49HF.d.mts → types-Beemor2E.d.mts} +58 -24
  67. package/dist/types-COdhCX0U.d.mts +1 -0
  68. package/dist/types.d.mts +6 -5
  69. package/dist/types.mjs +3 -4
  70. package/dist/utf16-slice-qz3nsy87.mjs +84 -0
  71. package/dist/{validation-DYNNrU9u.d.mts → validation-CC6s7Smp.d.mts} +1 -2
  72. package/dist/{validation-B61OhAio.mjs → validation-CJZtym2g.mjs} +7 -5
  73. package/dist/validation.d.mts +1 -1
  74. package/dist/validation.mjs +1 -1
  75. package/package.json +6 -6
  76. package/dist/anthropic-BECQCNdF.d.mts +0 -98
  77. package/dist/event-stream-BVVgDSdq.d.mts +0 -1
  78. package/dist/headers-B_e4-1J0.mjs +0 -9
  79. package/dist/index-BVVgDSdq.d.mts +0 -1
  80. package/dist/openai-completions-D88orSJ9.mjs +0 -632
  81. package/dist/openai-responses-contracts-DvILoqBk.mjs +0 -247
  82. package/dist/openai-responses-payload-policy-BDo8CQsx.mjs +0 -208
  83. package/dist/openai-stop-reason-9OONKyAm.mjs +0 -579
  84. package/dist/openai-tool-projection-CHGLt03m.mjs +0 -426
  85. package/dist/provider-options-AvldWZt8.mjs +0 -21
  86. package/dist/record-coerce-DdXsgUd_.mjs +0 -23
  87. package/dist/src-D2H6yKkH.mjs +0 -2
  88. package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
  89. package/dist/string-coerce-fsri9iCu.mjs +0 -34
  90. package/dist/types-BVVgDSdq.d.mts +0 -1
  91. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,632 +0,0 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
3
- import { i as clampThinkingLevel } from "./sanitize-unicode-BP7HLLZn.mjs";
4
- import { n as getAiTransportHost } from "./host-DF_yxOsA.mjs";
5
- import { n as projectProviderError } from "./provider-error-C8mBRJDl.mjs";
6
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
7
- import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
8
- import { A as splitSystemPromptCacheBoundary, C as withProviderResponseHook, P as sortPromptCacheToolsByName, n as buildBaseOptions, x as transportAbortError } from "./simple-options-oqsXB6U3.mjs";
9
- import { a as createOpenAICompletionsToolCallDeltaNormalizer, c as resolveOpenAICompletionsCompat, d as clearPendingCommentaryText, f as rememberPendingCommentaryTags, h as tagUnresolvedTextAsCommentary, i as hasToolCallHistory, l as resolveOpenAICompletionsResponseFormat, m as tagPendingCommentaryText, n as resolveOpenAIReasoningEffortMap, o as finalizeOpenAICompletionsToolCalls, p as tagInterruptedTextPhases, r as convertMessages, t as mapOpenAIStopReason, u as shouldOmitOllamaCompatResponseFormat } from "./openai-stop-reason-9OONKyAm.mjs";
10
- import { n as parseStreamingJson } from "./json-parse-CDnesDM_.mjs";
11
- import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
12
- import { c as isOpenAICompletionsThinkingEnabled, d as parseOpenAICompletionsUsage, f as readOpenAICompletionsContentDeltas, n as reconcileOpenAICompletionsToolChoice, o as createOpenAIProviderAcceptanceHook, p as readOpenAICompletionsReasoningBatch, t as projectOpenAITools } from "./openai-tool-projection-CHGLt03m.mjs";
13
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
14
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-5ygO2rZc.mjs";
15
- import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
16
- import OpenAI from "openai";
17
- //#region packages/ai/src/providers/openai-completions.ts
18
- var openai_completions_exports = /* @__PURE__ */ __exportAll({
19
- convertMessages: () => convertMessages,
20
- streamOpenAICompletions: () => streamOpenAICompletions,
21
- streamSimpleOpenAICompletions: () => streamSimpleOpenAICompletions
22
- });
23
- function isEncryptedReasoningDetail(detail) {
24
- if (typeof detail !== "object" || detail === null) return false;
25
- const candidate = detail;
26
- return candidate.type === "reasoning.encrypted" && typeof candidate.id === "string" && candidate.id.length > 0 && typeof candidate.data === "string" && candidate.data.length > 0;
27
- }
28
- const streamOpenAICompletions = (model, context, options) => {
29
- const stream = new AssistantMessageEventStream();
30
- (async () => {
31
- const output = {
32
- role: "assistant",
33
- content: [],
34
- api: model.api,
35
- provider: model.provider,
36
- model: model.id,
37
- usage: {
38
- input: 0,
39
- output: 0,
40
- cacheRead: 0,
41
- cacheWrite: 0,
42
- totalTokens: 0,
43
- cost: {
44
- input: 0,
45
- output: 0,
46
- cacheRead: 0,
47
- cacheWrite: 0,
48
- total: 0
49
- }
50
- },
51
- stopReason: "stop",
52
- timestamp: Date.now()
53
- };
54
- const provisionalCommentaryTags = /* @__PURE__ */ new Map();
55
- let firstEventAbort;
56
- try {
57
- const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
58
- const compat = resolveOpenAICompletionsCompat(model);
59
- const visibleReasoningDetailTypes = new Set(compat.visibleReasoningDetailTypes);
60
- const shouldEmitReasoning = Boolean(model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
61
- const cacheRetention = resolveCacheRetention(options?.cacheRetention);
62
- const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
63
- const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
64
- let params = buildParams(model, context, options, compat, cacheRetention);
65
- const nextParams = await options?.onPayload?.(params, model);
66
- if (nextParams !== void 0) params = nextParams;
67
- firstEventAbort = createFirstStreamEventAbortController(options?.signal);
68
- const requestOptions = {
69
- signal: firstEventAbort.signal,
70
- ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
71
- maxRetries: options?.maxRetries ?? 0
72
- };
73
- const { data: openaiStream, response } = await client.chat.completions.create(params, requestOptions).withResponse();
74
- const hookedOpenAIStream = withProviderResponseHook({
75
- stream: openaiStream,
76
- signal: firstEventAbort.signal,
77
- abort: firstEventAbort.abort,
78
- hook: createOpenAIProviderAcceptanceHook(options, response, model),
79
- onReady: () => stream.push({
80
- type: "start",
81
- partial: output
82
- })
83
- });
84
- let textBlock = null;
85
- let textBlockSource;
86
- let thinkingBlock = null;
87
- let pendingInterruptedTextBlock = null;
88
- let confirmedInterruptedTextBlock = null;
89
- let hasFinishReason = false;
90
- const toolCallBlocksByIndex = /* @__PURE__ */ new Map();
91
- const toolCallBlocksById = /* @__PURE__ */ new Map();
92
- const toolCallBlocksByFirstId = /* @__PURE__ */ new Map();
93
- const normalizeToolCallDeltas = createOpenAICompletionsToolCallDeltaNormalizer();
94
- const pendingReasoningDetailsByToolCallId = /* @__PURE__ */ new Map();
95
- const blocks = output.content;
96
- const finishedBlocks = /* @__PURE__ */ new Set();
97
- const contentIndices = /* @__PURE__ */ new WeakMap();
98
- let explicitVisibleTextBlocks;
99
- const appendBlock = (block) => {
100
- contentIndices.set(block, blocks.length);
101
- blocks.push(block);
102
- };
103
- const getContentIndex = (block) => contentIndices.get(block) ?? -1;
104
- const rememberFirstToolCallById = (id, block) => {
105
- if (toolCallBlocksByFirstId.has(id)) return;
106
- toolCallBlocksByFirstId.set(id, block);
107
- const pendingDetail = pendingReasoningDetailsByToolCallId.get(id);
108
- if (pendingDetail) {
109
- block.thoughtSignature = pendingDetail;
110
- pendingReasoningDetailsByToolCallId.delete(id);
111
- }
112
- };
113
- const finishBlock = (block) => {
114
- const contentIndex = getContentIndex(block);
115
- if (contentIndex === -1 || finishedBlocks.has(block)) return;
116
- finishedBlocks.add(block);
117
- if (block.type === "text") stream.push({
118
- type: "text_end",
119
- contentIndex,
120
- content: block.text,
121
- partial: output
122
- });
123
- else if (block.type === "thinking") stream.push({
124
- type: "thinking_end",
125
- contentIndex,
126
- content: block.thinking,
127
- partial: output
128
- });
129
- else if (block.type === "toolCall") stream.push({
130
- type: "toolcall_end",
131
- contentIndex,
132
- toolCall: block,
133
- partial: output
134
- });
135
- };
136
- const finishTextBlock = () => {
137
- if (!textBlock) return;
138
- finishBlock(textBlock);
139
- textBlock = null;
140
- textBlockSource = void 0;
141
- };
142
- const ensureTextBlock = (source) => {
143
- if (textBlock && textBlockSource !== source) finishTextBlock();
144
- if (!textBlock) {
145
- textBlock = {
146
- type: "text",
147
- text: ""
148
- };
149
- textBlockSource = source;
150
- if (source === "reasoning_detail") (explicitVisibleTextBlocks ??= /* @__PURE__ */ new Set()).add(textBlock);
151
- appendBlock(textBlock);
152
- stream.push({
153
- type: "text_start",
154
- contentIndex: getContentIndex(textBlock),
155
- partial: output
156
- });
157
- }
158
- return textBlock;
159
- };
160
- const ensureThinkingBlock = (thinkingSignature) => {
161
- if (!thinkingBlock) {
162
- thinkingBlock = {
163
- type: "thinking",
164
- thinking: "",
165
- ...thinkingSignature ? { thinkingSignature } : {}
166
- };
167
- appendBlock(thinkingBlock);
168
- stream.push({
169
- type: "thinking_start",
170
- contentIndex: getContentIndex(thinkingBlock),
171
- partial: output
172
- });
173
- }
174
- return thinkingBlock;
175
- };
176
- const sealNativeReasoningBeforeText = () => {
177
- if (thinkingBlock && !reasoningTagTextPartitioner.isInsideReasoning()) {
178
- finishBlock(thinkingBlock);
179
- thinkingBlock = null;
180
- }
181
- };
182
- const appendTextDelta = (delta, source) => {
183
- sealNativeReasoningBeforeText();
184
- const block = ensureTextBlock(source);
185
- block.text += delta;
186
- if (pendingInterruptedTextBlock && delta.trim()) {
187
- confirmedInterruptedTextBlock = pendingInterruptedTextBlock;
188
- pendingInterruptedTextBlock = null;
189
- }
190
- stream.push({
191
- type: "text_delta",
192
- contentIndex: getContentIndex(block),
193
- delta,
194
- partial: output
195
- });
196
- };
197
- const appendThinkingDelta = (thinkingSignature, delta) => {
198
- const block = ensureThinkingBlock(thinkingSignature);
199
- block.thinking += delta;
200
- stream.push({
201
- type: "thinking_delta",
202
- contentIndex: getContentIndex(block),
203
- delta,
204
- partial: output
205
- });
206
- };
207
- const appendReasoningDeltas = (reasoningDeltas) => {
208
- for (const reasoningDelta of reasoningDeltas) if (reasoningDelta.kind === "thinking") {
209
- if (!shouldEmitReasoning) continue;
210
- finishTextBlock();
211
- const signature = reasoningDelta.signature;
212
- const thinkingSignature = model.provider === "opencode-go" && signature === "reasoning" ? "reasoning_content" : signature;
213
- appendThinkingDelta(thinkingSignature, reasoningDelta.text);
214
- } else appendTextDelta(reasoningDelta.text, reasoningDelta.source);
215
- };
216
- const ensureToolCallBlock = (toolCall) => {
217
- const streamIndex = typeof toolCall.index === "number" ? toolCall.index : void 0;
218
- let block = streamIndex !== void 0 ? toolCallBlocksByIndex.get(streamIndex) : void 0;
219
- if (!block && toolCall.id) block = toolCallBlocksById.get(toolCall.id);
220
- if (!block) {
221
- block = {
222
- type: "toolCall",
223
- id: toolCall.id || "",
224
- name: toolCall.function?.name || "",
225
- arguments: {},
226
- partialArgs: "",
227
- streamIndex
228
- };
229
- if (streamIndex !== void 0) toolCallBlocksByIndex.set(streamIndex, block);
230
- if (toolCall.id) {
231
- toolCallBlocksById.set(toolCall.id, block);
232
- rememberFirstToolCallById(toolCall.id, block);
233
- }
234
- appendBlock(block);
235
- stream.push({
236
- type: "toolcall_start",
237
- contentIndex: getContentIndex(block),
238
- partial: output
239
- });
240
- }
241
- if (streamIndex !== void 0 && block.streamIndex === void 0) {
242
- block.streamIndex = streamIndex;
243
- toolCallBlocksByIndex.set(streamIndex, block);
244
- }
245
- if (toolCall.id) toolCallBlocksById.set(toolCall.id, block);
246
- return block;
247
- };
248
- const reasoningTagTextPartitioner = createReasoningTagTextPartitioner();
249
- const appendPartitionedContent = (text, hasMirroredReasoning) => {
250
- const routedDeltas = hasMirroredReasoning ? reasoningTagTextPartitioner.push(text) : reasoningTagTextPartitioner.pushVisible(text);
251
- for (const delta of routedDeltas) if (delta.kind === "text") appendTextDelta(delta.text);
252
- };
253
- const flushPartitionedContent = () => {
254
- for (const delta of reasoningTagTextPartitioner.flush()) if (delta.kind === "text") appendTextDelta(delta.text);
255
- };
256
- const sealTextBeforeReasoning = () => {
257
- if (!textBlock && !reasoningTagTextPartitioner.hasPending()) return;
258
- flushPartitionedContent();
259
- if (!textBlock) return;
260
- if (textBlockSource !== "reasoning_detail" && textBlock.text.trim()) pendingInterruptedTextBlock = textBlock;
261
- finishTextBlock();
262
- };
263
- const beginReasoning = (hasFollowingVisibleText, forceStrict = false) => {
264
- if (!output.openclawDelivery?.textPhaseRequiresTerminal) output.openclawDelivery = {
265
- ...output.openclawDelivery,
266
- textPhaseRequiresTerminal: true
267
- };
268
- if (forceStrict || reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
269
- if (!hasFollowingVisibleText || !reasoningTagTextPartitioner.hasPendingSyntax()) sealTextBeforeReasoning();
270
- };
271
- const guardedOpenaiStream = withFirstStreamEventTimeout(hookedOpenAIStream, {
272
- provider: model.provider,
273
- api: model.api,
274
- model: model.id,
275
- timeoutMs: getFirstStreamEventTimeoutMs(options) ?? 0,
276
- stage: "completions",
277
- abort: firstEventAbort.abort,
278
- onTimeout: getFirstStreamEventTimeoutHandler(options),
279
- hint: "The provider may be stalled while parsing the tool payload; retry with a smaller tool surface or enable OPENCLAW_DEBUG_MODEL_PAYLOAD=tools to inspect exposed tools."
280
- });
281
- for await (const chunk of guardedOpenaiStream) {
282
- if (!chunk || typeof chunk !== "object") continue;
283
- notifyLlmRequestActivity(options?.signal);
284
- output.responseId ||= chunk.id;
285
- if (typeof chunk.model === "string" && chunk.model.length > 0 && chunk.model !== model.id) output.responseModel ||= chunk.model;
286
- if (chunk.usage) output.usage = parseOpenAICompletionsUsage(chunk.usage, model, { includeReasoningTokens: false });
287
- const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
288
- if (!choice) continue;
289
- const choiceUsage = choice.usage;
290
- if (!chunk.usage && choiceUsage) output.usage = parseOpenAICompletionsUsage(choiceUsage, model, { includeReasoningTokens: false });
291
- if (choice.finish_reason) {
292
- const finishReasonResult = mapOpenAIStopReason(choice.finish_reason);
293
- output.stopReason = finishReasonResult.stopReason;
294
- if (finishReasonResult.errorMessage) output.errorMessage = finishReasonResult.errorMessage;
295
- hasFinishReason = true;
296
- }
297
- const rawChoiceDelta = choice.delta ?? choice.message;
298
- if (rawChoiceDelta) for (const normalizedDelta of normalizeToolCallDeltas(rawChoiceDelta, choice.finish_reason)) {
299
- const choiceDelta = normalizedDelta.delta;
300
- const reasoningBatch = readOpenAICompletionsReasoningBatch(choiceDelta, visibleReasoningDetailTypes);
301
- const reasoningDeltas = reasoningBatch.deltas;
302
- const hasReasoningThinking = reasoningBatch.hasThinking;
303
- const contentDeltas = readOpenAICompletionsContentDeltas(choiceDelta.content, choiceDelta.refusal, reasoningBatch.mirroredThinking);
304
- const lastVisibleTextIndex = contentDeltas.findLastIndex((delta) => delta.kind === "text");
305
- const hasSameChunkVisibleText = reasoningBatch.hasVisibleText || lastVisibleTextIndex !== -1;
306
- if (hasReasoningThinking) {
307
- beginReasoning(hasSameChunkVisibleText, true);
308
- appendReasoningDeltas(reasoningDeltas);
309
- }
310
- for (const [contentDeltaIndex, contentDelta] of contentDeltas.entries()) if (contentDelta.kind === "thinking") {
311
- beginReasoning(contentDeltaIndex < lastVisibleTextIndex);
312
- if (shouldEmitReasoning) appendThinkingDelta(contentDelta.signature, contentDelta.text);
313
- } else appendPartitionedContent(contentDelta.text, hasReasoningThinking);
314
- if (!hasReasoningThinking) appendReasoningDeltas(reasoningDeltas);
315
- const toolCallDeltas = normalizedDelta.toolCalls;
316
- if (toolCallDeltas.length > 0) {
317
- flushPartitionedContent();
318
- sealNativeReasoningBeforeText();
319
- rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
320
- for (const toolCall of toolCallDeltas) {
321
- const block = ensureToolCallBlock(toolCall);
322
- if (!block.id && toolCall.id) {
323
- block.id = toolCall.id;
324
- toolCallBlocksById.set(toolCall.id, block);
325
- rememberFirstToolCallById(toolCall.id, block);
326
- }
327
- if (!block.name && toolCall.function?.name) block.name = toolCall.function.name;
328
- let delta = "";
329
- if (toolCall.function?.arguments) {
330
- delta = toolCall.function.arguments;
331
- block.partialArgs = (block.partialArgs ?? "") + toolCall.function.arguments;
332
- block.arguments = parseStreamingJson(block.partialArgs);
333
- }
334
- stream.push({
335
- type: "toolcall_delta",
336
- contentIndex: getContentIndex(block),
337
- delta,
338
- partial: output
339
- });
340
- }
341
- }
342
- const reasoningDetails = choiceDelta.reasoning_details;
343
- if (Array.isArray(reasoningDetails)) {
344
- for (const detail of reasoningDetails) if (isEncryptedReasoningDetail(detail)) {
345
- const serializedDetail = JSON.stringify(detail);
346
- const matchingToolCall = toolCallBlocksByFirstId.get(detail.id);
347
- if (matchingToolCall) matchingToolCall.thoughtSignature = serializedDetail;
348
- else pendingReasoningDetailsByToolCallId.set(detail.id, serializedDetail);
349
- }
350
- }
351
- }
352
- }
353
- flushPartitionedContent();
354
- let terminalError;
355
- if (options?.signal?.aborted) terminalError = transportAbortError(options.signal);
356
- else if (output.stopReason === "aborted") terminalError = /* @__PURE__ */ new Error("Request was aborted");
357
- else if (output.stopReason === "error") terminalError = new Error(output.errorMessage || "Provider returned an error stop reason");
358
- else if (!hasFinishReason) terminalError = /* @__PURE__ */ new Error("Stream ended without finish_reason");
359
- if (terminalError) {
360
- for (const block of blocks) if (block.type !== "toolCall") finishBlock(block);
361
- throw terminalError;
362
- }
363
- finalizeOpenAICompletionsToolCalls(output);
364
- if (output.stopReason === "aborted" || output.stopReason === "error") {
365
- for (const block of blocks) if (block.type !== "toolCall") finishBlock(block);
366
- throw new Error(output.errorMessage || (output.stopReason === "aborted" ? "Request was aborted" : "Provider returned an invalid tool call"));
367
- }
368
- if (output.stopReason !== "toolUse" && confirmedInterruptedTextBlock) tagInterruptedTextPhases(output.content, confirmedInterruptedTextBlock, explicitVisibleTextBlocks);
369
- for (const block of blocks) if (block.type !== "toolCall" || output.stopReason === "toolUse") finishBlock(block);
370
- if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
371
- if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
372
- stream.push({
373
- type: "done",
374
- reason: output.stopReason,
375
- message: output
376
- });
377
- stream.end();
378
- } catch (error) {
379
- const terminal = projectProviderError(error, options?.signal);
380
- Object.assign(output, terminal);
381
- finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
382
- clearPendingCommentaryText(provisionalCommentaryTags);
383
- tagUnresolvedTextAsCommentary(output);
384
- for (const block of output.content) {
385
- delete block.index;
386
- delete block.partialArgs;
387
- delete block.streamIndex;
388
- }
389
- stream.push({
390
- type: "error",
391
- reason: terminal.stopReason,
392
- error: output
393
- });
394
- stream.end();
395
- } finally {
396
- firstEventAbort?.dispose();
397
- }
398
- })();
399
- return stream;
400
- };
401
- const streamSimpleOpenAICompletions = (model, context, options) => {
402
- const apiKey = options?.apiKey || getEnvApiKey(model.provider);
403
- if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
404
- const base = buildBaseOptions(model, options, apiKey);
405
- const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
406
- const reasoningEffort = clampedReasoning === "off" ? void 0 : clampedReasoning === "max" ? "xhigh" : clampedReasoning;
407
- const toolChoice = options?.toolChoice;
408
- return streamOpenAICompletions(model, context, {
409
- ...base,
410
- reasoningEffort,
411
- toolChoice
412
- });
413
- };
414
- function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = resolveOpenAICompletionsCompat(model)) {
415
- if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
416
- const headers = { ...model.headers };
417
- if (model.provider === "github-copilot") {
418
- const hasImages = hasCopilotVisionInput(context.messages);
419
- const copilotHeaders = buildCopilotDynamicHeaders({
420
- messages: context.messages,
421
- hasImages
422
- });
423
- Object.assign(headers, copilotHeaders);
424
- }
425
- if (sessionId && compat.sessionAffinity !== "none") if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
426
- else {
427
- headers.session_id = sessionId;
428
- headers["x-client-request-id"] = sessionId;
429
- headers["x-session-affinity"] = sessionId;
430
- }
431
- if (optionsHeaders) Object.assign(headers, optionsHeaders);
432
- const defaultHeaders = model.provider === "cloudflare-ai-gateway" ? {
433
- ...headers,
434
- Authorization: headers.Authorization ?? null,
435
- "cf-aig-authorization": `Bearer ${apiKey}`
436
- } : headers;
437
- return new OpenAI({
438
- apiKey,
439
- baseURL: isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl,
440
- dangerouslyAllowBrowser: true,
441
- defaultHeaders,
442
- fetch: getAiTransportHost().buildModelFetch(model)
443
- });
444
- }
445
- function buildParams(model, context, options, compat = resolveOpenAICompletionsCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
446
- const cacheControl = getCompatCacheControl(compat, cacheRetention);
447
- const cacheOptOutIndexes = /* @__PURE__ */ new Set();
448
- const messages = convertMessages(model, context, compat, {
449
- cacheOptOutIndexes,
450
- preserveSystemPromptCacheBoundary: cacheControl !== void 0
451
- });
452
- const supportsPromptCacheKey = model.baseUrl.includes("api.openai.com") || compat.supportsPromptCacheKey;
453
- const promptCacheKey = supportsPromptCacheKey && cacheRetention !== "none" ? clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId) : void 0;
454
- const params = {
455
- model: model.id,
456
- messages,
457
- stream: true,
458
- prompt_cache_key: promptCacheKey,
459
- prompt_cache_retention: supportsPromptCacheKey && cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : void 0
460
- };
461
- if (compat.supportsUsageInStreaming) params.stream_options = { include_usage: true };
462
- if (compat.supportsStore) params.store = false;
463
- if (options?.maxTokens) {
464
- const maxTokens = clampOpenAICompletionsMaxTokens(model, options.maxTokens);
465
- if (compat.maxTokensField === "max_tokens") params.max_tokens = maxTokens;
466
- else params.max_completion_tokens = maxTokens;
467
- }
468
- if (options?.temperature !== void 0) params.temperature = options.temperature;
469
- if (options?.stop !== void 0 && options.stop.length > 0) params.stop = options.stop;
470
- const requestedResponseFormat = options?.responseFormat;
471
- const responseFormat = requestedResponseFormat === void 0 ? void 0 : resolveOpenAICompletionsResponseFormat(shouldOmitOllamaCompatResponseFormat({
472
- provider: model.provider,
473
- baseUrl: model.baseUrl,
474
- hasTools: () => Boolean(context.tools?.length)
475
- }) ? void 0 : requestedResponseFormat, compat.supportsJsonSchemaResponseFormat);
476
- if (responseFormat !== void 0) params.response_format = responseFormat;
477
- let toolProjection;
478
- if (context.tools) {
479
- const converted = convertTools(context.tools, compat);
480
- toolProjection = converted.projection;
481
- if (converted.tools.length > 0) params.tools = converted.tools;
482
- else if (hasToolCallHistory(context.messages)) params.tools = [];
483
- if (compat.zaiToolStream && converted.tools.length > 0) params.tool_stream = true;
484
- } else if (hasToolCallHistory(context.messages)) params.tools = [];
485
- if (cacheControl) applyAnthropicCacheControl(messages, params.tools, cacheControl, cacheOptOutIndexes);
486
- if (options?.toolChoice) {
487
- const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
488
- if (toolChoice !== void 0) params.tool_choice = toolChoice;
489
- }
490
- const reasoningEffortMap = resolveOpenAIReasoningEffortMap(model);
491
- const thinkingLevelMap = model.thinkingLevelMap;
492
- const reasoningEffort = options?.reasoningEffort === void 0 ? void 0 : reasoningEffortMap[options.reasoningEffort] ?? thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
493
- const reasoningEnabled = reasoningEffort !== void 0 && reasoningEffort !== "none";
494
- const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
495
- if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
496
- type: "enabled",
497
- clear_thinking: false
498
- } : { type: "disabled" };
499
- else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = reasoningEnabled;
500
- else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = {
501
- enable_thinking: reasoningEnabled,
502
- preserve_thinking: true
503
- };
504
- else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
505
- params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
506
- if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
507
- } else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
508
- const openRouterParams = params;
509
- if (reasoningEnabled) openRouterParams.reasoning = { effort: reasoningEffort };
510
- else if (offReasoningEffort !== null) openRouterParams.reasoning = { effort: offReasoningEffort ?? "none" };
511
- } else if (compat.thinkingFormat === "together" && model.reasoning) {
512
- const togetherParams = params;
513
- togetherParams.reasoning = { enabled: reasoningEnabled };
514
- if (reasoningEnabled && compat.supportsReasoningEffort) togetherParams.reasoning_effort = reasoningEffort;
515
- } else if (reasoningEnabled && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
516
- else if (model.reasoning && compat.supportsReasoningEffort) {
517
- if (typeof offReasoningEffort === "string") params.reasoning_effort = offReasoningEffort;
518
- }
519
- if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
520
- if (model.baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
521
- const routing = model.compat.vercelGatewayRouting;
522
- if (routing.only || routing.order) {
523
- const gatewayOptions = {};
524
- if (routing.only) gatewayOptions.only = routing.only;
525
- if (routing.order) gatewayOptions.order = routing.order;
526
- params.providerOptions = { gateway: gatewayOptions };
527
- }
528
- }
529
- return params;
530
- }
531
- function clampOpenAICompletionsMaxTokens(model, requestedMaxTokens) {
532
- const modelMaxTokens = typeof model.maxTokens === "number" && Number.isFinite(model.maxTokens) && model.maxTokens > 0 ? Math.floor(model.maxTokens) : void 0;
533
- return modelMaxTokens === void 0 || requestedMaxTokens <= modelMaxTokens ? requestedMaxTokens : modelMaxTokens;
534
- }
535
- function getCompatCacheControl(compat, cacheRetention) {
536
- if (compat.cacheControlFormat !== "anthropic" || cacheRetention === "none") return;
537
- const ttl = cacheRetention === "long" && compat.supportsLongCacheRetention ? "1h" : void 0;
538
- return {
539
- type: "ephemeral",
540
- ...ttl ? { ttl } : {}
541
- };
542
- }
543
- function applyAnthropicCacheControl(messages, tools, cacheControl, cacheOptOutIndexes) {
544
- addCacheControlToSystemPrompt(messages, cacheControl);
545
- addCacheControlToLastTool(tools, cacheControl);
546
- addCacheControlToLastConversationMessage(messages, cacheControl, cacheOptOutIndexes);
547
- }
548
- function addCacheControlToSystemPrompt(messages, cacheControl) {
549
- for (const message of messages) if (message.role === "system" || message.role === "developer") {
550
- addCacheControlToInstructionMessage(message, cacheControl);
551
- return;
552
- }
553
- }
554
- function addCacheControlToLastConversationMessage(messages, cacheControl, cacheOptOutIndexes) {
555
- for (let i = messages.length - 1; i >= 0; i--) {
556
- const message = messages[i];
557
- if (!message || cacheOptOutIndexes.has(i)) continue;
558
- if (message.role === "user" || message.role === "assistant") {
559
- if (addCacheControlToMessage(message, cacheControl)) return;
560
- }
561
- }
562
- }
563
- function addCacheControlToLastTool(tools, cacheControl) {
564
- if (!tools || tools.length === 0) return;
565
- const lastTool = tools.at(-1);
566
- if (!lastTool) return;
567
- lastTool.cache_control = cacheControl;
568
- }
569
- function addCacheControlToInstructionMessage(message, cacheControl) {
570
- return addCacheControlToTextContent(message, cacheControl);
571
- }
572
- function addCacheControlToMessage(message, cacheControl) {
573
- if (message.role === "user" || message.role === "assistant") return addCacheControlToTextContent(message, cacheControl);
574
- return false;
575
- }
576
- function addCacheControlToTextContent(message, cacheControl) {
577
- const content = message.content;
578
- if (typeof content === "string") {
579
- if (content.length === 0) return false;
580
- message.content = buildCacheControlledTextParts(content, cacheControl);
581
- return true;
582
- }
583
- if (!Array.isArray(content)) return false;
584
- for (let i = content.length - 1; i >= 0; i--) {
585
- const part = content[i];
586
- if (part?.type === "text") {
587
- const text = part.text;
588
- content.splice(i, 1, ...buildCacheControlledTextParts(text, cacheControl));
589
- return true;
590
- }
591
- }
592
- return false;
593
- }
594
- function buildCacheControlledTextParts(text, cacheControl) {
595
- const split = splitSystemPromptCacheBoundary(text);
596
- if (!split) return [{
597
- type: "text",
598
- text,
599
- cache_control: cacheControl
600
- }];
601
- const parts = [];
602
- if (split.stablePrefix) parts.push({
603
- type: "text",
604
- text: split.stablePrefix,
605
- cache_control: cacheControl
606
- });
607
- if (split.dynamicSuffix) parts.push({
608
- type: "text",
609
- text: split.dynamicSuffix
610
- });
611
- return parts.length > 0 ? parts : [{
612
- type: "text",
613
- text: ""
614
- }];
615
- }
616
- function convertTools(tools, compat) {
617
- const projection = projectOpenAITools(tools);
618
- return {
619
- projection,
620
- tools: sortPromptCacheToolsByName(projection.tools).map((tool) => ({
621
- type: "function",
622
- function: {
623
- name: tool.name,
624
- description: tool.description,
625
- parameters: tool.parameters,
626
- ...compat.supportsStrictMode && { strict: false }
627
- }
628
- }))
629
- };
630
- }
631
- //#endregion
632
- export { streamOpenAICompletions as n, streamSimpleOpenAICompletions as r, openai_completions_exports as t };