@openclaw/ai 2026.7.2-beta.3 → 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.
- package/README.md +6 -5
- package/dist/{anthropic-D7SyZQ5v.mjs → anthropic-CrUDIBpM.mjs} +123 -16
- package/dist/{api-registry-DXBIXISf.d.mts → api-registry-BMphkFf1.d.mts} +1 -2
- package/dist/{azure-openai-responses-BkZgyZ3I.mjs → azure-openai-responses-CbrpVeEv.mjs} +7 -10
- package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
- package/dist/{event-stream-BPemFrFW.d.mts → event-stream-Douf9dob.d.mts} +1 -1
- package/dist/event-stream.d.mts +1 -1
- package/dist/{google-C_biGbV7.mjs → google-Cs62KA7t.mjs} +4 -4
- package/dist/{google-shared-BK-NoHl8.mjs → google-shared-CMLI-tCZ.mjs} +3 -3
- package/dist/{google-vertex-CvdzF1U7.mjs → google-vertex-B4SD3U0f.mjs} +3 -3
- package/dist/host-WvWBo4h8.d.mts +173 -0
- package/dist/host-XYGZcgO8.mjs +98 -0
- package/dist/index-BVVgDSdq.d.mts +1 -0
- package/dist/index.d.mts +7 -50
- package/dist/index.mjs +1 -1
- package/dist/internal/anthropic.d.mts +2 -2
- package/dist/internal/anthropic.mjs +2 -2
- package/dist/internal/openai.d.mts +2 -280
- package/dist/internal/openai.mjs +5 -5
- package/dist/internal/runtime.d.mts +8 -5
- package/dist/internal/runtime.mjs +19 -10
- package/dist/internal/shared.d.mts +1 -1
- package/dist/internal/shared.mjs +1 -1
- package/dist/{mistral-BdrQmDWp.mjs → mistral-D5Ps7Led.mjs} +4 -4
- package/dist/openai-CoGicoDt.d.mts +332 -0
- package/dist/{openai-chatgpt-responses-DP63Qt01.mjs → openai-chatgpt-responses-h0o5yV8Y.mjs} +40 -43
- package/dist/{openai-completions-zLDfebnN.mjs → openai-completions-exO8NFQf.mjs} +316 -100
- package/dist/{openai-responses-ClspWt4I.mjs → openai-responses-BHpmtUKo.mjs} +5 -5
- package/dist/{openai-responses-shared-CwnGU0KW.mjs → openai-responses-shared-CzCurmY1.mjs} +230 -71
- package/dist/{openai-tool-projection-WHf2nuOI.mjs → openai-tool-projection-ITOU9bG1.mjs} +1 -1
- package/dist/{provider-error-LMfTEkfO.mjs → provider-error-C4VvV_3t.mjs} +2 -1
- package/dist/providers.d.mts +1 -1
- package/dist/providers.mjs +8 -8
- package/dist/{stream-first-event-timeout-RjWszj8c.mjs → stream-first-event-timeout-DP4xEyBY.mjs} +45 -1
- package/dist/{transform-messages-eb6lxDLB.mjs → system-prompt-cache-boundary-CbHeV4_l.mjs} +164 -160
- package/dist/transports.d.mts +590 -0
- package/dist/transports.mjs +5701 -0
- package/dist/{types-CYORveZ7.d.mts → types-AFwwWium.d.mts} +1 -0
- package/dist/types.d.mts +4 -4
- package/dist/{validation-BX8euiDv.d.mts → validation-sxvxC8J-.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/npm-shrinkwrap.json +43 -50
- package/package.json +36 -10
- package/dist/host-4t713IeR.mjs +0 -37
- /package/dist/{index-BoTnz8cv.d.mts → anthropic-BoTnz8cv.d.mts} +0 -0
|
@@ -1,17 +1,299 @@
|
|
|
1
|
-
import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-
|
|
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-
|
|
3
|
+
import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
|
|
4
|
+
import { C as isImageWithMediaPayload, D as buildBaseOptions, a as stripSystemPromptCacheBoundary, c as transformMessages, g as normalizeLowercaseStringOrEmpty, i as splitSystemPromptCacheBoundary, x as extractToolResultText, y as describeToolResultMediaPlaceholder } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
|
|
5
|
+
import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
|
|
4
6
|
import { n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "./model-utils-1GiZ2_rr.mjs";
|
|
5
7
|
import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
|
|
6
8
|
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
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
10
|
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-
|
|
13
|
-
import {
|
|
11
|
+
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DP4xEyBY.mjs";
|
|
12
|
+
import { t as formatProviderError } from "./provider-error-C4VvV_3t.mjs";
|
|
13
|
+
import { a as clampOpenAIPromptCacheKey, n as reconcileOpenAICompletionsToolChoice, t as projectOpenAITools } from "./openai-tool-projection-ITOU9bG1.mjs";
|
|
14
14
|
import OpenAI from "openai";
|
|
15
|
+
//#region packages/ai/src/utils/assistant-text-phase.ts
|
|
16
|
+
function isAssistantTextPhaseBlock(block) {
|
|
17
|
+
if (!block || typeof block !== "object") return false;
|
|
18
|
+
const record = block;
|
|
19
|
+
return record.type === "text" && typeof record.text === "string";
|
|
20
|
+
}
|
|
21
|
+
function encodeAssistantTextSignatureV1(id, phase) {
|
|
22
|
+
return JSON.stringify({
|
|
23
|
+
v: 1,
|
|
24
|
+
id,
|
|
25
|
+
...phase ? { phase } : {}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Tags unphased narration before a tool-call event becomes consumer-visible. */
|
|
29
|
+
function tagPendingCommentaryText(content) {
|
|
30
|
+
const textBlocks = content.filter(isAssistantTextPhaseBlock);
|
|
31
|
+
let commentaryIndex = textBlocks.filter((block) => block.textSignature !== void 0).length;
|
|
32
|
+
const tagged = /* @__PURE__ */ new Map();
|
|
33
|
+
for (const block of textBlocks) {
|
|
34
|
+
if (block.text.trim().length === 0 || block.textSignature !== void 0) continue;
|
|
35
|
+
const signature = encodeAssistantTextSignatureV1(`commentary-${commentaryIndex}`, "commentary");
|
|
36
|
+
block.textSignature = signature;
|
|
37
|
+
tagged.set(block, signature);
|
|
38
|
+
commentaryIndex += 1;
|
|
39
|
+
}
|
|
40
|
+
return tagged;
|
|
41
|
+
}
|
|
42
|
+
/** Rolls back only the exact provisional signatures created by this transport turn. */
|
|
43
|
+
function clearPendingCommentaryText(tags) {
|
|
44
|
+
for (const [block, signature] of tags) if (block.textSignature === signature) delete block.textSignature;
|
|
45
|
+
tags.clear();
|
|
46
|
+
}
|
|
47
|
+
function rememberPendingCommentaryTags(target, tagged) {
|
|
48
|
+
for (const [block, signature] of tagged) target.set(block, signature);
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region packages/ai/src/transports/openai-reasoning-compat.ts
|
|
52
|
+
/**
|
|
53
|
+
* OpenAI reasoning-effort compatibility helpers.
|
|
54
|
+
*
|
|
55
|
+
* Keeps provider metadata and built-in model exceptions on one path before request payloads are built.
|
|
56
|
+
*/
|
|
57
|
+
const OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.1-codex-mini"]);
|
|
58
|
+
function readCompatReasoningEffortMap(compat) {
|
|
59
|
+
if (!compat || typeof compat !== "object") return {};
|
|
60
|
+
const rawMap = compat.reasoningEffortMap;
|
|
61
|
+
if (!rawMap || typeof rawMap !== "object") return {};
|
|
62
|
+
return Object.fromEntries(Object.entries(rawMap).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
|
|
63
|
+
}
|
|
64
|
+
/** Resolves the reasoning effort remap for an OpenAI-compatible model. */
|
|
65
|
+
function resolveOpenAIReasoningEffortMap(model, fallbackMap = {}) {
|
|
66
|
+
const provider = normalizeLowercaseStringOrEmpty(model.provider ?? "");
|
|
67
|
+
const id = normalizeLowercaseStringOrEmpty(model.id ?? "");
|
|
68
|
+
const builtinMap = provider === "openai" && OPENAI_MEDIUM_ONLY_REASONING_MODEL_IDS.has(id) ? {
|
|
69
|
+
minimal: "medium",
|
|
70
|
+
low: "medium"
|
|
71
|
+
} : {};
|
|
72
|
+
return {
|
|
73
|
+
...fallbackMap,
|
|
74
|
+
...builtinMap,
|
|
75
|
+
...readCompatReasoningEffortMap(model.compat)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region packages/ai/src/providers/openai-completions-compat.ts
|
|
80
|
+
const DEFAULT_OPENAI_COMPLETIONS_COMPAT = {
|
|
81
|
+
supportsStore: true,
|
|
82
|
+
supportsDeveloperRole: true,
|
|
83
|
+
supportsReasoningEffort: true,
|
|
84
|
+
supportsUsageInStreaming: true,
|
|
85
|
+
maxTokensField: "max_completion_tokens",
|
|
86
|
+
requiresToolResultName: false,
|
|
87
|
+
requiresAssistantAfterToolResult: false,
|
|
88
|
+
requiresThinkingAsText: false,
|
|
89
|
+
requiresReasoningContentOnAssistantMessages: false,
|
|
90
|
+
thinkingFormat: "openai",
|
|
91
|
+
vercelGatewayRouting: {},
|
|
92
|
+
zaiToolStream: false,
|
|
93
|
+
supportsStrictMode: true,
|
|
94
|
+
cacheControlFormat: void 0,
|
|
95
|
+
sessionAffinityFormat: "openai",
|
|
96
|
+
supportsPromptCacheKey: false,
|
|
97
|
+
supportsLongCacheRetention: true
|
|
98
|
+
};
|
|
99
|
+
const OPENAI_COMPLETIONS_COMPAT_MATRIX = {
|
|
100
|
+
openrouter: {
|
|
101
|
+
priority: 10,
|
|
102
|
+
providers: ["openrouter"],
|
|
103
|
+
baseUrlIncludes: ["openrouter.ai"],
|
|
104
|
+
compat: {
|
|
105
|
+
supportsDeveloperRole: false,
|
|
106
|
+
thinkingFormat: "openrouter",
|
|
107
|
+
sessionAffinityFormat: "openrouter"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
cerebras: {
|
|
111
|
+
priority: 20,
|
|
112
|
+
providers: ["cerebras"],
|
|
113
|
+
baseUrlIncludes: ["cerebras.ai"],
|
|
114
|
+
compat: {
|
|
115
|
+
supportsStore: false,
|
|
116
|
+
supportsDeveloperRole: false
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
xai: {
|
|
120
|
+
priority: 20,
|
|
121
|
+
providers: ["xai"],
|
|
122
|
+
baseUrlIncludes: ["api.x.ai"],
|
|
123
|
+
compat: {
|
|
124
|
+
supportsStore: false,
|
|
125
|
+
supportsDeveloperRole: false,
|
|
126
|
+
supportsReasoningEffort: false
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
moonshot: {
|
|
130
|
+
priority: 20,
|
|
131
|
+
providers: ["moonshotai", "moonshotai-cn"],
|
|
132
|
+
baseUrlIncludes: ["api.moonshot."],
|
|
133
|
+
compat: {
|
|
134
|
+
supportsStore: false,
|
|
135
|
+
supportsDeveloperRole: false,
|
|
136
|
+
supportsReasoningEffort: false,
|
|
137
|
+
maxTokensField: "max_tokens",
|
|
138
|
+
supportsStrictMode: false
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
cloudflareWorkersAi: {
|
|
142
|
+
priority: 20,
|
|
143
|
+
providers: ["cloudflare-workers-ai"],
|
|
144
|
+
baseUrlIncludes: ["api.cloudflare.com"],
|
|
145
|
+
compat: {
|
|
146
|
+
supportsStore: false,
|
|
147
|
+
supportsDeveloperRole: false,
|
|
148
|
+
supportsLongCacheRetention: false
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
cloudflareAiGateway: {
|
|
152
|
+
priority: 20,
|
|
153
|
+
providers: ["cloudflare-ai-gateway"],
|
|
154
|
+
baseUrlIncludes: ["gateway.ai.cloudflare.com"],
|
|
155
|
+
compat: {
|
|
156
|
+
supportsStore: false,
|
|
157
|
+
supportsDeveloperRole: false,
|
|
158
|
+
supportsReasoningEffort: false,
|
|
159
|
+
maxTokensField: "max_tokens",
|
|
160
|
+
supportsStrictMode: false,
|
|
161
|
+
supportsLongCacheRetention: false
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
opencode: {
|
|
165
|
+
priority: 20,
|
|
166
|
+
providers: ["opencode"],
|
|
167
|
+
baseUrlIncludes: ["opencode.ai"],
|
|
168
|
+
compat: {
|
|
169
|
+
supportsStore: false,
|
|
170
|
+
supportsDeveloperRole: false
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
chutes: {
|
|
174
|
+
priority: 20,
|
|
175
|
+
baseUrlIncludes: ["chutes.ai"],
|
|
176
|
+
compat: {
|
|
177
|
+
supportsStore: false,
|
|
178
|
+
supportsDeveloperRole: false,
|
|
179
|
+
maxTokensField: "max_tokens"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
together: {
|
|
183
|
+
priority: 30,
|
|
184
|
+
providers: ["together"],
|
|
185
|
+
baseUrlIncludes: ["api.together.ai", "api.together.xyz"],
|
|
186
|
+
compat: {
|
|
187
|
+
supportsStore: false,
|
|
188
|
+
supportsDeveloperRole: false,
|
|
189
|
+
supportsReasoningEffort: false,
|
|
190
|
+
maxTokensField: "max_tokens",
|
|
191
|
+
thinkingFormat: "together",
|
|
192
|
+
supportsStrictMode: false,
|
|
193
|
+
supportsLongCacheRetention: false
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
zai: {
|
|
197
|
+
priority: 40,
|
|
198
|
+
providers: ["zai"],
|
|
199
|
+
baseUrlIncludes: ["api.z.ai"],
|
|
200
|
+
compat: {
|
|
201
|
+
supportsStore: false,
|
|
202
|
+
supportsDeveloperRole: false,
|
|
203
|
+
supportsReasoningEffort: false,
|
|
204
|
+
maxTokensField: "max_tokens",
|
|
205
|
+
thinkingFormat: "zai"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
xiaomi: {
|
|
209
|
+
priority: 50,
|
|
210
|
+
providers: ["xiaomi"],
|
|
211
|
+
baseUrlIncludes: ["xiaomimimo.com"],
|
|
212
|
+
compat: {
|
|
213
|
+
thinkingFormat: "deepseek",
|
|
214
|
+
requiresReasoningContentOnAssistantMessages: true
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
deepseekProvider: {
|
|
218
|
+
priority: 60,
|
|
219
|
+
providers: ["deepseek"],
|
|
220
|
+
compat: {
|
|
221
|
+
thinkingFormat: "deepseek",
|
|
222
|
+
requiresReasoningContentOnAssistantMessages: true
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
deepseekEndpoint: {
|
|
226
|
+
priority: 60,
|
|
227
|
+
baseUrlIncludes: ["deepseek.com"],
|
|
228
|
+
compat: {
|
|
229
|
+
supportsStore: false,
|
|
230
|
+
supportsDeveloperRole: false,
|
|
231
|
+
thinkingFormat: "deepseek",
|
|
232
|
+
requiresReasoningContentOnAssistantMessages: true
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
const OPENAI_COMPLETIONS_MODEL_COMPAT_MATRIX = [{
|
|
237
|
+
profile: "openrouter",
|
|
238
|
+
modelIdPrefixes: ["anthropic/", "openai/"],
|
|
239
|
+
compat: { supportsDeveloperRole: true }
|
|
240
|
+
}, {
|
|
241
|
+
providers: ["openrouter"],
|
|
242
|
+
modelIdPrefixes: ["anthropic/"],
|
|
243
|
+
compat: { cacheControlFormat: "anthropic" }
|
|
244
|
+
}];
|
|
245
|
+
const SORTED_OPENAI_COMPLETIONS_COMPAT_RULES = Object.entries(OPENAI_COMPLETIONS_COMPAT_MATRIX).toSorted(([, left], [, right]) => left.priority - right.priority);
|
|
246
|
+
function matchesCompatRule(model, rule) {
|
|
247
|
+
return rule.providers?.includes(model.provider) === true || rule.baseUrlIncludes?.some((fragment) => model.baseUrl.includes(fragment)) === true;
|
|
248
|
+
}
|
|
249
|
+
function matchesModelCompatRule(model, matchedProfiles, rule) {
|
|
250
|
+
if (rule.profile !== void 0 && !matchedProfiles.has(rule.profile)) return false;
|
|
251
|
+
if (rule.providers !== void 0 && !rule.providers.includes(model.provider)) return false;
|
|
252
|
+
return rule.modelIdPrefixes.some((prefix) => model.id.startsWith(prefix));
|
|
253
|
+
}
|
|
254
|
+
/** Detects request compatibility from the provider, endpoint, and model family matrices. */
|
|
255
|
+
function detectOpenAICompletionsCompat(model) {
|
|
256
|
+
const compat = { ...DEFAULT_OPENAI_COMPLETIONS_COMPAT };
|
|
257
|
+
const matchedProfiles = /* @__PURE__ */ new Set();
|
|
258
|
+
for (const [profile, rule] of SORTED_OPENAI_COMPLETIONS_COMPAT_RULES) {
|
|
259
|
+
if (!matchesCompatRule(model, rule)) continue;
|
|
260
|
+
Object.assign(compat, rule.compat);
|
|
261
|
+
matchedProfiles.add(profile);
|
|
262
|
+
}
|
|
263
|
+
for (const rule of OPENAI_COMPLETIONS_MODEL_COMPAT_MATRIX) if (matchesModelCompatRule(model, matchedProfiles, rule)) Object.assign(compat, rule.compat);
|
|
264
|
+
return compat;
|
|
265
|
+
}
|
|
266
|
+
function resolveSessionAffinity(model, detectedFormat) {
|
|
267
|
+
if (model.compat?.sendSessionAffinityHeaders !== true) return "none";
|
|
268
|
+
if (detectedFormat === "openrouter" || model.compat.thinkingFormat === "openrouter" || model.compat.openRouterRouting !== void 0) return "openrouter";
|
|
269
|
+
return "openai";
|
|
270
|
+
}
|
|
271
|
+
/** Applies explicit model overrides to the detected compatibility defaults. */
|
|
272
|
+
function resolveOpenAICompletionsCompat(model) {
|
|
273
|
+
const detected = detectOpenAICompletionsCompat(model);
|
|
274
|
+
const configured = model.compat;
|
|
275
|
+
return {
|
|
276
|
+
supportsStore: configured?.supportsStore ?? detected.supportsStore,
|
|
277
|
+
supportsDeveloperRole: configured?.supportsDeveloperRole ?? detected.supportsDeveloperRole,
|
|
278
|
+
supportsReasoningEffort: configured?.supportsReasoningEffort ?? detected.supportsReasoningEffort,
|
|
279
|
+
supportsUsageInStreaming: configured?.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
|
|
280
|
+
maxTokensField: configured?.maxTokensField ?? detected.maxTokensField,
|
|
281
|
+
requiresToolResultName: configured?.requiresToolResultName ?? detected.requiresToolResultName,
|
|
282
|
+
requiresAssistantAfterToolResult: configured?.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
|
|
283
|
+
requiresThinkingAsText: configured?.requiresThinkingAsText ?? detected.requiresThinkingAsText,
|
|
284
|
+
requiresReasoningContentOnAssistantMessages: configured?.requiresReasoningContentOnAssistantMessages ?? detected.requiresReasoningContentOnAssistantMessages,
|
|
285
|
+
thinkingFormat: configured?.thinkingFormat ?? detected.thinkingFormat,
|
|
286
|
+
openRouterRouting: configured?.openRouterRouting,
|
|
287
|
+
vercelGatewayRouting: configured?.vercelGatewayRouting ?? detected.vercelGatewayRouting,
|
|
288
|
+
zaiToolStream: configured?.zaiToolStream ?? detected.zaiToolStream,
|
|
289
|
+
supportsStrictMode: configured?.supportsStrictMode ?? detected.supportsStrictMode,
|
|
290
|
+
cacheControlFormat: configured?.cacheControlFormat ?? detected.cacheControlFormat,
|
|
291
|
+
sessionAffinity: resolveSessionAffinity(model, detected.sessionAffinityFormat),
|
|
292
|
+
supportsPromptCacheKey: configured?.supportsPromptCacheKey ?? detected.supportsPromptCacheKey,
|
|
293
|
+
supportsLongCacheRetention: configured?.supportsLongCacheRetention ?? detected.supportsLongCacheRetention
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
//#endregion
|
|
15
297
|
//#region packages/ai/src/providers/openai-stop-reason.ts
|
|
16
298
|
function mapOpenAIStopReason(reason, options) {
|
|
17
299
|
if (reason === null) return { stopReason: "stop" };
|
|
@@ -104,10 +386,11 @@ const streamOpenAICompletions = (model, context, options) => {
|
|
|
104
386
|
stopReason: "stop",
|
|
105
387
|
timestamp: Date.now()
|
|
106
388
|
};
|
|
389
|
+
const provisionalCommentaryTags = /* @__PURE__ */ new Map();
|
|
107
390
|
let firstEventAbort;
|
|
108
391
|
try {
|
|
109
392
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
110
|
-
const compat =
|
|
393
|
+
const compat = resolveOpenAICompletionsCompat(model);
|
|
111
394
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention);
|
|
112
395
|
const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
|
|
113
396
|
const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
|
|
@@ -328,9 +611,10 @@ const streamOpenAICompletions = (model, context, options) => {
|
|
|
328
611
|
if (choiceDelta.content !== null && choiceDelta.content !== void 0 && choiceDelta.content.length > 0) appendPartitionedContent(choiceDelta.content, Boolean(foundReasoningField));
|
|
329
612
|
const refusalText = typeof choiceDelta.refusal === "string" ? choiceDelta.refusal : "";
|
|
330
613
|
if (refusalText.length > 0) appendPartitionedContent(refusalText, Boolean(foundReasoningField));
|
|
331
|
-
if (choiceDelta.tool_calls) {
|
|
614
|
+
if (choiceDelta.tool_calls && choiceDelta.tool_calls.length > 0) {
|
|
332
615
|
flushPartitionedContent();
|
|
333
616
|
sealNativeReasoningBeforeText();
|
|
617
|
+
rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
|
|
334
618
|
for (const toolCall of choiceDelta.tool_calls) {
|
|
335
619
|
const block = ensureToolCallBlock(toolCall);
|
|
336
620
|
if (!block.id && toolCall.id) {
|
|
@@ -375,6 +659,8 @@ const streamOpenAICompletions = (model, context, options) => {
|
|
|
375
659
|
if (output.stopReason === "toolUse" && !hasToolCalls) output.stopReason = "stop";
|
|
376
660
|
if (output.stopReason === "stop" && hasToolCalls && !hasVisibleText) output.stopReason = "toolUse";
|
|
377
661
|
if (hasToolCalls && output.stopReason !== "toolUse") output.content = output.content.filter((block) => block.type !== "toolCall");
|
|
662
|
+
if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
|
|
663
|
+
if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
|
|
378
664
|
stream.push({
|
|
379
665
|
type: "done",
|
|
380
666
|
reason: output.stopReason,
|
|
@@ -416,7 +702,7 @@ const streamSimpleOpenAICompletions = (model, context, options) => {
|
|
|
416
702
|
toolChoice
|
|
417
703
|
});
|
|
418
704
|
};
|
|
419
|
-
function createClient(model, context, apiKey, optionsHeaders, sessionId, compat =
|
|
705
|
+
function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = resolveOpenAICompletionsCompat(model)) {
|
|
420
706
|
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
421
707
|
const headers = { ...model.headers };
|
|
422
708
|
if (model.provider === "github-copilot") {
|
|
@@ -427,7 +713,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
|
|
|
427
713
|
});
|
|
428
714
|
Object.assign(headers, copilotHeaders);
|
|
429
715
|
}
|
|
430
|
-
if (sessionId && compat.
|
|
716
|
+
if (sessionId && compat.sessionAffinity !== "none") if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
|
|
431
717
|
else {
|
|
432
718
|
headers.session_id = sessionId;
|
|
433
719
|
headers["x-client-request-id"] = sessionId;
|
|
@@ -447,7 +733,7 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
|
|
|
447
733
|
fetch: getAiTransportHost().buildModelFetch(model)
|
|
448
734
|
});
|
|
449
735
|
}
|
|
450
|
-
function buildParams(model, context, options, compat =
|
|
736
|
+
function buildParams(model, context, options, compat = resolveOpenAICompletionsCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
|
|
451
737
|
const cacheControl = getCompatCacheControl(compat, cacheRetention);
|
|
452
738
|
const cacheOptOutIndexes = /* @__PURE__ */ new Set();
|
|
453
739
|
const messages = convertMessages(model, context, compat, {
|
|
@@ -485,32 +771,35 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
|
|
|
485
771
|
const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
|
|
486
772
|
if (toolChoice !== void 0) params.tool_choice = toolChoice;
|
|
487
773
|
}
|
|
488
|
-
|
|
774
|
+
const reasoningEffortMap = resolveOpenAIReasoningEffortMap(model);
|
|
775
|
+
const reasoningEffort = options?.reasoningEffort === void 0 ? void 0 : reasoningEffortMap[options.reasoningEffort] ?? model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
|
|
776
|
+
const reasoningEnabled = reasoningEffort !== void 0;
|
|
777
|
+
const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
|
|
778
|
+
if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
|
|
489
779
|
type: "enabled",
|
|
490
780
|
clear_thinking: false
|
|
491
781
|
} : { type: "disabled" };
|
|
492
|
-
else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking =
|
|
782
|
+
else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = reasoningEnabled;
|
|
493
783
|
else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = {
|
|
494
|
-
enable_thinking:
|
|
784
|
+
enable_thinking: reasoningEnabled,
|
|
495
785
|
preserve_thinking: true
|
|
496
786
|
};
|
|
497
787
|
else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
|
|
498
|
-
params.thinking = { type:
|
|
499
|
-
if (
|
|
788
|
+
params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
|
|
789
|
+
if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
|
|
500
790
|
} else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
|
|
501
791
|
const openRouterParams = params;
|
|
502
|
-
if (
|
|
503
|
-
else if (
|
|
792
|
+
if (reasoningEnabled) openRouterParams.reasoning = { effort: reasoningEffort };
|
|
793
|
+
else if (offReasoningEffort !== null) openRouterParams.reasoning = { effort: offReasoningEffort ?? "none" };
|
|
504
794
|
} else if (compat.thinkingFormat === "together" && model.reasoning) {
|
|
505
795
|
const togetherParams = params;
|
|
506
|
-
togetherParams.reasoning = { enabled:
|
|
507
|
-
if (
|
|
508
|
-
} else if (
|
|
509
|
-
else if (
|
|
510
|
-
|
|
511
|
-
if (typeof offValue === "string") params.reasoning_effort = offValue;
|
|
796
|
+
togetherParams.reasoning = { enabled: reasoningEnabled };
|
|
797
|
+
if (reasoningEnabled && compat.supportsReasoningEffort) togetherParams.reasoning_effort = reasoningEffort;
|
|
798
|
+
} else if (reasoningEnabled && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
|
|
799
|
+
else if (model.reasoning && compat.supportsReasoningEffort) {
|
|
800
|
+
if (typeof offReasoningEffort === "string") params.reasoning_effort = offReasoningEffort;
|
|
512
801
|
}
|
|
513
|
-
if (
|
|
802
|
+
if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
|
|
514
803
|
if (model.baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
|
|
515
804
|
const routing = model.compat.vercelGatewayRouting;
|
|
516
805
|
if (routing.only || routing.order) {
|
|
@@ -791,78 +1080,5 @@ function parseChunkUsage(rawUsage, model) {
|
|
|
791
1080
|
applyProviderReportedUsageCost(usage, rawUsage.cost);
|
|
792
1081
|
return usage;
|
|
793
1082
|
}
|
|
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
1083
|
//#endregion
|
|
868
|
-
export { mapOpenAIStopReason as a, streamSimpleOpenAICompletions as i, openai_completions_exports as n, streamOpenAICompletions as r, convertMessages as t };
|
|
1084
|
+
export { mapOpenAIStopReason as a, rememberPendingCommentaryTags as c, streamSimpleOpenAICompletions as i, tagPendingCommentaryText as l, openai_completions_exports as n, resolveOpenAIReasoningEffortMap as o, streamOpenAICompletions as r, clearPendingCommentaryText as s, convertMessages as t };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { n as getEnvApiKey, r as __exportAll } from "./env-api-keys-
|
|
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-
|
|
4
|
-
import {
|
|
3
|
+
import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
|
|
4
|
+
import { D as buildBaseOptions } from "./system-prompt-cache-boundary-CbHeV4_l.mjs";
|
|
5
5
|
import { a as resolveCacheRetention, i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-BsH5cqGj.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-
|
|
6
|
+
import { L as supportsOpenAITemperature, a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-CzCurmY1.mjs";
|
|
7
|
+
import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-ITOU9bG1.mjs";
|
|
8
8
|
import OpenAI from "openai";
|
|
9
9
|
//#region packages/ai/src/providers/openai-responses.ts
|
|
10
10
|
var openai_responses_exports = /* @__PURE__ */ __exportAll({
|