@openclaw/ai 2026.9.1 → 2026.9.3

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 (111) hide show
  1. package/README.md +3 -2
  2. package/dist/anthropic-CZy5U0NY.mjs +376 -0
  3. package/dist/anthropic-payload-policy-wuRCb6MH.d.mts +85 -0
  4. package/dist/anthropic-stream-reducer-B_yo_7pf.mjs +1669 -0
  5. package/dist/{api-registry-Cs6HGNqY.d.mts → api-registry-CB1-1oQ2.d.mts} +2 -2
  6. package/dist/assistant-output-iqnlJCV2.mjs +16 -0
  7. package/dist/assistant-text-phase-C20rxWwP.mjs +55 -0
  8. package/dist/{azure-openai-responses-CN4Fy5zV.mjs → azure-openai-responses-Crpa40QR.mjs} +5 -5
  9. package/dist/{base64-CEFBpSkN.mjs → base64-D-su8YVo.mjs} +1 -27
  10. package/dist/{diagnostics-KhXK-QJI.mjs → diagnostics-dV98PqIy.mjs} +96 -21
  11. package/dist/diagnostics.d.mts +3 -1
  12. package/dist/diagnostics.mjs +3 -3
  13. package/dist/{event-stream-vK_7r3bj.d.mts → event-stream-C1Z2piyk.d.mts} +11 -3
  14. package/dist/{event-stream-uSMZJ3FA.mjs → event-stream-D8PARQfL.mjs} +48 -10
  15. package/dist/event-stream-I_GlBsuZ.d.mts +1 -0
  16. package/dist/event-stream.d.mts +2 -2
  17. package/dist/event-stream.mjs +1 -1
  18. package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-B37TB3rB.mjs} +3 -10
  19. package/dist/github-copilot-request-facts-BTEBMeOv.mjs +16 -0
  20. package/dist/{google-CC-nrwXg.mjs → google-BDPriaVe.mjs} +10 -10
  21. package/dist/google-messages-CVn9eFpF.mjs +449 -0
  22. package/dist/google-shared-BedY23XS.mjs +185 -0
  23. package/dist/{google-vertex-DCr0pyzQ.mjs → google-vertex-DMz8XQCn.mjs} +7 -6
  24. package/dist/{host-BIaiBURL.mjs → host-CWuF-sS3.mjs} +84 -34
  25. package/dist/{host-BztR4tQj.d.mts → host-DK3wmS3e.d.mts} +3 -3
  26. package/dist/host-policy-CAopLRKA.mjs +37 -0
  27. package/dist/{index-AfaxKT8w.d.mts → index-CQ6LTHw8.d.mts} +11 -5
  28. package/dist/index.d.mts +7 -7
  29. package/dist/index.mjs +5 -5
  30. package/dist/internal/anthropic.d.mts +14 -11
  31. package/dist/internal/anthropic.mjs +5 -5
  32. package/dist/internal/google-model-family.d.mts +5 -0
  33. package/dist/internal/google-model-family.mjs +15 -0
  34. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  35. package/dist/internal/openai-responses-payload-policy.mjs +1 -1
  36. package/dist/internal/openai.d.mts +8 -103
  37. package/dist/internal/openai.mjs +10 -10
  38. package/dist/internal/retry-after.d.mts +2 -4
  39. package/dist/internal/retry-after.mjs +57 -8
  40. package/dist/internal/runtime.d.mts +7 -6
  41. package/dist/internal/runtime.mjs +8 -7
  42. package/dist/internal/shared.d.mts +14 -3
  43. package/dist/internal/shared.mjs +6 -4
  44. package/dist/internal/tool-schema.d.mts +63 -0
  45. package/dist/internal/tool-schema.mjs +3 -0
  46. package/dist/{json-parse-BuAJEbdW.mjs → json-parse-Dw_hnxsA.mjs} +1 -1
  47. package/dist/{mistral-B7etBd_H.mjs → mistral--m-Jm6VZ.mjs} +16 -38
  48. package/dist/model-transport-url-DKocrEsb.d.mts +28 -0
  49. package/dist/{openai-chatgpt-responses-BAJ4gq3i.mjs → openai-chatgpt-responses-nDZccFW-.mjs} +62 -54
  50. package/dist/openai-completions-KuoZyx0d.mjs +187 -0
  51. package/dist/{openai-completions-compat-4IjSBpr6.d.mts → openai-completions-compat-CXn3T1we.d.mts} +26 -4
  52. package/dist/{openai-completions-stream-DZjwK8vp.mjs → openai-completions-stream-BQk3SkLD.mjs} +621 -451
  53. package/dist/openai-prompt-cache-BI0rkM-5.mjs +220 -0
  54. package/dist/openai-prompt-cache-rrutvqxq.d.mts +16 -0
  55. package/dist/openai-provider-client-ha_WxTyj.mjs +24 -0
  56. package/dist/openai-reasoning-effort-BK7FbcLT.mjs +167 -0
  57. package/dist/{openai-responses-BEUlxfDu.mjs → openai-responses-D99dOzKI.mjs} +14 -32
  58. package/dist/{openai-responses-compaction-window-DO7yV7az.mjs → openai-responses-compaction-window-D5jbzCi3.mjs} +7 -159
  59. package/dist/{openai-responses-contracts-bPzSN_Ba.d.mts → openai-responses-contracts-B55afwRo.d.mts} +12 -4
  60. package/dist/{openai-responses-prompt-observer-internal-C7x4IK7r.mjs → openai-responses-prompt-observer-internal-tApyTLVu.mjs} +3 -3
  61. package/dist/{openai-responses-shared-DiAdpNAM.mjs → openai-responses-shared-ZyQEzS5i.mjs} +217 -212
  62. package/dist/openai-tool-projection-793cE3QX.d.mts +37 -0
  63. package/dist/{openai-tool-schema-BMiHFH36.mjs → openai-tool-schema-CzjyYXun.mjs} +53 -583
  64. package/dist/openai-tool-schema-ynZBgqW-.d.mts +38 -0
  65. package/dist/openai-transport-params-DNasp2fU.mjs +674 -0
  66. package/dist/{provider-error-B6EGq6gg.mjs → provider-error-C6TbKiey.mjs} +29 -13
  67. package/dist/{provider-options-CxFPtvh7.d.mts → provider-options-BXr9Ec83.d.mts} +19 -42
  68. package/dist/provider-replay-context-BuSUaAk5.mjs +21 -0
  69. package/dist/{provider-transcript-transform-WvJmFUAf.mjs → provider-transcript-transform-pPmUIwKt.mjs} +1 -1
  70. package/dist/provider-types-CAV0Og3m.d.mts +29 -0
  71. package/dist/provider-types.d.mts +6 -31
  72. package/dist/providers.d.mts +2 -2
  73. package/dist/providers.mjs +11 -11
  74. package/dist/{reasoning-tag-text-partitioner-C-4uedDb.mjs → reasoning-tag-text-partitioner-BQBi4B9d.mjs} +90 -35
  75. package/dist/record-coerce-DwRYMj3t.mjs +32 -0
  76. package/dist/retry-after-CdCURCVg.d.mts +15 -0
  77. package/dist/{sanitize-unicode-S6binQG-.mjs → sanitize-unicode-Bb-v9meu.mjs} +1 -1
  78. package/dist/session-affinity-CCH7eYdB.mjs +20 -0
  79. package/dist/{simple-options-0PLDyJ-d.mjs → simple-options-tcKOqnpF.mjs} +3 -3
  80. package/dist/{src-C8U7lkoa.mjs → src-B2Q_6G8V.mjs} +10 -2
  81. package/dist/{stream-first-event-timeout-DcNjoFQE.mjs → stream-first-event-timeout-2hfrquuz.mjs} +1 -1
  82. package/dist/string-coerce-fsri9iCu.mjs +34 -0
  83. package/dist/{string-normalization--fwJ4S2q.mjs → string-normalization-CmLIasuf.mjs} +1 -1
  84. package/dist/{tool-schema-json-projection-BtZiml7r.mjs → tool-schema-json-projection-ClptDdAO.mjs} +2 -38
  85. package/dist/{transport-stream-shared-CytPVLIg.mjs → transport-stream-shared-Cu3ZPhNW.mjs} +5 -5
  86. package/dist/{transport-stream-shared-BrvFTkoO.d.mts → transport-stream-shared-DOxpGJ-H.d.mts} +4 -4
  87. package/dist/transport-utils-CCooe-cr.mjs +121 -0
  88. package/dist/transports.d.mts +114 -41
  89. package/dist/transports.mjs +796 -1596
  90. package/dist/types-BADKjDBI.d.mts +1 -0
  91. package/dist/{types-DbrhszyQ.d.mts → types-Dy1q0CSu.d.mts} +101 -64
  92. package/dist/types.d.mts +6 -6
  93. package/dist/types.mjs +4 -4
  94. package/dist/utf16-slice-CvGodqok.mjs +29 -0
  95. package/dist/{validation-CJZtym2g.mjs → validation-BDzVDnTs.mjs} +9 -1
  96. package/dist/{validation-BOwtcl9X.d.mts → validation-CaFUZN9B.d.mts} +1 -1
  97. package/dist/validation.d.mts +1 -1
  98. package/dist/validation.mjs +1 -1
  99. package/package.json +14 -4
  100. package/dist/anthropic-compaction-replay-OMJZ0uyo.mjs +0 -838
  101. package/dist/anthropic-hk7F7ptG.mjs +0 -883
  102. package/dist/anthropic-payload-policy-DBT1itQ-.d.mts +0 -51
  103. package/dist/event-stream-DeDhbCc5.d.mts +0 -1
  104. package/dist/google-shared-CjPY0hZM.mjs +0 -634
  105. package/dist/google-thinking-level-C-V3tecN.mjs +0 -9
  106. package/dist/openai-completions-D0QZ0AyB.mjs +0 -403
  107. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
  108. package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
  109. package/dist/transport-utils-CtuS1Upe.mjs +0 -138
  110. package/dist/types-B5EFUmXs.d.mts +0 -1
  111. package/dist/utf16-slice-qz3nsy87.mjs +0 -84
@@ -0,0 +1,220 @@
1
+ import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
2
+ import { a as resolveProviderRequestCapabilities } from "./host-policy-CAopLRKA.mjs";
3
+ //#region packages/normalization-core/src/code-points.ts
4
+ /** Truncates to a nonnegative code-point budget; grapheme clusters may be split. */
5
+ function truncateCodePoints(text, maxCodePoints) {
6
+ const limit = Math.max(0, Math.trunc(maxCodePoints) || 0);
7
+ if (text.length <= limit) return text;
8
+ const prefix = [];
9
+ for (const codePoint of text) {
10
+ if (prefix.length >= limit) break;
11
+ prefix.push(codePoint);
12
+ }
13
+ return prefix.join("");
14
+ }
15
+ //#endregion
16
+ //#region packages/ai/src/providers/openai-response-format.ts
17
+ const JSON_SCHEMA_RESPONSE_FORMAT_NAME = "openclaw_response";
18
+ const OLLAMA_CLOUD_ORIGIN = "https://ollama.com";
19
+ function isKnownOpenAIJsonSchemaModelId(modelId) {
20
+ if (typeof modelId !== "string") return false;
21
+ if (/^gpt-5(?:[.-]|$)/i.test(modelId) || /^gpt-4\.1(?:-|$)/i.test(modelId)) return true;
22
+ const gpt4o = /^gpt-4o(-mini)?(?:-(\d{4}-\d{2}-\d{2}))?$/i.exec(modelId);
23
+ if (gpt4o) {
24
+ const snapshot = gpt4o[2];
25
+ return !snapshot || snapshot >= (gpt4o[1] ? "2024-07-18" : "2024-08-06");
26
+ }
27
+ return /^(?:o1|o3(?:-mini|-pro)?|o4-mini)(?:-\d{4}-\d{2}-\d{2})?$/i.test(modelId);
28
+ }
29
+ function shouldOmitOllamaCompatResponseFormat(params) {
30
+ if (!params.provider.includes("ollama")) return false;
31
+ if (params.hasTools()) return true;
32
+ try {
33
+ return new URL(params.baseUrl).origin === OLLAMA_CLOUD_ORIGIN;
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Maps the shared JSON Schema option to Chat Completions while preserving the
40
+ * older provider-shaped json_object/json_schema inputs accepted by model params.
41
+ */
42
+ function resolveOpenAICompletionsResponseFormat(responseFormat, supportsJsonSchemaResponseFormat) {
43
+ if (!responseFormat) return;
44
+ if (responseFormat.type === "json_object") return responseFormat;
45
+ if (responseFormat.type === "text") return responseFormat;
46
+ if (responseFormat.type === "json_schema" && isRecord(responseFormat.json_schema)) return responseFormat;
47
+ if (!supportsJsonSchemaResponseFormat) return;
48
+ return {
49
+ type: "json_schema",
50
+ json_schema: {
51
+ name: JSON_SCHEMA_RESPONSE_FORMAT_NAME,
52
+ schema: responseFormat
53
+ }
54
+ };
55
+ }
56
+ //#endregion
57
+ //#region packages/ai/src/transports/openai-completions-compat.ts
58
+ function isDefaultRouteProvider(provider, ...ids) {
59
+ return provider !== void 0 && ids.includes(provider);
60
+ }
61
+ /** Native OpenAI defaults never apply to a configured proxy endpoint. */
62
+ function isNativeOpenAIEndpoint(model) {
63
+ const baseUrl = model.baseUrl?.trim();
64
+ if (!baseUrl) return model.provider === "openai";
65
+ const endpoint = URL.parse(baseUrl);
66
+ return endpoint?.protocol === "https:" && (endpoint.hostname === "api.openai.com" || endpoint.hostname.endsWith(".api.openai.com"));
67
+ }
68
+ function isOpenAICodexResponsesModel(model) {
69
+ return model.provider === "openai" && (model.api === "openai-chatgpt-responses" || model.api === "openclaw-openai-chatgpt-responses-transport");
70
+ }
71
+ function isNativeOpenAICodexResponsesBaseUrl(baseUrl) {
72
+ const trimmed = typeof baseUrl === "string" ? baseUrl.trim() : "";
73
+ if (!trimmed) return false;
74
+ try {
75
+ const url = new URL(trimmed);
76
+ if (url.protocol !== "http:" && url.protocol !== "https:") return false;
77
+ if (url.hostname.toLowerCase() !== "chatgpt.com") return false;
78
+ const pathname = url.pathname.replace(/\/+$/u, "").toLowerCase();
79
+ return [
80
+ "/backend-api",
81
+ "/backend-api/v1",
82
+ "/backend-api/codex",
83
+ "/backend-api/codex/v1",
84
+ "/backend-api/codex/responses"
85
+ ].includes(pathname);
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
90
+ function usesNativeOpenAICodexResponsesBackend(model) {
91
+ return isOpenAICodexResponsesModel(model) && isNativeOpenAICodexResponsesBaseUrl(model.baseUrl);
92
+ }
93
+ function resolveOpenAIPromptCacheKeySupport(model) {
94
+ return model.compat?.supportsPromptCacheKey ?? (isNativeOpenAIEndpoint(model) || usesNativeOpenAICodexResponsesBackend(model));
95
+ }
96
+ /** Resolves default request flags for an OpenAI-compatible completions endpoint. */
97
+ function resolveOpenAICompletionsCompatDefaults(input) {
98
+ const { provider, modelId, endpointClass, knownProviderFamily, supportsNativeStreamingUsageCompat = false, supportsOpenAICompletionsStreamingUsageCompat = false, usesExplicitProxyLikeEndpoint = false } = input;
99
+ const isDefaultRoute = endpointClass === "default";
100
+ const usesConfiguredNonOpenAIEndpoint = endpointClass !== "default" && endpointClass !== "openai-public";
101
+ const isMoonshot = knownProviderFamily === "moonshot" || endpointClass === "moonshot-native";
102
+ const isMoonshotLike = isMoonshot || knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native";
103
+ const isModelStudioLike = knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native" || isDefaultRoute && isDefaultRouteProvider(provider, "dashscope", "modelstudio", "qwen");
104
+ const isZai = endpointClass === "zai-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "zai");
105
+ const isDeepSeek = endpointClass === "deepseek-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "deepseek");
106
+ const isTogether = knownProviderFamily === "together" || input.baseUrl?.includes("api.together.ai") === true || input.baseUrl?.includes("api.together.xyz") === true || isDefaultRoute && isDefaultRouteProvider(input.provider, "together");
107
+ const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || input.baseUrl?.includes("gateway.ai.cloudflare.com") === true;
108
+ const isXiaomi = endpointClass === "xiaomi-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "xiaomi");
109
+ const isNonStandard = endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "mistral-public" || endpointClass === "opencode-native" || endpointClass === "opencode-go-native" || endpointClass === "xai-native" || isXiaomi || isZai || isDefaultRoute && isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai");
110
+ const isOpenRouterLike = input.provider === "openrouter" || endpointClass === "openrouter";
111
+ const isLocalEndpoint = endpointClass === "local";
112
+ const usesMaxTokens = endpointClass === "chutes-native" || endpointClass === "mistral-public" || knownProviderFamily === "mistral" || isMoonshot || isCloudflareAiGateway || isZai || isTogether || isDefaultRoute && isDefaultRouteProvider(provider, "chutes");
113
+ return {
114
+ supportsStore: !isNonStandard && knownProviderFamily !== "mistral" && !usesExplicitProxyLikeEndpoint,
115
+ supportsDeveloperRole: !isNonStandard && !isMoonshotLike && !usesConfiguredNonOpenAIEndpoint,
116
+ supportsReasoningEffort: !isZai && !isTogether && knownProviderFamily !== "mistral" && endpointClass !== "xai-native" && !usesExplicitProxyLikeEndpoint,
117
+ supportsUsageInStreaming: supportsOpenAICompletionsStreamingUsageCompat || !isNonStandard && (isLocalEndpoint || !usesConfiguredNonOpenAIEndpoint || supportsNativeStreamingUsageCompat),
118
+ maxTokensField: usesMaxTokens ? "max_tokens" : "max_completion_tokens",
119
+ thinkingFormat: isDeepSeek || isXiaomi ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isOpenRouterLike ? "openrouter" : "openai",
120
+ visibleReasoningDetailTypes: isOpenRouterLike ? ["response.output_text", "response.text"] : [],
121
+ supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint,
122
+ supportsJsonSchemaResponseFormat: (endpointClass === "openai-public" || isDefaultRoute && isDefaultRouteProvider(provider, "openai")) && isKnownOpenAIJsonSchemaModelId(modelId),
123
+ requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi,
124
+ requiresNonEmptyUserOrAssistantMessage: isModelStudioLike,
125
+ cacheControlFormat: isModelStudioLike && endpointClass !== "custom" || modelId?.toLowerCase().startsWith("anthropic/") === true && (endpointClass === "openrouter" || isDefaultRoute && provider === "openrouter" || provider === "deepinfra") ? "anthropic" : void 0,
126
+ sessionAffinityFormat: isOpenRouterLike ? "openrouter" : "openai",
127
+ supportsLongCacheRetention: !isModelStudioLike && 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")
128
+ };
129
+ }
130
+ function resolveOpenAICompletionsCompatDefaultsFromCapabilities(input) {
131
+ return resolveOpenAICompletionsCompatDefaults(input);
132
+ }
133
+ /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */
134
+ function detectOpenAICompletionsCompat(model, resolveCapabilities) {
135
+ const capabilities = (resolveCapabilities ?? ((input) => resolveProviderRequestCapabilities(input, model)))({
136
+ provider: model.provider,
137
+ api: "openai-completions",
138
+ baseUrl: model.baseUrl,
139
+ capability: "llm",
140
+ transport: "stream",
141
+ modelId: model.id,
142
+ compat: model.compat && typeof model.compat === "object" ? model.compat : void 0
143
+ });
144
+ return {
145
+ capabilities,
146
+ defaults: resolveOpenAICompletionsCompatDefaultsFromCapabilities({
147
+ provider: model.provider,
148
+ modelId: model.id,
149
+ baseUrl: model.baseUrl,
150
+ ...capabilities
151
+ })
152
+ };
153
+ }
154
+ function resolveSessionAffinity(model, detectedFormat) {
155
+ if (model.compat?.sendSessionAffinityHeaders !== true) return "none";
156
+ if (detectedFormat === "openrouter" || model.compat.thinkingFormat === "openrouter" || model.compat.openRouterRouting !== void 0) return "openrouter";
157
+ return "openai";
158
+ }
159
+ /** Applies explicit model overrides once on top of the canonical transport defaults. */
160
+ function resolveOpenAICompletionsCompat(model, resolveCapabilities) {
161
+ const { defaults } = detectOpenAICompletionsCompat(model, resolveCapabilities);
162
+ const configured = model.compat;
163
+ return {
164
+ supportsStore: configured?.supportsStore ?? defaults.supportsStore,
165
+ supportsDeveloperRole: configured?.supportsDeveloperRole ?? defaults.supportsDeveloperRole,
166
+ supportsReasoningEffort: configured?.supportsReasoningEffort ?? defaults.supportsReasoningEffort,
167
+ supportsUsageInStreaming: configured?.supportsUsageInStreaming ?? defaults.supportsUsageInStreaming,
168
+ maxTokensField: configured?.maxTokensField ?? defaults.maxTokensField,
169
+ requiresToolResultName: configured?.requiresToolResultName ?? false,
170
+ requiresAssistantAfterToolResult: configured?.requiresAssistantAfterToolResult ?? false,
171
+ requiresThinkingAsText: configured?.requiresThinkingAsText ?? false,
172
+ requiresReasoningContentOnAssistantMessages: configured?.requiresReasoningContentOnAssistantMessages ?? defaults.requiresReasoningContentOnAssistantMessages,
173
+ thinkingFormat: configured?.thinkingFormat ?? defaults.thinkingFormat,
174
+ openRouterRouting: configured?.openRouterRouting,
175
+ vercelGatewayRouting: configured?.vercelGatewayRouting ?? {},
176
+ zaiToolStream: configured?.zaiToolStream ?? false,
177
+ supportsStrictMode: configured?.supportsStrictMode ?? defaults.supportsStrictMode,
178
+ supportsJsonSchemaResponseFormat: configured?.supportsJsonSchemaResponseFormat ?? defaults.supportsJsonSchemaResponseFormat,
179
+ cacheControlFormat: configured?.cacheControlFormat ?? defaults.cacheControlFormat,
180
+ sessionAffinity: resolveSessionAffinity(model, defaults.sessionAffinityFormat),
181
+ supportsPromptCacheKey: resolveOpenAIPromptCacheKeySupport(model),
182
+ supportsLongCacheRetention: configured?.supportsLongCacheRetention ?? (usesNativeOpenAICodexResponsesBackend(model) ? false : defaults.supportsLongCacheRetention),
183
+ configuredSupportsLongCacheRetention: configured?.supportsLongCacheRetention,
184
+ visibleReasoningDetailTypes: configured && "visibleReasoningDetailTypes" in configured ? configured.visibleReasoningDetailTypes ?? defaults.visibleReasoningDetailTypes : defaults.visibleReasoningDetailTypes,
185
+ requiresNonEmptyUserOrAssistantMessage: defaults.requiresNonEmptyUserOrAssistantMessage
186
+ };
187
+ }
188
+ //#endregion
189
+ //#region packages/ai/src/providers/openai-prompt-cache.ts
190
+ const EXTENDED_RETENTION_MODELS = /* @__PURE__ */ new Set([
191
+ "gpt-5.5",
192
+ "gpt-5.5-pro",
193
+ "gpt-5.4",
194
+ "gpt-5.2",
195
+ "gpt-5.1-codex-max",
196
+ "gpt-5.1",
197
+ "gpt-5.1-codex",
198
+ "gpt-5.1-codex-mini",
199
+ "gpt-5.1-chat-latest",
200
+ "gpt-5",
201
+ "gpt-5-codex",
202
+ "gpt-4.1"
203
+ ]);
204
+ /** Selects documented lifetime fields shared by Responses and Chat Completions. */
205
+ function resolveOpenAIPromptCacheParams(model, cacheRetention, compat) {
206
+ if (cacheRetention !== "long" || !compat.supportsPromptCacheKey || !compat.supportsLongCacheRetention) return {};
207
+ const version = /^gpt-(\d+)(?:\.(\d+))?(?:-|$)/.exec(model.id);
208
+ if (version && (Number(version[1]) > 5 || Number(version[1]) === 5 && Number(version[2]) >= 6)) return { prompt_cache_options: { ttl: "30m" } };
209
+ const modelId = model.id.replace(/-\d{4}-\d{2}-\d{2}$/, "");
210
+ return !isNativeOpenAIEndpoint(model) || EXTENDED_RETENTION_MODELS.has(modelId) ? { prompt_cache_retention: "24h" } : {};
211
+ }
212
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
213
+ const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
214
+ /** Truncates a prompt cache key by Unicode code point count. */
215
+ function clampOpenAIPromptCacheKey(key) {
216
+ if (key === void 0) return;
217
+ return truncateCodePoints(key, 64);
218
+ }
219
+ //#endregion
220
+ export { isNativeOpenAIEndpoint as a, resolveOpenAIPromptCacheKeySupport as c, shouldOmitOllamaCompatResponseFormat as d, detectOpenAICompletionsCompat as i, usesNativeOpenAICodexResponsesBackend as l, clampOpenAIPromptCacheKey as n, isOpenAICodexResponsesModel as o, resolveOpenAIPromptCacheParams as r, resolveOpenAICompletionsCompat as s, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t, resolveOpenAICompletionsResponseFormat as u };
@@ -0,0 +1,16 @@
1
+ import { D as Model, j as OpenAICompletionsCompat, l as CacheRetention } from "./types-Dy1q0CSu.mjs";
2
+ import "./types-BADKjDBI.mjs";
3
+ //#region packages/ai/src/providers/openai-prompt-cache.d.ts
4
+ /** Selects documented lifetime fields shared by Responses and Chat Completions. */
5
+ declare function resolveOpenAIPromptCacheParams(model: Pick<Model, "id" | "provider" | "baseUrl">, cacheRetention: CacheRetention, compat: Required<Pick<OpenAICompletionsCompat, "supportsPromptCacheKey" | "supportsLongCacheRetention">>): {
6
+ prompt_cache_retention?: "24h";
7
+ prompt_cache_options?: {
8
+ ttl: "30m";
9
+ };
10
+ };
11
+ /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
12
+ declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
13
+ /** Truncates a prompt cache key by Unicode code point count. */
14
+ declare function clampOpenAIPromptCacheKey(key: string | undefined): string | undefined;
15
+ //#endregion
16
+ export { clampOpenAIPromptCacheKey as n, resolveOpenAIPromptCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
@@ -0,0 +1,24 @@
1
+ import { n as getAiTransportHost } from "./host-CWuF-sS3.mjs";
2
+ import { T as resolveOpenAIClientBaseUrl } from "./openai-transport-params-DNasp2fU.mjs";
3
+ import { i as resolveCloudflareBaseUrl, r as isCloudflareProvider } from "./github-copilot-headers-B37TB3rB.mjs";
4
+ import OpenAI from "openai";
5
+ //#region packages/ai/src/providers/openai-provider-client.ts
6
+ function createOpenAIProviderClient(model, apiKey, headers, optionsHeaders) {
7
+ if (optionsHeaders) Object.assign(headers, optionsHeaders);
8
+ const defaultHeaders = model.provider === "cloudflare-ai-gateway" ? {
9
+ ...headers,
10
+ Authorization: headers.Authorization ?? null,
11
+ "cf-aig-authorization": `Bearer ${apiKey}`
12
+ } : headers;
13
+ const baseUrl = isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl;
14
+ return new OpenAI({
15
+ apiKey,
16
+ baseURL: resolveOpenAIClientBaseUrl(model, baseUrl),
17
+ dangerouslyAllowBrowser: true,
18
+ defaultHeaders,
19
+ maxRetries: 0,
20
+ fetch: getAiTransportHost().buildModelFetch(model)
21
+ });
22
+ }
23
+ //#endregion
24
+ export { createOpenAIProviderClient as t };
@@ -0,0 +1,167 @@
1
+ import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
2
+ import { n as uniqueStrings, t as normalizeStringEntries } from "./string-normalization-CmLIasuf.mjs";
3
+ //#region packages/ai/src/providers/openai-reasoning-effort.ts
4
+ /**
5
+ * OpenAI-compatible reasoning-effort normalization. Different GPT families
6
+ * expose different accepted effort enums, so callers map requested values here
7
+ * before constructing provider payloads.
8
+ */
9
+ const GPT_5_REASONING_EFFORTS = [
10
+ "minimal",
11
+ "low",
12
+ "medium",
13
+ "high"
14
+ ];
15
+ const GPT_51_REASONING_EFFORTS = [
16
+ "none",
17
+ "low",
18
+ "medium",
19
+ "high"
20
+ ];
21
+ const GPT_52_REASONING_EFFORTS = [
22
+ "none",
23
+ "low",
24
+ "medium",
25
+ "high",
26
+ "xhigh"
27
+ ];
28
+ const GPT_56_REASONING_EFFORTS = [
29
+ "none",
30
+ "low",
31
+ "medium",
32
+ "high",
33
+ "xhigh",
34
+ "max"
35
+ ];
36
+ const GPT_6_ASTRA_REASONING_EFFORTS = [
37
+ "low",
38
+ "medium",
39
+ "high",
40
+ "xhigh",
41
+ "max"
42
+ ];
43
+ const GPT_CODEX_REASONING_EFFORTS = [
44
+ "low",
45
+ "medium",
46
+ "high",
47
+ "xhigh"
48
+ ];
49
+ const GPT_PRO_REASONING_EFFORTS = [
50
+ "medium",
51
+ "high",
52
+ "xhigh"
53
+ ];
54
+ const GPT_5_PRO_REASONING_EFFORTS = ["high"];
55
+ const GPT_51_CODEX_MAX_REASONING_EFFORTS = [
56
+ "none",
57
+ "medium",
58
+ "high",
59
+ "xhigh"
60
+ ];
61
+ const GPT_51_CODEX_MINI_REASONING_EFFORTS = ["medium"];
62
+ const GENERIC_REASONING_EFFORTS = [
63
+ "low",
64
+ "medium",
65
+ "high"
66
+ ];
67
+ const CANONICAL_REASONING_EFFORTS = /* @__PURE__ */ new Set([
68
+ "none",
69
+ "minimal",
70
+ "low",
71
+ "medium",
72
+ "high",
73
+ "xhigh",
74
+ "max",
75
+ "off"
76
+ ]);
77
+ function normalizeModelId(id) {
78
+ return normalizeLowercaseStringOrEmpty(id ?? "").replace(/-\d{4}-\d{2}-\d{2}$/u, "");
79
+ }
80
+ /** Return whether a model is the GPT-5.4 mini family. */
81
+ function isOpenAIGpt54MiniModel(model) {
82
+ const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
83
+ return /^gpt-5\.4-mini(?:-|$)/u.test(id);
84
+ }
85
+ /** Return whether a model is the GPT-5.5 family. */
86
+ function isOpenAIGpt55Model(model) {
87
+ const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
88
+ const name = normalizeModelId(typeof model.name === "string" ? model.name : void 0);
89
+ return /^gpt-5\.5(?:-|$)/u.test(id) || /^gpt-5\.5(?:\s|\(|-|$)/u.test(name);
90
+ }
91
+ /** Return whether a model is the GPT-5.6 family. */
92
+ function isOpenAIGpt56Model(model) {
93
+ const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
94
+ const name = normalizeModelId(typeof model.name === "string" ? model.name : void 0);
95
+ return /^gpt-5\.6(?:-|$)/u.test(id) || /^gpt-5\.6(?:\s|\(|-|$)/u.test(name);
96
+ }
97
+ /** Normalize user-facing reasoning effort names to API effort names. */
98
+ function normalizeOpenAIReasoningEffort(effort) {
99
+ const trimmed = effort.trim();
100
+ const folded = trimmed.toLowerCase();
101
+ return CANONICAL_REASONING_EFFORTS.has(folded) ? folded : trimmed;
102
+ }
103
+ function readCompatReasoningEfforts(compat) {
104
+ if (!compat || typeof compat !== "object") return;
105
+ if (compat.supportsReasoningEffort === false) return [];
106
+ const raw = compat.supportedReasoningEfforts;
107
+ if (!Array.isArray(raw)) return;
108
+ const supported = uniqueStrings(normalizeStringEntries(raw.filter((value) => typeof value === "string")));
109
+ return supported.length > 0 ? supported : void 0;
110
+ }
111
+ function isDisabledReasoningEffort(effort) {
112
+ return effort === "none" || effort === "off";
113
+ }
114
+ /** Resolve the reasoning efforts accepted by a specific OpenAI-compatible model. */
115
+ function resolveOpenAISupportedReasoningEfforts(model) {
116
+ return resolveOpenAIModelReasoningEfforts(model) ?? GENERIC_REASONING_EFFORTS;
117
+ }
118
+ /** Read a declared or known model contract, leaving unknown compatible models unspecified. */
119
+ function resolveOpenAIModelReasoningEfforts(model) {
120
+ const compatEfforts = readCompatReasoningEfforts(model.compat);
121
+ if (compatEfforts) return compatEfforts;
122
+ const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
123
+ if (id === "gpt-6-astra" && model.api !== "azure-openai-responses") return GPT_6_ASTRA_REASONING_EFFORTS;
124
+ if (/^gpt-5\.6(?:-|$)/u.test(id)) return GPT_56_REASONING_EFFORTS;
125
+ if (id === "gpt-5.1-codex-mini") return GPT_51_CODEX_MINI_REASONING_EFFORTS;
126
+ if (id === "gpt-5.1-codex-max") return GPT_51_CODEX_MAX_REASONING_EFFORTS;
127
+ if (/^gpt-5(?:\.\d+)?-codex(?:-|$)/u.test(id)) return GPT_CODEX_REASONING_EFFORTS;
128
+ if (id === "gpt-5-pro") return GPT_5_PRO_REASONING_EFFORTS;
129
+ if (/^gpt-5\.[2-9](?:\.\d+)?-pro(?:-|$)/u.test(id)) return GPT_PRO_REASONING_EFFORTS;
130
+ if (/^gpt-5\.[2-9](?:\.\d+)?(?:-|$)/u.test(id)) return GPT_52_REASONING_EFFORTS;
131
+ if (/^gpt-5\.1(?:-|$)/u.test(id)) return GPT_51_REASONING_EFFORTS;
132
+ if (/^gpt-5(?:-|$)/u.test(id)) return GPT_5_REASONING_EFFORTS;
133
+ }
134
+ /**
135
+ * Return whether a model accepts temperature. GPT-5.6 and GPT-6 Astra
136
+ * reject it with a 400; catalog compat can override per model.
137
+ */
138
+ function supportsOpenAITemperature(model) {
139
+ const compat = model.compat;
140
+ if (compat && typeof compat === "object") {
141
+ const declared = compat.supportsTemperature;
142
+ if (typeof declared === "boolean") return declared;
143
+ }
144
+ const id = normalizeModelId(typeof model.id === "string" ? model.id : void 0);
145
+ return (id !== "gpt-6-astra" || model.api === "azure-openai-responses") && !/^gpt-5\.6(?:-|$)/u.test(id);
146
+ }
147
+ /** Return whether a model accepts a requested reasoning effort. */
148
+ function supportsOpenAIReasoningEffort(model, effort) {
149
+ return resolveOpenAISupportedReasoningEfforts(model).includes(normalizeOpenAIReasoningEffort(effort));
150
+ }
151
+ /** Resolve a requested reasoning effort to the closest value supported by the model. */
152
+ function resolveOpenAIReasoningEffortForModel(params) {
153
+ const requested = normalizeOpenAIReasoningEffort(params.effort);
154
+ const mapped = params.fallbackMap?.[requested] ?? (params.fallbackMap && CANONICAL_REASONING_EFFORTS.has(requested) ? Object.entries(params.fallbackMap).find(([effort]) => normalizeOpenAIReasoningEffort(effort) === requested)?.[1] : void 0);
155
+ const normalized = mapped === void 0 ? requested : mapped.trim();
156
+ const supported = resolveOpenAISupportedReasoningEfforts(params.model);
157
+ if (supported.includes(normalized)) return normalized;
158
+ if (requested === "off" && supported.includes("none")) return "none";
159
+ if (isDisabledReasoningEffort(requested) || isDisabledReasoningEffort(normalized)) return;
160
+ if (requested === "minimal" && supported.includes("low")) return "low";
161
+ if ((requested === "minimal" || requested === "low") && supported.includes("medium")) return "medium";
162
+ if (requested === "xhigh" && supported.includes("high")) return "high";
163
+ if (requested === "max" && supported.includes("xhigh")) return "xhigh";
164
+ return supported.find((effort) => !isDisabledReasoningEffort(normalizeOpenAIReasoningEffort(effort)));
165
+ }
166
+ //#endregion
167
+ export { resolveOpenAIModelReasoningEfforts as a, supportsOpenAIReasoningEffort as c, normalizeOpenAIReasoningEffort as i, supportsOpenAITemperature as l, isOpenAIGpt55Model as n, resolveOpenAIReasoningEffortForModel as o, isOpenAIGpt56Model as r, resolveOpenAISupportedReasoningEfforts as s, isOpenAIGpt54MiniModel as t };
@@ -1,15 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
3
- import { n as getAiTransportHost } from "./host-BIaiBURL.mjs";
4
- import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
2
+ import { t as AssistantMessageEventStream } from "./event-stream-D8PARQfL.mjs";
3
+ import { n as clampOpenAIPromptCacheKey, r as resolveOpenAIPromptCacheParams, s as resolveOpenAICompletionsCompat } from "./openai-prompt-cache-BI0rkM-5.mjs";
5
4
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
6
- import { n as buildBaseOptions } from "./simple-options-0PLDyJ-d.mjs";
5
+ import { n as buildBaseOptions } from "./simple-options-tcKOqnpF.mjs";
7
6
  import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
8
- import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, o as runResponsesStreamLifecycle, r as convertResponsesMessages, t as applyCommonResponsesParams } from "./openai-responses-shared-DiAdpNAM.mjs";
9
- import { j as resolveOpenAIClientBaseUrl } from "./openai-tool-schema-BMiHFH36.mjs";
10
- import { A as supportsOpenAITemperature } from "./openai-responses-compaction-window-DO7yV7az.mjs";
11
- import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
12
- import OpenAI from "openai";
7
+ import { t as resolveOpencodeSessionHeaders } from "./session-affinity-CCH7eYdB.mjs";
8
+ import { l as supportsOpenAITemperature } from "./openai-reasoning-effort-BK7FbcLT.mjs";
9
+ import { a as resolveResponsesReasoningEffort, i as createResponsesAssistantOutput, n as applyResponsesServiceTierPricing, r as convertResponsesMessages, s as runResponsesStreamLifecycle, t as applyCommonResponsesParams } from "./openai-responses-shared-ZyQEzS5i.mjs";
10
+ import { n as hasCopilotVisionInput, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-B37TB3rB.mjs";
11
+ import { t as createOpenAIProviderClient } from "./openai-provider-client-ha_WxTyj.mjs";
13
12
  //#region packages/ai/src/providers/openai-responses.ts
14
13
  var openai_responses_exports = /* @__PURE__ */ __exportAll({
15
14
  streamOpenAIResponses: () => streamOpenAIResponses,
@@ -18,13 +17,10 @@ var openai_responses_exports = /* @__PURE__ */ __exportAll({
18
17
  const OPENAI_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "opencode"]);
19
18
  function getCompat(model) {
20
19
  return {
21
- sendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true,
22
- supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true
20
+ ...resolveOpenAICompletionsCompat(model),
21
+ sendSessionIdHeader: model.compat?.sendSessionIdHeader ?? true
23
22
  };
24
23
  }
25
- function getPromptCacheRetention(compat, cacheRetention) {
26
- return cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : void 0;
27
- }
28
24
  /**
29
25
  * Generate function for OpenAI Responses API
30
26
  */
@@ -39,7 +35,7 @@ const streamOpenAIResponses = (model, context, options) => {
39
35
  createClient: () => {
40
36
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
41
37
  const cacheSessionId = resolveCacheRetention(options?.cacheRetention) === "none" ? void 0 : options?.sessionId;
42
- return createClient(model, context, apiKey, options?.headers, cacheSessionId);
38
+ return createClient(model, context, apiKey, resolveOpencodeSessionHeaders(model, options), cacheSessionId);
43
39
  },
44
40
  buildParams: (_requestModel, replayMode) => buildParams(model, context, options, replayMode),
45
41
  processStreamOptions: {
@@ -77,21 +73,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
77
73
  if (compat.sendSessionIdHeader) headers.session_id = sessionId;
78
74
  headers["x-client-request-id"] = sessionId;
79
75
  }
80
- if (optionsHeaders) Object.assign(headers, optionsHeaders);
81
- const defaultHeaders = model.provider === "cloudflare-ai-gateway" ? {
82
- ...headers,
83
- Authorization: headers.Authorization ?? null,
84
- "cf-aig-authorization": `Bearer ${apiKey}`
85
- } : headers;
86
- const baseUrl = isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl;
87
- return new OpenAI({
88
- apiKey,
89
- baseURL: resolveOpenAIClientBaseUrl(model, baseUrl),
90
- dangerouslyAllowBrowser: true,
91
- defaultHeaders,
92
- maxRetries: 0,
93
- fetch: getAiTransportHost().buildModelFetch(model)
94
- });
76
+ return createOpenAIProviderClient(model, apiKey, headers, optionsHeaders);
95
77
  }
96
78
  function buildParams(model, context, options, replayMode = "checkpoint") {
97
79
  const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS, {
@@ -106,8 +88,8 @@ function buildParams(model, context, options, replayMode = "checkpoint") {
106
88
  model: model.id,
107
89
  input: messages,
108
90
  stream: true,
109
- prompt_cache_key: cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
110
- prompt_cache_retention: getPromptCacheRetention(compat, cacheRetention),
91
+ prompt_cache_key: cacheRetention === "none" || !compat.supportsPromptCacheKey ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
92
+ ...resolveOpenAIPromptCacheParams(model, cacheRetention, compat),
111
93
  store: false
112
94
  };
113
95
  if (options?.maxTokens) params.max_output_tokens = options?.maxTokens;