@openclaw/ai 2026.7.1 → 2026.7.2-beta.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 (47) hide show
  1. package/dist/{anthropic-B5gZQM5X.mjs → anthropic-BIRSg5x9.mjs} +23 -101
  2. package/dist/{api-registry-BXYnCOIR.d.mts → api-registry-Byvoz8Ha.d.mts} +1 -1
  3. package/dist/{azure-openai-responses-DNoSk8Uy.mjs → azure-openai-responses-CHi7Wo4A.mjs} +6 -6
  4. package/dist/{azure-openai-responses-client-compat-a_O_GVQV.mjs → azure-openai-responses-client-compat-C7K7QfUE.mjs} +23 -2
  5. package/dist/{env-api-keys-CtMlqaQ4.mjs → env-api-keys-DnhYpc27.mjs} +4 -3
  6. package/dist/{event-stream-ReMmOTzX.mjs → event-stream-D8n2uFee.mjs} +14 -6
  7. package/dist/{event-stream-0nZeBKl2.d.mts → event-stream-uQspnL8S.d.mts} +1 -1
  8. package/dist/event-stream.d.mts +1 -1
  9. package/dist/event-stream.mjs +1 -1
  10. package/dist/{google-D6sIQ1bL.mjs → google-BmsqsNwR.mjs} +4 -4
  11. package/dist/{google-shared-ZPSl2qTi.mjs → google-shared-Dx2aba47.mjs} +30 -21
  12. package/dist/{google-vertex-rDGwkoZK.mjs → google-vertex-HZ_0rTwS.mjs} +5 -18
  13. package/dist/index.d.mts +4 -4
  14. package/dist/index.mjs +3 -3
  15. package/dist/internal/anthropic.d.mts +1 -1
  16. package/dist/internal/anthropic.mjs +3 -3
  17. package/dist/internal/openai.d.mts +38 -3
  18. package/dist/internal/openai.mjs +7 -7
  19. package/dist/internal/retry-after.d.mts +5 -0
  20. package/dist/internal/retry-after.mjs +101 -0
  21. package/dist/internal/runtime.d.mts +2 -2
  22. package/dist/internal/runtime.mjs +6 -5
  23. package/dist/internal/shared.d.mts +12 -2
  24. package/dist/internal/shared.mjs +2 -2
  25. package/dist/{json-parse-DzNSIQBq.mjs → json-parse-BvXNt1-7.mjs} +4 -6
  26. package/dist/{mistral-CePVNdws.mjs → mistral-DxMPt9q9.mjs} +116 -33
  27. package/dist/{model-utils-DgmOla96.mjs → model-utils-Q1LSRIdo.mjs} +5 -12
  28. package/dist/{openai-chatgpt-responses-DVC4Bk_A.mjs → openai-chatgpt-responses-BuH2NvsR.mjs} +40 -96
  29. package/dist/{openai-completions-B9QLIq2U.mjs → openai-completions-DPR_O2RW.mjs} +28 -28
  30. package/dist/{openai-responses-B6LylGxM.mjs → openai-responses-Cov-Vdc2.mjs} +6 -6
  31. package/dist/{openai-responses-shared-sj2YUPYc.mjs → openai-responses-shared-Befb4D6R.mjs} +240 -51
  32. package/dist/{openai-tool-projection-BknoV11q.mjs → openai-tool-projection-CFqm42J2.mjs} +8 -3
  33. package/dist/providers.d.mts +1 -1
  34. package/dist/providers.mjs +9 -9
  35. package/dist/{reasoning-tag-text-partitioner-axhAdUwg.mjs → reasoning-tag-text-partitioner-BlVe67g6.mjs} +14 -8
  36. package/dist/{src-CZ503MYJ.mjs → src-CXno1H5g.mjs} +1 -1
  37. package/dist/{tool-schema-json-projection-BXtBc_mD.mjs → tool-schema-json-projection-BwNu3nDi.mjs} +22 -2
  38. package/dist/{transform-messages-BhGF_fF4.mjs → transform-messages-BmS70CP5.mjs} +12 -3
  39. package/dist/{types-DRgdPqaZ.d.mts → types-Cx2zJtyz.d.mts} +5 -0
  40. package/dist/types.d.mts +3 -3
  41. package/dist/types.mjs +3 -3
  42. package/dist/{validation-BDMWOr8d.d.mts → validation-Cej7htKc.d.mts} +1 -1
  43. package/dist/{validation-FrchoOlv.mjs → validation-DAa_yFOM.mjs} +2 -7
  44. package/dist/validation.d.mts +1 -1
  45. package/dist/validation.mjs +1 -1
  46. package/npm-shrinkwrap.json +2 -2
  47. package/package.json +1 -1
@@ -1,14 +1,35 @@
1
- import { n as getEnvApiKey } from "./env-api-keys-CtMlqaQ4.mjs";
1
+ import { n as getEnvApiKey } from "./env-api-keys-DnhYpc27.mjs";
2
2
  import { i as formatThrownValue, n as createAssistantMessageDiagnostic, t as appendAssistantMessageDiagnostic } from "./diagnostics-COpOtRwq.mjs";
3
- import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
3
+ import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
4
4
  import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
5
5
  import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
6
- import { b as stripSystemPromptCacheBoundary, o as buildBaseOptions } from "./transform-messages-BhGF_fF4.mjs";
7
- import { a as resolveResponsesReasoningEffort, i as processResponsesStream, n as convertResponsesMessages, s as convertResponsesToolPayload } from "./openai-responses-shared-sj2YUPYc.mjs";
6
+ import { C as stripSystemPromptCacheBoundary, l as buildBaseOptions } from "./transform-messages-BmS70CP5.mjs";
7
+ import { M as supportsOpenAITemperature, a as resolveResponsesReasoningEffort, i as processResponsesStream, n as convertResponsesMessages, s as convertResponsesToolPayload } from "./openai-responses-shared-Befb4D6R.mjs";
8
8
  import { i as getFirstStreamEventTimeoutMs, o as clampTimerTimeoutMs, r as getFirstStreamEventTimeoutHandler, s as resolveTimerTimeoutMs, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-RjWszj8c.mjs";
9
- import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-BknoV11q.mjs";
9
+ import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-CFqm42J2.mjs";
10
+ import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
10
11
  import { i as registerSessionResourceCleanup, n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-DhAAzLkj.mjs";
11
12
  import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
13
+ //#region packages/ai/src/internal/retry-sleep.ts
14
+ function sleepWithAbort(ms, signal) {
15
+ return new Promise((resolve, reject) => {
16
+ if (signal?.aborted) {
17
+ reject(/* @__PURE__ */ new Error("Request was aborted"));
18
+ return;
19
+ }
20
+ const onAbort = () => {
21
+ clearTimeout(timeout);
22
+ signal?.removeEventListener("abort", onAbort);
23
+ reject(/* @__PURE__ */ new Error("Request was aborted"));
24
+ };
25
+ const timeout = setTimeout(() => {
26
+ signal?.removeEventListener("abort", onAbort);
27
+ resolve();
28
+ }, ms);
29
+ signal?.addEventListener("abort", onAbort, { once: true });
30
+ });
31
+ }
32
+ //#endregion
12
33
  //#region packages/ai/src/providers/openai-chatgpt-responses.ts
13
34
  const dynamicImport = (specifier) => import(specifier);
14
35
  function loadNodeOs() {
@@ -20,7 +41,6 @@ const DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
20
41
  const MAX_RETRIES = 3;
21
42
  const BASE_DELAY_MS = 1e3;
22
43
  const REQUEST_COMPRESSION_ZSTD_LEVEL = 3;
23
- const RETRY_AFTER_HTTP_DATE_RE = /^(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT|(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), \d{2}-(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-\d{2} \d{2}:\d{2}:\d{2} GMT|(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [ \d]\d \d{2}:\d{2}:\d{2} \d{4})$/;
24
44
  const CODEX_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "opencode"]);
25
45
  const WEBSOCKET_MESSAGE_TOO_BIG_CLOSE_CODE = 1009;
26
46
  const WEBSOCKET_CONNECTION_LIMIT_REACHED_CODE = "websocket_connection_limit_reached";
@@ -38,19 +58,6 @@ function isRetryableError(status, errorText) {
38
58
  if (status === 429 || status === 500 || status === 502 || status === 503 || status === 504) return true;
39
59
  return /rate.?limit|overloaded|service.?unavailable|upstream.?connect|connection.?refused/i.test(errorText);
40
60
  }
41
- function sleep(ms, signal) {
42
- return new Promise((resolve, reject) => {
43
- if (signal?.aborted) {
44
- reject(/* @__PURE__ */ new Error("Request was aborted"));
45
- return;
46
- }
47
- const timeout = setTimeout(resolve, ms);
48
- signal?.addEventListener("abort", () => {
49
- clearTimeout(timeout);
50
- reject(/* @__PURE__ */ new Error("Request was aborted"));
51
- });
52
- });
53
- }
54
61
  function resolveRequestTimeoutMs(options) {
55
62
  const timeoutMs = options?.timeoutMs;
56
63
  return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? resolveTimerTimeoutMs(timeoutMs, 1) : void 0;
@@ -134,7 +141,6 @@ const streamOpenAICodexResponses = (model, context, options) => {
134
141
  };
135
142
  const transport = options?.transport || "auto";
136
143
  const websocketDisabledForSession = transport === "auto" && isWebSocketSseFallbackActive(options?.sessionId);
137
- if (websocketDisabledForSession) recordWebSocketSseFallback(options?.sessionId);
138
144
  if (transport !== "sse" && !websocketDisabledForSession) {
139
145
  let websocketStarted = false;
140
146
  let retriedWebSocketConnectionLimit = false;
@@ -167,9 +173,8 @@ const streamOpenAICodexResponses = (model, context, options) => {
167
173
  phase: websocketStarted ? "after_message_stream_start" : "before_message_stream_start",
168
174
  requestBytes: new TextEncoder().encode(bodyJson).byteLength
169
175
  }));
170
- recordWebSocketFailure(options?.sessionId, error, { activateSseFallback: transport === "auto" });
176
+ if (transport === "auto" && options?.sessionId) websocketSseFallbackSessions.add(options.sessionId);
171
177
  if (websocketStarted || transport !== "auto") throw error;
172
- recordWebSocketSseFallback(options?.sessionId);
173
178
  break;
174
179
  }
175
180
  }
@@ -207,13 +212,13 @@ const streamOpenAICodexResponses = (model, context, options) => {
207
212
  const trimmedRetryAfter = retryAfter.trim();
208
213
  const seconds = Number(trimmedRetryAfter);
209
214
  if (/^\d+$/.test(trimmedRetryAfter) && Number.isFinite(seconds)) delayMs = clampTimerTimeoutMs(seconds * 1e3, 0) ?? delayMs;
210
- else if (RETRY_AFTER_HTTP_DATE_RE.test(trimmedRetryAfter)) {
211
- const date = Date.parse(trimmedRetryAfter);
212
- if (!Number.isNaN(date)) delayMs = clampTimerTimeoutMs(date - Date.now(), 0) ?? delayMs;
215
+ else {
216
+ const retryAt = parseRetryAfterHttpDateMs(trimmedRetryAfter);
217
+ if (retryAt !== void 0) delayMs = clampTimerTimeoutMs(retryAt - Date.now(), 0) ?? delayMs;
213
218
  }
214
219
  }
215
220
  }
216
- await sleep(delayMs, activeSignal);
221
+ await sleepWithAbort(delayMs, activeSignal);
217
222
  continue;
218
223
  }
219
224
  const info = await parseErrorResponse(new Response(errorText, {
@@ -229,7 +234,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
229
234
  }
230
235
  lastError = error instanceof Error ? error : new Error(String(error));
231
236
  if (attempt < MAX_RETRIES && !lastError.message.includes("usage limit")) {
232
- await sleep(BASE_DELAY_MS * 2 ** attempt, activeSignal);
237
+ await sleepWithAbort(BASE_DELAY_MS * 2 ** attempt, activeSignal);
233
238
  continue;
234
239
  }
235
240
  throw lastError;
@@ -292,7 +297,7 @@ function buildRequestBody(model, context, options) {
292
297
  tool_choice: "auto",
293
298
  parallel_tool_calls: true
294
299
  };
295
- if (options?.temperature !== void 0) body.temperature = options.temperature;
300
+ if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) body.temperature = options.temperature;
296
301
  if (options?.serviceTier !== void 0) body.service_tier = options.serviceTier;
297
302
  if (context.tools) {
298
303
  const converted = convertResponsesToolPayload(context.tools, { strict: null });
@@ -473,36 +478,10 @@ const OPENAI_BETA_RESPONSES_WEBSOCKETS = "responses_websockets=2026-02-06";
473
478
  const SESSION_WEBSOCKET_CACHE_TTL_MS = 300 * 1e3;
474
479
  const SESSION_WEBSOCKET_MAX_AGE_MS = 3300 * 1e3;
475
480
  const websocketSessionCache = /* @__PURE__ */ new Map();
476
- const websocketDebugStats = /* @__PURE__ */ new Map();
477
481
  const websocketSseFallbackSessions = /* @__PURE__ */ new Set();
478
482
  let cachedWebsocket = null;
479
- function getOrCreateWebSocketDebugStats(sessionId) {
480
- let stats = websocketDebugStats.get(sessionId);
481
- if (!stats) {
482
- stats = {
483
- requests: 0,
484
- connectionsCreated: 0,
485
- connectionsReused: 0,
486
- cachedContextRequests: 0,
487
- storeTrueRequests: 0,
488
- fullContextRequests: 0,
489
- deltaRequests: 0,
490
- lastInputItems: 0,
491
- websocketFailures: 0,
492
- sseFallbacks: 0
493
- };
494
- websocketDebugStats.set(sessionId, stats);
495
- }
496
- return stats;
497
- }
498
- function resetOpenAICodexWebSocketDebugStats(sessionId) {
483
+ function resetOpenAICodexWebSocketStateForTest() {
499
484
  cachedWebsocket = null;
500
- if (sessionId) {
501
- websocketDebugStats.delete(sessionId);
502
- websocketSseFallbackSessions.delete(sessionId);
503
- return;
504
- }
505
- websocketDebugStats.clear();
506
485
  websocketSseFallbackSessions.clear();
507
486
  }
508
487
  function closeOpenAICodexWebSocketSessions(sessionId) {
@@ -523,20 +502,6 @@ registerSessionResourceCleanup(closeOpenAICodexWebSocketSessions);
523
502
  function isWebSocketSseFallbackActive(sessionId) {
524
503
  return sessionId ? websocketSseFallbackSessions.has(sessionId) : false;
525
504
  }
526
- function recordWebSocketSseFallback(sessionId) {
527
- if (!sessionId) return;
528
- const stats = getOrCreateWebSocketDebugStats(sessionId);
529
- stats.sseFallbacks++;
530
- stats.websocketFallbackActive = isWebSocketSseFallbackActive(sessionId);
531
- }
532
- function recordWebSocketFailure(sessionId, error, options) {
533
- if (!sessionId) return;
534
- if (options.activateSseFallback) websocketSseFallbackSessions.add(sessionId);
535
- const stats = getOrCreateWebSocketDebugStats(sessionId);
536
- stats.websocketFailures++;
537
- stats.lastWebSocketError = formatThrownValue(error);
538
- stats.websocketFallbackActive = isWebSocketSseFallbackActive(sessionId);
539
- }
540
505
  async function getWebSocketConstructor() {
541
506
  if (cachedWebsocket) return cachedWebsocket;
542
507
  if (process?.versions?.bun && (process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.https_proxy)) {
@@ -654,7 +619,6 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
654
619
  const socket = await connectWebSocket(url, headers, signal);
655
620
  return {
656
621
  socket,
657
- reused: false,
658
622
  release: ({ keep } = {}) => {
659
623
  if (keep === false) {
660
624
  closeWebSocketSilently(socket);
@@ -678,7 +642,6 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
678
642
  return {
679
643
  socket: cached.socket,
680
644
  entry: cached,
681
- reused: true,
682
645
  release: ({ keep } = {}) => {
683
646
  if (!keep || !isWebSocketReusable(cached.socket)) {
684
647
  closeWebSocketSilently(cached.socket);
@@ -694,7 +657,6 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
694
657
  const socket = await connectWebSocket(url, headers, signal);
695
658
  return {
696
659
  socket,
697
- reused: false,
698
660
  release: () => {
699
661
  closeWebSocketSilently(socket);
700
662
  }
@@ -715,7 +677,6 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
715
677
  return {
716
678
  socket,
717
679
  entry,
718
- reused: false,
719
680
  release: ({ keep } = {}) => {
720
681
  if (!keep || !isWebSocketReusable(entry.socket)) {
721
682
  closeWebSocketSilently(entry.socket);
@@ -834,8 +795,9 @@ async function* parseWebSocket(socket, signal) {
834
795
  try {
835
796
  while (true) {
836
797
  if (signal?.aborted) throw new Error("Request was aborted");
837
- if (queue.length > 0) {
838
- yield queue.shift();
798
+ const next = queue.shift();
799
+ if (next !== void 0) {
800
+ yield next;
839
801
  continue;
840
802
  }
841
803
  if (done) break;
@@ -899,29 +861,11 @@ async function* startWebSocketOutputOnFirstEvent(events, output, stream, onStart
899
861
  }
900
862
  }
901
863
  async function processWebSocketStream(url, body, headers, output, stream, model, onStart, options, abortFirstEventStream) {
902
- const { socket, entry, reused, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal);
864
+ const { socket, entry, release } = await acquireWebSocket(url, headers, options?.sessionId, options?.signal);
903
865
  let keepConnection = true;
904
866
  const useCachedContext = options?.transport === "websocket-cached" || options?.transport === "auto";
905
867
  const fullBody = body;
906
868
  const requestBody = useCachedContext && entry ? buildCachedWebSocketRequestBody(entry, fullBody) : fullBody;
907
- const stats = options?.sessionId ? getOrCreateWebSocketDebugStats(options.sessionId) : void 0;
908
- if (stats) {
909
- stats.requests++;
910
- if (reused) stats.connectionsReused++;
911
- else stats.connectionsCreated++;
912
- if (useCachedContext) stats.cachedContextRequests++;
913
- if (requestBody.store === true) stats.storeTrueRequests++;
914
- stats.lastInputItems = requestBody.input?.length ?? 0;
915
- if (requestBody.previous_response_id) {
916
- stats.deltaRequests++;
917
- stats.lastDeltaInputItems = requestBody.input?.length ?? 0;
918
- stats.lastPreviousResponseId = requestBody.previous_response_id;
919
- } else {
920
- stats.fullContextRequests++;
921
- stats.lastDeltaInputItems = void 0;
922
- stats.lastPreviousResponseId = void 0;
923
- }
924
- }
925
869
  try {
926
870
  if (options?.signal?.aborted) throw new Error("Request was aborted");
927
871
  socket.send(JSON.stringify({
@@ -981,7 +925,7 @@ async function readChatGptResponsesErrorTextLimited(response) {
981
925
  break;
982
926
  }
983
927
  }
984
- text += decoder.decode();
928
+ if (!reachedLimit) text += decoder.decode();
985
929
  } finally {
986
930
  if (reachedLimit) await reader.cancel().catch(() => {});
987
931
  try {
@@ -1065,4 +1009,4 @@ function toLintErrorObject(value, fallbackMessage) {
1065
1009
  return error;
1066
1010
  }
1067
1011
  //#endregion
1068
- export { closeOpenAICodexWebSocketSessions, extractOpenAICodexAccountId, parseSSEForTest, resetOpenAICodexWebSocketDebugStats, streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };
1012
+ export { closeOpenAICodexWebSocketSessions, extractOpenAICodexAccountId, parseSSEForTest, resetOpenAICodexWebSocketStateForTest, streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };
@@ -1,15 +1,15 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-CtMlqaQ4.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
1
+ import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DnhYpc27.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
3
3
  import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
4
- import { n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "./model-utils-DgmOla96.mjs";
4
+ import { n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "./model-utils-Q1LSRIdo.mjs";
5
5
  import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
6
- import { n as parseStreamingJson } from "./json-parse-DzNSIQBq.mjs";
6
+ import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
7
7
  import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
8
- import { b as stripSystemPromptCacheBoundary, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as buildBaseOptions, t as transformMessages, y as splitSystemPromptCacheBoundary } from "./transform-messages-BhGF_fF4.mjs";
8
+ import { C as stripSystemPromptCacheBoundary, S as splitSystemPromptCacheBoundary, i as extractToolResultText, l as buildBaseOptions, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages } from "./transform-messages-BmS70CP5.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 createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-axhAdUwg.mjs";
10
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-BlVe67g6.mjs";
11
11
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-RjWszj8c.mjs";
12
- import { a as clampOpenAIPromptCacheKey, n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-BknoV11q.mjs";
12
+ import { a as clampOpenAIPromptCacheKey, n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-CFqm42J2.mjs";
13
13
  import OpenAI from "openai";
14
14
  //#region packages/ai/src/providers/openai-stop-reason.ts
15
15
  function mapOpenAIStopReason(reason, options) {
@@ -67,9 +67,6 @@ function isThinkingContentBlock(block) {
67
67
  function isToolCallBlock(block) {
68
68
  return block.type === "toolCall";
69
69
  }
70
- function isImageContentBlock(block) {
71
- return block.type === "image";
72
- }
73
70
  const EMPTY_TOOL_RESULT_TEXT = "(no output)";
74
71
  function sanitizeToolResultText(text, fallback) {
75
72
  const sanitized = sanitizeSurrogates(text);
@@ -160,7 +157,6 @@ const streamOpenAICompletions = (model, context, options) => {
160
157
  partial: output
161
158
  });
162
159
  else if (block.type === "toolCall") {
163
- block.arguments = parseStreamingJson(block.partialArgs);
164
160
  delete block.partialArgs;
165
161
  delete block.streamIndex;
166
162
  stream.push({
@@ -473,7 +469,7 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
473
469
  const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
474
470
  if (toolChoice !== void 0) params.tool_choice = toolChoice;
475
471
  }
476
- if (compat.thinkingFormat === "zai" && model.reasoning) params.enable_thinking = Boolean(options?.reasoningEffort);
472
+ if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = { type: options?.reasoningEffort ? "enabled" : "disabled" };
477
473
  else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = Boolean(options?.reasoningEffort);
478
474
  else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = {
479
475
  enable_thinking: Boolean(options?.reasoningEffort),
@@ -533,7 +529,7 @@ function addCacheControlToSystemPrompt(messages, cacheControl) {
533
529
  function addCacheControlToLastConversationMessage(messages, cacheControl, cacheOptOutIndexes) {
534
530
  for (let i = messages.length - 1; i >= 0; i--) {
535
531
  const message = messages[i];
536
- if (cacheOptOutIndexes.has(i)) continue;
532
+ if (!message || cacheOptOutIndexes.has(i)) continue;
537
533
  if (message.role === "user" || message.role === "assistant") {
538
534
  if (addCacheControlToMessage(message, cacheControl)) return;
539
535
  }
@@ -541,7 +537,8 @@ function addCacheControlToLastConversationMessage(messages, cacheControl, cacheO
541
537
  }
542
538
  function addCacheControlToLastTool(tools, cacheControl) {
543
539
  if (!tools || tools.length === 0) return;
544
- const lastTool = tools[tools.length - 1];
540
+ const lastTool = tools.at(-1);
541
+ if (!lastTool) return;
545
542
  lastTool.cache_control = cacheControl;
546
543
  }
547
544
  function addCacheControlToInstructionMessage(message, cacheControl) {
@@ -594,10 +591,7 @@ function buildCacheControlledTextParts(text, cacheControl) {
594
591
  function convertMessages(model, context, compat, options = {}) {
595
592
  const params = [];
596
593
  const normalizeToolCallId = (id) => {
597
- if (id.includes("|")) {
598
- const [callId] = id.split("|");
599
- return callId.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
600
- }
594
+ if (id.includes("|")) return id.slice(0, id.indexOf("|")).replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
601
595
  if (model.provider === "openai") return id.length > 40 ? id.slice(0, 40) : id;
602
596
  return id;
603
597
  };
@@ -613,6 +607,7 @@ function convertMessages(model, context, compat, options = {}) {
613
607
  let lastRole = null;
614
608
  for (let i = 0; i < transformedMessages.length; i++) {
615
609
  const msg = transformedMessages[i];
610
+ if (!msg) continue;
616
611
  if (compat.requiresAssistantAfterToolResult && lastRole === "toolResult" && msg.role === "user") params.push({
617
612
  role: "assistant",
618
613
  content: "I have processed the tool results."
@@ -662,7 +657,7 @@ function convertMessages(model, context, compat, options = {}) {
662
657
  }, ...assistantTextParts];
663
658
  else {
664
659
  if (assistantText.length > 0) assistantMsg.content = assistantText;
665
- let signature = nonEmptyThinkingBlocks[0].thinkingSignature;
660
+ let signature = nonEmptyThinkingBlocks.at(0)?.thinkingSignature;
666
661
  if (model.provider === "opencode-go" && signature === "reasoning") signature = "reasoning_content";
667
662
  if (signature && signature.length > 0) assistantMsg[signature] = nonEmptyThinkingBlocks.map((block) => block.thinking).join("\n");
668
663
  }
@@ -677,13 +672,16 @@ function convertMessages(model, context, compat, options = {}) {
677
672
  arguments: JSON.stringify(tc.arguments)
678
673
  }
679
674
  }));
680
- const reasoningDetails = toolCalls.filter((tc) => tc.thoughtSignature).map((tc) => {
675
+ const reasoningDetails = toolCalls.flatMap((tc) => {
676
+ const signature = tc.thoughtSignature;
677
+ if (!signature) return [];
681
678
  try {
682
- return JSON.parse(tc.thoughtSignature);
679
+ const parsed = JSON.parse(signature);
680
+ return parsed ? [parsed] : [];
683
681
  } catch {
684
- return null;
682
+ return [];
685
683
  }
686
- }).filter(Boolean);
684
+ });
687
685
  if (reasoningDetails.length > 0) assistantMsg.reasoning_details = reasoningDetails;
688
686
  }
689
687
  if (compat.requiresReasoningContentOnAssistantMessages && model.reasoning && assistantMsg.reasoning_content === void 0) assistantMsg.reasoning_content = "";
@@ -693,11 +691,12 @@ function convertMessages(model, context, compat, options = {}) {
693
691
  } else if (msg.role === "toolResult") {
694
692
  const imageBlocks = [];
695
693
  let j = i;
696
- for (; j < transformedMessages.length && transformedMessages[j].role === "toolResult"; j++) {
697
- const toolMsg = transformedMessages[j];
694
+ while (j < transformedMessages.length) {
695
+ const toolMsg = transformedMessages.at(j);
696
+ if (toolMsg?.role !== "toolResult") break;
698
697
  const textResult = extractToolResultText(toolMsg.content);
699
698
  const mediaPlaceholder = describeToolResultMediaPlaceholder(toolMsg.content);
700
- const hasImages = toolMsg.content.some((c) => c.type === "image");
699
+ const hasImages = toolMsg.content.some(isImageWithMediaPayload);
701
700
  const toolResultMsg = {
702
701
  role: "tool",
703
702
  content: sanitizeToolResultText(textResult, mediaPlaceholder ?? EMPTY_TOOL_RESULT_TEXT),
@@ -706,11 +705,12 @@ function convertMessages(model, context, compat, options = {}) {
706
705
  if (compat.requiresToolResultName && toolMsg.toolName) toolResultMsg.name = toolMsg.toolName;
707
706
  params.push(toolResultMsg);
708
707
  if (hasImages && model.input.includes("image")) {
709
- for (const block of toolMsg.content) if (isImageContentBlock(block)) imageBlocks.push({
708
+ for (const block of toolMsg.content) if (isImageWithMediaPayload(block)) imageBlocks.push({
710
709
  type: "image_url",
711
710
  image_url: { url: `data:${block.mimeType};base64,${block.data}` }
712
711
  });
713
712
  }
713
+ j += 1;
714
714
  }
715
715
  i = j - 1;
716
716
  if (imageBlocks.length > 0) {
@@ -786,7 +786,7 @@ function detectCompat(model) {
786
786
  const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
787
787
  const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
788
788
  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;
789
- const useMaxTokens = baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether;
789
+ const useMaxTokens = baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether || isZai;
790
790
  const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
791
791
  const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
792
792
  const isXiaomi = provider === "xiaomi" || baseUrl.includes("xiaomimimo.com");
@@ -1,10 +1,10 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-CtMlqaQ4.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
1
+ import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DnhYpc27.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
3
3
  import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
4
- import { o as buildBaseOptions } from "./transform-messages-BhGF_fF4.mjs";
4
+ import { l as buildBaseOptions } from "./transform-messages-BmS70CP5.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 { a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-sj2YUPYc.mjs";
7
- import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-BknoV11q.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-Befb4D6R.mjs";
7
+ import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-CFqm42J2.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({
@@ -111,7 +111,7 @@ function buildParams(model, context, options) {
111
111
  store: false
112
112
  };
113
113
  if (options?.maxTokens) params.max_output_tokens = options?.maxTokens;
114
- if (options?.temperature !== void 0) params.temperature = options?.temperature;
114
+ if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options?.temperature;
115
115
  if (options?.serviceTier !== void 0) params.service_tier = options.serviceTier;
116
116
  applyCommonResponsesParams(params, model, context, options, { setDefaultReasoningOff: model.provider !== "github-copilot" });
117
117
  return params;