@openclaw/ai 2026.9.2 → 2026.9.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 +3 -2
- package/dist/anthropic-C4Qu4H0Z.mjs +377 -0
- package/dist/{anthropic-payload-policy-d46X2pR0.d.mts → anthropic-payload-policy-BZ8umAbk.d.mts} +16 -6
- package/dist/{anthropic-compaction-replay-DB2FGLQc.mjs → anthropic-stream-reducer-CILWF7JD.mjs} +931 -184
- package/dist/{api-registry-DWtPjzyn.d.mts → api-registry-ByUwIR0e.d.mts} +2 -2
- package/dist/assistant-output-tLt4H-iQ.mjs +16 -0
- package/dist/assistant-text-phase-C20rxWwP.mjs +55 -0
- package/dist/{azure-openai-responses-C5bZRfAP.mjs → azure-openai-responses-BAlqlKKc.mjs} +5 -5
- package/dist/{base64-CEFBpSkN.mjs → base64-D-su8YVo.mjs} +1 -27
- package/dist/{diagnostics-DfFyKeX_.mjs → diagnostics-QuErwCIl.mjs} +96 -21
- package/dist/diagnostics.d.mts +3 -1
- package/dist/diagnostics.mjs +3 -3
- package/dist/{event-stream-BhT5T1Ay.d.mts → event-stream-Bt5Y4Pav.d.mts} +11 -3
- package/dist/event-stream-C3WGFsum.d.mts +1 -0
- package/dist/{event-stream-BgDvQeum.mjs → event-stream-D8PARQfL.mjs} +45 -1
- package/dist/event-stream.d.mts +2 -2
- package/dist/event-stream.mjs +1 -1
- package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-B37TB3rB.mjs} +3 -10
- package/dist/github-copilot-request-facts-BTEBMeOv.mjs +16 -0
- package/dist/{google-4qeuE8iX.mjs → google-DPBAOaOW.mjs} +10 -10
- package/dist/google-messages-6JkpHrhJ.mjs +448 -0
- package/dist/google-shared-BvBeW9aq.mjs +185 -0
- package/dist/{google-vertex-O9BcnB6X.mjs → google-vertex-k-TMCAYD.mjs} +7 -6
- package/dist/{host-DjzGmdZ2.d.mts → host-4atIX-2V.d.mts} +5 -3
- package/dist/{host-CEvLw30U.mjs → host-B8YfDGd4.mjs} +181 -41
- package/dist/host-policy-Zcg_cNz8.mjs +37 -0
- package/dist/{index-FnHM2FcI.d.mts → index-DdD3qerf.d.mts} +4 -4
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +7 -6
- package/dist/internal/anthropic.d.mts +7 -7
- package/dist/internal/anthropic.mjs +4 -4
- package/dist/internal/google-model-family.d.mts +5 -0
- package/dist/internal/google-model-family.mjs +15 -0
- package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
- package/dist/internal/openai-responses-payload-policy.mjs +3 -2
- package/dist/internal/openai.d.mts +8 -103
- package/dist/internal/openai.mjs +9 -10
- package/dist/internal/retry-after.d.mts +2 -4
- package/dist/internal/retry-after.mjs +57 -8
- package/dist/internal/runtime.d.mts +43 -7
- package/dist/internal/runtime.mjs +6 -7
- package/dist/internal/shared.d.mts +43 -3
- package/dist/internal/shared.mjs +5 -4
- package/dist/internal/tool-schema.d.mts +63 -0
- package/dist/internal/tool-schema.mjs +3 -0
- package/dist/{mistral-Tb6oalqH.mjs → mistral-CxUZ1jUb.mjs} +10 -37
- package/dist/model-transport-url-DKocrEsb.d.mts +28 -0
- package/dist/{openai-chatgpt-responses-yUXjPNfu.mjs → openai-chatgpt-responses-CgO6kZfo.mjs} +50 -41
- package/dist/{openai-completions-compat-CpjYUArk.d.mts → openai-completions-compat-eHgh5UPE.d.mts} +26 -4
- package/dist/{openai-completions-stream-BsrBe3Gg.mjs → openai-completions-stream-Da2vvl-S.mjs} +654 -453
- package/dist/openai-completions-yJuk7eis.mjs +187 -0
- package/dist/openai-prompt-cache-B4eYo2-I.d.mts +16 -0
- package/dist/openai-prompt-cache-Bds-n_9Q.mjs +220 -0
- package/dist/openai-provider-client-S2gCrM2Z.mjs +24 -0
- package/dist/{openai-responses-CCL41ALM.mjs → openai-responses-DaYwH05E.mjs} +14 -29
- package/dist/{openai-responses-compaction-window-BMVHFOtq.mjs → openai-responses-compaction-window-CIhBAkkq.mjs} +6 -246
- package/dist/{openai-responses-contracts-rF5DDRNS.d.mts → openai-responses-contracts-BjBAqAg_.d.mts} +5 -38
- package/dist/openai-responses-contracts-DDOHA62Y.mjs +245 -0
- package/dist/{openai-responses-prompt-observer-internal-D0bhBfgL.mjs → openai-responses-prompt-observer-internal-f8J7wpsk.mjs} +3 -3
- package/dist/{openai-responses-shared-Bmma_3Qc.mjs → openai-responses-shared-B8RdBPCv.mjs} +47 -118
- package/dist/openai-tool-projection-793cE3QX.d.mts +37 -0
- package/dist/{openai-tool-schema-_pTAJqKF.mjs → openai-tool-schema-CzjyYXun.mjs} +38 -556
- package/dist/openai-tool-schema-ynZBgqW-.d.mts +38 -0
- package/dist/openai-transport-params-9aPuV5YY.mjs +675 -0
- package/dist/positive-integer-41zhOdcV.mjs +8 -0
- package/dist/{provider-error-9TraxGvt.mjs → provider-error-BA-v_tKd.mjs} +70 -11
- package/dist/{provider-options-Bcc_p-TU.d.mts → provider-options-Ceqv1OKk.d.mts} +4 -39
- package/dist/{provider-replay-context-BuSUaAk5.mjs → provider-replay-context-CJ_YvcEW.mjs} +1 -1
- package/dist/{provider-transcript-transform-BaMbI1hr.mjs → provider-transcript-transform-V5YzU9zh.mjs} +1 -1
- package/dist/provider-transport-turn-state-D5EXOFL2.mjs +42 -0
- package/dist/provider-types-CVjKjsuq.d.mts +29 -0
- package/dist/provider-types.d.mts +6 -31
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +11 -11
- package/dist/{reasoning-tag-text-partitioner-DLCNXki6.mjs → reasoning-tag-text-partitioner-BcR5pztD.mjs} +19 -19
- package/dist/record-coerce-DwRYMj3t.mjs +32 -0
- package/dist/retry-after-CdCURCVg.d.mts +15 -0
- package/dist/session-affinity-Bcunsn4I.mjs +23 -0
- package/dist/{simple-options-BjHCCh4v.mjs → simple-options-BQbb4yQL.mjs} +24 -5
- package/dist/src-DDmEryvj.mjs +2 -0
- package/dist/{stream-first-event-timeout-DcNjoFQE.mjs → stream-first-event-timeout-2hfrquuz.mjs} +1 -1
- package/dist/string-coerce-fsri9iCu.mjs +34 -0
- package/dist/{string-normalization--fwJ4S2q.mjs → string-normalization-CmLIasuf.mjs} +1 -1
- package/dist/{tool-schema-json-projection-mJhXDcyz.mjs → tool-schema-json-projection-ClptDdAO.mjs} +2 -38
- package/dist/{transport-stream-shared-xnaqxmbP.d.mts → transport-stream-shared-DNvmoWnv.d.mts} +20 -36
- package/dist/{transport-stream-shared-CZqMhfIw.mjs → transport-stream-shared-zHll9BxO.mjs} +225 -13
- package/dist/transport-utils-zrYjICLZ.mjs +118 -0
- package/dist/transports.d.mts +137 -193
- package/dist/transports.mjs +204 -1334
- package/dist/types-DlfwzH3T.d.mts +1 -0
- package/dist/types-LFWwv0cF.mjs +8 -0
- package/dist/{types-CJ1-Ht7A.d.mts → types-Ntv5z2g2.d.mts} +74 -57
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +6 -5
- package/dist/{src-2qBGKg8O.mjs → usage-cost-BNWbbXav.mjs} +0 -1
- package/dist/utf16-slice-CvGodqok.mjs +29 -0
- package/dist/{validation-AKZBDGQd.d.mts → validation-B0t_G2H6.d.mts} +1 -1
- package/dist/{validation-CJZtym2g.mjs → validation-BDzVDnTs.mjs} +9 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +13 -3
- package/dist/anthropic-BDdqdVLK.mjs +0 -886
- package/dist/event-stream-zctLx0yr.d.mts +0 -1
- package/dist/google-shared-CWeG8RIl.mjs +0 -636
- package/dist/google-thinking-level-C-V3tecN.mjs +0 -9
- package/dist/hash-CHgqbJmD.mjs +0 -16
- package/dist/json-parse-BuAJEbdW.mjs +0 -146
- package/dist/openai-completions-BIUV3RDT.mjs +0 -403
- package/dist/openai-prompt-cache-CGnVB74a.mjs +0 -21
- package/dist/openai-prompt-cache-CNoIfHYC.d.mts +0 -16
- package/dist/sanitize-unicode-D6xUvZaS.mjs +0 -83
- package/dist/transport-utils-7il795_9.mjs +0 -138
- package/dist/types-3Lnm-QSJ.d.mts +0 -1
- package/dist/types-BDdaOVi2.mjs +0 -6
- package/dist/utf16-slice-qz3nsy87.mjs +0 -84
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { n as asNonArrayRecord } from "./utf16-slice-qz3nsy87.mjs";
|
|
2
|
-
import { parse } from "partial-json";
|
|
3
|
-
//#region packages/ai/src/utils/json-parse.ts
|
|
4
|
-
const VALID_JSON_ESCAPES = /* @__PURE__ */ new Set([
|
|
5
|
-
"\"",
|
|
6
|
-
"\\",
|
|
7
|
-
"/",
|
|
8
|
-
"b",
|
|
9
|
-
"f",
|
|
10
|
-
"n",
|
|
11
|
-
"r",
|
|
12
|
-
"t",
|
|
13
|
-
"u"
|
|
14
|
-
]);
|
|
15
|
-
const JSON_CONTROL_ESCAPES = /* @__PURE__ */ new Set([
|
|
16
|
-
"b",
|
|
17
|
-
"f",
|
|
18
|
-
"n",
|
|
19
|
-
"r",
|
|
20
|
-
"t"
|
|
21
|
-
]);
|
|
22
|
-
function isControlCharacter(char) {
|
|
23
|
-
const codePoint = char.codePointAt(0);
|
|
24
|
-
return codePoint !== void 0 && codePoint >= 0 && codePoint <= 31;
|
|
25
|
-
}
|
|
26
|
-
function escapeControlCharacter(char) {
|
|
27
|
-
switch (char) {
|
|
28
|
-
case "\b": return "\\b";
|
|
29
|
-
case "\f": return "\\f";
|
|
30
|
-
case "\n": return "\\n";
|
|
31
|
-
case "\r": return "\\r";
|
|
32
|
-
case " ": return "\\t";
|
|
33
|
-
default: return `\\u${char.codePointAt(0)?.toString(16).padStart(4, "0") ?? "0000"}`;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Repairs malformed JSON string literals by:
|
|
38
|
-
* - escaping raw control characters inside strings
|
|
39
|
-
* - doubling backslashes before invalid escape characters
|
|
40
|
-
*/
|
|
41
|
-
function repairJson(json) {
|
|
42
|
-
let repaired = "";
|
|
43
|
-
let inString = false;
|
|
44
|
-
let stringValuePrefix = "";
|
|
45
|
-
for (let index = 0; index < json.length; index++) {
|
|
46
|
-
const char = json.charAt(index);
|
|
47
|
-
if (!inString) {
|
|
48
|
-
repaired += char;
|
|
49
|
-
if (char === "\"") {
|
|
50
|
-
inString = true;
|
|
51
|
-
stringValuePrefix = "";
|
|
52
|
-
}
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (char === "\"") {
|
|
56
|
-
repaired += char;
|
|
57
|
-
inString = false;
|
|
58
|
-
stringValuePrefix = "";
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (char === "\\") {
|
|
62
|
-
const nextChar = json.charAt(index + 1);
|
|
63
|
-
if (!nextChar) {
|
|
64
|
-
repaired += "\\\\";
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (nextChar === "u") {
|
|
68
|
-
const unicodeDigits = json.slice(index + 2, index + 6);
|
|
69
|
-
if (/^[0-9a-fA-F]{4}$/.test(unicodeDigits)) {
|
|
70
|
-
repaired += `\\u${unicodeDigits}`;
|
|
71
|
-
stringValuePrefix += `\\u${unicodeDigits}`;
|
|
72
|
-
index += 5;
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
repaired += "\\\\";
|
|
76
|
-
stringValuePrefix += "\\";
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
if (JSON_CONTROL_ESCAPES.has(nextChar) && looksLikeWindowsPathPrefix(stringValuePrefix)) {
|
|
80
|
-
repaired += "\\\\";
|
|
81
|
-
stringValuePrefix += "\\";
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (VALID_JSON_ESCAPES.has(nextChar)) {
|
|
85
|
-
repaired += `\\${nextChar}`;
|
|
86
|
-
stringValuePrefix += nextChar === "\\" ? "\\" : `\\${nextChar}`;
|
|
87
|
-
index += 1;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
repaired += "\\\\";
|
|
91
|
-
stringValuePrefix += "\\";
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
repaired += isControlCharacter(char) ? escapeControlCharacter(char) : char;
|
|
95
|
-
stringValuePrefix += char;
|
|
96
|
-
}
|
|
97
|
-
return repaired;
|
|
98
|
-
}
|
|
99
|
-
function parseJsonWithRepair(json) {
|
|
100
|
-
return JSON.parse(repairJson(json));
|
|
101
|
-
}
|
|
102
|
-
function looksLikeWindowsPathPrefix(prefix) {
|
|
103
|
-
const tail = prefix.slice(-160);
|
|
104
|
-
return /(?:^|[^A-Za-z0-9])[A-Za-z]:(?:[\\/][^"\\/:*?<>|\r\n]*)*$/.test(tail);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Attempts to parse potentially incomplete JSON during streaming.
|
|
108
|
-
* Always returns a valid object, even if the JSON is incomplete.
|
|
109
|
-
*
|
|
110
|
-
* @param partialJson The partial JSON string from streaming
|
|
111
|
-
* @returns Parsed object or empty object if parsing fails
|
|
112
|
-
*/
|
|
113
|
-
function parseStreamingJson(partialJson) {
|
|
114
|
-
if (!partialJson || partialJson.trim() === "") return {};
|
|
115
|
-
try {
|
|
116
|
-
return asNonArrayRecord(parseJsonWithRepair(partialJson));
|
|
117
|
-
} catch {
|
|
118
|
-
try {
|
|
119
|
-
return asNonArrayRecord(parse(partialJson));
|
|
120
|
-
} catch {
|
|
121
|
-
try {
|
|
122
|
-
return asNonArrayRecord(parse(repairJson(partialJson)));
|
|
123
|
-
} catch {
|
|
124
|
-
return {};
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const TOOL_ARGUMENT_PREVIEW_FIRST_CHECKPOINT_CHARS = 512;
|
|
130
|
-
/**
|
|
131
|
-
* Streamed tool-call arguments are preview-only; the terminal parse re-reads
|
|
132
|
-
* the full buffer authoritatively at content_block_stop. Reparsing every delta
|
|
133
|
-
* scans an ever-growing buffer and makes assembly quadratic in the argument
|
|
134
|
-
* size, so refresh previews on a geometric length schedule instead — bounded
|
|
135
|
-
* staleness, linear total parse work.
|
|
136
|
-
*/
|
|
137
|
-
function createToolArgumentPreviewSchedule() {
|
|
138
|
-
let nextCheckpointChars = TOOL_ARGUMENT_PREVIEW_FIRST_CHECKPOINT_CHARS;
|
|
139
|
-
return (accumulatedChars) => {
|
|
140
|
-
if (accumulatedChars < nextCheckpointChars) return false;
|
|
141
|
-
nextCheckpointChars = accumulatedChars * 2;
|
|
142
|
-
return true;
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
//#endregion
|
|
146
|
-
export { repairJson as i, parseJsonWithRepair as n, parseStreamingJson as r, createToolArgumentPreviewSchedule as t };
|
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
-
import { t as AssistantMessageEventStream } from "./event-stream-BgDvQeum.mjs";
|
|
3
|
-
import { i as clampThinkingLevel } from "./sanitize-unicode-D6xUvZaS.mjs";
|
|
4
|
-
import { n as getAiTransportHost } from "./host-CEvLw30U.mjs";
|
|
5
|
-
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-CGnVB74a.mjs";
|
|
6
|
-
import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
|
|
7
|
-
import { m as sortPromptCacheToolsByName, n as buildBaseOptions, o as reasoningTagTextPolicy, u as splitSystemPromptCacheBoundary } from "./simple-options-BjHCCh4v.mjs";
|
|
8
|
-
import { n as getEnvApiKey } from "./env-api-keys-bktO00EJ.mjs";
|
|
9
|
-
import { _ as transportAbortError, t as assignTransportErrorDetails, y as withProviderResponseHook } from "./transport-stream-shared-CZqMhfIw.mjs";
|
|
10
|
-
import { E as tagUnresolvedTextAsCommentary, S as shouldOmitOllamaCompatResponseFormat, _ as hasToolCallHistory, b as resolveOpenAICompletionsCompat, g as convertMessages, h as resolveOpenAIReasoningEffortMap, t as processCompletionsStream, v as finalizeOpenAICompletionsToolCalls, w as clearPendingCommentaryText, x as resolveOpenAICompletionsResponseFormat } from "./openai-completions-stream-BsrBe3Gg.mjs";
|
|
11
|
-
import { C as createOpenAIProviderAcceptanceHook, T as isOpenAICompletionsThinkingEnabled, j as resolveOpenAIClientBaseUrl, v as projectOpenAITools, y as reconcileOpenAICompletionsToolChoice } from "./openai-tool-schema-_pTAJqKF.mjs";
|
|
12
|
-
import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DcNjoFQE.mjs";
|
|
13
|
-
import { i as resolveCloudflareBaseUrl, n as hasCopilotVisionInput, r as isCloudflareProvider, t as buildCopilotDynamicHeaders } from "./github-copilot-headers-NCJtz9i0.mjs";
|
|
14
|
-
import OpenAI from "openai";
|
|
15
|
-
//#region packages/ai/src/providers/openai-completions.ts
|
|
16
|
-
var openai_completions_exports = /* @__PURE__ */ __exportAll({
|
|
17
|
-
convertMessages: () => convertMessages,
|
|
18
|
-
streamOpenAICompletions: () => streamOpenAICompletions,
|
|
19
|
-
streamSimpleOpenAICompletions: () => streamSimpleOpenAICompletions
|
|
20
|
-
});
|
|
21
|
-
const streamOpenAICompletions = (model, context, options) => {
|
|
22
|
-
const stream = new AssistantMessageEventStream();
|
|
23
|
-
(async () => {
|
|
24
|
-
const output = {
|
|
25
|
-
role: "assistant",
|
|
26
|
-
content: [],
|
|
27
|
-
api: model.api,
|
|
28
|
-
provider: model.provider,
|
|
29
|
-
model: model.id,
|
|
30
|
-
usage: {
|
|
31
|
-
input: 0,
|
|
32
|
-
output: 0,
|
|
33
|
-
cacheRead: 0,
|
|
34
|
-
cacheWrite: 0,
|
|
35
|
-
totalTokens: 0,
|
|
36
|
-
cost: {
|
|
37
|
-
input: 0,
|
|
38
|
-
output: 0,
|
|
39
|
-
cacheRead: 0,
|
|
40
|
-
cacheWrite: 0,
|
|
41
|
-
total: 0
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
stopReason: "stop",
|
|
45
|
-
timestamp: Date.now()
|
|
46
|
-
};
|
|
47
|
-
const provisionalCommentaryTags = /* @__PURE__ */ new Map();
|
|
48
|
-
let firstEventAbort;
|
|
49
|
-
try {
|
|
50
|
-
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
51
|
-
const compat = resolveOpenAICompletionsCompat(model);
|
|
52
|
-
const shouldEmitReasoning = Boolean(model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
|
|
53
|
-
const cacheRetention = resolveCacheRetention(options?.cacheRetention);
|
|
54
|
-
const cacheSessionId = cacheRetention === "none" ? void 0 : options?.sessionId;
|
|
55
|
-
const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
|
|
56
|
-
let params = buildParams(model, context, options, compat, cacheRetention);
|
|
57
|
-
const nextParams = await options?.onPayload?.(params, model);
|
|
58
|
-
if (nextParams !== void 0) params = nextParams;
|
|
59
|
-
firstEventAbort = createFirstStreamEventAbortController(options?.signal);
|
|
60
|
-
const requestOptions = {
|
|
61
|
-
signal: firstEventAbort.signal,
|
|
62
|
-
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
63
|
-
maxRetries: 0
|
|
64
|
-
};
|
|
65
|
-
const { data: openaiStream, response } = await client.chat.completions.create(params, requestOptions).withResponse();
|
|
66
|
-
const hookedOpenAIStream = withProviderResponseHook({
|
|
67
|
-
stream: openaiStream,
|
|
68
|
-
signal: firstEventAbort.signal,
|
|
69
|
-
abort: firstEventAbort.abort,
|
|
70
|
-
hook: createOpenAIProviderAcceptanceHook(options, response, model),
|
|
71
|
-
onReady: () => stream.push({
|
|
72
|
-
type: "start",
|
|
73
|
-
partial: output
|
|
74
|
-
})
|
|
75
|
-
});
|
|
76
|
-
const finishedBlocks = /* @__PURE__ */ new Set();
|
|
77
|
-
const contentIndices = /* @__PURE__ */ new WeakMap();
|
|
78
|
-
let openTextBlock;
|
|
79
|
-
let openThinkingBlock;
|
|
80
|
-
const finishBlock = (block) => {
|
|
81
|
-
const contentIndex = contentIndices.get(block);
|
|
82
|
-
if (contentIndex === void 0 || finishedBlocks.has(block)) return;
|
|
83
|
-
finishedBlocks.add(block);
|
|
84
|
-
if (block.type === "text") {
|
|
85
|
-
openTextBlock = void 0;
|
|
86
|
-
stream.push({
|
|
87
|
-
type: "text_end",
|
|
88
|
-
contentIndex,
|
|
89
|
-
content: block.text,
|
|
90
|
-
partial: output
|
|
91
|
-
});
|
|
92
|
-
} else if (block.type === "thinking") {
|
|
93
|
-
openThinkingBlock = void 0;
|
|
94
|
-
stream.push({
|
|
95
|
-
type: "thinking_end",
|
|
96
|
-
contentIndex,
|
|
97
|
-
content: block.thinking,
|
|
98
|
-
partial: output
|
|
99
|
-
});
|
|
100
|
-
} else if (block.type === "toolCall") stream.push({
|
|
101
|
-
type: "toolcall_end",
|
|
102
|
-
contentIndex,
|
|
103
|
-
toolCall: block,
|
|
104
|
-
partial: output
|
|
105
|
-
});
|
|
106
|
-
};
|
|
107
|
-
const directEventStream = { push(event) {
|
|
108
|
-
if (event.type === "text_start" || event.type === "thinking_start" || event.type === "toolcall_start") {
|
|
109
|
-
const block = output.content[event.contentIndex];
|
|
110
|
-
if (block) {
|
|
111
|
-
contentIndices.set(block, event.contentIndex);
|
|
112
|
-
if (block.type === "text") openTextBlock = block;
|
|
113
|
-
else if (block.type === "thinking") openThinkingBlock = block;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
stream.push(event);
|
|
117
|
-
} };
|
|
118
|
-
try {
|
|
119
|
-
await processCompletionsStream(hookedOpenAIStream, output, model, directEventStream, {
|
|
120
|
-
mode: "direct",
|
|
121
|
-
beforeContentBlock(nextType) {
|
|
122
|
-
if (openThinkingBlock) finishBlock(openThinkingBlock);
|
|
123
|
-
if (openTextBlock && nextType !== "toolCall") finishBlock(openTextBlock);
|
|
124
|
-
},
|
|
125
|
-
provisionalCommentaryTags,
|
|
126
|
-
signal: options?.signal,
|
|
127
|
-
emitReasoning: shouldEmitReasoning,
|
|
128
|
-
strictReasoningTags: reasoningTagTextPolicy.isStrict(options),
|
|
129
|
-
firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
|
|
130
|
-
abortFirstEventStream: firstEventAbort.abort,
|
|
131
|
-
onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options)
|
|
132
|
-
});
|
|
133
|
-
if (options?.signal?.aborted) throw transportAbortError(options.signal);
|
|
134
|
-
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage || (output.stopReason === "aborted" ? "Request was aborted" : "Provider returned an invalid tool call"));
|
|
135
|
-
} catch (error) {
|
|
136
|
-
for (const block of output.content) if (block.type !== "toolCall") finishBlock(block);
|
|
137
|
-
throw error;
|
|
138
|
-
}
|
|
139
|
-
for (const block of output.content) if (block.type !== "toolCall" || output.stopReason === "toolUse") finishBlock(block);
|
|
140
|
-
stream.push({
|
|
141
|
-
type: "done",
|
|
142
|
-
reason: output.stopReason,
|
|
143
|
-
message: output
|
|
144
|
-
});
|
|
145
|
-
stream.end();
|
|
146
|
-
} catch (error) {
|
|
147
|
-
const terminal = assignTransportErrorDetails(output, error, options?.signal);
|
|
148
|
-
finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
|
|
149
|
-
clearPendingCommentaryText(provisionalCommentaryTags);
|
|
150
|
-
tagUnresolvedTextAsCommentary(output);
|
|
151
|
-
for (const block of output.content) {
|
|
152
|
-
delete block.index;
|
|
153
|
-
delete block.partialArgs;
|
|
154
|
-
delete block.streamIndex;
|
|
155
|
-
}
|
|
156
|
-
stream.push({
|
|
157
|
-
type: "error",
|
|
158
|
-
reason: terminal.stopReason,
|
|
159
|
-
error: output
|
|
160
|
-
});
|
|
161
|
-
stream.end();
|
|
162
|
-
} finally {
|
|
163
|
-
firstEventAbort?.dispose();
|
|
164
|
-
}
|
|
165
|
-
})();
|
|
166
|
-
return stream;
|
|
167
|
-
};
|
|
168
|
-
const streamSimpleOpenAICompletions = (model, context, options) => {
|
|
169
|
-
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
|
|
170
|
-
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
171
|
-
const base = buildBaseOptions(model, options, apiKey);
|
|
172
|
-
const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
|
|
173
|
-
const reasoningEffort = clampedReasoning === "off" ? void 0 : clampedReasoning === "max" ? "xhigh" : clampedReasoning;
|
|
174
|
-
const toolChoice = options?.toolChoice;
|
|
175
|
-
return streamOpenAICompletions(model, context, {
|
|
176
|
-
...base,
|
|
177
|
-
reasoningEffort,
|
|
178
|
-
toolChoice
|
|
179
|
-
});
|
|
180
|
-
};
|
|
181
|
-
function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = resolveOpenAICompletionsCompat(model)) {
|
|
182
|
-
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
183
|
-
const headers = { ...model.headers };
|
|
184
|
-
if (model.provider === "github-copilot") {
|
|
185
|
-
const hasImages = hasCopilotVisionInput(context.messages);
|
|
186
|
-
const copilotHeaders = buildCopilotDynamicHeaders({
|
|
187
|
-
messages: context.messages,
|
|
188
|
-
hasImages
|
|
189
|
-
});
|
|
190
|
-
Object.assign(headers, copilotHeaders);
|
|
191
|
-
}
|
|
192
|
-
if (sessionId && compat.sessionAffinity !== "none") {
|
|
193
|
-
if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
|
|
194
|
-
else {
|
|
195
|
-
headers.session_id = sessionId;
|
|
196
|
-
headers["x-client-request-id"] = sessionId;
|
|
197
|
-
headers["x-session-affinity"] = sessionId;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
if (optionsHeaders) Object.assign(headers, optionsHeaders);
|
|
201
|
-
const defaultHeaders = model.provider === "cloudflare-ai-gateway" ? {
|
|
202
|
-
...headers,
|
|
203
|
-
Authorization: headers.Authorization ?? null,
|
|
204
|
-
"cf-aig-authorization": `Bearer ${apiKey}`
|
|
205
|
-
} : headers;
|
|
206
|
-
const baseUrl = isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl;
|
|
207
|
-
return new OpenAI({
|
|
208
|
-
apiKey,
|
|
209
|
-
baseURL: resolveOpenAIClientBaseUrl(model, baseUrl),
|
|
210
|
-
dangerouslyAllowBrowser: true,
|
|
211
|
-
defaultHeaders,
|
|
212
|
-
maxRetries: 0,
|
|
213
|
-
fetch: getAiTransportHost().buildModelFetch(model)
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
function buildParams(model, context, options, compat = resolveOpenAICompletionsCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention)) {
|
|
217
|
-
const cacheControl = getCompatCacheControl(compat, cacheRetention);
|
|
218
|
-
const cacheOptOutIndexes = /* @__PURE__ */ new Set();
|
|
219
|
-
const messages = convertMessages(model, context, compat, {
|
|
220
|
-
cacheOptOutIndexes,
|
|
221
|
-
preserveSystemPromptCacheBoundary: cacheControl !== void 0
|
|
222
|
-
});
|
|
223
|
-
const supportsPromptCacheKey = model.baseUrl.includes("api.openai.com") || compat.supportsPromptCacheKey;
|
|
224
|
-
const promptCacheKey = supportsPromptCacheKey && cacheRetention !== "none" ? clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId) : void 0;
|
|
225
|
-
const params = {
|
|
226
|
-
model: model.id,
|
|
227
|
-
messages,
|
|
228
|
-
stream: true,
|
|
229
|
-
prompt_cache_key: promptCacheKey,
|
|
230
|
-
prompt_cache_retention: supportsPromptCacheKey && cacheRetention === "long" && compat.supportsLongCacheRetention ? "24h" : void 0
|
|
231
|
-
};
|
|
232
|
-
if (compat.supportsUsageInStreaming) params.stream_options = { include_usage: true };
|
|
233
|
-
if (compat.supportsStore) params.store = false;
|
|
234
|
-
if (options?.maxTokens) {
|
|
235
|
-
const maxTokens = clampOpenAICompletionsMaxTokens(model, options.maxTokens);
|
|
236
|
-
if (compat.maxTokensField === "max_tokens") params.max_tokens = maxTokens;
|
|
237
|
-
else params.max_completion_tokens = maxTokens;
|
|
238
|
-
}
|
|
239
|
-
if (options?.temperature !== void 0) params.temperature = options.temperature;
|
|
240
|
-
if (options?.stop !== void 0 && options.stop.length > 0) params.stop = options.stop;
|
|
241
|
-
const requestedResponseFormat = options?.responseFormat;
|
|
242
|
-
const responseFormat = requestedResponseFormat === void 0 ? void 0 : resolveOpenAICompletionsResponseFormat(shouldOmitOllamaCompatResponseFormat({
|
|
243
|
-
provider: model.provider,
|
|
244
|
-
baseUrl: model.baseUrl,
|
|
245
|
-
hasTools: () => Boolean(context.tools?.length)
|
|
246
|
-
}) ? void 0 : requestedResponseFormat, compat.supportsJsonSchemaResponseFormat);
|
|
247
|
-
if (responseFormat !== void 0) params.response_format = responseFormat;
|
|
248
|
-
let toolProjection;
|
|
249
|
-
if (context.tools) {
|
|
250
|
-
const converted = convertTools(context.tools, compat);
|
|
251
|
-
toolProjection = converted.projection;
|
|
252
|
-
if (converted.tools.length > 0) params.tools = converted.tools;
|
|
253
|
-
else if (hasToolCallHistory(context.messages)) params.tools = [];
|
|
254
|
-
if (compat.zaiToolStream && converted.tools.length > 0) params.tool_stream = true;
|
|
255
|
-
} else if (hasToolCallHistory(context.messages)) params.tools = [];
|
|
256
|
-
if (cacheControl) applyAnthropicCacheControl(messages, params.tools, cacheControl, cacheOptOutIndexes);
|
|
257
|
-
if (options?.toolChoice) {
|
|
258
|
-
const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, toolProjection ?? projectOpenAITools([]));
|
|
259
|
-
if (toolChoice !== void 0) params.tool_choice = toolChoice;
|
|
260
|
-
}
|
|
261
|
-
const reasoningEffortMap = resolveOpenAIReasoningEffortMap(model);
|
|
262
|
-
const thinkingLevelMap = model.thinkingLevelMap;
|
|
263
|
-
const offReasoningEffort = reasoningEffortMap.off ?? model.thinkingLevelMap?.off;
|
|
264
|
-
const reasoningEffort = options?.reasoningEffort === void 0 ? offReasoningEffort ?? void 0 : reasoningEffortMap[options.reasoningEffort] ?? thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
|
|
265
|
-
const reasoningEnabled = reasoningEffort !== void 0 && reasoningEffort !== "none";
|
|
266
|
-
if (compat.thinkingFormat === "zai" && model.reasoning) params.thinking = reasoningEnabled ? {
|
|
267
|
-
type: "enabled",
|
|
268
|
-
clear_thinking: false
|
|
269
|
-
} : { type: "disabled" };
|
|
270
|
-
else if (compat.thinkingFormat === "qwen" && model.reasoning) params.enable_thinking = reasoningEnabled;
|
|
271
|
-
else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = {
|
|
272
|
-
enable_thinking: reasoningEnabled,
|
|
273
|
-
preserve_thinking: true
|
|
274
|
-
};
|
|
275
|
-
else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
|
|
276
|
-
params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
|
|
277
|
-
if (reasoningEnabled && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
|
|
278
|
-
} else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
|
|
279
|
-
const openRouterParams = params;
|
|
280
|
-
if (reasoningEnabled) openRouterParams.reasoning = { effort: reasoningEffort };
|
|
281
|
-
else if (offReasoningEffort !== null) openRouterParams.reasoning = { effort: offReasoningEffort ?? "none" };
|
|
282
|
-
} else if (compat.thinkingFormat === "together" && model.reasoning) {
|
|
283
|
-
const togetherParams = params;
|
|
284
|
-
togetherParams.reasoning = { enabled: reasoningEnabled };
|
|
285
|
-
if (reasoningEnabled && compat.supportsReasoningEffort) togetherParams.reasoning_effort = reasoningEffort;
|
|
286
|
-
} else if (reasoningEnabled && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = reasoningEffort;
|
|
287
|
-
else if (model.reasoning && compat.supportsReasoningEffort) {
|
|
288
|
-
if (typeof offReasoningEffort === "string") params.reasoning_effort = offReasoningEffort;
|
|
289
|
-
}
|
|
290
|
-
if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
|
|
291
|
-
if (model.baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
|
|
292
|
-
const routing = model.compat.vercelGatewayRouting;
|
|
293
|
-
if (routing.only || routing.order) {
|
|
294
|
-
const gatewayOptions = {};
|
|
295
|
-
if (routing.only) gatewayOptions.only = routing.only;
|
|
296
|
-
if (routing.order) gatewayOptions.order = routing.order;
|
|
297
|
-
params.providerOptions = { gateway: gatewayOptions };
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
return params;
|
|
301
|
-
}
|
|
302
|
-
function clampOpenAICompletionsMaxTokens(model, requestedMaxTokens) {
|
|
303
|
-
const modelMaxTokens = typeof model.maxTokens === "number" && Number.isFinite(model.maxTokens) && model.maxTokens > 0 ? Math.floor(model.maxTokens) : void 0;
|
|
304
|
-
return modelMaxTokens === void 0 || requestedMaxTokens <= modelMaxTokens ? requestedMaxTokens : modelMaxTokens;
|
|
305
|
-
}
|
|
306
|
-
function getCompatCacheControl(compat, cacheRetention) {
|
|
307
|
-
if (compat.cacheControlFormat !== "anthropic" || cacheRetention === "none") return;
|
|
308
|
-
const ttl = cacheRetention === "long" && compat.supportsLongCacheRetention ? "1h" : void 0;
|
|
309
|
-
return {
|
|
310
|
-
type: "ephemeral",
|
|
311
|
-
...ttl ? { ttl } : {}
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
function applyAnthropicCacheControl(messages, tools, cacheControl, cacheOptOutIndexes) {
|
|
315
|
-
addCacheControlToSystemPrompt(messages, cacheControl);
|
|
316
|
-
addCacheControlToLastTool(tools, cacheControl);
|
|
317
|
-
addCacheControlToLastConversationMessage(messages, cacheControl, cacheOptOutIndexes);
|
|
318
|
-
}
|
|
319
|
-
function addCacheControlToSystemPrompt(messages, cacheControl) {
|
|
320
|
-
for (const message of messages) if (message.role === "system" || message.role === "developer") {
|
|
321
|
-
addCacheControlToInstructionMessage(message, cacheControl);
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
function addCacheControlToLastConversationMessage(messages, cacheControl, cacheOptOutIndexes) {
|
|
326
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
327
|
-
const message = messages[i];
|
|
328
|
-
if (!message || cacheOptOutIndexes.has(i)) continue;
|
|
329
|
-
if (message.role === "user" || message.role === "assistant") {
|
|
330
|
-
if (addCacheControlToMessage(message, cacheControl)) return;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
function addCacheControlToLastTool(tools, cacheControl) {
|
|
335
|
-
if (!tools || tools.length === 0) return;
|
|
336
|
-
const lastTool = tools.at(-1);
|
|
337
|
-
if (!lastTool) return;
|
|
338
|
-
lastTool.cache_control = cacheControl;
|
|
339
|
-
}
|
|
340
|
-
function addCacheControlToInstructionMessage(message, cacheControl) {
|
|
341
|
-
return addCacheControlToTextContent(message, cacheControl);
|
|
342
|
-
}
|
|
343
|
-
function addCacheControlToMessage(message, cacheControl) {
|
|
344
|
-
if (message.role === "user" || message.role === "assistant") return addCacheControlToTextContent(message, cacheControl);
|
|
345
|
-
return false;
|
|
346
|
-
}
|
|
347
|
-
function addCacheControlToTextContent(message, cacheControl) {
|
|
348
|
-
const content = message.content;
|
|
349
|
-
if (typeof content === "string") {
|
|
350
|
-
if (content.length === 0) return false;
|
|
351
|
-
message.content = buildCacheControlledTextParts(content, cacheControl);
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
if (!Array.isArray(content)) return false;
|
|
355
|
-
for (let i = content.length - 1; i >= 0; i--) {
|
|
356
|
-
const part = content[i];
|
|
357
|
-
if (part?.type === "text") {
|
|
358
|
-
const text = part.text;
|
|
359
|
-
content.splice(i, 1, ...buildCacheControlledTextParts(text, cacheControl));
|
|
360
|
-
return true;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
function buildCacheControlledTextParts(text, cacheControl) {
|
|
366
|
-
const split = splitSystemPromptCacheBoundary(text);
|
|
367
|
-
if (!split) return [{
|
|
368
|
-
type: "text",
|
|
369
|
-
text,
|
|
370
|
-
cache_control: cacheControl
|
|
371
|
-
}];
|
|
372
|
-
const parts = [];
|
|
373
|
-
if (split.stablePrefix) parts.push({
|
|
374
|
-
type: "text",
|
|
375
|
-
text: split.stablePrefix,
|
|
376
|
-
cache_control: cacheControl
|
|
377
|
-
});
|
|
378
|
-
if (split.dynamicSuffix) parts.push({
|
|
379
|
-
type: "text",
|
|
380
|
-
text: split.dynamicSuffix
|
|
381
|
-
});
|
|
382
|
-
return parts.length > 0 ? parts : [{
|
|
383
|
-
type: "text",
|
|
384
|
-
text: ""
|
|
385
|
-
}];
|
|
386
|
-
}
|
|
387
|
-
function convertTools(tools, compat) {
|
|
388
|
-
const projection = projectOpenAITools(tools);
|
|
389
|
-
return {
|
|
390
|
-
projection,
|
|
391
|
-
tools: sortPromptCacheToolsByName(projection.tools).map((tool) => ({
|
|
392
|
-
type: "function",
|
|
393
|
-
function: {
|
|
394
|
-
name: tool.name,
|
|
395
|
-
description: tool.description,
|
|
396
|
-
parameters: tool.parameters,
|
|
397
|
-
...compat.supportsStrictMode && { strict: false }
|
|
398
|
-
}
|
|
399
|
-
}))
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
//#endregion
|
|
403
|
-
export { streamOpenAICompletions as n, streamSimpleOpenAICompletions as r, openai_completions_exports as t };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
//#region packages/ai/src/providers/openai-prompt-cache.ts
|
|
2
|
-
/** Selects the documented cache lifetime fields for a Responses request. */
|
|
3
|
-
function resolveOpenAIResponsesCacheParams(model, cacheRetention, supportsLongCacheRetention) {
|
|
4
|
-
if (cacheRetention === "none") return {};
|
|
5
|
-
if (model.id === "gpt-6-astra" && model.api === "openai-responses") {
|
|
6
|
-
const endpoint = URL.parse(model.baseUrl ?? "https://api.openai.com/v1");
|
|
7
|
-
if (endpoint?.protocol === "https:" && (endpoint.hostname === "api.openai.com" || endpoint.hostname.endsWith(".api.openai.com"))) return { prompt_cache_options: { ttl: "30m" } };
|
|
8
|
-
}
|
|
9
|
-
return cacheRetention === "long" && supportsLongCacheRetention ? { prompt_cache_retention: "24h" } : {};
|
|
10
|
-
}
|
|
11
|
-
/** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
|
|
12
|
-
const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
|
|
13
|
-
/** Truncates a prompt cache key by Unicode code point count. */
|
|
14
|
-
function clampOpenAIPromptCacheKey(key) {
|
|
15
|
-
if (key === void 0) return;
|
|
16
|
-
const chars = Array.from(key);
|
|
17
|
-
if (chars.length <= 64) return key;
|
|
18
|
-
return chars.slice(0, 64).join("");
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
export { clampOpenAIPromptCacheKey as n, resolveOpenAIResponsesCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { D as Model, l as CacheRetention } from "./types-CJ1-Ht7A.mjs";
|
|
2
|
-
import "./types-3Lnm-QSJ.mjs";
|
|
3
|
-
//#region packages/ai/src/providers/openai-prompt-cache.d.ts
|
|
4
|
-
/** Selects the documented cache lifetime fields for a Responses request. */
|
|
5
|
-
declare function resolveOpenAIResponsesCacheParams(model: Pick<Model, "id" | "api" | "baseUrl">, cacheRetention: CacheRetention, supportsLongCacheRetention: boolean): {
|
|
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, resolveOpenAIResponsesCacheParams as r, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { l as requiresClaudeMandatoryAdaptiveThinking, p as resolveClaudeNativeThinkingLevelMap, t as calculateUsageCost } from "./src-2qBGKg8O.mjs";
|
|
2
|
-
//#region packages/ai/src/model-utils.ts
|
|
3
|
-
/** Calculates and stores model cost fields from token usage and per-million pricing. */
|
|
4
|
-
function calculateCost(model, usage) {
|
|
5
|
-
Object.assign(usage.cost, calculateUsageCost(usage, model.cost));
|
|
6
|
-
return usage.cost;
|
|
7
|
-
}
|
|
8
|
-
/** Replaces the catalog estimate when the provider reports an authoritative billed total. */
|
|
9
|
-
function applyProviderReportedUsageCost(usage, reportedCost) {
|
|
10
|
-
if (typeof reportedCost !== "number" || !Number.isFinite(reportedCost) || reportedCost < 0) return;
|
|
11
|
-
usage.cost.total = reportedCost;
|
|
12
|
-
usage.cost.totalOrigin = "provider-billed";
|
|
13
|
-
}
|
|
14
|
-
const EXTENDED_THINKING_LEVELS = [
|
|
15
|
-
"off",
|
|
16
|
-
"minimal",
|
|
17
|
-
"low",
|
|
18
|
-
"medium",
|
|
19
|
-
"high",
|
|
20
|
-
"xhigh",
|
|
21
|
-
"max"
|
|
22
|
-
];
|
|
23
|
-
function resolveThinkingLevelMap(model) {
|
|
24
|
-
return model.api === "anthropic-messages" ? resolveClaudeNativeThinkingLevelMap(model) ?? model.thinkingLevelMap : model.thinkingLevelMap;
|
|
25
|
-
}
|
|
26
|
-
/** Returns thinking levels exposed by a reasoning-capable model. */
|
|
27
|
-
function getSupportedThinkingLevels(model) {
|
|
28
|
-
const mandatoryAdaptiveContract = model.api === "anthropic-messages" && requiresClaudeMandatoryAdaptiveThinking(model);
|
|
29
|
-
if (!model.reasoning && !mandatoryAdaptiveContract) return ["off"];
|
|
30
|
-
const thinkingLevelMap = resolveThinkingLevelMap(model);
|
|
31
|
-
return EXTENDED_THINKING_LEVELS.filter((level) => {
|
|
32
|
-
const mapped = thinkingLevelMap?.[level];
|
|
33
|
-
if (mapped === null) return false;
|
|
34
|
-
if (level === "xhigh" || level === "max") return mapped !== void 0;
|
|
35
|
-
return true;
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
/** Clamps a requested thinking level to the closest supported level for a model. */
|
|
39
|
-
function clampThinkingLevel(model, level) {
|
|
40
|
-
const availableLevels = getSupportedThinkingLevels(model);
|
|
41
|
-
if (availableLevels.includes(level)) return level;
|
|
42
|
-
const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
|
|
43
|
-
if (requestedIndex === -1) return availableLevels[0] ?? "off";
|
|
44
|
-
const thinkingLevelMap = resolveThinkingLevelMap(model);
|
|
45
|
-
if ((level === "xhigh" || level === "max") && thinkingLevelMap?.[level] === null) {
|
|
46
|
-
for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
|
|
47
|
-
}
|
|
48
|
-
for (const candidate of EXTENDED_THINKING_LEVELS.slice(requestedIndex)) if (availableLevels.includes(candidate)) return candidate;
|
|
49
|
-
for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
|
|
50
|
-
return availableLevels[0] ?? "off";
|
|
51
|
-
}
|
|
52
|
-
/** Compares model identity by provider and id. */
|
|
53
|
-
function modelsAreEqual(a, b) {
|
|
54
|
-
if (!a || !b) return false;
|
|
55
|
-
return a.id === b.id && a.provider === b.provider;
|
|
56
|
-
}
|
|
57
|
-
//#endregion
|
|
58
|
-
//#region packages/ai/src/utils/sanitize-unicode.ts
|
|
59
|
-
/**
|
|
60
|
-
* Removes unpaired Unicode surrogate characters from a string.
|
|
61
|
-
*
|
|
62
|
-
* Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
|
|
63
|
-
* or vice versa) cause JSON serialization errors in many API providers.
|
|
64
|
-
*
|
|
65
|
-
* Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
|
|
66
|
-
* surrogates and will NOT be affected by this function.
|
|
67
|
-
*
|
|
68
|
-
* @param text - The text to sanitize
|
|
69
|
-
* @returns The sanitized text with unpaired surrogates removed
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* // Valid emoji (properly paired surrogates) are preserved
|
|
73
|
-
* sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
|
|
74
|
-
*
|
|
75
|
-
* // Unpaired high surrogate is removed
|
|
76
|
-
* const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
|
|
77
|
-
* sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
|
|
78
|
-
*/
|
|
79
|
-
function sanitizeSurrogates(text) {
|
|
80
|
-
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
81
|
-
}
|
|
82
|
-
//#endregion
|
|
83
|
-
export { getSupportedThinkingLevels as a, clampThinkingLevel as i, applyProviderReportedUsageCost as n, modelsAreEqual as o, calculateCost as r, sanitizeSurrogates as t };
|