@openclaw/ai 2026.7.2-beta.4 → 2026.7.2-beta.6

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 (68) hide show
  1. package/dist/{anthropic-CrUDIBpM.mjs → anthropic-CH4UUnZr.mjs} +26 -441
  2. package/dist/{anthropic-BoTnz8cv.d.mts → anthropic-SrGtwsJu.d.mts} +27 -1
  3. package/dist/anthropic-usage-DWU-x8MI.mjs +459 -0
  4. package/dist/{api-registry-BMphkFf1.d.mts → api-registry-DlMgPR39.d.mts} +1 -1
  5. package/dist/{azure-openai-responses-CbrpVeEv.mjs → azure-openai-responses-CImcwB83.mjs} +4 -4
  6. package/dist/cache-retention-0x979a5V.mjs +12 -0
  7. package/dist/deferred-event-buffer-DAvyP7qA.mjs +19 -0
  8. package/dist/error-coercion-DgxlWC0n.mjs +15 -0
  9. package/dist/{event-stream-Douf9dob.d.mts → event-stream-YjaPW20U.d.mts} +1 -1
  10. package/dist/event-stream.d.mts +1 -1
  11. package/dist/{github-copilot-headers-BsH5cqGj.mjs → github-copilot-headers-NCJtz9i0.mjs} +1 -12
  12. package/dist/{google-Cs62KA7t.mjs → google-CtSg0iTS.mjs} +3 -3
  13. package/dist/{google-shared-CMLI-tCZ.mjs → google-shared-DNBz5rcD.mjs} +7 -4
  14. package/dist/{google-vertex-B4SD3U0f.mjs → google-vertex-31f1uS9L.mjs} +3 -3
  15. package/dist/{host-WvWBo4h8.d.mts → host-B9GUmcra.d.mts} +2 -2
  16. package/dist/host-Dog2WQiR.mjs +369 -0
  17. package/dist/index.d.mts +7 -7
  18. package/dist/index.mjs +3 -3
  19. package/dist/internal/anthropic.d.mts +16 -62
  20. package/dist/internal/anthropic.mjs +5 -4
  21. package/dist/internal/openai.d.mts +260 -2
  22. package/dist/internal/openai.mjs +7 -5
  23. package/dist/internal/runtime.d.mts +8 -32
  24. package/dist/internal/runtime.mjs +7 -6
  25. package/dist/internal/shared.d.mts +14 -9
  26. package/dist/internal/shared.mjs +6 -2
  27. package/dist/{llm-request-activity-CehVkZP-.mjs → llm-request-activity-BjtkplhG.mjs} +1 -19
  28. package/dist/{mistral-D5Ps7Led.mjs → mistral-CWmpvWYh.mjs} +7 -4
  29. package/dist/number-coercion-DvG7SNMg.mjs +129 -0
  30. package/dist/{openai-chatgpt-responses-h0o5yV8Y.mjs → openai-chatgpt-responses-B84Ibtrd.mjs} +33 -29
  31. package/dist/{openai-completions-exO8NFQf.mjs → openai-completions-DsOxhOD1.mjs} +28 -482
  32. package/dist/openai-completions-compat-DBWjXoMZ.d.mts +43 -0
  33. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +7 -0
  34. package/dist/openai-prompt-cache-mZTCdRPo.mjs +12 -0
  35. package/dist/openai-reasoning-compat-YgeLncHw.mjs +396 -0
  36. package/dist/{openai-responses-BHpmtUKo.mjs → openai-responses-BT7A3sLu.mjs} +7 -5
  37. package/dist/openai-responses-shared-pXl6Wd8S.mjs +392 -0
  38. package/dist/{openai-responses-shared-CzCurmY1.mjs → openai-responses-stream-internal-Cw5txaGW.mjs} +1609 -1037
  39. package/dist/{openai-tool-projection-ITOU9bG1.mjs → openai-tool-projection-OhX64DoP.mjs} +26 -11
  40. package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +13 -0
  41. package/dist/{provider-error-C4VvV_3t.mjs → provider-error-CAEvRjry.mjs} +8 -2
  42. package/dist/provider-options-D8bB3z9b.d.mts +144 -0
  43. package/dist/providers.d.mts +3 -2
  44. package/dist/providers.mjs +10 -9
  45. package/dist/reasoning-tag-text-partitioner-CGDyLWUR.mjs +12209 -0
  46. package/dist/simple-options-9lhRrN73.mjs +50 -0
  47. package/dist/{src-CXno1H5g.mjs → src-QkygScBs.mjs} +23 -4
  48. package/dist/stream-first-event-timeout-BBys9hSb.mjs +86 -0
  49. package/dist/stream-first-event-timeout-DvDeSucC.d.mts +29 -0
  50. package/dist/tls-certificate-errors-DXSpluKI.mjs +93 -0
  51. package/dist/tool-result-text-CTpIRbYd.mjs +225 -0
  52. package/dist/transform-messages-C8mBqZxF.mjs +2 -0
  53. package/dist/transport-stream-shared-D81p90xq.mjs +297 -0
  54. package/dist/transports.d.mts +115 -132
  55. package/dist/transports.mjs +400 -1991
  56. package/dist/{types-AFwwWium.d.mts → types-bzp5k29J.d.mts} +7 -0
  57. package/dist/types.d.mts +5 -5
  58. package/dist/types.mjs +2 -2
  59. package/dist/{validation-sxvxC8J-.d.mts → validation-B-j7cOYp.d.mts} +1 -1
  60. package/dist/validation.d.mts +1 -1
  61. package/package.json +4 -5
  62. package/dist/host-XYGZcgO8.mjs +0 -98
  63. package/dist/model-utils-1GiZ2_rr.mjs +0 -64
  64. package/dist/openai-CoGicoDt.d.mts +0 -332
  65. package/dist/reasoning-tag-text-partitioner-BlVe67g6.mjs +0 -400
  66. package/dist/stream-first-event-timeout-DP4xEyBY.mjs +0 -150
  67. package/dist/system-prompt-cache-boundary-CbHeV4_l.mjs +0 -526
  68. package/npm-shrinkwrap.json +0 -638
@@ -1,326 +1,22 @@
1
1
  import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
3
- import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
4
- import { C as isImageWithMediaPayload, D as buildBaseOptions, a as stripSystemPromptCacheBoundary, c as transformMessages, g as normalizeLowercaseStringOrEmpty, i as splitSystemPromptCacheBoundary, x as extractToolResultText, y as describeToolResultMediaPlaceholder } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
5
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
6
- import { n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "./model-utils-1GiZ2_rr.mjs";
7
- import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
3
+ import { n as getAiTransportHost } from "./host-Dog2WQiR.mjs";
4
+ import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
5
+ import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
6
+ import { u as splitSystemPromptCacheBoundary } from "./tool-result-text-CTpIRbYd.mjs";
7
+ import { n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-OhX64DoP.mjs";
8
+ import { c as calculateCost, l as clampThinkingLevel, s as applyProviderReportedUsageCost } from "./number-coercion-DvG7SNMg.mjs";
9
+ import { a as resolveOpenAICompletionsCompat, c as clearPendingCommentaryText, l as rememberPendingCommentaryTags, n as mapOpenAIStopReason, o as resolveOpenAICompletionsResponseFormat, r as convertMessages, s as shouldOmitOllamaCompatResponseFormat, t as resolveOpenAIReasoningEffortMap, u as tagPendingCommentaryText } from "./openai-reasoning-compat-YgeLncHw.mjs";
8
10
  import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
9
- import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BsH5cqGj.mjs";
10
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-BlVe67g6.mjs";
11
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DP4xEyBY.mjs";
12
- import { t as formatProviderError } from "./provider-error-C4VvV_3t.mjs";
13
- import { a as clampOpenAIPromptCacheKey, n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-ITOU9bG1.mjs";
11
+ import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
12
+ import { d as transportAbortError } from "./transport-stream-shared-D81p90xq.mjs";
13
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-CGDyLWUR.mjs";
14
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BBys9hSb.mjs";
15
+ import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
16
+ import { t as formatProviderError } from "./provider-error-CAEvRjry.mjs";
17
+ import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
18
+ import { n as buildBaseOptions } from "./simple-options-9lhRrN73.mjs";
14
19
  import OpenAI from "openai";
15
- //#region packages/ai/src/utils/assistant-text-phase.ts
16
- function isAssistantTextPhaseBlock(block) {
17
- if (!block || typeof block !== "object") return false;
18
- const record = block;
19
- return record.type === "text" && typeof record.text === "string";
20
- }
21
- function encodeAssistantTextSignatureV1(id, phase) {
22
- return JSON.stringify({
23
- v: 1,
24
- id,
25
- ...phase ? { phase } : {}
26
- });
27
- }
28
- /** Tags unphased narration before a tool-call event becomes consumer-visible. */
29
- function tagPendingCommentaryText(content) {
30
- const textBlocks = content.filter(isAssistantTextPhaseBlock);
31
- let commentaryIndex = textBlocks.filter((block) => block.textSignature !== void 0).length;
32
- const tagged = /* @__PURE__ */ new Map();
33
- for (const block of textBlocks) {
34
- if (block.text.trim().length === 0 || block.textSignature !== void 0) continue;
35
- const signature = encodeAssistantTextSignatureV1(`commentary-${commentaryIndex}`, "commentary");
36
- block.textSignature = signature;
37
- tagged.set(block, signature);
38
- commentaryIndex += 1;
39
- }
40
- return tagged;
41
- }
42
- /** Rolls back only the exact provisional signatures created by this transport turn. */
43
- function clearPendingCommentaryText(tags) {
44
- for (const [block, signature] of tags) if (block.textSignature === signature) delete block.textSignature;
45
- tags.clear();
46
- }
47
- function rememberPendingCommentaryTags(target, tagged) {
48
- for (const [block, signature] of tagged) target.set(block, signature);
49
- }
50
- //#endregion
51
- //#region packages/ai/src/transports/openai-reasoning-compat.ts
52
- /**
53
- * OpenAI reasoning-effort compatibility helpers.
54
- *
55
- * Keeps provider metadata and built-in model exceptions on one path before request payloads are built.
56
- */
57
- const OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.1-codex-mini"]);
58
- function readCompatReasoningEffortMap(compat) {
59
- if (!compat || typeof compat !== "object") return {};
60
- const rawMap = compat.reasoningEffortMap;
61
- if (!rawMap || typeof rawMap !== "object") return {};
62
- return Object.fromEntries(Object.entries(rawMap).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
63
- }
64
- /** Resolves the reasoning effort remap for an OpenAI-compatible model. */
65
- function resolveOpenAIReasoningEffortMap(model, fallbackMap = {}) {
66
- const provider = normalizeLowercaseStringOrEmpty(model.provider ?? "");
67
- const id = normalizeLowercaseStringOrEmpty(model.id ?? "");
68
- const builtinMap = provider === "openai" && OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS.has(id) ? {
69
- minimal: "medium",
70
- low: "medium"
71
- } : {};
72
- return {
73
- ...fallbackMap,
74
- ...builtinMap,
75
- ...readCompatReasoningEffortMap(model.compat)
76
- };
77
- }
78
- //#endregion
79
- //#region packages/ai/src/providers/openai-completions-compat.ts
80
- const DEFAULT_OPENAI_COMPLETIONS_COMPAT = {
81
- supportsStore: true,
82
- supportsDeveloperRole: true,
83
- supportsReasoningEffort: true,
84
- supportsUsageInStreaming: true,
85
- maxTokensField: "max_completion_tokens",
86
- requiresToolResultName: false,
87
- requiresAssistantAfterToolResult: false,
88
- requiresThinkingAsText: false,
89
- requiresReasoningContentOnAssistantMessages: false,
90
- thinkingFormat: "openai",
91
- vercelGatewayRouting: {},
92
- zaiToolStream: false,
93
- supportsStrictMode: true,
94
- cacheControlFormat: void 0,
95
- sessionAffinityFormat: "openai",
96
- supportsPromptCacheKey: false,
97
- supportsLongCacheRetention: true
98
- };
99
- const OPENAI_COMPLETIONS_COMPAT_MATRIX = {
100
- openrouter: {
101
- priority: 10,
102
- providers: ["openrouter"],
103
- baseUrlIncludes: ["openrouter.ai"],
104
- compat: {
105
- supportsDeveloperRole: false,
106
- thinkingFormat: "openrouter",
107
- sessionAffinityFormat: "openrouter"
108
- }
109
- },
110
- cerebras: {
111
- priority: 20,
112
- providers: ["cerebras"],
113
- baseUrlIncludes: ["cerebras.ai"],
114
- compat: {
115
- supportsStore: false,
116
- supportsDeveloperRole: false
117
- }
118
- },
119
- xai: {
120
- priority: 20,
121
- providers: ["xai"],
122
- baseUrlIncludes: ["api.x.ai"],
123
- compat: {
124
- supportsStore: false,
125
- supportsDeveloperRole: false,
126
- supportsReasoningEffort: false
127
- }
128
- },
129
- moonshot: {
130
- priority: 20,
131
- providers: ["moonshotai", "moonshotai-cn"],
132
- baseUrlIncludes: ["api.moonshot."],
133
- compat: {
134
- supportsStore: false,
135
- supportsDeveloperRole: false,
136
- supportsReasoningEffort: false,
137
- maxTokensField: "max_tokens",
138
- supportsStrictMode: false
139
- }
140
- },
141
- cloudflareWorkersAi: {
142
- priority: 20,
143
- providers: ["cloudflare-workers-ai"],
144
- baseUrlIncludes: ["api.cloudflare.com"],
145
- compat: {
146
- supportsStore: false,
147
- supportsDeveloperRole: false,
148
- supportsLongCacheRetention: false
149
- }
150
- },
151
- cloudflareAiGateway: {
152
- priority: 20,
153
- providers: ["cloudflare-ai-gateway"],
154
- baseUrlIncludes: ["gateway.ai.cloudflare.com"],
155
- compat: {
156
- supportsStore: false,
157
- supportsDeveloperRole: false,
158
- supportsReasoningEffort: false,
159
- maxTokensField: "max_tokens",
160
- supportsStrictMode: false,
161
- supportsLongCacheRetention: false
162
- }
163
- },
164
- opencode: {
165
- priority: 20,
166
- providers: ["opencode"],
167
- baseUrlIncludes: ["opencode.ai"],
168
- compat: {
169
- supportsStore: false,
170
- supportsDeveloperRole: false
171
- }
172
- },
173
- chutes: {
174
- priority: 20,
175
- baseUrlIncludes: ["chutes.ai"],
176
- compat: {
177
- supportsStore: false,
178
- supportsDeveloperRole: false,
179
- maxTokensField: "max_tokens"
180
- }
181
- },
182
- together: {
183
- priority: 30,
184
- providers: ["together"],
185
- baseUrlIncludes: ["api.together.ai", "api.together.xyz"],
186
- compat: {
187
- supportsStore: false,
188
- supportsDeveloperRole: false,
189
- supportsReasoningEffort: false,
190
- maxTokensField: "max_tokens",
191
- thinkingFormat: "together",
192
- supportsStrictMode: false,
193
- supportsLongCacheRetention: false
194
- }
195
- },
196
- zai: {
197
- priority: 40,
198
- providers: ["zai"],
199
- baseUrlIncludes: ["api.z.ai"],
200
- compat: {
201
- supportsStore: false,
202
- supportsDeveloperRole: false,
203
- supportsReasoningEffort: false,
204
- maxTokensField: "max_tokens",
205
- thinkingFormat: "zai"
206
- }
207
- },
208
- xiaomi: {
209
- priority: 50,
210
- providers: ["xiaomi"],
211
- baseUrlIncludes: ["xiaomimimo.com"],
212
- compat: {
213
- thinkingFormat: "deepseek",
214
- requiresReasoningContentOnAssistantMessages: true
215
- }
216
- },
217
- deepseekProvider: {
218
- priority: 60,
219
- providers: ["deepseek"],
220
- compat: {
221
- thinkingFormat: "deepseek",
222
- requiresReasoningContentOnAssistantMessages: true
223
- }
224
- },
225
- deepseekEndpoint: {
226
- priority: 60,
227
- baseUrlIncludes: ["deepseek.com"],
228
- compat: {
229
- supportsStore: false,
230
- supportsDeveloperRole: false,
231
- thinkingFormat: "deepseek",
232
- requiresReasoningContentOnAssistantMessages: true
233
- }
234
- }
235
- };
236
- const OPENAI_COMPLETIONS_MODEL_COMPAT_MATRIX = [{
237
- profile: "openrouter",
238
- modelIdPrefixes: ["anthropic/", "openai/"],
239
- compat: { supportsDeveloperRole: true }
240
- }, {
241
- providers: ["openrouter"],
242
- modelIdPrefixes: ["anthropic/"],
243
- compat: { cacheControlFormat: "anthropic" }
244
- }];
245
- const SORTED_OPENAI_COMPLETIONS_COMPAT_RULES = Object.entries(OPENAI_COMPLETIONS_COMPAT_MATRIX).toSorted(([, left], [, right]) => left.priority - right.priority);
246
- function matchesCompatRule(model, rule) {
247
- return rule.providers?.includes(model.provider) === true || rule.baseUrlIncludes?.some((fragment) => model.baseUrl.includes(fragment)) === true;
248
- }
249
- function matchesModelCompatRule(model, matchedProfiles, rule) {
250
- if (rule.profile !== void 0 && !matchedProfiles.has(rule.profile)) return false;
251
- if (rule.providers !== void 0 && !rule.providers.includes(model.provider)) return false;
252
- return rule.modelIdPrefixes.some((prefix) => model.id.startsWith(prefix));
253
- }
254
- /** Detects request compatibility from the provider, endpoint, and model family matrices. */
255
- function detectOpenAICompletionsCompat(model) {
256
- const compat = { ...DEFAULT_OPENAI_COMPLETIONS_COMPAT };
257
- const matchedProfiles = /* @__PURE__ */ new Set();
258
- for (const [profile, rule] of SORTED_OPENAI_COMPLETIONS_COMPAT_RULES) {
259
- if (!matchesCompatRule(model, rule)) continue;
260
- Object.assign(compat, rule.compat);
261
- matchedProfiles.add(profile);
262
- }
263
- for (const rule of OPENAI_COMPLETIONS_MODEL_COMPAT_MATRIX) if (matchesModelCompatRule(model, matchedProfiles, rule)) Object.assign(compat, rule.compat);
264
- return compat;
265
- }
266
- function resolveSessionAffinity(model, detectedFormat) {
267
- if (model.compat?.sendSessionAffinityHeaders !== true) return "none";
268
- if (detectedFormat === "openrouter" || model.compat.thinkingFormat === "openrouter" || model.compat.openRouterRouting !== void 0) return "openrouter";
269
- return "openai";
270
- }
271
- /** Applies explicit model overrides to the detected compatibility defaults. */
272
- function resolveOpenAICompletionsCompat(model) {
273
- const detected = detectOpenAICompletionsCompat(model);
274
- const configured = model.compat;
275
- return {
276
- supportsStore: configured?.supportsStore ?? detected.supportsStore,
277
- supportsDeveloperRole: configured?.supportsDeveloperRole ?? detected.supportsDeveloperRole,
278
- supportsReasoningEffort: configured?.supportsReasoningEffort ?? detected.supportsReasoningEffort,
279
- supportsUsageInStreaming: configured?.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
280
- maxTokensField: configured?.maxTokensField ?? detected.maxTokensField,
281
- requiresToolResultName: configured?.requiresToolResultName ?? detected.requiresToolResultName,
282
- requiresAssistantAfterToolResult: configured?.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
283
- requiresThinkingAsText: configured?.requiresThinkingAsText ?? detected.requiresThinkingAsText,
284
- requiresReasoningContentOnAssistantMessages: configured?.requiresReasoningContentOnAssistantMessages ?? detected.requiresReasoningContentOnAssistantMessages,
285
- thinkingFormat: configured?.thinkingFormat ?? detected.thinkingFormat,
286
- openRouterRouting: configured?.openRouterRouting,
287
- vercelGatewayRouting: configured?.vercelGatewayRouting ?? detected.vercelGatewayRouting,
288
- zaiToolStream: configured?.zaiToolStream ?? detected.zaiToolStream,
289
- supportsStrictMode: configured?.supportsStrictMode ?? detected.supportsStrictMode,
290
- cacheControlFormat: configured?.cacheControlFormat ?? detected.cacheControlFormat,
291
- sessionAffinity: resolveSessionAffinity(model, detected.sessionAffinityFormat),
292
- supportsPromptCacheKey: configured?.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,
293
- supportsLongCacheRetention: configured?.supportsLongCacheRetention ?? detected.supportsLongCacheRetention
294
- };
295
- }
296
- //#endregion
297
- //#region packages/ai/src/providers/openai-stop-reason.ts
298
- function mapOpenAIStopReason(reason, options) {
299
- if (reason === null) return { stopReason: "stop" };
300
- switch (reason) {
301
- case "stop":
302
- case "end": return { stopReason: "stop" };
303
- case "length": return { stopReason: "length" };
304
- case "function_call":
305
- case "tool_calls": return { stopReason: "toolUse" };
306
- case "tool_call":
307
- if (options?.allowSingularToolCall) return { stopReason: "toolUse" };
308
- break;
309
- case "content_filter": return {
310
- stopReason: "error",
311
- errorMessage: "Provider finish_reason: content_filter"
312
- };
313
- case "network_error": return {
314
- stopReason: "error",
315
- errorMessage: "Provider finish_reason: network_error"
316
- };
317
- }
318
- return {
319
- stopReason: "error",
320
- errorMessage: `Provider finish_reason: ${reason}`
321
- };
322
- }
323
- //#endregion
324
20
  //#region packages/ai/src/providers/openai-completions.ts
325
21
  var openai_completions_exports = /* @__PURE__ */ __exportAll({
326
22
  convertMessages: () => convertMessages,
@@ -341,20 +37,6 @@ function hasToolHistory(messages) {
341
37
  }
342
38
  return false;
343
39
  }
344
- function isTextContentBlock(block) {
345
- return block.type === "text";
346
- }
347
- function isThinkingContentBlock(block) {
348
- return block.type === "thinking";
349
- }
350
- function isToolCallBlock(block) {
351
- return block.type === "toolCall";
352
- }
353
- const EMPTY_TOOL_RESULT_TEXT = "(no output)";
354
- function sanitizeToolResultText(text, fallback) {
355
- const sanitized = sanitizeSurrogates(text);
356
- return sanitized.trim().length > 0 ? sanitized : fallback;
357
- }
358
40
  function isEncryptedReasoningDetail(detail) {
359
41
  if (typeof detail !== "object" || detail === null) return false;
360
42
  const candidate = detail;
@@ -573,6 +255,7 @@ const streamOpenAICompletions = (model, context, options) => {
573
255
  });
574
256
  for await (const chunk of guardedOpenaiStream) {
575
257
  if (!chunk || typeof chunk !== "object") continue;
258
+ notifyLlmRequestActivity(options?.signal);
576
259
  output.responseId ||= chunk.id;
577
260
  if (typeof chunk.model === "string" && chunk.model.length > 0 && chunk.model !== model.id) output.responseModel ||= chunk.model;
578
261
  if (chunk.usage) output.usage = parseChunkUsage(chunk.usage, model);
@@ -650,7 +333,7 @@ const streamOpenAICompletions = (model, context, options) => {
650
333
  }
651
334
  flushPartitionedContent();
652
335
  for (const block of blocks) finishBlock(block);
653
- if (options?.signal?.aborted) throw new Error("Request was aborted");
336
+ if (options?.signal?.aborted) throw transportAbortError(options.signal);
654
337
  if (output.stopReason === "aborted") throw new Error("Request was aborted");
655
338
  if (output.stopReason === "error") throw new Error(output.errorMessage || "Provider returned an error stop reason");
656
339
  if (!hasFinishReason) throw new Error("Stream ended without finish_reason");
@@ -758,6 +441,13 @@ function buildParams(model, context, options, compat = resolveOpenAICompletionsC
758
441
  }
759
442
  if (options?.temperature !== void 0) params.temperature = options.temperature;
760
443
  if (options?.stop !== void 0 && options.stop.length > 0) params.stop = options.stop;
444
+ const requestedResponseFormat = options?.responseFormat;
445
+ const responseFormat = requestedResponseFormat === void 0 ? void 0 : resolveOpenAICompletionsResponseFormat(shouldOmitOllamaCompatResponseFormat({
446
+ provider: model.provider,
447
+ baseUrl: model.baseUrl,
448
+ hasTools: () => Boolean(context.tools?.length)
449
+ }) ? void 0 : requestedResponseFormat, compat.supportsJsonSchemaResponseFormat);
450
+ if (responseFormat !== void 0) params.response_format = responseFormat;
761
451
  let toolProjection;
762
452
  if (context.tools) {
763
453
  const converted = convertTools(context.tools, compat);
@@ -772,8 +462,9 @@ function buildParams(model, context, options, compat = resolveOpenAICompletionsC
772
462
  if (toolChoice !== void 0) params.tool_choice = toolChoice;
773
463
  }
774
464
  const reasoningEffortMap = resolveOpenAIReasoningEffortMap(model);
775
- const reasoningEffort = options?.reasoningEffort === void 0 ? void 0 : reasoningEffortMap[options.reasoningEffort] ?? model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
776
- const reasoningEnabled = reasoningEffort !== void 0;
465
+ const thinkingLevelMap = model.thinkingLevelMap;
466
+ const reasoningEffort = options?.reasoningEffort === void 0 ? void 0 : reasoningEffortMap[options.reasoningEffort] ?? thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
467
+ const reasoningEnabled = reasoningEffort !== void 0 && reasoningEffort !== "none";
777
468
  const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
778
469
  if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
779
470
  type: "enabled",
@@ -896,151 +587,6 @@ function buildCacheControlledTextParts(text, cacheControl) {
896
587
  text: ""
897
588
  }];
898
589
  }
899
- function convertMessages(model, context, compat, options = {}) {
900
- const params = [];
901
- const normalizeToolCallId = (id) => {
902
- if (id.includes("|")) return id.slice(0, id.indexOf("|")).replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
903
- if (model.provider === "openai") return id.length > 40 ? id.slice(0, 40) : id;
904
- return id;
905
- };
906
- const transformedMessages = transformMessages(context.messages, model, (id) => normalizeToolCallId(id));
907
- if (context.systemPrompt) {
908
- const role = model.reasoning && compat.supportsDeveloperRole ? "developer" : "system";
909
- const systemPrompt = options.preserveSystemPromptCacheBoundary ? context.systemPrompt : stripSystemPromptCacheBoundary(context.systemPrompt);
910
- params.push({
911
- role,
912
- content: sanitizeSurrogates(systemPrompt)
913
- });
914
- }
915
- let lastRole = null;
916
- for (let i = 0; i < transformedMessages.length; i++) {
917
- const msg = transformedMessages[i];
918
- if (!msg) continue;
919
- if (compat.requiresAssistantAfterToolResult && lastRole === "toolResult" && msg.role === "user") params.push({
920
- role: "assistant",
921
- content: "I have processed the tool results."
922
- });
923
- if (msg.role === "user") {
924
- const isRuntimeContextCarrier = msg.runtimeContextCarrier === true;
925
- if (typeof msg.content === "string") {
926
- const userParam = {
927
- role: "user",
928
- content: sanitizeSurrogates(msg.content)
929
- };
930
- if (isRuntimeContextCarrier) options.cacheOptOutIndexes?.add(params.length);
931
- params.push(userParam);
932
- } else {
933
- const content = msg.content.map((item) => {
934
- if (item.type === "text") return {
935
- type: "text",
936
- text: sanitizeSurrogates(item.text)
937
- };
938
- return {
939
- type: "image_url",
940
- image_url: { url: `data:${item.mimeType};base64,${item.data}` }
941
- };
942
- });
943
- if (content.length === 0) continue;
944
- const userParam = {
945
- role: "user",
946
- content
947
- };
948
- if (isRuntimeContextCarrier) options.cacheOptOutIndexes?.add(params.length);
949
- params.push(userParam);
950
- }
951
- } else if (msg.role === "assistant") {
952
- const assistantMsg = {
953
- role: "assistant",
954
- content: compat.requiresAssistantAfterToolResult ? "" : null
955
- };
956
- const assistantTextParts = msg.content.filter(isTextContentBlock).filter((block) => block.text.trim().length > 0).map((block) => ({
957
- type: "text",
958
- text: sanitizeSurrogates(block.text)
959
- }));
960
- const assistantText = assistantTextParts.map((part) => part.text).join("");
961
- const nonEmptyThinkingBlocks = msg.content.filter(isThinkingContentBlock).filter((block) => block.thinking.trim().length > 0);
962
- if (nonEmptyThinkingBlocks.length > 0) if (compat.requiresThinkingAsText) assistantMsg.content = [{
963
- type: "text",
964
- text: nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)).join("\n\n")
965
- }, ...assistantTextParts];
966
- else {
967
- if (assistantText.length > 0) assistantMsg.content = assistantText;
968
- let signature = nonEmptyThinkingBlocks.at(0)?.thinkingSignature;
969
- if (model.provider === "opencode-go" && signature === "reasoning") signature = "reasoning_content";
970
- if (signature && signature.length > 0) assistantMsg[signature] = nonEmptyThinkingBlocks.map((block) => block.thinking).join("\n");
971
- }
972
- else if (assistantText.length > 0) assistantMsg.content = assistantText;
973
- const toolCalls = msg.content.filter(isToolCallBlock);
974
- if (toolCalls.length > 0) {
975
- assistantMsg.tool_calls = toolCalls.map((tc) => ({
976
- id: tc.id,
977
- type: "function",
978
- function: {
979
- name: tc.name,
980
- arguments: JSON.stringify(tc.arguments)
981
- }
982
- }));
983
- const reasoningDetails = toolCalls.flatMap((tc) => {
984
- const signature = tc.thoughtSignature;
985
- if (!signature) return [];
986
- try {
987
- const parsed = JSON.parse(signature);
988
- return parsed ? [parsed] : [];
989
- } catch {
990
- return [];
991
- }
992
- });
993
- if (reasoningDetails.length > 0) assistantMsg.reasoning_details = reasoningDetails;
994
- }
995
- if (compat.requiresReasoningContentOnAssistantMessages && model.reasoning && assistantMsg.reasoning_content === void 0) assistantMsg.reasoning_content = "";
996
- const content = assistantMsg.content;
997
- if (!(content !== null && content !== void 0 && (typeof content === "string" ? content.length > 0 : content.length > 0)) && !assistantMsg.tool_calls) continue;
998
- params.push(assistantMsg);
999
- } else if (msg.role === "toolResult") {
1000
- const imageBlocks = [];
1001
- let j = i;
1002
- while (j < transformedMessages.length) {
1003
- const toolMsg = transformedMessages.at(j);
1004
- if (toolMsg?.role !== "toolResult") break;
1005
- const textResult = extractToolResultText(toolMsg.content);
1006
- const mediaPlaceholder = describeToolResultMediaPlaceholder(toolMsg.content);
1007
- const hasImages = toolMsg.content.some(isImageWithMediaPayload);
1008
- const toolResultMsg = {
1009
- role: "tool",
1010
- content: sanitizeToolResultText(textResult, mediaPlaceholder ?? EMPTY_TOOL_RESULT_TEXT),
1011
- tool_call_id: toolMsg.toolCallId
1012
- };
1013
- if (compat.requiresToolResultName && toolMsg.toolName) toolResultMsg.name = toolMsg.toolName;
1014
- params.push(toolResultMsg);
1015
- if (hasImages && model.input.includes("image")) {
1016
- for (const block of toolMsg.content) if (isImageWithMediaPayload(block)) imageBlocks.push({
1017
- type: "image_url",
1018
- image_url: { url: `data:${block.mimeType};base64,${block.data}` }
1019
- });
1020
- }
1021
- j += 1;
1022
- }
1023
- i = j - 1;
1024
- if (imageBlocks.length > 0) {
1025
- if (compat.requiresAssistantAfterToolResult) params.push({
1026
- role: "assistant",
1027
- content: "I have processed the tool results."
1028
- });
1029
- params.push({
1030
- role: "user",
1031
- content: [{
1032
- type: "text",
1033
- text: "Attached image(s) from tool result:"
1034
- }, ...imageBlocks]
1035
- });
1036
- lastRole = "user";
1037
- } else lastRole = "toolResult";
1038
- continue;
1039
- }
1040
- lastRole = msg.role;
1041
- }
1042
- return params;
1043
- }
1044
590
  function convertTools(tools, compat) {
1045
591
  const projection = projectOpenAITools(tools);
1046
592
  return {
@@ -1081,4 +627,4 @@ function parseChunkUsage(rawUsage, model) {
1081
627
  return usage;
1082
628
  }
1083
629
  //#endregion
1084
- export { mapOpenAIStopReason as a, rememberPendingCommentaryTags as c, streamSimpleOpenAICompletions as i, tagPendingCommentaryText as l, openai_completions_exports as n, resolveOpenAIReasoningEffortMap as o, streamOpenAICompletions as r, clearPendingCommentaryText as s, convertMessages as t };
630
+ export { streamOpenAICompletions as n, streamSimpleOpenAICompletions as r, openai_completions_exports as t };
@@ -0,0 +1,43 @@
1
+ import { E as Model, O as OpenAICompletionsCompat } from "./types-bzp5k29J.mjs";
2
+ import { a as AiProviderRequestPolicyInput, i as AiProviderRequestCapabilities } from "./host-B9GUmcra.mjs";
3
+
4
+ //#region packages/ai/src/transports/openai-completions-compat.d.ts
5
+ type ProviderRequestCapabilities = AiProviderRequestCapabilities;
6
+ type OpenAICompletionsSessionAffinity = "none" | "openai" | "openrouter";
7
+ type OpenAICompletionsCompatDefaults = {
8
+ supportsStore: boolean;
9
+ supportsDeveloperRole: boolean;
10
+ supportsReasoningEffort: boolean;
11
+ supportsUsageInStreaming: boolean;
12
+ maxTokensField: "max_completion_tokens" | "max_tokens";
13
+ thinkingFormat: "openai" | "openrouter" | "deepseek" | "together" | "zai";
14
+ visibleReasoningDetailTypes: string[];
15
+ supportsStrictMode: boolean;
16
+ supportsJsonSchemaResponseFormat: boolean;
17
+ requiresReasoningContentOnAssistantMessages: boolean;
18
+ requiresNonEmptyUserOrAssistantMessage: boolean;
19
+ cacheControlFormat?: OpenAICompletionsCompat["cacheControlFormat"];
20
+ sessionAffinityFormat: Exclude<OpenAICompletionsSessionAffinity, "none">;
21
+ supportsLongCacheRetention: boolean;
22
+ };
23
+ type DetectedOpenAICompletionsCompat = {
24
+ capabilities: ProviderRequestCapabilities;
25
+ defaults: OpenAICompletionsCompatDefaults;
26
+ };
27
+ type ResolvedOpenAICompletionsCompat = Omit<Required<OpenAICompletionsCompat>, "cacheControlFormat" | "openRouterRouting" | "sendSessionAffinityHeaders"> & {
28
+ cacheControlFormat?: OpenAICompletionsCompat["cacheControlFormat"];
29
+ openRouterRouting?: OpenAICompletionsCompat["openRouterRouting"];
30
+ sessionAffinity: OpenAICompletionsSessionAffinity;
31
+ visibleReasoningDetailTypes: string[];
32
+ requiresNonEmptyUserOrAssistantMessage: boolean;
33
+ };
34
+ /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */
35
+ declare function detectOpenAICompletionsCompat(model: Pick<Model<"openai-completions">, "provider" | "baseUrl" | "id"> & {
36
+ compat?: {
37
+ supportsStore?: boolean;
38
+ } | null;
39
+ }, resolveCapabilities?: (input: AiProviderRequestPolicyInput) => ProviderRequestCapabilities): DetectedOpenAICompletionsCompat;
40
+ /** Applies explicit model overrides once on top of the canonical transport defaults. */
41
+ declare function resolveOpenAICompletionsCompat(model: Model<"openai-completions">, resolveCapabilities?: (input: AiProviderRequestPolicyInput) => ProviderRequestCapabilities): ResolvedOpenAICompletionsCompat;
42
+ //#endregion
43
+ export { detectOpenAICompletionsCompat as n, resolveOpenAICompletionsCompat as r, ResolvedOpenAICompletionsCompat as t };
@@ -0,0 +1,7 @@
1
+ //#region packages/ai/src/providers/openai-prompt-cache.d.ts
2
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
3
+ declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
4
+ /** Truncates a prompt cache key by Unicode code point count. */
5
+ declare function clampOpenAIPromptCacheKey(key: string | undefined): string | undefined;
6
+ //#endregion
7
+ export { clampOpenAIPromptCacheKey as n, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
@@ -0,0 +1,12 @@
1
+ //#region packages/ai/src/providers/openai-prompt-cache.ts
2
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
3
+ const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
4
+ /** Truncates a prompt cache key by Unicode code point count. */
5
+ function clampOpenAIPromptCacheKey(key) {
6
+ if (key === void 0) return;
7
+ const chars = Array.from(key);
8
+ if (chars.length <= 64) return key;
9
+ return chars.slice(0, 64).join("");
10
+ }
11
+ //#endregion
12
+ export { clampOpenAIPromptCacheKey as n, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };