@openclaw/ai 2026.7.2-beta.2 → 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 (46) hide show
  1. package/README.md +6 -5
  2. package/dist/{anthropic-BIRSg5x9.mjs → anthropic-CrUDIBpM.mjs} +173 -47
  3. package/dist/{api-registry-Byvoz8Ha.d.mts → api-registry-BMphkFf1.d.mts} +1 -2
  4. package/dist/{azure-openai-responses-CHi7Wo4A.mjs → azure-openai-responses-CbrpVeEv.mjs} +9 -11
  5. package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
  6. package/dist/{event-stream-uQspnL8S.d.mts → event-stream-Douf9dob.d.mts} +1 -1
  7. package/dist/event-stream.d.mts +1 -1
  8. package/dist/{google-BmsqsNwR.mjs → google-Cs62KA7t.mjs} +4 -4
  9. package/dist/{google-shared-Dx2aba47.mjs → google-shared-CMLI-tCZ.mjs} +4 -3
  10. package/dist/{google-vertex-HZ_0rTwS.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 +9 -3
  17. package/dist/internal/anthropic.mjs +3 -3
  18. package/dist/internal/openai.d.mts +2 -279
  19. package/dist/internal/openai.mjs +5 -5
  20. package/dist/internal/runtime.d.mts +8 -5
  21. package/dist/internal/runtime.mjs +22 -12
  22. package/dist/internal/shared.d.mts +4 -2
  23. package/dist/internal/shared.mjs +2 -2
  24. package/dist/{mistral-DxMPt9q9.mjs → mistral-D5Ps7Led.mjs} +26 -10
  25. package/dist/{model-utils-Q1LSRIdo.mjs → model-utils-1GiZ2_rr.mjs} +3 -1
  26. package/dist/openai-CoGicoDt.d.mts +332 -0
  27. package/dist/{openai-chatgpt-responses-BuH2NvsR.mjs → openai-chatgpt-responses-h0o5yV8Y.mjs} +47 -48
  28. package/dist/{openai-completions-DPR_O2RW.mjs → openai-completions-exO8NFQf.mjs} +342 -102
  29. package/dist/{openai-responses-Cov-Vdc2.mjs → openai-responses-BHpmtUKo.mjs} +5 -5
  30. package/dist/{openai-responses-shared-Befb4D6R.mjs → openai-responses-shared-CzCurmY1.mjs} +527 -268
  31. package/dist/{openai-tool-projection-CFqm42J2.mjs → openai-tool-projection-ITOU9bG1.mjs} +1 -1
  32. package/dist/provider-error-C4VvV_3t.mjs +41 -0
  33. package/dist/providers.d.mts +1 -1
  34. package/dist/providers.mjs +8 -8
  35. package/dist/{stream-first-event-timeout-RjWszj8c.mjs → stream-first-event-timeout-DP4xEyBY.mjs} +45 -1
  36. package/dist/{transform-messages-BmS70CP5.mjs → system-prompt-cache-boundary-CbHeV4_l.mjs} +171 -161
  37. package/dist/transports.d.mts +590 -0
  38. package/dist/transports.mjs +5701 -0
  39. package/dist/{types-Cx2zJtyz.d.mts → types-AFwwWium.d.mts} +7 -0
  40. package/dist/types.d.mts +4 -4
  41. package/dist/{validation-Cej7htKc.d.mts → validation-sxvxC8J-.d.mts} +1 -1
  42. package/dist/validation.d.mts +1 -1
  43. package/npm-shrinkwrap.json +43 -50
  44. package/package.json +36 -10
  45. package/dist/host-4t713IeR.mjs +0 -37
  46. /package/dist/{index-BoTnz8cv.d.mts → anthropic-BoTnz8cv.d.mts} +0 -0
@@ -0,0 +1,332 @@
1
+ import { E as Model, F as SimpleStreamOptions, I as StopReason, O as OpenAICompletionsCompat, R as StreamFunction, X as Usage, u as Context, z as StreamOptions } from "./types-AFwwWium.mjs";
2
+ import OpenAI from "openai";
3
+ import { TSchema } from "typebox";
4
+ import { ChatCompletionMessageParam } from "openai/resources/chat/completions.js";
5
+ import { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
6
+
7
+ //#region packages/ai/src/providers/agent-tools-parameter-schema.d.ts
8
+ /**
9
+ * Narrow structural view of the host's model compat config. packages/ai must stay
10
+ * config-agnostic, so only tool-schema-relevant fields are modeled here; the host's
11
+ * ModelCompatConfig remains structurally assignable.
12
+ */
13
+ type ToolSchemaModelCompat = {
14
+ toolSchemaProfile?: string;
15
+ unsupportedToolSchemaKeywords?: string[];
16
+ omitEmptyArrayItems?: boolean;
17
+ };
18
+ /** Extracts the compat record whether callers pass a model (`{ compat }`) or the compat itself. */
19
+ declare function extractToolSchemaModelCompat(modelOrCompat: {
20
+ compat?: unknown;
21
+ } | ToolSchemaModelCompat | undefined): ToolSchemaModelCompat | undefined;
22
+ /** JSON Schema keywords this model/provider rejects in tool schemas. */
23
+ declare function resolveUnsupportedToolSchemaKeywords(modelOrCompat: {
24
+ compat?: unknown;
25
+ } | ToolSchemaModelCompat | undefined): ReadonlySet<string>;
26
+ /** Whether empty `items: {}` on array schemas must be omitted for this model/provider. */
27
+ declare function shouldOmitEmptyArrayItems(modelOrCompat: {
28
+ compat?: unknown;
29
+ } | ToolSchemaModelCompat | undefined): boolean;
30
+ type ToolParameterSchemaOptions = {
31
+ modelProvider?: string;
32
+ modelId?: string;
33
+ modelCompat?: ToolSchemaModelCompat;
34
+ };
35
+ /** Return a provider-compatible JSON schema for a model-facing tool. */
36
+ declare function normalizeToolParameterSchema(schema: unknown, options?: ToolParameterSchemaOptions): TSchema;
37
+ //#endregion
38
+ //#region packages/ai/src/providers/azure-deployment-map.d.ts
39
+ /** Parses AZURE_OPENAI_DEPLOYMENT_MAP-style model=deployment entries. */
40
+ declare function parseAzureDeploymentNameMap(value: string | undefined): Map<string, string>;
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
+ */
48
+ declare function resolveAzureDeploymentNameFromMap(params: {
49
+ modelId: string;
50
+ deploymentMap?: string;
51
+ }): string;
52
+ //#endregion
53
+ //#region packages/ai/src/providers/azure-openai-responses-client-compat.d.ts
54
+ declare function isTraditionalAzureOpenAIHost(hostname: string): boolean;
55
+ declare function isOpenAICompatibleAzureResponsesBaseUrl(baseUrl: string): boolean;
56
+ //#endregion
57
+ //#region packages/ai/src/providers/clean-for-gemini.d.ts
58
+ declare const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS: Set<string>;
59
+ declare function cleanSchemaForGemini(schema: unknown): TSchema;
60
+ //#endregion
61
+ //#region packages/ai/src/providers/openai-completions-compat.d.ts
62
+ type OpenAICompletionsSessionAffinity = "none" | "openai" | "openrouter";
63
+ type ResolvedOpenAICompletionsCompat = Omit<Required<OpenAICompletionsCompat>, "cacheControlFormat" | "openRouterRouting" | "sendSessionAffinityHeaders"> & {
64
+ cacheControlFormat?: OpenAICompletionsCompat["cacheControlFormat"];
65
+ openRouterRouting?: OpenAICompletionsCompat["openRouterRouting"];
66
+ sessionAffinity: OpenAICompletionsSessionAffinity;
67
+ };
68
+ //#endregion
69
+ //#region packages/ai/src/providers/openai-tool-projection.d.ts
70
+ type OpenAIToolDescriptor = {
71
+ readonly name?: unknown;
72
+ readonly description?: unknown;
73
+ readonly parameters: unknown;
74
+ };
75
+ type OpenAIProjectedTool = {
76
+ readonly toolIndex: number;
77
+ readonly name: string;
78
+ readonly description?: string;
79
+ readonly parameters: Record<string, unknown>;
80
+ };
81
+ type OpenAIToolProjectionDiagnostic = {
82
+ readonly toolIndex: number;
83
+ readonly toolName?: string;
84
+ readonly violations: readonly string[];
85
+ };
86
+ type OpenAIToolProjection = {
87
+ readonly inputToolCount: number;
88
+ readonly tools: readonly OpenAIProjectedTool[];
89
+ readonly diagnostics: readonly OpenAIToolProjectionDiagnostic[];
90
+ };
91
+ type OpenAIResponsesToolChoice = ResponseCreateParamsStreaming["tool_choice"];
92
+ type OpenAICompletionsSdkToolChoice = OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming["tool_choice"];
93
+ type OpenAICompletionsToolChoice = Exclude<OpenAICompletionsSdkToolChoice, {
94
+ type: "custom";
95
+ }>;
96
+ /** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
97
+ declare function projectOpenAITools(tools: readonly OpenAIToolDescriptor[]): OpenAIToolProjection;
98
+ /** Keeps Responses tool choices aligned with surviving function schemas. */
99
+ declare function reconcileOpenAIResponsesToolChoice(choice: OpenAIResponsesToolChoice, projection: OpenAIToolProjection): OpenAIResponsesToolChoice | undefined;
100
+ /** Keeps Chat Completions tool choices aligned with surviving function schemas. */
101
+ declare function reconcileOpenAICompletionsToolChoice(choice: OpenAICompletionsSdkToolChoice, projection: OpenAIToolProjection): OpenAICompletionsSdkToolChoice | undefined;
102
+ //#endregion
103
+ //#region packages/ai/src/providers/openai-completions.d.ts
104
+ interface OpenAICompletionsOptions extends StreamOptions {
105
+ toolChoice?: OpenAICompletionsToolChoice;
106
+ reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
107
+ }
108
+ declare const streamOpenAICompletions: StreamFunction<"openai-completions", OpenAICompletionsOptions>;
109
+ declare const streamSimpleOpenAICompletions: StreamFunction<"openai-completions", SimpleStreamOptions>;
110
+ declare function convertMessages(model: Model<"openai-completions">, context: Context, compat: ResolvedOpenAICompletionsCompat, options?: {
111
+ cacheOptOutIndexes?: Set<number>;
112
+ preserveSystemPromptCacheBoundary?: boolean;
113
+ }): ChatCompletionMessageParam[];
114
+ //#endregion
115
+ //#region packages/ai/src/providers/openai-prompt-cache.d.ts
116
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
117
+ declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
118
+ /** Truncates a prompt cache key by Unicode code point count. */
119
+ declare function clampOpenAIPromptCacheKey(key: string | undefined): string | undefined;
120
+ //#endregion
121
+ //#region packages/ai/src/providers/openai-reasoning-effort.d.ts
122
+ type OpenAIReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
123
+ type OpenAIApiReasoningEffort = OpenAIReasoningEffort | (string & {});
124
+ type OpenAIReasoningModel = {
125
+ provider?: unknown;
126
+ id?: unknown;
127
+ name?: unknown;
128
+ api?: unknown;
129
+ baseUrl?: unknown;
130
+ compat?: unknown;
131
+ };
132
+ /** Return whether a model is the GPT-5.4 mini family. */
133
+ declare function isOpenAIGpt54MiniModel(model: OpenAIReasoningModel): boolean;
134
+ /** Return whether a model is the GPT-5.5 family. */
135
+ declare function isOpenAIGpt55Model(model: OpenAIReasoningModel): boolean;
136
+ /** Return whether a model is the GPT-5.6 family. */
137
+ declare function isOpenAIGpt56Model(model: OpenAIReasoningModel): boolean;
138
+ /** Normalize user-facing reasoning effort names to API effort names. */
139
+ declare function normalizeOpenAIReasoningEffort(effort: string): string;
140
+ /** Resolve the reasoning efforts accepted by a specific OpenAI-compatible model. */
141
+ declare function resolveOpenAISupportedReasoningEfforts(model: OpenAIReasoningModel): readonly OpenAIApiReasoningEffort[];
142
+ /**
143
+ * Return whether a model accepts the temperature parameter. The GPT-5.6
144
+ * family rejects it with a 400; catalog compat can override per model.
145
+ */
146
+ declare function supportsOpenAITemperature(model: OpenAIReasoningModel): boolean;
147
+ /** Return whether a model accepts a requested reasoning effort. */
148
+ declare function supportsOpenAIReasoningEffort(model: OpenAIReasoningModel, effort: string): boolean;
149
+ /** Resolve a requested reasoning effort to the closest value supported by the model. */
150
+ declare function resolveOpenAIReasoningEffortForModel(params: {
151
+ model: OpenAIReasoningModel;
152
+ effort: string;
153
+ fallbackMap?: Record<string, string>;
154
+ }): OpenAIApiReasoningEffort | undefined;
155
+ //#endregion
156
+ //#region packages/ai/src/providers/openai-responses.d.ts
157
+ interface OpenAIResponsesOptions extends StreamOptions {
158
+ reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
159
+ reasoningSummary?: "auto" | "detailed" | "concise" | null;
160
+ replayResponsesItemIds?: boolean;
161
+ serviceTier?: ResponseCreateParamsStreaming["service_tier"];
162
+ }
163
+ /**
164
+ * Generate function for OpenAI Responses API
165
+ */
166
+ declare const streamOpenAIResponses: StreamFunction<"openai-responses", OpenAIResponsesOptions>;
167
+ declare const streamSimpleOpenAIResponses: StreamFunction<"openai-responses", SimpleStreamOptions>;
168
+ //#endregion
169
+ //#region packages/ai/src/providers/openai-responses-stream-compat.d.ts
170
+ declare const OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE = "output_text";
171
+ declare const AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE = "text";
172
+ declare const OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE = "response.output_text.delta";
173
+ declare const AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE = "response.text.delta";
174
+ type ResponsesTextContentPartType = typeof OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE | typeof AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE;
175
+ type ResponsesTextDeltaEventType = typeof OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE | typeof AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE;
176
+ type AzureResponsesTextContentPart = {
177
+ type: typeof AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE;
178
+ text: string;
179
+ };
180
+ type AzureResponsesTextDeltaEvent = {
181
+ type: typeof AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE;
182
+ delta: string;
183
+ };
184
+ declare function isResponsesTextContentPartType(type: unknown): type is ResponsesTextContentPartType;
185
+ declare function isResponsesTextDeltaEventType(type: unknown): type is ResponsesTextDeltaEventType;
186
+ declare function isAzureResponsesTextDeltaEventType(type: unknown): type is typeof AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE;
187
+ declare function isAzureResponsesTextDeltaEvent(event: {
188
+ type?: unknown;
189
+ delta?: unknown;
190
+ }): event is AzureResponsesTextDeltaEvent;
191
+ type ResponsesMessageSnapshotCollapse = {
192
+ kind: "extend";
193
+ text: string;
194
+ } | {
195
+ kind: "keep";
196
+ };
197
+ declare function resolveResponsesMessageSnapshotCollapse(params: {
198
+ prior: {
199
+ text: string;
200
+ phase: string | undefined;
201
+ } | null;
202
+ nextText: string;
203
+ nextPhase: string | undefined;
204
+ }): ResponsesMessageSnapshotCollapse;
205
+ //#endregion
206
+ //#region packages/ai/src/providers/openai-responses-terminal-usage.d.ts
207
+ /** Terminal usage payload, modeled structurally so untyped callers can pass raw records. */
208
+ type ResponsesTerminalUsagePayload = {
209
+ input_tokens?: number | null;
210
+ output_tokens?: number | null;
211
+ total_tokens?: number | null;
212
+ input_tokens_details?: {
213
+ cached_tokens?: number | null;
214
+ cache_write_tokens?: number | null;
215
+ } | null;
216
+ output_tokens_details?: {
217
+ reasoning_tokens?: number | null;
218
+ } | null;
219
+ };
220
+ /**
221
+ * Split a terminal usage payload into the priced buckets.
222
+ *
223
+ * OpenAI includes cache reads and writes in `input_tokens`, so both are subtracted out of the
224
+ * billable input bucket. `total_tokens` comes from the payload, but never below the sum of the
225
+ * split buckets: proxies routinely omit it (reporting 0 would understate the turn), and a payload
226
+ * whose `cached_tokens` exceeds `input_tokens` clamps the input bucket, leaving the reported total
227
+ * short of what the buckets actually price.
228
+ */
229
+ declare function mapResponsesTerminalUsage(usage: ResponsesTerminalUsagePayload | undefined | null): Pick<Usage, "input" | "output" | "cacheRead" | "cacheWrite" | "totalTokens"> | undefined;
230
+ /** Reasoning tokens are reported by the agent path only; the package path does not track them. */
231
+ declare function readResponsesReasoningTokens(usage: ResponsesTerminalUsagePayload | undefined | null): number | undefined;
232
+ /**
233
+ * Resolve the terminal stop reason, including the two overrides every Responses path shares: a
234
+ * content-filtered turn is a provider error rather than a truncated answer, and a turn that
235
+ * produced tool calls reports `toolUse` instead of a plain stop.
236
+ */
237
+ declare function resolveResponsesTerminalStopReason(params: {
238
+ status: OpenAI.Responses.ResponseStatus | undefined;
239
+ incompleteReason?: string;
240
+ hasToolCall: boolean;
241
+ }): {
242
+ stopReason: StopReason;
243
+ errorMessage?: string;
244
+ };
245
+ //#endregion
246
+ //#region packages/ai/src/providers/openai-responses-tool-call-tracker.d.ts
247
+ type ResponsesToolCallIdentity = {
248
+ itemId?: string;
249
+ callId?: string;
250
+ };
251
+ type ResponsesToolCallState = ResponsesToolCallIdentity & {
252
+ argumentStreamReliable: boolean;
253
+ };
254
+ type ResponsesToolCallEvent = {
255
+ output_index?: unknown;
256
+ item_id?: unknown;
257
+ };
258
+ declare function readResponsesToolCallItemIdentity(item: {
259
+ id?: unknown;
260
+ call_id?: unknown;
261
+ }): ResponsesToolCallIdentity;
262
+ declare function createResponsesToolCallTracker<TState extends ResponsesToolCallState>(): {
263
+ register(event: ResponsesToolCallEvent, state: TState): void;
264
+ resolve(event: ResponsesToolCallEvent, identity?: ResponsesToolCallIdentity): TState | undefined;
265
+ forget(toolCall: TState): void;
266
+ markArgumentsUnreliable(): void;
267
+ hasActive(): boolean;
268
+ };
269
+ //#endregion
270
+ //#region packages/ai/src/providers/openai-stop-reason.d.ts
271
+ type OpenAIStopReasonResult = {
272
+ stopReason: StopReason;
273
+ errorMessage?: string;
274
+ };
275
+ declare function mapOpenAIStopReason(reason: string | null, options?: {
276
+ allowSingularToolCall?: boolean;
277
+ }): OpenAIStopReasonResult;
278
+ //#endregion
279
+ //#region packages/ai/src/providers/openai-tool-schema-compat.d.ts
280
+ /** Repairs recoverable OpenAI tool-schema shapes before canonical normalization. */
281
+ declare function normalizeOpenAIStrictCompatSchema(schema: unknown): TSchema;
282
+ /** Finds schema paths that violate OpenAI strict tool-schema requirements. */
283
+ declare function findOpenAIStrictSchemaViolations(schema: unknown, path: string, options?: {
284
+ requireObjectRoot?: boolean;
285
+ }): string[];
286
+ //#endregion
287
+ //#region packages/ai/src/providers/openai-tool-schema.d.ts
288
+ /**
289
+ * OpenAI strict-tool-schema normalization and diagnostics.
290
+ *
291
+ * Strict schemas need all object properties required and `additionalProperties: false`; model
292
+ * compatibility settings can also remove unsupported schema constructs before strict checks run.
293
+ */
294
+ type ToolSchemaCompatInput = {
295
+ unsupportedToolSchemaKeywords?: unknown;
296
+ omitEmptyArrayItems?: unknown;
297
+ };
298
+ declare function clearOpenAIToolSchemaCacheForTest(): void;
299
+ /** Normalizes a tool parameter schema into the OpenAI strict JSON-schema subset. */
300
+ declare function normalizeStrictOpenAIJsonSchema(schema: unknown, modelCompat?: ToolSchemaCompatInput | null): unknown;
301
+ /** Normalizes tool parameters using strict OpenAI rules only when strict mode is active. */
302
+ declare function normalizeOpenAIStrictToolParameters<T>(schema: T, strict: boolean, modelCompat?: ToolSchemaCompatInput | null): T;
303
+ /** Returns whether a schema already satisfies OpenAI strict tool-schema constraints. */
304
+ declare function isStrictOpenAIJsonSchemaCompatible(schema: unknown): boolean;
305
+ type OpenAIStrictToolSchemaDiagnostic = {
306
+ toolIndex: number;
307
+ toolName?: string;
308
+ violations: string[];
309
+ };
310
+ /** Returns strict-schema diagnostics for an already materialized OpenAI tool projection. */
311
+ declare function findOpenAIStrictToolProjectionDiagnostics(projection: OpenAIToolProjection): OpenAIStrictToolSchemaDiagnostic[];
312
+ /** Resolves strict mode for the projected tools that will be emitted in the request payload. */
313
+ declare function resolveOpenAIProjectedToolsStrictToolFlag(projection: OpenAIToolProjection, strict: boolean | null | undefined): boolean | undefined;
314
+ //#endregion
315
+ //#region packages/ai/src/providers/schema-keyword-strip.d.ts
316
+ /** Recursively remove schema keywords unsupported by a target provider/tool surface. */
317
+ declare function stripUnsupportedSchemaKeywords(schema: unknown, unsupportedKeywords: ReadonlySet<string>): unknown;
318
+ //#endregion
319
+ //#region packages/ai/src/providers/tool-schema-json-projection.d.ts
320
+ /** JSON-safe schema value used when projecting runtime tool parameters. */
321
+ type RuntimeToolInputSchemaJson = null | boolean | number | string | RuntimeToolInputSchemaJson[] | {
322
+ [key: string]: RuntimeToolInputSchemaJson;
323
+ };
324
+ /** Projected runtime tool schema plus validation violations. */
325
+ type RuntimeToolInputSchemaProjection = {
326
+ readonly schema: RuntimeToolInputSchemaJson;
327
+ readonly violations: readonly string[];
328
+ };
329
+ /** Projects one runtime tool input schema to JSON and reports runtime incompatibilities. */
330
+ declare function projectRuntimeToolInputSchema(schema: unknown, path?: string): RuntimeToolInputSchemaProjection;
331
+ //#endregion
332
+ export { convertMessages as $, ResponsesTextContentPartType as A, OpenAIApiReasoningEffort as B, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as C, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as D, AzureResponsesTextDeltaEvent as E, isResponsesTextDeltaEventType as F, normalizeOpenAIReasoningEffort as G, isOpenAIGpt54MiniModel as H, resolveResponsesMessageSnapshotCollapse as I, supportsOpenAIReasoningEffort as J, resolveOpenAIReasoningEffortForModel as K, OpenAIResponsesOptions as L, isAzureResponsesTextDeltaEvent as M, isAzureResponsesTextDeltaEventType as N, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as O, isResponsesTextContentPartType as P, OpenAICompletionsOptions as Q, streamOpenAIResponses as R, resolveResponsesTerminalStopReason as S, AzureResponsesTextContentPart as T, isOpenAIGpt55Model as U, OpenAIReasoningEffort as V, isOpenAIGpt56Model as W, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as X, supportsOpenAITemperature as Y, clampOpenAIPromptCacheKey as Z, createResponsesToolCallTracker as _, resolveUnsupportedToolSchemaKeywords as _t, clearOpenAIToolSchemaCacheForTest as a, reconcileOpenAICompletionsToolChoice as at, mapResponsesTerminalUsage as b, normalizeOpenAIStrictToolParameters as c, cleanSchemaForGemini as ct, findOpenAIStrictSchemaViolations as d, parseAzureDeploymentNameMap as dt, streamOpenAICompletions as et, normalizeOpenAIStrictCompatSchema as f, resolveAzureDeploymentNameFromMap as ft, ResponsesToolCallState as g, normalizeToolParameterSchema as gt, ResponsesToolCallIdentity as h, extractToolSchemaModelCompat as ht, stripUnsupportedSchemaKeywords as i, projectOpenAITools as it, ResponsesTextDeltaEventType as j, ResponsesMessageSnapshotCollapse as k, normalizeStrictOpenAIJsonSchema as l, isOpenAICompatibleAzureResponsesBaseUrl as lt, mapOpenAIStopReason as m, ToolSchemaModelCompat as mt, RuntimeToolInputSchemaProjection as n, OpenAICompletionsToolChoice as nt, findOpenAIStrictToolProjectionDiagnostics as o, reconcileOpenAIResponsesToolChoice as ot, OpenAIStopReasonResult as p, ToolParameterSchemaOptions as pt, resolveOpenAISupportedReasoningEfforts as q, projectRuntimeToolInputSchema as r, OpenAIToolProjection as rt, isStrictOpenAIJsonSchemaCompatible as s, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as st, RuntimeToolInputSchemaJson as t, streamSimpleOpenAICompletions as tt, resolveOpenAIProjectedToolsStrictToolFlag as u, isTraditionalAzureOpenAIHost as ut, readResponsesToolCallItemIdentity as v, shouldOmitEmptyArrayItems as vt, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as w, readResponsesReasoningTokens as x, ResponsesTerminalUsagePayload as y, streamSimpleOpenAIResponses as z };
@@ -1,15 +1,15 @@
1
- import { n as getEnvApiKey } from "./env-api-keys-DnhYpc27.mjs";
1
+ import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { i as formatThrownValue, n as createAssistantMessageDiagnostic, t as appendAssistantMessageDiagnostic } from "./diagnostics-COpOtRwq.mjs";
3
3
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
4
- import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
4
+ import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-XYGZcgO8.mjs";
5
+ import { D as buildBaseOptions, a as stripSystemPromptCacheBoundary } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
5
6
  import { t as headersToRecord } from "./headers-B_e4-1J0.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
- 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-CFqm42J2.mjs";
10
- import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
11
7
  import { i as registerSessionResourceCleanup, n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-DhAAzLkj.mjs";
8
+ import { d as resolveTimerTimeoutMs, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, s as clampTimerTimeoutMs, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DP4xEyBY.mjs";
12
9
  import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
10
+ import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
11
+ import { L as supportsOpenAITemperature, a as resolveResponsesReasoningEffort, i as processResponsesStream, n as convertResponsesMessages, s as convertResponsesToolPayload } from "./openai-responses-shared-CzCurmY1.mjs";
12
+ import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-ITOU9bG1.mjs";
13
13
  //#region packages/ai/src/internal/retry-sleep.ts
14
14
  function sleepWithAbort(ms, signal) {
15
15
  return new Promise((resolve, reject) => {
@@ -38,7 +38,7 @@ function loadNodeOs() {
38
38
  }
39
39
  const os = loadNodeOs();
40
40
  const DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
41
- const MAX_RETRIES = 3;
41
+ const DEFAULT_MAX_RETRIES = 3;
42
42
  const BASE_DELAY_MS = 1e3;
43
43
  const REQUEST_COMPRESSION_ZSTD_LEVEL = 3;
44
44
  const CODEX_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "opencode"]);
@@ -58,6 +58,22 @@ function isRetryableError(status, errorText) {
58
58
  if (status === 429 || status === 500 || status === 502 || status === 503 || status === 504) return true;
59
59
  return /rate.?limit|overloaded|service.?unavailable|upstream.?connect|connection.?refused/i.test(errorText);
60
60
  }
61
+ function resolveHttpRetryDelayMs(response, attempt) {
62
+ const fallbackMs = BASE_DELAY_MS * 2 ** attempt;
63
+ const retryAfterMs = response.headers.get("retry-after-ms");
64
+ if (retryAfterMs) {
65
+ const trimmed = retryAfterMs.trim();
66
+ const millis = Number(trimmed);
67
+ if (/^\d+(?:\.\d+)?$/.test(trimmed) && Number.isFinite(millis)) return clampTimerTimeoutMs(millis, 0) ?? fallbackMs;
68
+ }
69
+ const retryAfter = response.headers.get("retry-after");
70
+ if (!retryAfter) return fallbackMs;
71
+ const trimmed = retryAfter.trim();
72
+ const seconds = Number(trimmed);
73
+ if (/^\d+$/.test(trimmed) && Number.isFinite(seconds)) return clampTimerTimeoutMs(seconds * 1e3, 0) ?? fallbackMs;
74
+ const retryAt = parseRetryAfterHttpDateMs(trimmed);
75
+ return retryAt === void 0 ? fallbackMs : clampTimerTimeoutMs(retryAt - Date.now(), 0) ?? fallbackMs;
76
+ }
61
77
  function resolveRequestTimeoutMs(options) {
62
78
  const timeoutMs = options?.timeoutMs;
63
79
  return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? resolveTimerTimeoutMs(timeoutMs, 1) : void 0;
@@ -127,8 +143,9 @@ const streamOpenAICodexResponses = (model, context, options) => {
127
143
  let body = buildRequestBody(model, context, options);
128
144
  const nextBody = await options?.onPayload?.(body, model);
129
145
  if (nextBody !== void 0) body = nextBody;
130
- const websocketRequestId = options?.sessionId || createCodexRequestId();
131
- const sseHeaders = buildSSEHeaders(modelHeaders, optionHeaders, accountId, apiKey, options?.sessionId);
146
+ const sessionId = clampOpenAIPromptCacheKey(options?.sessionId);
147
+ const websocketRequestId = sessionId || createCodexRequestId();
148
+ const sseHeaders = buildSSEHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId);
132
149
  const websocketHeaders = buildWebSocketHeaders(modelHeaders, optionHeaders, accountId, apiKey, websocketRequestId);
133
150
  const bodyJson = JSON.stringify(body);
134
151
  requestTimeoutMs = resolveRequestTimeoutMs(options);
@@ -184,48 +201,25 @@ const streamOpenAICodexResponses = (model, context, options) => {
184
201
  const sseBody = compressedBody ?? bodyJson;
185
202
  let response;
186
203
  let lastError;
187
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
204
+ const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
205
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
188
206
  if (activeSignal?.aborted) throw new Error("Request was aborted");
207
+ let attemptResponse;
208
+ let errorText;
189
209
  try {
190
- response = await fetch(resolveCodexUrl(model.baseUrl), {
210
+ attemptResponse = await fetch(resolveCodexUrl(model.baseUrl), {
191
211
  method: "POST",
192
212
  headers: sseHeaders,
193
213
  body: sseBody,
194
214
  signal: activeSignal
195
215
  });
216
+ response = attemptResponse;
196
217
  await options?.onResponse?.({
197
- status: response.status,
198
- headers: headersToRecord(response.headers)
218
+ status: attemptResponse.status,
219
+ headers: headersToRecord(attemptResponse.headers)
199
220
  }, model);
200
- if (response.ok) break;
201
- const errorText = await readChatGptResponsesErrorTextLimited(response);
202
- if (attempt < MAX_RETRIES && isRetryableError(response.status, errorText)) {
203
- let delayMs = BASE_DELAY_MS * 2 ** attempt;
204
- const retryAfterMs = response.headers.get("retry-after-ms");
205
- if (retryAfterMs !== null) {
206
- const trimmedRetryAfterMs = retryAfterMs.trim();
207
- const millis = Number(trimmedRetryAfterMs);
208
- if (/^\d+(?:\.\d+)?$/.test(trimmedRetryAfterMs) && Number.isFinite(millis)) delayMs = clampTimerTimeoutMs(millis, 0) ?? delayMs;
209
- } else {
210
- const retryAfter = response.headers.get("retry-after");
211
- if (retryAfter) {
212
- const trimmedRetryAfter = retryAfter.trim();
213
- const seconds = Number(trimmedRetryAfter);
214
- if (/^\d+$/.test(trimmedRetryAfter) && Number.isFinite(seconds)) delayMs = clampTimerTimeoutMs(seconds * 1e3, 0) ?? delayMs;
215
- else {
216
- const retryAt = parseRetryAfterHttpDateMs(trimmedRetryAfter);
217
- if (retryAt !== void 0) delayMs = clampTimerTimeoutMs(retryAt - Date.now(), 0) ?? delayMs;
218
- }
219
- }
220
- }
221
- await sleepWithAbort(delayMs, activeSignal);
222
- continue;
223
- }
224
- const info = await parseErrorResponse(new Response(errorText, {
225
- status: response.status,
226
- statusText: response.statusText
227
- }));
228
- throw new Error(info.friendlyMessage || info.message);
221
+ if (attemptResponse.ok) break;
222
+ errorText = await readChatGptResponsesErrorTextLimited(attemptResponse);
229
223
  } catch (error) {
230
224
  if (error instanceof Error) {
231
225
  if (isRequestTimeoutError(error, options?.signal, requestTimeoutSignal, requestTimeoutMs) && requestTimeoutMs !== void 0) throw formatRequestTimeoutError(requestTimeoutMs, error);
@@ -233,12 +227,18 @@ const streamOpenAICodexResponses = (model, context, options) => {
233
227
  if (error.name === "TimeoutError" && requestTimeoutMs !== void 0) throw new Error(`Request timed out after ${requestTimeoutMs}ms`, { cause: error });
234
228
  }
235
229
  lastError = error instanceof Error ? error : new Error(String(error));
236
- if (attempt < MAX_RETRIES && !lastError.message.includes("usage limit")) {
230
+ if (attempt < maxRetries && !lastError.message.includes("usage limit")) {
237
231
  await sleepWithAbort(BASE_DELAY_MS * 2 ** attempt, activeSignal);
238
232
  continue;
239
233
  }
240
234
  throw lastError;
241
235
  }
236
+ if (attempt < maxRetries && isRetryableError(attemptResponse.status, errorText)) {
237
+ await sleepWithAbort(resolveHttpRetryDelayMs(attemptResponse, attempt), activeSignal);
238
+ continue;
239
+ }
240
+ const info = parseErrorResponseText(errorText, attemptResponse.status, attemptResponse.statusText);
241
+ throw new Error(info.friendlyMessage || info.message);
242
242
  }
243
243
  if (!response?.ok) throw lastError ?? /* @__PURE__ */ new Error("Failed after retries");
244
244
  if (!response.body) throw new Error("No response body");
@@ -934,15 +934,14 @@ async function readChatGptResponsesErrorTextLimited(response) {
934
934
  }
935
935
  return text;
936
936
  }
937
- async function parseErrorResponse(response) {
938
- const raw = await readChatGptResponsesErrorTextLimited(response);
939
- let message = raw || response.statusText || "Request failed";
937
+ function parseErrorResponseText(raw, status, statusText) {
938
+ let message = raw || statusText || "Request failed";
940
939
  let friendlyMessage;
941
940
  try {
942
941
  const err = JSON.parse(raw)?.error;
943
942
  if (err) {
944
943
  const code = err.code || err.type || "";
945
- if (/usage_limit_reached|usage_not_included|rate_limit_exceeded/i.test(code) || response.status === 429) {
944
+ if (/usage_limit_reached|usage_not_included|rate_limit_exceeded/i.test(code) || status === 429) {
946
945
  const plan = err.plan_type ? ` (${err.plan_type.toLowerCase()} plan)` : "";
947
946
  const mins = err.resets_at ? Math.max(0, Math.round((err.resets_at * 1e3 - Date.now()) / 6e4)) : void 0;
948
947
  friendlyMessage = `You have hit your ChatGPT usage limit${plan}.${mins !== void 0 ? ` Try again in ~${mins} min.` : ""}`.trim();