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

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 (60) hide show
  1. package/README.md +6 -5
  2. package/dist/{anthropic-D7SyZQ5v.mjs → anthropic-CQVj3le6.mjs} +174 -33
  3. package/dist/{index-BoTnz8cv.d.mts → anthropic-SrGtwsJu.d.mts} +27 -1
  4. package/dist/{api-registry-DXBIXISf.d.mts → api-registry-DlMgPR39.d.mts} +1 -2
  5. package/dist/{azure-openai-responses-BkZgyZ3I.mjs → azure-openai-responses-DIYgsqFM.mjs} +7 -11
  6. package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
  7. package/dist/error-coercion-DgxlWC0n.mjs +15 -0
  8. package/dist/{event-stream-BPemFrFW.d.mts → event-stream-YjaPW20U.d.mts} +1 -1
  9. package/dist/event-stream.d.mts +1 -1
  10. package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → github-copilot-headers-BCoBNmL7.mjs} +48 -1
  11. package/dist/{google-C_biGbV7.mjs → google-f-A8xrae.mjs} +4 -4
  12. package/dist/{google-shared-BK-NoHl8.mjs → google-shared-J6qvYINH.mjs} +5 -4
  13. package/dist/{google-vertex-CvdzF1U7.mjs → google-vertex-D3yMVXIY.mjs} +3 -3
  14. package/dist/host-B9GUmcra.d.mts +173 -0
  15. package/dist/host-XYGZcgO8.mjs +98 -0
  16. package/dist/index-BVVgDSdq.d.mts +1 -0
  17. package/dist/index.d.mts +7 -50
  18. package/dist/index.mjs +3 -3
  19. package/dist/internal/anthropic.d.mts +15 -11
  20. package/dist/internal/anthropic.mjs +4 -4
  21. package/dist/internal/openai.d.mts +3 -280
  22. package/dist/internal/openai.mjs +5 -7
  23. package/dist/internal/runtime.d.mts +13 -34
  24. package/dist/internal/runtime.mjs +19 -11
  25. package/dist/internal/shared.d.mts +13 -8
  26. package/dist/internal/shared.mjs +2 -2
  27. package/dist/{mistral-BdrQmDWp.mjs → mistral-CKV-TOQj.mjs} +7 -6
  28. package/dist/number-coercion-DvG7SNMg.mjs +129 -0
  29. package/dist/openai-BPor_3WI.d.mts +358 -0
  30. package/dist/{openai-responses-shared-CwnGU0KW.mjs → openai-D3PD6PE-.mjs} +1890 -705
  31. package/dist/{openai-chatgpt-responses-DP63Qt01.mjs → openai-chatgpt-responses-CedIj0hk.mjs} +54 -58
  32. package/dist/{openai-completions-zLDfebnN.mjs → openai-completions-CiSutyu0.mjs} +459 -104
  33. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +7 -0
  34. package/dist/openai-prompt-cache-mZTCdRPo.mjs +12 -0
  35. package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +13 -0
  36. package/dist/{provider-error-LMfTEkfO.mjs → provider-error-apVOZI6G.mjs} +9 -2
  37. package/dist/providers.d.mts +3 -2
  38. package/dist/providers.mjs +10 -9
  39. package/dist/{transform-messages-eb6lxDLB.mjs → shared-CdjNZd35.mjs} +273 -161
  40. package/dist/{src-CXno1H5g.mjs → src-QkygScBs.mjs} +23 -4
  41. package/dist/stream-first-event-timeout-C3OgBjIk.mjs +12294 -0
  42. package/dist/stream-first-event-timeout-DvDeSucC.d.mts +29 -0
  43. package/dist/transport-stream-shared-BbMELSI4.mjs +297 -0
  44. package/dist/transports.d.mts +593 -0
  45. package/dist/transports.mjs +4069 -0
  46. package/dist/{types-CYORveZ7.d.mts → types-bzp5k29J.d.mts} +8 -0
  47. package/dist/types.d.mts +5 -5
  48. package/dist/types.mjs +2 -2
  49. package/dist/{validation-BX8euiDv.d.mts → validation-B-j7cOYp.d.mts} +1 -1
  50. package/dist/validation.d.mts +1 -1
  51. package/package.json +36 -11
  52. package/dist/azure-openai-responses-client-compat-C7K7QfUE.mjs +0 -62
  53. package/dist/github-copilot-headers-BsH5cqGj.mjs +0 -48
  54. package/dist/host-4t713IeR.mjs +0 -37
  55. package/dist/model-utils-1GiZ2_rr.mjs +0 -64
  56. package/dist/openai-responses-ClspWt4I.mjs +0 -136
  57. package/dist/openai-tool-projection-WHf2nuOI.mjs +0 -200
  58. package/dist/reasoning-tag-text-partitioner-BlVe67g6.mjs +0 -400
  59. package/dist/stream-first-event-timeout-RjWszj8c.mjs +0 -106
  60. package/npm-shrinkwrap.json +0 -645
@@ -1,17 +1,245 @@
1
- import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DnhYpc27.mjs";
1
+ import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-DrgeBuva.mjs";
2
2
  import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
3
- import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
4
- import { n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "./model-utils-1GiZ2_rr.mjs";
3
+ import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
4
+ import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
5
+ import { A as buildBaseOptions, E as isImageWithMediaPayload, O as isRecord, S as describeToolResultMediaPlaceholder, a as splitSystemPromptCacheBoundary, o as stripSystemPromptCacheBoundary, u as transformMessages, w as extractToolResultText, y as normalizeLowercaseStringOrEmpty } from "./shared-CdjNZd35.mjs";
6
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
7
+ import { c as calculateCost, l as clampThinkingLevel, s as applyProviderReportedUsageCost } from "./number-coercion-DvG7SNMg.mjs";
8
+ import { d as transportAbortError } from "./transport-stream-shared-BbMELSI4.mjs";
5
9
  import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
6
10
  import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
7
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
8
- import { C as splitSystemPromptCacheBoundary, i as extractToolResultText, l as buildBaseOptions, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages, w as stripSystemPromptCacheBoundary } from "./transform-messages-eb6lxDLB.mjs";
9
- import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BsH5cqGj.mjs";
10
- import { t as formatProviderError } from "./provider-error-LMfTEkfO.mjs";
11
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-BlVe67g6.mjs";
12
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-RjWszj8c.mjs";
13
- import { a as clampOpenAIPromptCacheKey, n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-WHf2nuOI.mjs";
11
+ import { t as formatProviderError } from "./provider-error-apVOZI6G.mjs";
12
+ import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, o as projectRuntimeToolInputSchema, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BCoBNmL7.mjs";
13
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, o as createReasoningTagTextPartitioner, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-C3OgBjIk.mjs";
14
14
  import OpenAI from "openai";
15
+ //#region packages/ai/src/transports/host-policy.ts
16
+ function buildGuardedModelFetch(model, timeoutMs, options) {
17
+ const host = getAiTransportHost();
18
+ if (options !== void 0) return host.buildModelFetch(model, timeoutMs, options) ?? globalThis.fetch;
19
+ if (timeoutMs !== void 0) return host.buildModelFetch(model, timeoutMs) ?? globalThis.fetch;
20
+ return host.buildModelFetch(model) ?? globalThis.fetch;
21
+ }
22
+ function resolveProviderEndpoint(baseUrl) {
23
+ return { endpointClass: getAiTransportHost().resolveProviderEndpointClass(baseUrl) };
24
+ }
25
+ function resolveProviderRequestCapabilities(input) {
26
+ return getAiTransportHost().resolveProviderRequestCapabilities(input);
27
+ }
28
+ function resolveProviderRequestPolicyConfig(input) {
29
+ return { headers: getAiTransportHost().resolveProviderRequestHeaders(input) };
30
+ }
31
+ function resolveModelRequestTimeoutMs(model, timeoutMs) {
32
+ return timeoutMs ?? getAiTransportHost().resolveModelRequestTimeoutMs(model);
33
+ }
34
+ function resolveOpenAIStrictToolSetting(model, options) {
35
+ return getAiTransportHost().resolveOpenAIStrictToolSetting(model, options);
36
+ }
37
+ function transformTransportMessages(messages, model, normalizeToolCallId, options) {
38
+ return getAiTransportHost().transformTransportMessages(messages, model, normalizeToolCallId, options);
39
+ }
40
+ //#endregion
41
+ //#region packages/ai/src/utils/assistant-text-phase.ts
42
+ function isAssistantTextPhaseBlock(block) {
43
+ if (!block || typeof block !== "object") return false;
44
+ const record = block;
45
+ return record.type === "text" && typeof record.text === "string";
46
+ }
47
+ function encodeAssistantTextSignatureV1(id, phase) {
48
+ return JSON.stringify({
49
+ v: 1,
50
+ id,
51
+ ...phase ? { phase } : {}
52
+ });
53
+ }
54
+ /** Tags unphased narration before a tool-call event becomes consumer-visible. */
55
+ function tagPendingCommentaryText(content) {
56
+ const textBlocks = content.filter(isAssistantTextPhaseBlock);
57
+ let commentaryIndex = textBlocks.filter((block) => block.textSignature !== void 0).length;
58
+ const tagged = /* @__PURE__ */ new Map();
59
+ for (const block of textBlocks) {
60
+ if (block.text.trim().length === 0 || block.textSignature !== void 0) continue;
61
+ const signature = encodeAssistantTextSignatureV1(`commentary-${commentaryIndex}`, "commentary");
62
+ block.textSignature = signature;
63
+ tagged.set(block, signature);
64
+ commentaryIndex += 1;
65
+ }
66
+ return tagged;
67
+ }
68
+ /** Rolls back only the exact provisional signatures created by this transport turn. */
69
+ function clearPendingCommentaryText(tags) {
70
+ for (const [block, signature] of tags) if (block.textSignature === signature) delete block.textSignature;
71
+ tags.clear();
72
+ }
73
+ function rememberPendingCommentaryTags(target, tagged) {
74
+ for (const [block, signature] of tagged) target.set(block, signature);
75
+ }
76
+ //#endregion
77
+ //#region packages/ai/src/providers/openai-response-format.ts
78
+ const JSON_SCHEMA_RESPONSE_FORMAT_NAME = "openclaw_response";
79
+ const OLLAMA_CLOUD_ORIGIN = "https://ollama.com";
80
+ function isKnownOpenAIJsonSchemaModelId(modelId) {
81
+ if (typeof modelId !== "string") return false;
82
+ if (/^gpt-5(?:[.-]|$)/i.test(modelId) || /^gpt-4\.1(?:-|$)/i.test(modelId)) return true;
83
+ const gpt4o = /^gpt-4o(-mini)?(?:-(\d{4}-\d{2}-\d{2}))?$/i.exec(modelId);
84
+ if (gpt4o) {
85
+ const snapshot = gpt4o[2];
86
+ return !snapshot || snapshot >= (gpt4o[1] ? "2024-07-18" : "2024-08-06");
87
+ }
88
+ return /^(?:o1|o3(?:-mini|-pro)?|o4-mini)(?:-\d{4}-\d{2}-\d{2})?$/i.test(modelId);
89
+ }
90
+ function shouldOmitOllamaCompatResponseFormat(params) {
91
+ if (!params.provider.includes("ollama")) return false;
92
+ if (params.hasTools()) return true;
93
+ try {
94
+ return new URL(params.baseUrl).origin === OLLAMA_CLOUD_ORIGIN;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+ /**
100
+ * Maps the shared JSON Schema option to Chat Completions while preserving the
101
+ * older provider-shaped json_object/json_schema inputs accepted by model params.
102
+ */
103
+ function resolveOpenAICompletionsResponseFormat(responseFormat, supportsJsonSchemaResponseFormat) {
104
+ if (!responseFormat) return;
105
+ if (responseFormat.type === "json_object") return responseFormat;
106
+ if (responseFormat.type === "text") return responseFormat;
107
+ if (responseFormat.type === "json_schema" && isRecord(responseFormat.json_schema)) return responseFormat;
108
+ if (!supportsJsonSchemaResponseFormat) return;
109
+ return {
110
+ type: "json_schema",
111
+ json_schema: {
112
+ name: JSON_SCHEMA_RESPONSE_FORMAT_NAME,
113
+ schema: responseFormat
114
+ }
115
+ };
116
+ }
117
+ //#endregion
118
+ //#region packages/ai/src/transports/openai-completions-compat.ts
119
+ function isDefaultRouteProvider(provider, ...ids) {
120
+ return provider !== void 0 && ids.includes(provider);
121
+ }
122
+ /** Resolves default request flags for an OpenAI-compatible completions endpoint. */
123
+ function resolveOpenAICompletionsCompatDefaults(input) {
124
+ const { provider, modelId, endpointClass, knownProviderFamily, supportsNativeStreamingUsageCompat = false, supportsOpenAICompletionsStreamingUsageCompat = false, usesExplicitProxyLikeEndpoint = false } = input;
125
+ const isDefaultRoute = endpointClass === "default";
126
+ const usesConfiguredNonOpenAIEndpoint = endpointClass !== "default" && endpointClass !== "openai-public";
127
+ const isMoonshot = knownProviderFamily === "moonshot" || endpointClass === "moonshot-native";
128
+ const isMoonshotLike = isMoonshot || knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native";
129
+ const isModelStudioLike = knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native" || isDefaultRoute && isDefaultRouteProvider(provider, "dashscope", "modelstudio", "qwen");
130
+ const isZai = endpointClass === "zai-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "zai");
131
+ const isDeepSeek = endpointClass === "deepseek-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "deepseek");
132
+ const isTogether = knownProviderFamily === "together" || input.baseUrl?.includes("api.together.ai") === true || input.baseUrl?.includes("api.together.xyz") === true || isDefaultRoute && isDefaultRouteProvider(input.provider, "together");
133
+ const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || input.baseUrl?.includes("gateway.ai.cloudflare.com") === true;
134
+ const isXiaomi = endpointClass === "xiaomi-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "xiaomi");
135
+ const isNonStandard = endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "mistral-public" || endpointClass === "opencode-native" || endpointClass === "xai-native" || isXiaomi || isZai || isDefaultRoute && isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai");
136
+ const isOpenRouterLike = input.provider === "openrouter" || endpointClass === "openrouter";
137
+ const isLocalEndpoint = endpointClass === "local";
138
+ const usesMaxTokens = endpointClass === "chutes-native" || endpointClass === "mistral-public" || knownProviderFamily === "mistral" || isMoonshot || isCloudflareAiGateway || isZai || isTogether || isDefaultRoute && isDefaultRouteProvider(provider, "chutes");
139
+ return {
140
+ supportsStore: !isNonStandard && knownProviderFamily !== "mistral" && !usesExplicitProxyLikeEndpoint,
141
+ supportsDeveloperRole: !isNonStandard && !isMoonshotLike && !usesConfiguredNonOpenAIEndpoint,
142
+ supportsReasoningEffort: !isZai && !isTogether && knownProviderFamily !== "mistral" && endpointClass !== "xai-native" && !usesExplicitProxyLikeEndpoint,
143
+ supportsUsageInStreaming: supportsOpenAICompletionsStreamingUsageCompat || !isNonStandard && (isLocalEndpoint || !usesConfiguredNonOpenAIEndpoint || supportsNativeStreamingUsageCompat),
144
+ maxTokensField: usesMaxTokens ? "max_tokens" : "max_completion_tokens",
145
+ thinkingFormat: isDeepSeek || isXiaomi ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isOpenRouterLike ? "openrouter" : "openai",
146
+ visibleReasoningDetailTypes: isOpenRouterLike ? ["response.output_text", "response.text"] : [],
147
+ supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint,
148
+ supportsJsonSchemaResponseFormat: (endpointClass === "openai-public" || isDefaultRoute && isDefaultRouteProvider(provider, "openai")) && isKnownOpenAIJsonSchemaModelId(modelId),
149
+ requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi,
150
+ requiresNonEmptyUserOrAssistantMessage: isModelStudioLike,
151
+ cacheControlFormat: provider === "openrouter" && modelId?.startsWith("anthropic/") === true ? "anthropic" : void 0,
152
+ sessionAffinityFormat: isOpenRouterLike ? "openrouter" : "openai",
153
+ supportsLongCacheRetention: provider !== "cloudflare-workers-ai" && provider !== "cloudflare-ai-gateway" && knownProviderFamily !== "together" && !input.baseUrl?.includes("api.cloudflare.com") && !input.baseUrl?.includes("gateway.ai.cloudflare.com") && !input.baseUrl?.includes("api.together.ai") && !input.baseUrl?.includes("api.together.xyz")
154
+ };
155
+ }
156
+ function resolveOpenAICompletionsCompatDefaultsFromCapabilities(input) {
157
+ return resolveOpenAICompletionsCompatDefaults(input);
158
+ }
159
+ /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */
160
+ function detectOpenAICompletionsCompat(model, resolveCapabilities = resolveProviderRequestCapabilities) {
161
+ const capabilities = resolveCapabilities({
162
+ provider: model.provider,
163
+ api: "openai-completions",
164
+ baseUrl: model.baseUrl,
165
+ capability: "llm",
166
+ transport: "stream",
167
+ modelId: model.id,
168
+ compat: model.compat && typeof model.compat === "object" ? model.compat : void 0
169
+ });
170
+ return {
171
+ capabilities,
172
+ defaults: resolveOpenAICompletionsCompatDefaultsFromCapabilities({
173
+ provider: model.provider,
174
+ modelId: model.id,
175
+ baseUrl: model.baseUrl,
176
+ ...capabilities
177
+ })
178
+ };
179
+ }
180
+ function resolveSessionAffinity(model, detectedFormat) {
181
+ if (model.compat?.sendSessionAffinityHeaders !== true) return "none";
182
+ if (detectedFormat === "openrouter" || model.compat.thinkingFormat === "openrouter" || model.compat.openRouterRouting !== void 0) return "openrouter";
183
+ return "openai";
184
+ }
185
+ /** Applies explicit model overrides once on top of the canonical transport defaults. */
186
+ function resolveOpenAICompletionsCompat(model, resolveCapabilities = resolveProviderRequestCapabilities) {
187
+ const { defaults } = detectOpenAICompletionsCompat(model, resolveCapabilities);
188
+ const configured = model.compat;
189
+ return {
190
+ supportsStore: configured?.supportsStore ?? defaults.supportsStore,
191
+ supportsDeveloperRole: configured?.supportsDeveloperRole ?? defaults.supportsDeveloperRole,
192
+ supportsReasoningEffort: configured?.supportsReasoningEffort ?? defaults.supportsReasoningEffort,
193
+ supportsUsageInStreaming: configured?.supportsUsageInStreaming ?? defaults.supportsUsageInStreaming,
194
+ maxTokensField: configured?.maxTokensField ?? defaults.maxTokensField,
195
+ requiresToolResultName: configured?.requiresToolResultName ?? false,
196
+ requiresAssistantAfterToolResult: configured?.requiresAssistantAfterToolResult ?? false,
197
+ requiresThinkingAsText: configured?.requiresThinkingAsText ?? false,
198
+ requiresReasoningContentOnAssistantMessages: configured?.requiresReasoningContentOnAssistantMessages ?? defaults.requiresReasoningContentOnAssistantMessages,
199
+ thinkingFormat: configured?.thinkingFormat ?? defaults.thinkingFormat,
200
+ openRouterRouting: configured?.openRouterRouting,
201
+ vercelGatewayRouting: configured?.vercelGatewayRouting ?? {},
202
+ zaiToolStream: configured?.zaiToolStream ?? false,
203
+ supportsStrictMode: configured?.supportsStrictMode ?? defaults.supportsStrictMode,
204
+ supportsJsonSchemaResponseFormat: configured?.supportsJsonSchemaResponseFormat ?? defaults.supportsJsonSchemaResponseFormat,
205
+ cacheControlFormat: configured?.cacheControlFormat ?? defaults.cacheControlFormat,
206
+ sessionAffinity: resolveSessionAffinity(model, defaults.sessionAffinityFormat),
207
+ supportsPromptCacheKey: configured?.supportsPromptCacheKey ?? false,
208
+ supportsLongCacheRetention: configured?.supportsLongCacheRetention ?? defaults.supportsLongCacheRetention,
209
+ visibleReasoningDetailTypes: configured && "visibleReasoningDetailTypes" in configured ? configured.visibleReasoningDetailTypes ?? defaults.visibleReasoningDetailTypes : defaults.visibleReasoningDetailTypes,
210
+ requiresNonEmptyUserOrAssistantMessage: defaults.requiresNonEmptyUserOrAssistantMessage
211
+ };
212
+ }
213
+ if (process.env.VITEST || false) globalThis[Symbol.for("openclaw.openAICompletionsCompatTestApi")] = { resolveOpenAICompletionsCompatDefaults };
214
+ //#endregion
215
+ //#region packages/ai/src/transports/openai-reasoning-compat.ts
216
+ /**
217
+ * OpenAI reasoning-effort compatibility helpers.
218
+ *
219
+ * Keeps provider metadata and built-in model exceptions on one path before request payloads are built.
220
+ */
221
+ const OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.1-codex-mini"]);
222
+ function readCompatReasoningEffortMap(compat) {
223
+ if (!compat || typeof compat !== "object") return {};
224
+ const rawMap = compat.reasoningEffortMap;
225
+ if (!rawMap || typeof rawMap !== "object") return {};
226
+ return Object.fromEntries(Object.entries(rawMap).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
227
+ }
228
+ /** Resolves the reasoning effort remap for an OpenAI-compatible model. */
229
+ function resolveOpenAIReasoningEffortMap(model, fallbackMap = {}) {
230
+ const provider = normalizeLowercaseStringOrEmpty(model.provider ?? "");
231
+ const id = normalizeLowercaseStringOrEmpty(model.id ?? "");
232
+ const builtinMap = provider === "openai" && OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS.has(id) ? {
233
+ minimal: "medium",
234
+ low: "medium"
235
+ } : {};
236
+ return {
237
+ ...fallbackMap,
238
+ ...builtinMap,
239
+ ...readCompatReasoningEffortMap(model.compat)
240
+ };
241
+ }
242
+ //#endregion
15
243
  //#region packages/ai/src/providers/openai-stop-reason.ts
16
244
  function mapOpenAIStopReason(reason, options) {
17
245
  if (reason === null) return { stopReason: "stop" };
@@ -39,6 +267,192 @@ function mapOpenAIStopReason(reason, options) {
39
267
  };
40
268
  }
41
269
  //#endregion
270
+ //#region packages/ai/src/providers/openai-tool-projection.ts
271
+ function unreadableToolDiagnostic(toolIndex) {
272
+ return {
273
+ toolIndex,
274
+ violations: [`tool[${toolIndex}] is unreadable`]
275
+ };
276
+ }
277
+ /** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
278
+ function projectOpenAITools(tools) {
279
+ let inputToolCount;
280
+ try {
281
+ inputToolCount = tools.length;
282
+ } catch {
283
+ return {
284
+ inputToolCount: 0,
285
+ tools: [],
286
+ diagnostics: [unreadableToolDiagnostic(0)]
287
+ };
288
+ }
289
+ const projectedTools = [];
290
+ const diagnostics = [];
291
+ for (let toolIndex = 0; toolIndex < inputToolCount; toolIndex += 1) {
292
+ let tool;
293
+ try {
294
+ const candidate = tools[toolIndex];
295
+ if (!candidate) {
296
+ diagnostics.push(unreadableToolDiagnostic(toolIndex));
297
+ continue;
298
+ }
299
+ tool = candidate;
300
+ } catch {
301
+ diagnostics.push(unreadableToolDiagnostic(toolIndex));
302
+ continue;
303
+ }
304
+ let name;
305
+ try {
306
+ name = tool.name;
307
+ } catch {
308
+ diagnostics.push({
309
+ toolIndex,
310
+ violations: [`tool[${toolIndex}].name is unreadable`]
311
+ });
312
+ continue;
313
+ }
314
+ if (typeof name !== "string" || !name) {
315
+ diagnostics.push({
316
+ toolIndex,
317
+ violations: [`tool[${toolIndex}].name is empty`]
318
+ });
319
+ continue;
320
+ }
321
+ let parameters;
322
+ try {
323
+ parameters = tool.parameters;
324
+ } catch {
325
+ diagnostics.push({
326
+ toolIndex,
327
+ toolName: name,
328
+ violations: [`${name}.parameters is unreadable`]
329
+ });
330
+ continue;
331
+ }
332
+ const schemaProjection = projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
333
+ if (!isRecord(schemaProjection.schema) || schemaProjection.violations.length > 0) {
334
+ diagnostics.push({
335
+ toolIndex,
336
+ toolName: name,
337
+ violations: schemaProjection.violations.length > 0 ? schemaProjection.violations : [`${name}.parameters must be a JSON object schema`]
338
+ });
339
+ continue;
340
+ }
341
+ let descriptionValue;
342
+ try {
343
+ descriptionValue = tool.description;
344
+ } catch {}
345
+ const description = typeof descriptionValue === "string" ? descriptionValue : void 0;
346
+ projectedTools.push({
347
+ toolIndex,
348
+ name,
349
+ ...description !== void 0 ? { description } : {},
350
+ parameters: schemaProjection.schema
351
+ });
352
+ }
353
+ return {
354
+ inputToolCount,
355
+ tools: projectedTools,
356
+ diagnostics
357
+ };
358
+ }
359
+ function requireProjectedFunction(name, projection, choiceLabel) {
360
+ if (!projection.tools.some((tool) => tool.name === name)) throw new Error(`${choiceLabel} requested unavailable tool "${name}" after schema conversion`);
361
+ }
362
+ /** Keeps Responses tool choices aligned with surviving function schemas. */
363
+ function reconcileOpenAIResponsesToolChoice(choice, projection) {
364
+ if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
365
+ if (choice === "required") {
366
+ if (projection.tools.length === 0) throw new Error("OpenAI Responses tool_choice requires a tool, but no tools survived schema conversion");
367
+ return choice;
368
+ }
369
+ if (choice === "none" || !isRecord(choice)) return choice;
370
+ const choiceType = choice.type;
371
+ if (choiceType === "function") {
372
+ const functionName = choice.name;
373
+ if (typeof functionName !== "string") return choice;
374
+ requireProjectedFunction(functionName, projection, "OpenAI Responses tool_choice");
375
+ return {
376
+ type: "function",
377
+ name: functionName
378
+ };
379
+ }
380
+ if (choiceType !== "allowed_tools") return choice;
381
+ const mode = choice.mode;
382
+ const tools = choice.tools;
383
+ if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
384
+ const normalizedAllowedTools = [];
385
+ for (const tool of tools) {
386
+ if (!isRecord(tool) || tool.type !== "function") {
387
+ normalizedAllowedTools.push(tool);
388
+ continue;
389
+ }
390
+ const functionName = tool.name;
391
+ if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
392
+ type: "function",
393
+ name: functionName
394
+ });
395
+ }
396
+ if (normalizedAllowedTools.length === 0) {
397
+ if (mode === "auto") return "none";
398
+ throw new Error("OpenAI Responses tool_choice requires a tool, but no allowed tools survived schema conversion");
399
+ }
400
+ return {
401
+ type: "allowed_tools",
402
+ mode,
403
+ tools: normalizedAllowedTools
404
+ };
405
+ }
406
+ /** Keeps Chat Completions tool choices aligned with surviving function schemas. */
407
+ function reconcileOpenAICompletionsToolChoice(choice, projection) {
408
+ if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
409
+ if (choice === "required") {
410
+ if (projection.tools.length === 0) throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no tools survived schema conversion");
411
+ return choice;
412
+ }
413
+ if (choice === "none" || !isRecord(choice)) return choice;
414
+ const choiceType = choice.type;
415
+ if (choiceType === "custom") throw new Error("OpenAI Chat Completions custom tool_choice is unsupported because this adapter emits function tools only");
416
+ if (choiceType === "function") {
417
+ const functionChoice = choice.function;
418
+ if (!isRecord(functionChoice)) return choice;
419
+ const functionName = functionChoice.name;
420
+ if (typeof functionName !== "string") return choice;
421
+ requireProjectedFunction(functionName, projection, "OpenAI Chat Completions tool_choice");
422
+ return {
423
+ type: "function",
424
+ function: { name: functionName }
425
+ };
426
+ }
427
+ if (choiceType !== "allowed_tools") return choice;
428
+ const allowedConfig = choice.allowed_tools;
429
+ if (!isRecord(allowedConfig)) return choice;
430
+ const mode = allowedConfig.mode;
431
+ const tools = allowedConfig.tools;
432
+ if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
433
+ const normalizedAllowedTools = [];
434
+ for (const tool of tools) {
435
+ if (!isRecord(tool) || tool.type !== "function") continue;
436
+ const functionChoice = tool.function;
437
+ const functionName = isRecord(functionChoice) ? functionChoice.name : void 0;
438
+ if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
439
+ type: "function",
440
+ function: { name: functionName }
441
+ });
442
+ }
443
+ if (normalizedAllowedTools.length === 0) {
444
+ if (mode === "auto") return "none";
445
+ throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no allowed tools survived schema conversion");
446
+ }
447
+ return {
448
+ type: "allowed_tools",
449
+ allowed_tools: {
450
+ mode,
451
+ tools: normalizedAllowedTools
452
+ }
453
+ };
454
+ }
455
+ //#endregion
42
456
  //#region packages/ai/src/providers/openai-completions.ts
43
457
  var openai_completions_exports = /* @__PURE__ */ __exportAll({
44
458
  convertMessages: () => convertMessages,
@@ -104,10 +518,11 @@ const streamOpenAICompletions = (model, context, options) => {
104
518
  stopReason: "stop",
105
519
  timestamp: Date.now()
106
520
  };
521
+ const provisionalCommentaryTags = /* @__PURE__ */ new Map();
107
522
  let firstEventAbort;
108
523
  try {
109
524
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
110
- const compat = getCompat(model);
525
+ const compat = resolveOpenAICompletionsCompat(model);
111
526
  const cacheRetention = resolveCacheRetention(options?.cacheRetention);
112
527
  const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
113
528
  const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
@@ -328,9 +743,10 @@ const streamOpenAICompletions = (model, context, options) => {
328
743
  if (choiceDelta.content !== null && choiceDelta.content !== void 0 && choiceDelta.content.length > 0) appendPartitionedContent(choiceDelta.content, Boolean(foundReasoningField));
329
744
  const refusalText = typeof choiceDelta.refusal === "string" ? choiceDelta.refusal : "";
330
745
  if (refusalText.length > 0) appendPartitionedContent(refusalText, Boolean(foundReasoningField));
331
- if (choiceDelta.tool_calls) {
746
+ if (choiceDelta.tool_calls && choiceDelta.tool_calls.length > 0) {
332
747
  flushPartitionedContent();
333
748
  sealNativeReasoningBeforeText();
749
+ rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
334
750
  for (const toolCall of choiceDelta.tool_calls) {
335
751
  const block = ensureToolCallBlock(toolCall);
336
752
  if (!block.id && toolCall.id) {
@@ -366,7 +782,7 @@ const streamOpenAICompletions = (model, context, options) => {
366
782
  }
367
783
  flushPartitionedContent();
368
784
  for (const block of blocks) finishBlock(block);
369
- if (options?.signal?.aborted) throw new Error("Request was aborted");
785
+ if (options?.signal?.aborted) throw transportAbortError(options.signal);
370
786
  if (output.stopReason === "aborted") throw new Error("Request was aborted");
371
787
  if (output.stopReason === "error") throw new Error(output.errorMessage || "Provider returned an error stop reason");
372
788
  if (!hasFinishReason) throw new Error("Stream ended without finish_reason");
@@ -375,6 +791,8 @@ const streamOpenAICompletions = (model, context, options) => {
375
791
  if (output.stopReason === "toolUse" && !hasToolCalls) output.stopReason = "stop";
376
792
  if (output.stopReason === "stop" && hasToolCalls && !hasVisibleText) output.stopReason = "toolUse";
377
793
  if (hasToolCalls && output.stopReason !== "toolUse") output.content = output.content.filter((block) => block.type !== "toolCall");
794
+ if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
795
+ if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
378
796
  stream.push({
379
797
  type: "done",
380
798
  reason: output.stopReason,
@@ -416,7 +834,7 @@ const streamSimpleOpenAICompletions = (model, context, options) => {
416
834
  toolChoice
417
835
  });
418
836
  };
419
- function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = getCompat(model)) {
837
+ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = resolveOpenAICompletionsCompat(model)) {
420
838
  if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
421
839
  const headers = { ...model.headers };
422
840
  if (model.provider === "github-copilot") {
@@ -427,7 +845,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
427
845
  });
428
846
  Object.assign(headers, copilotHeaders);
429
847
  }
430
- if (sessionId && compat.sendSessionAffinityHeaders) if (compat.sessionAffinityFormat === "openrouter") headers["x-session-id"] = sessionId;
848
+ if (sessionId && compat.sessionAffinity !== "none") if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
431
849
  else {
432
850
  headers.session_id = sessionId;
433
851
  headers["x-client-request-id"] = sessionId;
@@ -447,7 +865,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
447
865
  fetch: getAiTransportHost().buildModelFetch(model)
448
866
  });
449
867
  }
450
- function buildParams(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
868
+ function buildParams(model, context, options, compat = resolveOpenAICompletionsCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
451
869
  const cacheControl = getCompatCacheControl(compat, cacheRetention);
452
870
  const cacheOptOutIndexes = /* @__PURE__ */ new Set();
453
871
  const messages = convertMessages(model, context, compat, {
@@ -472,6 +890,13 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
472
890
  }
473
891
  if (options?.temperature !== void 0) params.temperature = options.temperature;
474
892
  if (options?.stop !== void 0 && options.stop.length > 0) params.stop = options.stop;
893
+ const requestedResponseFormat = options?.responseFormat;
894
+ const responseFormat = requestedResponseFormat === void 0 ? void 0 : resolveOpenAICompletionsResponseFormat(shouldOmitOllamaCompatResponseFormat({
895
+ provider: model.provider,
896
+ baseUrl: model.baseUrl,
897
+ hasTools: () => Boolean(context.tools?.length)
898
+ }) ? void 0 : requestedResponseFormat, compat.supportsJsonSchemaResponseFormat);
899
+ if (responseFormat !== void 0) params.response_format = responseFormat;
475
900
  let toolProjection;
476
901
  if (context.tools) {
477
902
  const converted = convertTools(context.tools, compat);
@@ -485,32 +910,35 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
485
910
  const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
486
911
  if (toolChoice !== void 0) params.tool_choice = toolChoice;
487
912
  }
488
- if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = options?.reasoningEffort ? {
913
+ const reasoningEffortMap = resolveOpenAIReasoningEffortMap(model);
914
+ const reasoningEffort = options?.reasoningEffort === void 0 ? void 0 : reasoningEffortMap[options.reasoningEffort] ?? model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
915
+ const reasoningEnabled = reasoningEffort !== void 0;
916
+ const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
917
+ if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
489
918
  type: "enabled",
490
919
  clear_thinking: false
491
920
  } : { type: "disabled" };
492
- else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = Boolean(options?.reasoningEffort);
921
+ else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = reasoningEnabled;
493
922
  else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = {
494
- enable_thinking: Boolean(options?.reasoningEffort),
923
+ enable_thinking: reasoningEnabled,
495
924
  preserve_thinking: true
496
925
  };
497
926
  else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
498
- params.thinking = { type: options?.reasoningEffort ? "enabled" : "disabled" };
499
- if (options?.reasoningEffort && compat.supportsReasoningEffort) params.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
927
+ params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
928
+ if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
500
929
  } else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
501
930
  const openRouterParams = params;
502
- if (options?.reasoningEffort) openRouterParams.reasoning = { effort: model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort };
503
- else if (model.thinkingLevelMap?.off !== null) openRouterParams.reasoning = { effort: model.thinkingLevelMap?.off ?? "none" };
931
+ if (reasoningEnabled) openRouterParams.reasoning = { effort: reasoningEffort };
932
+ else if (offReasoningEffort !== null) openRouterParams.reasoning = { effort: offReasoningEffort ?? "none" };
504
933
  } else if (compat.thinkingFormat === "together" && model.reasoning) {
505
934
  const togetherParams = params;
506
- togetherParams.reasoning = { enabled: Boolean(options?.reasoningEffort) };
507
- if (options?.reasoningEffort && compat.supportsReasoningEffort) togetherParams.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
508
- } else if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
509
- else if (!options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) {
510
- const offValue = model.thinkingLevelMap?.off;
511
- if (typeof offValue === "string") params.reasoning_effort = offValue;
935
+ togetherParams.reasoning = { enabled: reasoningEnabled };
936
+ if (reasoningEnabled && compat.supportsReasoningEffort) togetherParams.reasoning_effort = reasoningEffort;
937
+ } else if (reasoningEnabled && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
938
+ else if (model.reasoning && compat.supportsReasoningEffort) {
939
+ if (typeof offReasoningEffort === "string") params.reasoning_effort = offReasoningEffort;
512
940
  }
513
- if (model.compat?.openRouterRouting) params.provider = model.compat.openRouterRouting;
941
+ if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
514
942
  if (model.baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
515
943
  const routing = model.compat.vercelGatewayRouting;
516
944
  if (routing.only || routing.order) {
@@ -791,78 +1219,5 @@ function parseChunkUsage(rawUsage, model) {
791
1219
  applyProviderReportedUsageCost(usage, rawUsage.cost);
792
1220
  return usage;
793
1221
  }
794
- /**
795
- * Detect compatibility settings from provider and baseUrl for known providers.
796
- * Provider takes precedence over URL-based detection since it's explicitly configured.
797
- * Returns a fully resolved OpenAICompletionsCompat object with all fields set.
798
- */
799
- function detectCompat(model) {
800
- const provider = model.provider;
801
- const baseUrl = model.baseUrl;
802
- const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
803
- const isTogether = provider === "together" || baseUrl.includes("api.together.ai") || baseUrl.includes("api.together.xyz");
804
- const isMoonshot = provider === "moonshotai" || provider === "moonshotai-cn" || baseUrl.includes("api.moonshot.");
805
- const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
806
- const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
807
- const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
808
- const isNonStandard = provider === "cerebras" || baseUrl.includes("cerebras.ai") || provider === "xai" || baseUrl.includes("api.x.ai") || isTogether || baseUrl.includes("chutes.ai") || baseUrl.includes("deepseek.com") || isZai || isMoonshot || provider === "opencode" || baseUrl.includes("opencode.ai") || isCloudflareWorkersAI || isCloudflareAiGateway;
809
- const useMaxTokens = baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether || isZai;
810
- const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
811
- const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
812
- const isXiaomi = provider === "xiaomi" || baseUrl.includes("xiaomimimo.com");
813
- const supportsOpenRouterDeveloperRole = isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
814
- const usesOpenRouterSessionAffinity = isOpenRouter || model.compat?.thinkingFormat === "openrouter" || model.compat?.openRouterRouting !== void 0;
815
- const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : void 0;
816
- return {
817
- supportsStore: !isNonStandard,
818
- supportsDeveloperRole: supportsOpenRouterDeveloperRole || !isNonStandard && !isOpenRouter,
819
- supportsReasoningEffort: !isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway,
820
- supportsUsageInStreaming: true,
821
- maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
822
- requiresToolResultName: false,
823
- requiresAssistantAfterToolResult: false,
824
- requiresThinkingAsText: false,
825
- requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi,
826
- thinkingFormat: isDeepSeek ? "deepseek" : isXiaomi ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isOpenRouter ? "openrouter" : "openai",
827
- openRouterRouting: {},
828
- vercelGatewayRouting: {},
829
- zaiToolStream: false,
830
- supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway,
831
- cacheControlFormat,
832
- sendSessionAffinityHeaders: false,
833
- sessionAffinityFormat: usesOpenRouterSessionAffinity ? "openrouter" : "openai",
834
- supportsPromptCacheKey: false,
835
- supportsLongCacheRetention: !(isTogether || isCloudflareWorkersAI || isCloudflareAiGateway)
836
- };
837
- }
838
- /**
839
- * Get resolved compatibility settings for a model.
840
- * Uses explicit model.compat if provided, otherwise auto-detects from provider/URL.
841
- */
842
- function getCompat(model) {
843
- const detected = detectCompat(model);
844
- if (!model.compat) return detected;
845
- return {
846
- supportsStore: model.compat.supportsStore ?? detected.supportsStore,
847
- supportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,
848
- supportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,
849
- supportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
850
- maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
851
- requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
852
- requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
853
- requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
854
- requiresReasoningContentOnAssistantMessages: model.compat.requiresReasoningContentOnAssistantMessages ?? detected.requiresReasoningContentOnAssistantMessages,
855
- thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
856
- openRouterRouting: model.compat.openRouterRouting ?? {},
857
- vercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,
858
- zaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,
859
- supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,
860
- cacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,
861
- sendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,
862
- sessionAffinityFormat: detected.sessionAffinityFormat,
863
- supportsPromptCacheKey: model.compat.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,
864
- supportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention
865
- };
866
- }
867
1222
  //#endregion
868
- export { mapOpenAIStopReason as a, streamSimpleOpenAICompletions as i, openai_completions_exports as n, streamOpenAICompletions as r, convertMessages as t };
1223
+ export { transformTransportMessages as C, resolveProviderRequestPolicyConfig as S, buildGuardedModelFetch as _, projectOpenAITools as a, resolveProviderEndpoint as b, mapOpenAIStopReason as c, resolveOpenAICompletionsCompat as d, resolveOpenAICompletionsResponseFormat as f, tagPendingCommentaryText as g, rememberPendingCommentaryTags as h, streamSimpleOpenAICompletions as i, resolveOpenAIReasoningEffortMap as l, clearPendingCommentaryText as m, openai_completions_exports as n, reconcileOpenAICompletionsToolChoice as o, shouldOmitOllamaCompatResponseFormat as p, streamOpenAICompletions as r, reconcileOpenAIResponsesToolChoice as s, convertMessages as t, detectOpenAICompletionsCompat as u, resolveModelRequestTimeoutMs as v, resolveProviderRequestCapabilities as x, resolveOpenAIStrictToolSetting as y };