@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,4 +1,4 @@
1
- import { E as Model, F as SimpleStreamOptions, I as StopReason, O as OpenAICompletionsCompat, R as StreamFunction, u as Context, z as StreamOptions } from "../types-DRgdPqaZ.mjs";
1
+ import { E as Model, F as SimpleStreamOptions, I as StopReason, O as OpenAICompletionsCompat, R as StreamFunction, u as Context, z as StreamOptions } from "../types-Cx2zJtyz.mjs";
2
2
  import OpenAI from "openai";
3
3
  import { TSchema } from "typebox";
4
4
  import { ChatCompletionMessageParam } from "openai/resources/chat/completions.js";
@@ -38,7 +38,13 @@ declare function normalizeToolParameterSchema(schema: unknown, options?: ToolPar
38
38
  //#region packages/ai/src/providers/azure-deployment-map.d.ts
39
39
  /** Parses AZURE_OPENAI_DEPLOYMENT_MAP-style model=deployment entries. */
40
40
  declare function parseAzureDeploymentNameMap(value: string | undefined): Map<string, string>;
41
- /** Resolves the Azure deployment name for a model id, falling back to the model id. */
41
+ /**
42
+ * Resolves the Azure deployment name for a model id, falling back to the model id.
43
+ *
44
+ * An exact-case match always wins, so configs that intentionally distinguish keys by
45
+ * case keep their exact mappings; a case-insensitive match is only used as a fallback
46
+ * (e.g. `GPT-4o` against a `gpt-4o=...` map) to avoid 404s from casing differences.
47
+ */
42
48
  declare function resolveAzureDeploymentNameFromMap(params: {
43
49
  modelId: string;
44
50
  deploymentMap?: string;
@@ -128,6 +134,11 @@ declare function isOpenAIGpt56Model(model: OpenAIReasoningModel): boolean;
128
134
  declare function normalizeOpenAIReasoningEffort(effort: string): string;
129
135
  /** Resolve the reasoning efforts accepted by a specific OpenAI-compatible model. */
130
136
  declare function resolveOpenAISupportedReasoningEfforts(model: OpenAIReasoningModel): readonly OpenAIApiReasoningEffort[];
137
+ /**
138
+ * Return whether a model accepts the temperature parameter. The GPT-5.6
139
+ * family rejects it with a 400; catalog compat can override per model.
140
+ */
141
+ declare function supportsOpenAITemperature(model: OpenAIReasoningModel): boolean;
131
142
  /** Return whether a model accepts a requested reasoning effort. */
132
143
  declare function supportsOpenAIReasoningEffort(model: OpenAIReasoningModel, effort: string): boolean;
133
144
  /** Resolve a requested reasoning effort to the closest value supported by the model. */
@@ -187,6 +198,30 @@ declare function resolveResponsesMessageSnapshotCollapse(params: {
187
198
  nextPhase: string | undefined;
188
199
  }): ResponsesMessageSnapshotCollapse;
189
200
  //#endregion
201
+ //#region packages/ai/src/providers/openai-responses-tool-call-tracker.d.ts
202
+ type ResponsesToolCallIdentity = {
203
+ itemId?: string;
204
+ callId?: string;
205
+ };
206
+ type ResponsesToolCallState = ResponsesToolCallIdentity & {
207
+ argumentStreamReliable: boolean;
208
+ };
209
+ type ResponsesToolCallEvent = {
210
+ output_index?: unknown;
211
+ item_id?: unknown;
212
+ };
213
+ declare function readResponsesToolCallItemIdentity(item: {
214
+ id?: unknown;
215
+ call_id?: unknown;
216
+ }): ResponsesToolCallIdentity;
217
+ declare function createResponsesToolCallTracker<TState extends ResponsesToolCallState>(): {
218
+ register(event: ResponsesToolCallEvent, state: TState): void;
219
+ resolve(event: ResponsesToolCallEvent, identity?: ResponsesToolCallIdentity): TState | undefined;
220
+ forget(toolCall: TState): void;
221
+ markArgumentsUnreliable(): void;
222
+ hasActive(): boolean;
223
+ };
224
+ //#endregion
190
225
  //#region packages/ai/src/providers/openai-stop-reason.d.ts
191
226
  type OpenAIStopReasonResult = {
192
227
  stopReason: StopReason;
@@ -241,4 +276,4 @@ type RuntimeToolInputSchemaProjection = {
241
276
  /** Projects one runtime tool input schema to JSON and reports runtime incompatibilities. */
242
277
  declare function projectRuntimeToolInputSchema(schema: unknown, path?: string): RuntimeToolInputSchemaProjection;
243
278
  //#endregion
244
- export { AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE, AzureResponsesTextContentPart, AzureResponsesTextDeltaEvent, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE, OpenAIApiReasoningEffort, OpenAICompletionsOptions, OpenAICompletionsToolChoice, OpenAIReasoningEffort, OpenAIResponsesOptions, OpenAIStopReasonResult, OpenAIToolProjection, ResponsesMessageSnapshotCollapse, ResponsesTextContentPartType, ResponsesTextDeltaEventType, RuntimeToolInputSchemaJson, RuntimeToolInputSchemaProjection, ToolParameterSchemaOptions, ToolSchemaModelCompat, clampOpenAIPromptCacheKey, cleanSchemaForGemini, clearOpenAIToolSchemaCacheForTest, convertMessages, extractToolSchemaModelCompat, findOpenAIStrictToolProjectionDiagnostics, isAzureResponsesTextDeltaEvent, isAzureResponsesTextDeltaEventType, isOpenAICompatibleAzureResponsesBaseUrl, isOpenAIGpt54MiniModel, isOpenAIGpt55Model, isOpenAIGpt56Model, isResponsesTextContentPartType, isResponsesTextDeltaEventType, isStrictOpenAIJsonSchemaCompatible, isTraditionalAzureOpenAIHost, mapOpenAIStopReason, normalizeOpenAIReasoningEffort, normalizeOpenAIStrictToolParameters, normalizeStrictOpenAIJsonSchema, normalizeToolParameterSchema, parseAzureDeploymentNameMap, projectOpenAITools, projectRuntimeToolInputSchema, reconcileOpenAICompletionsToolChoice, reconcileOpenAIResponsesToolChoice, resolveAzureDeploymentNameFromMap, resolveOpenAIProjectedToolsStrictToolFlag, resolveOpenAIReasoningEffortForModel, resolveOpenAISupportedReasoningEfforts, resolveResponsesMessageSnapshotCollapse, resolveUnsupportedToolSchemaKeywords, shouldOmitEmptyArrayItems, streamOpenAICompletions, streamOpenAIResponses, streamSimpleOpenAICompletions, streamSimpleOpenAIResponses, stripUnsupportedSchemaKeywords, supportsOpenAIReasoningEffort };
279
+ export { AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE, AzureResponsesTextContentPart, AzureResponsesTextDeltaEvent, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE, OpenAIApiReasoningEffort, OpenAICompletionsOptions, OpenAICompletionsToolChoice, OpenAIReasoningEffort, OpenAIResponsesOptions, OpenAIStopReasonResult, OpenAIToolProjection, ResponsesMessageSnapshotCollapse, ResponsesTextContentPartType, ResponsesTextDeltaEventType, ResponsesToolCallIdentity, ResponsesToolCallState, RuntimeToolInputSchemaJson, RuntimeToolInputSchemaProjection, ToolParameterSchemaOptions, ToolSchemaModelCompat, clampOpenAIPromptCacheKey, cleanSchemaForGemini, clearOpenAIToolSchemaCacheForTest, convertMessages, createResponsesToolCallTracker, extractToolSchemaModelCompat, findOpenAIStrictToolProjectionDiagnostics, isAzureResponsesTextDeltaEvent, isAzureResponsesTextDeltaEventType, isOpenAICompatibleAzureResponsesBaseUrl, isOpenAIGpt54MiniModel, isOpenAIGpt55Model, isOpenAIGpt56Model, isResponsesTextContentPartType, isResponsesTextDeltaEventType, isStrictOpenAIJsonSchemaCompatible, isTraditionalAzureOpenAIHost, mapOpenAIStopReason, normalizeOpenAIReasoningEffort, normalizeOpenAIStrictToolParameters, normalizeStrictOpenAIJsonSchema, normalizeToolParameterSchema, parseAzureDeploymentNameMap, projectOpenAITools, projectRuntimeToolInputSchema, readResponsesToolCallItemIdentity, reconcileOpenAICompletionsToolChoice, reconcileOpenAIResponsesToolChoice, resolveAzureDeploymentNameFromMap, resolveOpenAIProjectedToolsStrictToolFlag, resolveOpenAIReasoningEffortForModel, resolveOpenAISupportedReasoningEfforts, resolveResponsesMessageSnapshotCollapse, resolveUnsupportedToolSchemaKeywords, shouldOmitEmptyArrayItems, streamOpenAICompletions, streamOpenAIResponses, streamSimpleOpenAICompletions, streamSimpleOpenAIResponses, stripUnsupportedSchemaKeywords, supportsOpenAIReasoningEffort, supportsOpenAITemperature };
@@ -1,7 +1,7 @@
1
- import { t as projectRuntimeToolInputSchema } from "../tool-schema-json-projection-BXtBc_mD.mjs";
2
- import { A as extractToolSchemaModelCompat, C as isOpenAIGpt54MiniModel, D as resolveOpenAIReasoningEffortForModel, E as normalizeOpenAIReasoningEffort, F as GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, I as cleanSchemaForGemini, M as resolveUnsupportedToolSchemaKeywords, N as shouldOmitEmptyArrayItems, O as resolveOpenAISupportedReasoningEfforts, P as stripUnsupportedSchemaKeywords, S as resolveResponsesMessageSnapshotCollapse, T as isOpenAIGpt56Model, _ as OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE, b as isResponsesTextContentPartType, c as clearOpenAIToolSchemaCacheForTest, d as normalizeOpenAIStrictToolParameters, f as normalizeStrictOpenAIJsonSchema, g as OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE, h as AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE, j as normalizeToolParameterSchema, k as supportsOpenAIReasoningEffort, l as findOpenAIStrictToolProjectionDiagnostics, m as AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE, p as resolveOpenAIProjectedToolsStrictToolFlag, u as isStrictOpenAIJsonSchemaCompatible, v as isAzureResponsesTextDeltaEvent, w as isOpenAIGpt55Model, x as isResponsesTextDeltaEventType, y as isAzureResponsesTextDeltaEventType } from "../openai-responses-shared-sj2YUPYc.mjs";
3
- import { i as resolveAzureDeploymentNameFromMap, n as isTraditionalAzureOpenAIHost, r as parseAzureDeploymentNameMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "../azure-openai-responses-client-compat-a_O_GVQV.mjs";
4
- import { a as clampOpenAIPromptCacheKey, i as OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, n as reconcileOpenAICompletionsToolChoice, r as reconcileOpenAIResponsesToolChoice, t as projectOpenAITools } from "../openai-tool-projection-BknoV11q.mjs";
5
- import { a as mapOpenAIStopReason, i as streamSimpleOpenAICompletions, r as streamOpenAICompletions, t as convertMessages } from "../openai-completions-B9QLIq2U.mjs";
6
- import { n as streamOpenAIResponses, r as streamSimpleOpenAIResponses } from "../openai-responses-B6LylGxM.mjs";
7
- export { AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE, clampOpenAIPromptCacheKey, cleanSchemaForGemini, clearOpenAIToolSchemaCacheForTest, convertMessages, extractToolSchemaModelCompat, findOpenAIStrictToolProjectionDiagnostics, isAzureResponsesTextDeltaEvent, isAzureResponsesTextDeltaEventType, isOpenAICompatibleAzureResponsesBaseUrl, isOpenAIGpt54MiniModel, isOpenAIGpt55Model, isOpenAIGpt56Model, isResponsesTextContentPartType, isResponsesTextDeltaEventType, isStrictOpenAIJsonSchemaCompatible, isTraditionalAzureOpenAIHost, mapOpenAIStopReason, normalizeOpenAIReasoningEffort, normalizeOpenAIStrictToolParameters, normalizeStrictOpenAIJsonSchema, normalizeToolParameterSchema, parseAzureDeploymentNameMap, projectOpenAITools, projectRuntimeToolInputSchema, reconcileOpenAICompletionsToolChoice, reconcileOpenAIResponsesToolChoice, resolveAzureDeploymentNameFromMap, resolveOpenAIProjectedToolsStrictToolFlag, resolveOpenAIReasoningEffortForModel, resolveOpenAISupportedReasoningEfforts, resolveResponsesMessageSnapshotCollapse, resolveUnsupportedToolSchemaKeywords, shouldOmitEmptyArrayItems, streamOpenAICompletions, streamOpenAIResponses, streamSimpleOpenAICompletions, streamSimpleOpenAIResponses, stripUnsupportedSchemaKeywords, supportsOpenAIReasoningEffort };
1
+ import { t as projectRuntimeToolInputSchema } from "../tool-schema-json-projection-BwNu3nDi.mjs";
2
+ import { A as resolveOpenAISupportedReasoningEfforts, C as isResponsesTextDeltaEventType, D as isOpenAIGpt56Model, E as isOpenAIGpt55Model, F as resolveUnsupportedToolSchemaKeywords, I as shouldOmitEmptyArrayItems, L as stripUnsupportedSchemaKeywords, M as supportsOpenAITemperature, N as extractToolSchemaModelCompat, O as normalizeOpenAIReasoningEffort, P as normalizeToolParameterSchema, R as GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, S as isResponsesTextContentPartType, T as isOpenAIGpt54MiniModel, _ as AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE, b as isAzureResponsesTextDeltaEvent, c as clearOpenAIToolSchemaCacheForTest, d as normalizeOpenAIStrictToolParameters, f as normalizeStrictOpenAIJsonSchema, g as AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE, h as readResponsesToolCallItemIdentity, j as supportsOpenAIReasoningEffort, k as resolveOpenAIReasoningEffortForModel, l as findOpenAIStrictToolProjectionDiagnostics, m as createResponsesToolCallTracker, p as resolveOpenAIProjectedToolsStrictToolFlag, u as isStrictOpenAIJsonSchemaCompatible, v as OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE, w as resolveResponsesMessageSnapshotCollapse, x as isAzureResponsesTextDeltaEventType, y as OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE, z as cleanSchemaForGemini } from "../openai-responses-shared-Befb4D6R.mjs";
3
+ import { i as resolveAzureDeploymentNameFromMap, n as isTraditionalAzureOpenAIHost, r as parseAzureDeploymentNameMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "../azure-openai-responses-client-compat-C7K7QfUE.mjs";
4
+ import { a as clampOpenAIPromptCacheKey, i as OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, n as reconcileOpenAICompletionsToolChoice, r as reconcileOpenAIResponsesToolChoice, t as projectOpenAITools } from "../openai-tool-projection-CFqm42J2.mjs";
5
+ import { a as mapOpenAIStopReason, i as streamSimpleOpenAICompletions, r as streamOpenAICompletions, t as convertMessages } from "../openai-completions-DPR_O2RW.mjs";
6
+ import { n as streamOpenAIResponses, r as streamSimpleOpenAIResponses } from "../openai-responses-Cov-Vdc2.mjs";
7
+ export { AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE, clampOpenAIPromptCacheKey, cleanSchemaForGemini, clearOpenAIToolSchemaCacheForTest, convertMessages, createResponsesToolCallTracker, extractToolSchemaModelCompat, findOpenAIStrictToolProjectionDiagnostics, isAzureResponsesTextDeltaEvent, isAzureResponsesTextDeltaEventType, isOpenAICompatibleAzureResponsesBaseUrl, isOpenAIGpt54MiniModel, isOpenAIGpt55Model, isOpenAIGpt56Model, isResponsesTextContentPartType, isResponsesTextDeltaEventType, isStrictOpenAIJsonSchemaCompatible, isTraditionalAzureOpenAIHost, mapOpenAIStopReason, normalizeOpenAIReasoningEffort, normalizeOpenAIStrictToolParameters, normalizeStrictOpenAIJsonSchema, normalizeToolParameterSchema, parseAzureDeploymentNameMap, projectOpenAITools, projectRuntimeToolInputSchema, readResponsesToolCallItemIdentity, reconcileOpenAICompletionsToolChoice, reconcileOpenAIResponsesToolChoice, resolveAzureDeploymentNameFromMap, resolveOpenAIProjectedToolsStrictToolFlag, resolveOpenAIReasoningEffortForModel, resolveOpenAISupportedReasoningEfforts, resolveResponsesMessageSnapshotCollapse, resolveUnsupportedToolSchemaKeywords, shouldOmitEmptyArrayItems, streamOpenAICompletions, streamOpenAIResponses, streamSimpleOpenAICompletions, streamSimpleOpenAIResponses, stripUnsupportedSchemaKeywords, supportsOpenAIReasoningEffort, supportsOpenAITemperature };
@@ -0,0 +1,5 @@
1
+ //#region packages/ai/src/internal/retry-after.d.ts
2
+ /** Parses the three HTTP-date forms accepted for Retry-After without Date.parse normalization. */
3
+ declare function parseRetryAfterHttpDateMs(value: string, nowMs?: number): number | undefined;
4
+ //#endregion
5
+ export { parseRetryAfterHttpDateMs };
@@ -0,0 +1,101 @@
1
+ //#region packages/ai/src/internal/retry-after.ts
2
+ const HTTP_DATE_MONTH_INDEX = new Map([
3
+ "Jan",
4
+ "Feb",
5
+ "Mar",
6
+ "Apr",
7
+ "May",
8
+ "Jun",
9
+ "Jul",
10
+ "Aug",
11
+ "Sep",
12
+ "Oct",
13
+ "Nov",
14
+ "Dec"
15
+ ].map((month, index) => [month, index]));
16
+ const HTTP_DATE_SHORT_WEEKDAY_INDEX = new Map([
17
+ "Sun",
18
+ "Mon",
19
+ "Tue",
20
+ "Wed",
21
+ "Thu",
22
+ "Fri",
23
+ "Sat"
24
+ ].map((weekday, index) => [weekday, index]));
25
+ const HTTP_DATE_LONG_WEEKDAY_INDEX = new Map([
26
+ "Sunday",
27
+ "Monday",
28
+ "Tuesday",
29
+ "Wednesday",
30
+ "Thursday",
31
+ "Friday",
32
+ "Saturday"
33
+ ].map((weekday, index) => [weekday, index]));
34
+ const IMF_FIXDATE_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$/;
35
+ const OBSOLETE_RFC850_DATE_RE = /^(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$/;
36
+ const OBSOLETE_ASCTIME_DATE_RE = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{2}| \d) (\d{2}):(\d{2}):(\d{2}) (\d{4})$/;
37
+ /** Parses the three HTTP-date forms accepted for Retry-After without Date.parse normalization. */
38
+ function parseRetryAfterHttpDateMs(value, nowMs = Date.now()) {
39
+ const imfFixdate = IMF_FIXDATE_RE.exec(value);
40
+ if (imfFixdate) return parseHttpDateComponentsMs({
41
+ weekday: HTTP_DATE_SHORT_WEEKDAY_INDEX.get(imfFixdate[1] ?? ""),
42
+ year: Number.parseInt(imfFixdate[4] ?? "", 10),
43
+ month: HTTP_DATE_MONTH_INDEX.get(imfFixdate[3] ?? ""),
44
+ day: Number.parseInt(imfFixdate[2] ?? "", 10),
45
+ hours: Number.parseInt(imfFixdate[5] ?? "", 10),
46
+ minutes: Number.parseInt(imfFixdate[6] ?? "", 10),
47
+ seconds: Number.parseInt(imfFixdate[7] ?? "", 10)
48
+ });
49
+ const rfc850Date = OBSOLETE_RFC850_DATE_RE.exec(value);
50
+ if (rfc850Date) {
51
+ const now = new Date(nowMs);
52
+ if (Number.isNaN(now.getTime())) return;
53
+ const shortYear = Number.parseInt(rfc850Date[4] ?? "", 10);
54
+ const candidateYear = Math.floor(now.getUTCFullYear() / 100) * 100 + shortYear;
55
+ const components = {
56
+ weekday: HTTP_DATE_LONG_WEEKDAY_INDEX.get(rfc850Date[1] ?? ""),
57
+ month: HTTP_DATE_MONTH_INDEX.get(rfc850Date[3] ?? ""),
58
+ day: Number.parseInt(rfc850Date[2] ?? "", 10),
59
+ hours: Number.parseInt(rfc850Date[5] ?? "", 10),
60
+ minutes: Number.parseInt(rfc850Date[6] ?? "", 10),
61
+ seconds: Number.parseInt(rfc850Date[7] ?? "", 10)
62
+ };
63
+ const candidate = parseHttpDateCalendarMs({
64
+ year: candidateYear,
65
+ ...components
66
+ });
67
+ if (candidate === void 0) return;
68
+ return parseHttpDateComponentsMs({
69
+ year: candidate > Date.UTC(now.getUTCFullYear() + 50, now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds()) ? candidateYear - 100 : candidateYear,
70
+ ...components
71
+ });
72
+ }
73
+ const asctimeDate = OBSOLETE_ASCTIME_DATE_RE.exec(value);
74
+ if (asctimeDate) return parseHttpDateComponentsMs({
75
+ weekday: HTTP_DATE_SHORT_WEEKDAY_INDEX.get(asctimeDate[1] ?? ""),
76
+ year: Number.parseInt(asctimeDate[7] ?? "", 10),
77
+ month: HTTP_DATE_MONTH_INDEX.get(asctimeDate[2] ?? ""),
78
+ day: Number.parseInt((asctimeDate[3] ?? "").trim(), 10),
79
+ hours: Number.parseInt(asctimeDate[4] ?? "", 10),
80
+ minutes: Number.parseInt(asctimeDate[5] ?? "", 10),
81
+ seconds: Number.parseInt(asctimeDate[6] ?? "", 10)
82
+ });
83
+ }
84
+ function parseHttpDateComponentsMs(components) {
85
+ const timestamp = parseHttpDateCalendarMs(components);
86
+ if (timestamp === void 0) return;
87
+ const weekdayTimestamp = components.seconds === 60 ? timestamp - 1e3 : timestamp;
88
+ if (new Date(weekdayTimestamp).getUTCDay() !== components.weekday) return;
89
+ return timestamp;
90
+ }
91
+ function parseHttpDateCalendarMs(components) {
92
+ const { year, month, day, hours, minutes, seconds } = components;
93
+ if (month === void 0 || !Number.isInteger(year) || year < 1900 || !Number.isInteger(day) || day < 1 || day > 31 || !Number.isInteger(hours) || hours < 0 || hours > 23 || !Number.isInteger(minutes) || minutes < 0 || minutes > 59 || !Number.isInteger(seconds) || seconds < 0 || seconds > 60) return;
94
+ const calendarSecond = Math.min(seconds, 59);
95
+ const timestamp = Date.UTC(year, month, day, hours, minutes, calendarSecond);
96
+ const parsedDate = new Date(timestamp);
97
+ if (parsedDate.getUTCFullYear() !== year || parsedDate.getUTCMonth() !== month || parsedDate.getUTCDate() !== day || parsedDate.getUTCHours() !== hours || parsedDate.getUTCMinutes() !== minutes || parsedDate.getUTCSeconds() !== calendarSecond) return;
98
+ return seconds === 60 ? timestamp + 1e3 : timestamp;
99
+ }
100
+ //#endregion
101
+ export { parseRetryAfterHttpDateMs };
@@ -1,5 +1,5 @@
1
- import { D as ModelThinkingLevel, E as Model, F as SimpleStreamOptions, P as ProviderStreamOptions, X as Usage, i as AssistantMessage, n as Api, o as AssistantMessageEventStreamContract, u as Context, z as StreamOptions } from "../types-DRgdPqaZ.mjs";
2
- import { a as RegisteredApiProvider, t as ApiProvider } from "../api-registry-BXYnCOIR.mjs";
1
+ import { D as ModelThinkingLevel, E as Model, F as SimpleStreamOptions, P as ProviderStreamOptions, X as Usage, i as AssistantMessage, n as Api, o as AssistantMessageEventStreamContract, u as Context, z as StreamOptions } from "../types-Cx2zJtyz.mjs";
2
+ import { a as RegisteredApiProvider, t as ApiProvider } from "../api-registry-Byvoz8Ha.mjs";
3
3
  import { t as sanitizeSurrogates } from "../sanitize-unicode-BZiVbGwK.mjs";
4
4
 
5
5
  //#region packages/ai/src/internal/default-runtime.d.ts
@@ -1,11 +1,11 @@
1
- import { n as getEnvApiKey, t as findEnvKeys } from "../env-api-keys-CtMlqaQ4.mjs";
1
+ import { n as getEnvApiKey, t as findEnvKeys } from "../env-api-keys-DnhYpc27.mjs";
2
2
  import { n as createApiRegistry, t as createLlmRuntime } from "../stream-CREqxHgU.mjs";
3
- import { a as modelsAreEqual, i as getSupportedThinkingLevels, n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "../model-utils-DgmOla96.mjs";
3
+ import { a as modelsAreEqual, i as getSupportedThinkingLevels, n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "../model-utils-Q1LSRIdo.mjs";
4
4
  import { n as onLlmRequestActivity, r as createDeferredEventBuffer, t as notifyLlmRequestActivity } from "../llm-request-activity-CehVkZP-.mjs";
5
5
  import { t as headersToRecord } from "../headers-B_e4-1J0.mjs";
6
- import { n as parseStreamingJson, r as repairJson, t as parseJsonWithRepair } from "../json-parse-DzNSIQBq.mjs";
6
+ import { n as parseStreamingJson, r as repairJson, t as parseJsonWithRepair } from "../json-parse-BvXNt1-7.mjs";
7
7
  import { t as sanitizeSurrogates } from "../sanitize-unicode-DT5o51ur.mjs";
8
- import { t as createReasoningTagTextPartitioner } from "../reasoning-tag-text-partitioner-axhAdUwg.mjs";
8
+ import { t as createReasoningTagTextPartitioner } from "../reasoning-tag-text-partitioner-BlVe67g6.mjs";
9
9
  import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, n as createFirstStreamEventTimeoutError, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "../stream-first-event-timeout-RjWszj8c.mjs";
10
10
  import { t as shortHash } from "../hash-CHgqbJmD.mjs";
11
11
  import { i as registerSessionResourceCleanup, n as resolveOpenAICodexAccountId, r as cleanupSessionResources, t as decodeOpenAICodexJwtPayload } from "../openai-chatgpt-jwt-DhAAzLkj.mjs";
@@ -160,7 +160,8 @@ function resolveContextInputTokens(message) {
160
160
  */
161
161
  function isContextOverflow(message, contextWindow) {
162
162
  if (message.stopReason === "error" && message.errorMessage) {
163
- if (!NON_OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage)) && OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage))) return true;
163
+ const errorMessage = message.errorMessage;
164
+ if (!NON_OVERFLOW_PATTERNS.some((p) => p.test(errorMessage)) && OVERFLOW_PATTERNS.some((p) => p.test(errorMessage))) return true;
164
165
  }
165
166
  if (contextWindow && message.stopReason === "stop") {
166
167
  const inputTokens = resolveContextInputTokens(message);
@@ -1,4 +1,4 @@
1
- import { E as Model, F as SimpleStreamOptions, H as ThinkingBudgets, T as Message, W as ThinkingLevel, i as AssistantMessage, n as Api, z as StreamOptions } from "../types-DRgdPqaZ.mjs";
1
+ import { E as Model, F as SimpleStreamOptions, H as ThinkingBudgets, T as Message, W as ThinkingLevel, i as AssistantMessage, n as Api, z as StreamOptions } from "../types-Cx2zJtyz.mjs";
2
2
  import { t as sanitizeSurrogates } from "../sanitize-unicode-BZiVbGwK.mjs";
3
3
 
4
4
  //#region packages/ai/src/providers/simple-options.d.ts
@@ -7,6 +7,7 @@ type FirstEventStreamOptions = {
7
7
  onFirstEventTimeout?: (reason: Error) => void;
8
8
  };
9
9
  declare function buildBaseOptions(model: Model, options?: SimpleStreamOptions, apiKey?: string): StreamOptions & FirstEventStreamOptions;
10
+ declare function clampReasoning(effort: ThinkingLevel): Exclude<ThinkingLevel, "xhigh">;
10
11
  declare function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh"> | undefined;
11
12
  declare function adjustMaxTokensForThinking(baseMaxTokens: number | undefined, modelMaxTokens: number, reasoningLevel: ThinkingLevel, customBudgets?: ThinkingBudgets): {
12
13
  maxTokens: number;
@@ -14,6 +15,15 @@ declare function adjustMaxTokensForThinking(baseMaxTokens: number | undefined, m
14
15
  };
15
16
  //#endregion
16
17
  //#region packages/ai/src/providers/tool-result-text.d.ts
18
+ /** Media metadata alone is not an attachment; provider emitters need inline bytes. */
19
+ declare function hasMediaPayload(block: unknown): block is Record<string, unknown> & {
20
+ data: string;
21
+ };
22
+ /** Image metadata alone is not an attachment; provider emitters need inline bytes. */
23
+ declare function isImageWithMediaPayload<T>(block: T): block is T & {
24
+ type: "image";
25
+ data: string;
26
+ };
17
27
  declare function describeToolResultMediaPlaceholder(blocks: readonly unknown[]): string | undefined;
18
28
  declare function extractToolResultBlockText(block: unknown): string | undefined;
19
29
  declare function extractToolResultText(blocks: readonly unknown[]): string;
@@ -45,4 +55,4 @@ declare function prependSystemPromptAdditionAfterCacheBoundary(params: {
45
55
  systemPromptAddition?: string;
46
56
  }): string;
47
57
  //#endregion
48
- export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
58
+ export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, hasMediaPayload, isImageWithMediaPayload, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
@@ -1,3 +1,3 @@
1
1
  import { t as sanitizeSurrogates } from "../sanitize-unicode-DT5o51ur.mjs";
2
- import { S as normalizeStructuredPromptSection, _ as ensureSystemPromptCacheBoundary, a as adjustMaxTokensForThinking, b as stripSystemPromptCacheBoundary, g as SYSTEM_PROMPT_CACHE_BOUNDARY, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as buildBaseOptions, r as extractToolResultBlockText, s as clampReasoning, t as transformMessages, v as prependSystemPromptAdditionAfterCacheBoundary, x as normalizePromptCapabilityIds, y as splitSystemPromptCacheBoundary } from "../transform-messages-BhGF_fF4.mjs";
3
- export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
2
+ import { C as stripSystemPromptCacheBoundary, S as splitSystemPromptCacheBoundary, T as normalizeStructuredPromptSection, a as hasMediaPayload, b as ensureSystemPromptCacheBoundary, c as adjustMaxTokensForThinking, i as extractToolResultText, l as buildBaseOptions, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, r as extractToolResultBlockText, t as transformMessages, u as clampReasoning, w as normalizePromptCapabilityIds, x as prependSystemPromptAdditionAfterCacheBoundary, y as SYSTEM_PROMPT_CACHE_BOUNDARY } from "../transform-messages-BmS70CP5.mjs";
3
+ export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, hasMediaPayload, isImageWithMediaPayload, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
@@ -42,7 +42,7 @@ function repairJson(json) {
42
42
  let inString = false;
43
43
  let stringValuePrefix = "";
44
44
  for (let index = 0; index < json.length; index++) {
45
- const char = json[index];
45
+ const char = json.charAt(index);
46
46
  if (!inString) {
47
47
  repaired += char;
48
48
  if (char === "\"") {
@@ -58,8 +58,8 @@ function repairJson(json) {
58
58
  continue;
59
59
  }
60
60
  if (char === "\\") {
61
- const nextChar = json[index + 1];
62
- if (nextChar === void 0) {
61
+ const nextChar = json.charAt(index + 1);
62
+ if (!nextChar) {
63
63
  repaired += "\\\\";
64
64
  continue;
65
65
  }
@@ -96,9 +96,7 @@ function repairJson(json) {
96
96
  return repaired;
97
97
  }
98
98
  function parseJsonWithRepair(json) {
99
- const repairedJson = repairJson(json);
100
- if (repairedJson !== json) return JSON.parse(repairedJson);
101
- return JSON.parse(json);
99
+ return JSON.parse(repairJson(json));
102
100
  }
103
101
  function looksLikeWindowsPathPrefix(prefix) {
104
102
  const tail = prefix.slice(-160);
@@ -1,12 +1,13 @@
1
- import { n as getEnvApiKey } from "./env-api-keys-CtMlqaQ4.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
1
+ import { n as getEnvApiKey } 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 } from "./model-utils-DgmOla96.mjs";
5
- import { n as parseStreamingJson } from "./json-parse-DzNSIQBq.mjs";
4
+ import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-Q1LSRIdo.mjs";
5
+ import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
6
6
  import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
7
- import { b as stripSystemPromptCacheBoundary, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as buildBaseOptions, t as transformMessages } from "./transform-messages-BhGF_fF4.mjs";
7
+ import { C as stripSystemPromptCacheBoundary, i as extractToolResultText, l as buildBaseOptions, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, s as truncateUtf16Safe, t as transformMessages } from "./transform-messages-BmS70CP5.mjs";
8
8
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
9
9
  import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
10
+ import { randomUUID } from "node:crypto";
10
11
  import { HTTPClient, Mistral } from "@mistralai/mistralai";
11
12
  //#region packages/ai/src/providers/mistral.ts
12
13
  const MISTRAL_TOOL_CALL_ID_LENGTH = 9;
@@ -70,7 +71,15 @@ const streamMistral = (model, context, options) => {
70
71
  let payload = buildChatPayload(model, context, transformMessages(context.messages, model, (id) => normalizeMistralToolCallId(id)), options);
71
72
  const nextPayload = await options?.onPayload?.(payload, model);
72
73
  if (nextPayload !== void 0) payload = nextPayload;
73
- const mistralStream = await mistral.chat.stream(payload, buildRequestOptions(model, options));
74
+ const headers = {
75
+ ...model.headers,
76
+ ...options?.headers
77
+ };
78
+ if (options?.sessionId) headers["x-affinity"] ||= options.sessionId;
79
+ const mistralStream = await mistral.chat.stream(payload, {
80
+ headers,
81
+ signal: options?.signal
82
+ });
74
83
  stream.push({
75
84
  type: "start",
76
85
  partial: output
@@ -162,7 +171,7 @@ function deriveMistralToolCallId(id, attempt) {
162
171
  const normalized = id.replace(/[^a-zA-Z0-9]/g, "");
163
172
  if (attempt === 0 && normalized.length === MISTRAL_TOOL_CALL_ID_LENGTH) return normalized;
164
173
  const seedBase = normalized || id;
165
- return shortHash(attempt === 0 ? seedBase : `${seedBase}:${attempt}`).replace(/[^a-zA-Z0-9]/g, "").slice(0, MISTRAL_TOOL_CALL_ID_LENGTH);
174
+ return shortHash(attempt === 0 ? seedBase : `${seedBase}:${attempt}`).replace(/[^a-zA-Z0-9]/g, "").padEnd(MISTRAL_TOOL_CALL_ID_LENGTH, "0").slice(0, MISTRAL_TOOL_CALL_ID_LENGTH);
166
175
  }
167
176
  function formatMistralError(error) {
168
177
  if (error instanceof Error) {
@@ -177,7 +186,8 @@ function formatMistralError(error) {
177
186
  }
178
187
  function truncateErrorText(text, maxChars) {
179
188
  if (text.length <= maxChars) return text;
180
- return `${text.slice(0, maxChars)}... [truncated ${text.length - maxChars} chars]`;
189
+ const truncated = truncateUtf16Safe(text, maxChars);
190
+ return `${truncated}... [truncated ${text.length - truncated.length} chars]`;
181
191
  }
182
192
  function safeJsonStringify(value) {
183
193
  try {
@@ -187,16 +197,6 @@ function safeJsonStringify(value) {
187
197
  return String(value);
188
198
  }
189
199
  }
190
- function buildRequestOptions(model, options) {
191
- const requestOptions = { retries: { strategy: "none" } };
192
- if (options?.signal) requestOptions.signal = options.signal;
193
- const headers = {};
194
- if (model.headers) Object.assign(headers, model.headers);
195
- if (options?.headers) Object.assign(headers, options.headers);
196
- if (options?.sessionId && !headers["x-affinity"]) headers["x-affinity"] = options.sessionId;
197
- if (Object.keys(headers).length > 0) requestOptions.headers = headers;
198
- return requestOptions;
199
- }
200
200
  function buildChatPayload(model, context, messages, options) {
201
201
  const payload = {
202
202
  model: model.id,
@@ -228,7 +228,65 @@ async function consumeChatStream(model, output, stream, mistralStream) {
228
228
  let currentBlock = null;
229
229
  const blocks = output.content;
230
230
  const blockIndex = () => blocks.length - 1;
231
- const toolBlocksByKey = /* @__PURE__ */ new Map();
231
+ const toolBlockIdentities = /* @__PURE__ */ new Map();
232
+ const normalizeMissingToolCallId = createMistralToolCallIdNormalizer();
233
+ const missingToolCallIdScope = randomUUID();
234
+ const createMissingToolCallId = (contentIndex) => normalizeMissingToolCallId(`${missingToolCallIdScope}:toolcall:${contentIndex}`);
235
+ const findIdentityCandidates = (matches, excludedContentIndexes) => {
236
+ const candidates = /* @__PURE__ */ new Set();
237
+ for (const [contentIndex, identity] of toolBlockIdentities) if (!excludedContentIndexes?.has(contentIndex) && matches(identity)) candidates.add(contentIndex);
238
+ return candidates;
239
+ };
240
+ const intersectCandidates = (left, right) => new Set([...left].filter((contentIndex) => right.has(contentIndex)));
241
+ const requireSingleCandidate = (candidates) => {
242
+ if (candidates.size > 1) throw new Error("Mistral streamed tool-call continuation is ambiguous; refusing to merge arguments");
243
+ return candidates.values().next().value;
244
+ };
245
+ const requireExistingCandidate = (candidates) => {
246
+ const candidate = requireSingleCandidate(candidates);
247
+ if (candidate === void 0) throw new Error("Mistral streamed tool-call identities conflict; refusing to merge arguments");
248
+ return candidate;
249
+ };
250
+ const resolveToolBlockIndex = (params) => {
251
+ const explicitId = params.explicitId;
252
+ const functionName = params.functionName;
253
+ const toolCallIndex = params.index;
254
+ const idCandidates = explicitId ? findIdentityCandidates((identity) => identity.explicitIds.has(explicitId), params.usedContentIndexes) : /* @__PURE__ */ new Set();
255
+ const nameCandidates = functionName ? findIdentityCandidates((identity) => identity.functionNames.has(functionName), params.usedContentIndexes) : /* @__PURE__ */ new Set();
256
+ const indexCandidates = toolCallIndex === void 0 ? /* @__PURE__ */ new Set() : findIdentityCandidates((identity) => identity.indexes.has(toolCallIndex), params.usedContentIndexes);
257
+ if (idCandidates.size > 0) {
258
+ let candidates = idCandidates;
259
+ if (nameCandidates.size > 0) candidates = intersectCandidates(candidates, nameCandidates);
260
+ return requireExistingCandidate(candidates);
261
+ }
262
+ if (nameCandidates.size > 0) {
263
+ const idCompatibleCandidates = new Set([...nameCandidates].filter((contentIndex) => {
264
+ const identity = toolBlockIdentities.get(contentIndex);
265
+ if (!identity) return false;
266
+ return !explicitId || identity.explicitIds.size === 0;
267
+ }));
268
+ if (idCompatibleCandidates.size <= 1 && (toolCallIndex === void 0 || toolCallIndex === 0)) return requireSingleCandidate(idCompatibleCandidates);
269
+ const indexCompatibleCandidates = new Set([...idCompatibleCandidates].filter((contentIndex) => {
270
+ const identity = toolBlockIdentities.get(contentIndex);
271
+ if (!identity) return false;
272
+ return toolCallIndex === void 0 || identity.indexes.size === 0 || identity.indexes.has(toolCallIndex);
273
+ }));
274
+ if (indexCompatibleCandidates.size === 0) return;
275
+ return requireSingleCandidate(indexCompatibleCandidates);
276
+ }
277
+ if (functionName) {
278
+ const namelessCandidates = new Set([...indexCandidates].filter((contentIndex) => {
279
+ const identity = toolBlockIdentities.get(contentIndex);
280
+ return identity?.functionNames.size === 0 && (!explicitId || identity.explicitIds.size === 0);
281
+ }));
282
+ return requireSingleCandidate(namelessCandidates);
283
+ }
284
+ if (explicitId) {
285
+ const idlessCandidates = new Set([...indexCandidates].filter((contentIndex) => toolBlockIdentities.get(contentIndex)?.explicitIds.size === 0));
286
+ return requireSingleCandidate(idlessCandidates);
287
+ }
288
+ return requireSingleCandidate(indexCandidates);
289
+ };
232
290
  const finishCurrentBlock = (block) => {
233
291
  if (!block) return;
234
292
  if (block.type === "text") {
@@ -340,52 +398,77 @@ async function consumeChatStream(model, output, stream, mistralStream) {
340
398
  }
341
399
  }
342
400
  const toolCalls = delta.toolCalls || [];
401
+ const usedToolBlockIndexes = /* @__PURE__ */ new Set();
343
402
  for (const toolCall of toolCalls) {
344
403
  if (currentBlock) {
345
404
  finishCurrentBlock(currentBlock);
346
405
  currentBlock = null;
347
406
  }
348
- const callId = toolCall.id && toolCall.id !== "null" ? toolCall.id : deriveMistralToolCallId(`toolcall:${toolCall.index ?? 0}`, 0);
349
- const key = `${callId}:${toolCall.index || 0}`;
350
- const existingIndex = toolBlocksByKey.get(key);
407
+ const toolCallIndex = typeof toolCall.index === "number" && Number.isInteger(toolCall.index) ? toolCall.index : void 0;
408
+ const providedCallId = toolCall.id && toolCall.id !== "null" ? toolCall.id : void 0;
409
+ const functionName = toolCall.function.name.trim() || void 0;
410
+ const existingIndex = resolveToolBlockIndex({
411
+ explicitId: providedCallId,
412
+ functionName,
413
+ index: toolCallIndex,
414
+ usedContentIndexes: usedToolBlockIndexes
415
+ });
351
416
  let block;
352
417
  if (existingIndex !== void 0) {
353
418
  const existing = output.content[existingIndex];
354
419
  if (existing?.type === "toolCall") block = existing;
355
420
  }
356
421
  if (!block) {
422
+ const contentIndex = output.content.length;
357
423
  block = {
358
424
  type: "toolCall",
359
- id: callId,
360
- name: toolCall.function.name,
425
+ id: providedCallId ?? createMissingToolCallId(contentIndex),
426
+ name: functionName ?? "",
361
427
  arguments: {},
362
428
  partialArgs: ""
363
429
  };
364
430
  output.content.push(block);
365
- toolBlocksByKey.set(key, output.content.length - 1);
431
+ toolBlockIdentities.set(contentIndex, {
432
+ explicitIds: new Set(providedCallId ? [providedCallId] : []),
433
+ functionNames: new Set(functionName ? [functionName] : []),
434
+ indexes: new Set(toolCallIndex === void 0 ? [] : [toolCallIndex])
435
+ });
366
436
  stream.push({
367
437
  type: "toolcall_start",
368
- contentIndex: output.content.length - 1,
438
+ contentIndex,
369
439
  partial: output
370
440
  });
371
441
  }
442
+ const contentIndex = output.content.indexOf(block);
443
+ const identity = toolBlockIdentities.get(contentIndex);
444
+ if (!identity) throw new Error("Mistral streamed tool-call identity is missing");
445
+ usedToolBlockIndexes.add(contentIndex);
446
+ if (providedCallId) {
447
+ block.id = providedCallId;
448
+ identity.explicitIds.add(providedCallId);
449
+ }
450
+ if (functionName) {
451
+ if (identity.functionNames.size > 0 && !identity.functionNames.has(functionName)) throw new Error("Mistral streamed tool-call continuation changed function name; refusing to merge arguments");
452
+ block.name = functionName;
453
+ identity.functionNames.add(functionName);
454
+ }
455
+ if (toolCallIndex !== void 0) identity.indexes.add(toolCallIndex);
372
456
  const argsDelta = typeof toolCall.function.arguments === "string" ? toolCall.function.arguments : JSON.stringify(toolCall.function.arguments || {});
373
457
  block.partialArgs = (block.partialArgs || "") + argsDelta;
374
458
  block.arguments = parseStreamingJson(block.partialArgs);
375
459
  stream.push({
376
460
  type: "toolcall_delta",
377
- contentIndex: toolBlocksByKey.get(key),
461
+ contentIndex,
378
462
  delta: argsDelta,
379
463
  partial: output
380
464
  });
381
465
  }
382
466
  }
383
467
  finishCurrentBlock(currentBlock);
384
- for (const index of toolBlocksByKey.values()) {
385
- const block = output.content[index];
386
- if (block.type !== "toolCall") continue;
468
+ for (const index of toolBlockIdentities.keys()) {
469
+ const block = output.content.at(index);
470
+ if (block?.type !== "toolCall") continue;
387
471
  const toolBlock = block;
388
- toolBlock.arguments = parseStreamingJson(toolBlock.partialArgs);
389
472
  delete toolBlock.partialArgs;
390
473
  stream.push({
391
474
  type: "toolcall_end",
@@ -493,14 +576,14 @@ function toChatMessages(messages, supportsImages) {
493
576
  continue;
494
577
  }
495
578
  const toolContent = [];
496
- const toolText = buildToolResultText(extractToolResultText(msg.content), describeToolResultMediaPlaceholder(msg.content), msg.content.some((part) => part.type === "image"), supportsImages, msg.isError);
579
+ const toolText = buildToolResultText(extractToolResultText(msg.content), describeToolResultMediaPlaceholder(msg.content), msg.content.some(isImageWithMediaPayload), supportsImages, msg.isError);
497
580
  toolContent.push({
498
581
  type: "text",
499
582
  text: toolText
500
583
  });
501
584
  for (const part of msg.content) {
502
585
  if (!supportsImages) continue;
503
- if (part.type !== "image") continue;
586
+ if (!isImageWithMediaPayload(part)) continue;
504
587
  toolContent.push({
505
588
  type: "image_url",
506
589
  imageUrl: `data:${part.mimeType};base64,${part.data}`
@@ -1,4 +1,4 @@
1
- import { c as resolveClaudeNativeThinkingLevelMap, i as requiresClaudeMandatoryAdaptiveThinking } from "./src-CZ503MYJ.mjs";
1
+ import { c as resolveClaudeNativeThinkingLevelMap, i as requiresClaudeMandatoryAdaptiveThinking } from "./src-CXno1H5g.mjs";
2
2
  //#region packages/ai/src/model-utils.ts
3
3
  /** Calculates and stores model cost fields from token usage and per-million pricing. */
4
4
  function calculateCost(model, usage) {
@@ -46,18 +46,11 @@ function clampThinkingLevel(model, level) {
46
46
  const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
47
47
  if (requestedIndex === -1) return availableLevels[0] ?? "off";
48
48
  const thinkingLevelMap = resolveThinkingLevelMap(model);
49
- if ((level === "xhigh" || level === "max") && thinkingLevelMap?.[level] === null) for (let i = requestedIndex - 1; i >= 0; i--) {
50
- const candidate = EXTENDED_THINKING_LEVELS[i];
51
- if (availableLevels.includes(candidate)) return candidate;
52
- }
53
- for (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {
54
- const candidate = EXTENDED_THINKING_LEVELS[i];
55
- if (availableLevels.includes(candidate)) return candidate;
56
- }
57
- for (let i = requestedIndex - 1; i >= 0; i--) {
58
- const candidate = EXTENDED_THINKING_LEVELS[i];
59
- if (availableLevels.includes(candidate)) return candidate;
49
+ if ((level === "xhigh" || level === "max") && thinkingLevelMap?.[level] === null) {
50
+ for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
60
51
  }
52
+ for (const candidate of EXTENDED_THINKING_LEVELS.slice(requestedIndex)) if (availableLevels.includes(candidate)) return candidate;
53
+ for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
61
54
  return availableLevels[0] ?? "off";
62
55
  }
63
56
  /** Compares model identity by provider and id. */