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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +6 -5
  2. package/dist/{anthropic-D7SyZQ5v.mjs → anthropic-CrUDIBpM.mjs} +123 -16
  3. package/dist/{api-registry-DXBIXISf.d.mts → api-registry-BMphkFf1.d.mts} +1 -2
  4. package/dist/{azure-openai-responses-BkZgyZ3I.mjs → azure-openai-responses-CbrpVeEv.mjs} +7 -10
  5. package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
  6. package/dist/{event-stream-BPemFrFW.d.mts → event-stream-Douf9dob.d.mts} +1 -1
  7. package/dist/event-stream.d.mts +1 -1
  8. package/dist/{google-C_biGbV7.mjs → google-Cs62KA7t.mjs} +4 -4
  9. package/dist/{google-shared-BK-NoHl8.mjs → google-shared-CMLI-tCZ.mjs} +3 -3
  10. package/dist/{google-vertex-CvdzF1U7.mjs → google-vertex-B4SD3U0f.mjs} +3 -3
  11. package/dist/host-WvWBo4h8.d.mts +173 -0
  12. package/dist/host-XYGZcgO8.mjs +98 -0
  13. package/dist/index-BVVgDSdq.d.mts +1 -0
  14. package/dist/index.d.mts +7 -50
  15. package/dist/index.mjs +1 -1
  16. package/dist/internal/anthropic.d.mts +2 -2
  17. package/dist/internal/anthropic.mjs +2 -2
  18. package/dist/internal/openai.d.mts +2 -280
  19. package/dist/internal/openai.mjs +5 -5
  20. package/dist/internal/runtime.d.mts +8 -5
  21. package/dist/internal/runtime.mjs +19 -10
  22. package/dist/internal/shared.d.mts +1 -1
  23. package/dist/internal/shared.mjs +1 -1
  24. package/dist/{mistral-BdrQmDWp.mjs → mistral-D5Ps7Led.mjs} +4 -4
  25. package/dist/openai-CoGicoDt.d.mts +332 -0
  26. package/dist/{openai-chatgpt-responses-DP63Qt01.mjs → openai-chatgpt-responses-h0o5yV8Y.mjs} +40 -43
  27. package/dist/{openai-completions-zLDfebnN.mjs → openai-completions-exO8NFQf.mjs} +316 -100
  28. package/dist/{openai-responses-ClspWt4I.mjs → openai-responses-BHpmtUKo.mjs} +5 -5
  29. package/dist/{openai-responses-shared-CwnGU0KW.mjs → openai-responses-shared-CzCurmY1.mjs} +230 -71
  30. package/dist/{openai-tool-projection-WHf2nuOI.mjs → openai-tool-projection-ITOU9bG1.mjs} +1 -1
  31. package/dist/{provider-error-LMfTEkfO.mjs → provider-error-C4VvV_3t.mjs} +2 -1
  32. package/dist/providers.d.mts +1 -1
  33. package/dist/providers.mjs +8 -8
  34. package/dist/{stream-first-event-timeout-RjWszj8c.mjs → stream-first-event-timeout-DP4xEyBY.mjs} +45 -1
  35. package/dist/{transform-messages-eb6lxDLB.mjs → system-prompt-cache-boundary-CbHeV4_l.mjs} +164 -160
  36. package/dist/transports.d.mts +590 -0
  37. package/dist/transports.mjs +5701 -0
  38. package/dist/{types-CYORveZ7.d.mts → types-AFwwWium.d.mts} +1 -0
  39. package/dist/types.d.mts +4 -4
  40. package/dist/{validation-BX8euiDv.d.mts → validation-sxvxC8J-.d.mts} +1 -1
  41. package/dist/validation.d.mts +1 -1
  42. package/npm-shrinkwrap.json +43 -50
  43. package/package.json +36 -10
  44. package/dist/host-4t713IeR.mjs +0 -37
  45. /package/dist/{index-BoTnz8cv.d.mts → anthropic-BoTnz8cv.d.mts} +0 -0
@@ -1,17 +1,299 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DnhYpc27.mjs";
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-4t713IeR.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";
4
6
  import { n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "./model-utils-1GiZ2_rr.mjs";
5
7
  import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
6
8
  import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
7
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
8
- import { C as splitSystemPromptCacheBoundary, i as extractToolResultText, l as buildBaseOptions, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages, w as stripSystemPromptCacheBoundary } from "./transform-messages-eb6lxDLB.mjs";
9
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 formatProviderError } from "./provider-error-LMfTEkfO.mjs";
11
10
  import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-BlVe67g6.mjs";
12
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-RjWszj8c.mjs";
13
- import { a as clampOpenAIPromptCacheKey, n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-WHf2nuOI.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";
14
14
  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
15
297
  //#region packages/ai/src/providers/openai-stop-reason.ts
16
298
  function mapOpenAIStopReason(reason, options) {
17
299
  if (reason === null) return { stopReason: "stop" };
@@ -104,10 +386,11 @@ const streamOpenAICompletions = (model, context, options) => {
104
386
  stopReason: "stop",
105
387
  timestamp: Date.now()
106
388
  };
389
+ const provisionalCommentaryTags = /* @__PURE__ */ new Map();
107
390
  let firstEventAbort;
108
391
  try {
109
392
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
110
- const compat = getCompat(model);
393
+ const compat = resolveOpenAICompletionsCompat(model);
111
394
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
112
395
  const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
113
396
  const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
@@ -328,9 +611,10 @@ const streamOpenAICompletions = (model, context, options) => {
328
611
  if (choiceDelta.content !== null && choiceDelta.content !== void 0 && choiceDelta.content.length > 0) appendPartitionedContent(choiceDelta.content, Boolean(foundReasoningField));
329
612
  const refusalText = typeof choiceDelta.refusal === "string" ? choiceDelta.refusal : "";
330
613
  if (refusalText.length > 0) appendPartitionedContent(refusalText, Boolean(foundReasoningField));
331
- if (choiceDelta.tool_calls) {
614
+ if (choiceDelta.tool_calls && choiceDelta.tool_calls.length > 0) {
332
615
  flushPartitionedContent();
333
616
  sealNativeReasoningBeforeText();
617
+ rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
334
618
  for (const toolCall of choiceDelta.tool_calls) {
335
619
  const block = ensureToolCallBlock(toolCall);
336
620
  if (!block.id && toolCall.id) {
@@ -375,6 +659,8 @@ const streamOpenAICompletions = (model, context, options) => {
375
659
  if (output.stopReason === "toolUse" && !hasToolCalls) output.stopReason = "stop";
376
660
  if (output.stopReason === "stop" && hasToolCalls && !hasVisibleText) output.stopReason = "toolUse";
377
661
  if (hasToolCalls && output.stopReason !== "toolUse") output.content = output.content.filter((block) => block.type !== "toolCall");
662
+ if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
663
+ if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
378
664
  stream.push({
379
665
  type: "done",
380
666
  reason: output.stopReason,
@@ -416,7 +702,7 @@ const streamSimpleOpenAICompletions = (model, context, options) => {
416
702
  toolChoice
417
703
  });
418
704
  };
419
- function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = getCompat(model)) {
705
+ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = resolveOpenAICompletionsCompat(model)) {
420
706
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
421
707
  const headers = { ...model.headers };
422
708
  if (model.provider === "github-copilot") {
@@ -427,7 +713,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
427
713
  });
428
714
  Object.assign(headers, copilotHeaders);
429
715
  }
430
- if (sessionId && compat.sendSessionAffinityHeaders) if (compat.sessionAffinityFormat === "openrouter") headers["x-session-id"] = sessionId;
716
+ if (sessionId && compat.sessionAffinity !== "none") if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
431
717
  else {
432
718
  headers.session_id = sessionId;
433
719
  headers["x-client-request-id"] = sessionId;
@@ -447,7 +733,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
447
733
  fetch: getAiTransportHost().buildModelFetch(model)
448
734
  });
449
735
  }
450
- function buildParams(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
736
+ function buildParams(model, context, options, compat = resolveOpenAICompletionsCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
451
737
  const cacheControl = getCompatCacheControl(compat, cacheRetention);
452
738
  const cacheOptOutIndexes = /* @__PURE__ */ new Set();
453
739
  const messages = convertMessages(model, context, compat, {
@@ -485,32 +771,35 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
485
771
  const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
486
772
  if (toolChoice !== void 0) params.tool_choice = toolChoice;
487
773
  }
488
- if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = options?.reasoningEffort ? {
774
+ 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;
777
+ const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
778
+ if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
489
779
  type: "enabled",
490
780
  clear_thinking: false
491
781
  } : { type: "disabled" };
492
- else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = Boolean(options?.reasoningEffort);
782
+ else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = reasoningEnabled;
493
783
  else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = {
494
- enable_thinking: Boolean(options?.reasoningEffort),
784
+ enable_thinking: reasoningEnabled,
495
785
  preserve_thinking: true
496
786
  };
497
787
  else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
498
- params.thinking = { type: options?.reasoningEffort ? "enabled" : "disabled" };
499
- if (options?.reasoningEffort && compat.supportsReasoningEffort) params.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
788
+ params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
789
+ if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
500
790
  } else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
501
791
  const openRouterParams = params;
502
- if (options?.reasoningEffort) openRouterParams.reasoning = { effort: model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort };
503
- else if (model.thinkingLevelMap?.off !== null) openRouterParams.reasoning = { effort: model.thinkingLevelMap?.off ?? "none" };
792
+ if (reasoningEnabled) openRouterParams.reasoning = { effort: reasoningEffort };
793
+ else if (offReasoningEffort !== null) openRouterParams.reasoning = { effort: offReasoningEffort ?? "none" };
504
794
  } else if (compat.thinkingFormat === "together" && model.reasoning) {
505
795
  const togetherParams = params;
506
- togetherParams.reasoning = { enabled: Boolean(options?.reasoningEffort) };
507
- if (options?.reasoningEffort && compat.supportsReasoningEffort) togetherParams.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
508
- } else if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
509
- else if (!options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) {
510
- const offValue = model.thinkingLevelMap?.off;
511
- if (typeof offValue === "string") params.reasoning_effort = offValue;
796
+ togetherParams.reasoning = { enabled: reasoningEnabled };
797
+ if (reasoningEnabled && compat.supportsReasoningEffort) togetherParams.reasoning_effort = reasoningEffort;
798
+ } else if (reasoningEnabled && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
799
+ else if (model.reasoning && compat.supportsReasoningEffort) {
800
+ if (typeof offReasoningEffort === "string") params.reasoning_effort = offReasoningEffort;
512
801
  }
513
- if (model.compat?.openRouterRouting) params.provider = model.compat.openRouterRouting;
802
+ if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
514
803
  if (model.baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
515
804
  const routing = model.compat.vercelGatewayRouting;
516
805
  if (routing.only || routing.order) {
@@ -791,78 +1080,5 @@ function parseChunkUsage(rawUsage, model) {
791
1080
  applyProviderReportedUsageCost(usage, rawUsage.cost);
792
1081
  return usage;
793
1082
  }
794
- /**
795
- * Detect compatibility settings from provider and baseUrl for known providers.
796
- * Provider takes precedence over URL-based detection since it's explicitly configured.
797
- * Returns a fully resolved OpenAICompletionsCompat object with all fields set.
798
- */
799
- function detectCompat(model) {
800
- const provider = model.provider;
801
- const baseUrl = model.baseUrl;
802
- const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
803
- const isTogether = provider === "together" || baseUrl.includes("api.together.ai") || baseUrl.includes("api.together.xyz");
804
- const isMoonshot = provider === "moonshotai" || provider === "moonshotai-cn" || baseUrl.includes("api.moonshot.");
805
- const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
806
- const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
807
- const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
808
- const isNonStandard = provider === "cerebras" || baseUrl.includes("cerebras.ai") || provider === "xai" || baseUrl.includes("api.x.ai") || isTogether || baseUrl.includes("chutes.ai") || baseUrl.includes("deepseek.com") || isZai || isMoonshot || provider === "opencode" || baseUrl.includes("opencode.ai") || isCloudflareWorkersAI || isCloudflareAiGateway;
809
- const useMaxTokens = baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether || isZai;
810
- const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
811
- const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
812
- const isXiaomi = provider === "xiaomi" || baseUrl.includes("xiaomimimo.com");
813
- const supportsOpenRouterDeveloperRole = isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
814
- const usesOpenRouterSessionAffinity = isOpenRouter || model.compat?.thinkingFormat === "openrouter" || model.compat?.openRouterRouting !== void 0;
815
- const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : void 0;
816
- return {
817
- supportsStore: !isNonStandard,
818
- supportsDeveloperRole: supportsOpenRouterDeveloperRole || !isNonStandard && !isOpenRouter,
819
- supportsReasoningEffort: !isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway,
820
- supportsUsageInStreaming: true,
821
- maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
822
- requiresToolResultName: false,
823
- requiresAssistantAfterToolResult: false,
824
- requiresThinkingAsText: false,
825
- requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi,
826
- thinkingFormat: isDeepSeek ? "deepseek" : isXiaomi ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isOpenRouter ? "openrouter" : "openai",
827
- openRouterRouting: {},
828
- vercelGatewayRouting: {},
829
- zaiToolStream: false,
830
- supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway,
831
- cacheControlFormat,
832
- sendSessionAffinityHeaders: false,
833
- sessionAffinityFormat: usesOpenRouterSessionAffinity ? "openrouter" : "openai",
834
- supportsPromptCacheKey: false,
835
- supportsLongCacheRetention: !(isTogether || isCloudflareWorkersAI || isCloudflareAiGateway)
836
- };
837
- }
838
- /**
839
- * Get resolved compatibility settings for a model.
840
- * Uses explicit model.compat if provided, otherwise auto-detects from provider/URL.
841
- */
842
- function getCompat(model) {
843
- const detected = detectCompat(model);
844
- if (!model.compat) return detected;
845
- return {
846
- supportsStore: model.compat.supportsStore ?? detected.supportsStore,
847
- supportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,
848
- supportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,
849
- supportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
850
- maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
851
- requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
852
- requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
853
- requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
854
- requiresReasoningContentOnAssistantMessages: model.compat.requiresReasoningContentOnAssistantMessages ?? detected.requiresReasoningContentOnAssistantMessages,
855
- thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
856
- openRouterRouting: model.compat.openRouterRouting ?? {},
857
- vercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,
858
- zaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,
859
- supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,
860
- cacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,
861
- sendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,
862
- sessionAffinityFormat: detected.sessionAffinityFormat,
863
- supportsPromptCacheKey: model.compat.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,
864
- supportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention
865
- };
866
- }
867
1083
  //#endregion
868
- export { mapOpenAIStopReason as a, streamSimpleOpenAICompletions as i, openai_completions_exports as n, streamOpenAICompletions as r, convertMessages as t };
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 };
@@ -1,10 +1,10 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DnhYpc27.mjs";
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-4t713IeR.mjs";
4
- import { l as buildBaseOptions } from "./transform-messages-eb6lxDLB.mjs";
3
+ import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
4
+ import { D as buildBaseOptions } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
5
5
  import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BsH5cqGj.mjs";
6
- import { M as supportsOpenAITemperature, a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-CwnGU0KW.mjs";
7
- import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-WHf2nuOI.mjs";
6
+ import { L as supportsOpenAITemperature, a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-CzCurmY1.mjs";
7
+ import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-ITOU9bG1.mjs";
8
8
  import OpenAI from "openai";
9
9
  //#region packages/ai/src/providers/openai-responses.ts
10
10
  var openai_responses_exports = /* @__PURE__ */ __exportAll({