pi2dsh 0.13.2 → 0.13.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.
- package/README.md +22 -19
- package/README.zh.md +18 -15
- package/dist/{analyzer-CJFwQlSG.mjs → analyzer-DBtUYKI1.mjs} +2 -2
- package/dist/{analyzer-CJFwQlSG.mjs.map → analyzer-DBtUYKI1.mjs.map} +1 -1
- package/dist/anthropic-messages-CaYTgvLF.mjs +6436 -0
- package/dist/anthropic-messages-CaYTgvLF.mjs.map +1 -0
- package/dist/azure-openai-responses-HKWkzl2m.mjs +208 -0
- package/dist/azure-openai-responses-HKWkzl2m.mjs.map +1 -0
- package/dist/cli.mjs +3 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/compat/pi-ai.d.mts +3 -2636
- package/dist/compat/pi-ai.mjs +3 -2
- package/dist/compat/pi-coding-agent.d.mts +2 -2
- package/dist/compat/pi-coding-agent.mjs +2 -2
- package/dist/{mcp-config-_idn-pzI.mjs → compatibility-Bz6ZXA7F.mjs} +8 -185
- package/dist/compatibility-Bz6ZXA7F.mjs.map +1 -0
- package/dist/completionchunk-Dhk56lZl.mjs +5212 -0
- package/dist/completionchunk-Dhk56lZl.mjs.map +1 -0
- package/dist/{credentials-oauth-Txs6oew8.mjs → credentials-oauth-CAohSLcB.mjs} +3 -3
- package/dist/{credentials-oauth-Txs6oew8.mjs.map → credentials-oauth-CAohSLcB.mjs.map} +1 -1
- package/dist/credentials-oauth.mjs +1 -1
- package/dist/deferred-tools-BD4g5QUx.mjs +32 -0
- package/dist/deferred-tools-BD4g5QUx.mjs.map +1 -0
- package/dist/diagnostics-BqYkodgB.mjs +35 -0
- package/dist/diagnostics-BqYkodgB.mjs.map +1 -0
- package/dist/dist-QBBA-dL_.mjs +1246 -0
- package/dist/dist-QBBA-dL_.mjs.map +1 -0
- package/dist/error-body-DKA3lknR.mjs +104 -0
- package/dist/error-body-DKA3lknR.mjs.map +1 -0
- package/dist/event-stream-QxN1yvIF.mjs +64 -0
- package/dist/event-stream-QxN1yvIF.mjs.map +1 -0
- package/dist/from-BCscBQ9P.mjs +3856 -0
- package/dist/from-BCscBQ9P.mjs.map +1 -0
- package/dist/github-copilot-headers-CZo2QHrt.mjs +25 -0
- package/dist/github-copilot-headers-CZo2QHrt.mjs.map +1 -0
- package/dist/google-generative-ai-2gCFYp-t.mjs +356 -0
- package/dist/google-generative-ai-2gCFYp-t.mjs.map +1 -0
- package/dist/google-shared-75IdVyrx.mjs +29041 -0
- package/dist/google-shared-75IdVyrx.mjs.map +1 -0
- package/dist/google-vertex-Bhyo4z2i.mjs +400 -0
- package/dist/google-vertex-Bhyo4z2i.mjs.map +1 -0
- package/dist/hash-Dbggamac.mjs +19 -0
- package/dist/hash-Dbggamac.mjs.map +1 -0
- package/dist/headers-CPzZhJQn.mjs +17 -0
- package/dist/headers-CPzZhJQn.mjs.map +1 -0
- package/dist/host.d.mts +12 -2
- package/dist/host.d.mts.map +1 -1
- package/dist/host.mjs +43 -5
- package/dist/host.mjs.map +1 -1
- package/dist/index.d.mts +5 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +40 -16
- package/dist/index.mjs.map +1 -1
- package/dist/json-parse-CZ0U0sj_.mjs +384 -0
- package/dist/json-parse-CZ0U0sj_.mjs.map +1 -0
- package/dist/mcp-config-jmzbgdHa.mjs +181 -0
- package/dist/mcp-config-jmzbgdHa.mjs.map +1 -0
- package/dist/mistral-conversations-DJyeTo8C.mjs +36921 -0
- package/dist/mistral-conversations-DJyeTo8C.mjs.map +1 -0
- package/dist/multipart-parser-SRcGkVuX.mjs +301 -0
- package/dist/multipart-parser-SRcGkVuX.mjs.map +1 -0
- package/dist/{pi-ai-D7PqVeWs.mjs → openai-DkzRh5_G.mjs} +78 -5063
- package/dist/openai-DkzRh5_G.mjs.map +1 -0
- package/dist/openai-codex-responses-DedxQjNG.mjs +1220 -0
- package/dist/openai-codex-responses-DedxQjNG.mjs.map +1 -0
- package/dist/openai-completions-DrjrWRdX.mjs +945 -0
- package/dist/openai-completions-DrjrWRdX.mjs.map +1 -0
- package/dist/openai-prompt-cache-BDWtZRKh.mjs +11 -0
- package/dist/openai-prompt-cache-BDWtZRKh.mjs.map +1 -0
- package/dist/openai-responses-BRdGpBX6.mjs +251 -0
- package/dist/openai-responses-BRdGpBX6.mjs.map +1 -0
- package/dist/openai-responses-shared-BmnSvdKL.mjs +570 -0
- package/dist/openai-responses-shared-BmnSvdKL.mjs.map +1 -0
- package/dist/otel-CBhmS-NR.mjs +24935 -0
- package/dist/otel-CBhmS-NR.mjs.map +1 -0
- package/dist/pi-ai-CfokFhIL.d.mts +2673 -0
- package/dist/pi-ai-CfokFhIL.d.mts.map +1 -0
- package/dist/pi-ai-Dh7HUxbt.mjs +3239 -0
- package/dist/pi-ai-Dh7HUxbt.mjs.map +1 -0
- package/dist/{pi-coding-agent-B0PT23gE.d.mts → pi-coding-agent-69yY0ke-.d.mts} +4 -2
- package/dist/{pi-coding-agent-B0PT23gE.d.mts.map → pi-coding-agent-69yY0ke-.d.mts.map} +1 -1
- package/dist/{pi-coding-agent-BVZu0dHG.mjs → pi-coding-agent-Cvez0jkF.mjs} +0 -0
- package/dist/{pi-coding-agent-BVZu0dHG.mjs.map → pi-coding-agent-Cvez0jkF.mjs.map} +1 -1
- package/dist/pi-messages-D61G2tgs.mjs +307 -0
- package/dist/pi-messages-D61G2tgs.mjs.map +1 -0
- package/dist/provider-env-C72pF4vP.mjs +40 -0
- package/dist/provider-env-C72pF4vP.mjs.map +1 -0
- package/dist/provider-retry-Cw6YJ4cr.mjs +80 -0
- package/dist/provider-retry-Cw6YJ4cr.mjs.map +1 -0
- package/dist/rolldown-runtime-CTfmNlz1.mjs +44 -0
- package/dist/{runtime-DEjs_Qlf.mjs → runtime-Dd2KhoX-.mjs} +659 -125
- package/dist/runtime-Dd2KhoX-.mjs.map +1 -0
- package/dist/runtime.d.mts +135 -26
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/simple-options-B_GO8FDE.mjs +456 -0
- package/dist/simple-options-B_GO8FDE.mjs.map +1 -0
- package/dist/src-DlTagfW5.mjs +1186 -0
- package/dist/src-DlTagfW5.mjs.map +1 -0
- package/dist/{types-7IWJPPvS.d.mts → types-B9VBF8le.d.mts} +2 -9
- package/dist/{types-7IWJPPvS.d.mts.map → types-B9VBF8le.d.mts.map} +1 -1
- package/package.json +2 -2
- package/dist/compat/pi-ai.d.mts.map +0 -1
- package/dist/mcp-config-_idn-pzI.mjs.map +0 -1
- package/dist/pi-ai-D7PqVeWs.mjs.map +0 -1
- package/dist/runtime-DEjs_Qlf.mjs.map +0 -1
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
|
|
2
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/models.js
|
|
3
|
+
function calculateCost(model, usage) {
|
|
4
|
+
const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
5
|
+
let rates = model.cost;
|
|
6
|
+
let matchedThreshold = -1;
|
|
7
|
+
for (const tier of model.cost.tiers ?? []) if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {
|
|
8
|
+
rates = tier;
|
|
9
|
+
matchedThreshold = tier.inputTokensAbove;
|
|
10
|
+
}
|
|
11
|
+
const longWrite = usage.cacheWrite1h ?? 0;
|
|
12
|
+
const shortWrite = usage.cacheWrite - longWrite;
|
|
13
|
+
usage.cost.input = rates.input / 1e6 * usage.input;
|
|
14
|
+
usage.cost.output = rates.output / 1e6 * usage.output;
|
|
15
|
+
usage.cost.cacheRead = rates.cacheRead / 1e6 * usage.cacheRead;
|
|
16
|
+
usage.cost.cacheWrite = (rates.cacheWrite * shortWrite + rates.input * 2 * longWrite) / 1e6;
|
|
17
|
+
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
18
|
+
return usage.cost;
|
|
19
|
+
}
|
|
20
|
+
const EXTENDED_THINKING_LEVELS = [
|
|
21
|
+
"off",
|
|
22
|
+
"minimal",
|
|
23
|
+
"low",
|
|
24
|
+
"medium",
|
|
25
|
+
"high",
|
|
26
|
+
"xhigh",
|
|
27
|
+
"max"
|
|
28
|
+
];
|
|
29
|
+
function getSupportedThinkingLevels(model) {
|
|
30
|
+
if (!model.reasoning) return ["off"];
|
|
31
|
+
return EXTENDED_THINKING_LEVELS.filter((level) => {
|
|
32
|
+
const mapped = model.thinkingLevelMap?.[level];
|
|
33
|
+
if (mapped === null) return false;
|
|
34
|
+
if (level === "xhigh" || level === "max") return mapped !== void 0;
|
|
35
|
+
return true;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function clampThinkingLevel(model, level) {
|
|
39
|
+
const availableLevels = getSupportedThinkingLevels(model);
|
|
40
|
+
if (availableLevels.includes(level)) return level;
|
|
41
|
+
const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
|
|
42
|
+
if (requestedIndex === -1) return availableLevels[0] ?? "off";
|
|
43
|
+
for (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {
|
|
44
|
+
const candidate = EXTENDED_THINKING_LEVELS[i];
|
|
45
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
46
|
+
}
|
|
47
|
+
for (let i = requestedIndex - 1; i >= 0; i--) {
|
|
48
|
+
const candidate = EXTENDED_THINKING_LEVELS[i];
|
|
49
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
50
|
+
}
|
|
51
|
+
return availableLevels[0] ?? "off";
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js
|
|
55
|
+
function getGrammarToolInput(toolName, arguments_, inputProperty) {
|
|
56
|
+
const input = arguments_[inputProperty];
|
|
57
|
+
if (typeof input !== "string") throw new Error(`Grammar tool call "${toolName}" requires argument "${inputProperty}" to be a string.`);
|
|
58
|
+
return input;
|
|
59
|
+
}
|
|
60
|
+
function appendGrammarToolInputJsonDelta(buffer, inputProperty, nextInput, close) {
|
|
61
|
+
if (buffer.closed) {
|
|
62
|
+
if (close && nextInput === buffer.input) return void 0;
|
|
63
|
+
throw new Error(`grammar tool input for property "${inputProperty}" changed after it was closed`);
|
|
64
|
+
}
|
|
65
|
+
if (!nextInput.startsWith(buffer.input)) throw new Error(`grammar tool input for property "${inputProperty}" changed non-monotonically`);
|
|
66
|
+
const inputDelta = nextInput.slice(buffer.input.length);
|
|
67
|
+
if (!close && inputDelta.length === 0) return void 0;
|
|
68
|
+
let delta = "";
|
|
69
|
+
if (!buffer.started) {
|
|
70
|
+
delta += `{${JSON.stringify(inputProperty)}:"`;
|
|
71
|
+
buffer.started = true;
|
|
72
|
+
}
|
|
73
|
+
delta += JSON.stringify(inputDelta).slice(1, -1);
|
|
74
|
+
buffer.input = nextInput;
|
|
75
|
+
if (close) {
|
|
76
|
+
delta += "\"}";
|
|
77
|
+
buffer.closed = true;
|
|
78
|
+
}
|
|
79
|
+
return delta;
|
|
80
|
+
}
|
|
81
|
+
function inferGrammarInputProperty(tool) {
|
|
82
|
+
const schema = tool.parameters;
|
|
83
|
+
if (schema.type !== "object") throw new Error("grammar constrained sampling requires an object parameter schema");
|
|
84
|
+
if (!Array.isArray(schema.required) || schema.required.length !== 1 || typeof schema.required[0] !== "string") throw new Error("grammar constrained sampling requires exactly one required string property");
|
|
85
|
+
const inputProperty = schema.required[0];
|
|
86
|
+
if (!schema.properties?.[inputProperty]) throw new Error(`grammar constrained sampling requires a properties entry for ${inputProperty}`);
|
|
87
|
+
if (schema.properties[inputProperty]?.type !== "string") throw new Error(`grammar constrained sampling property ${inputProperty} must have type string`);
|
|
88
|
+
return inputProperty;
|
|
89
|
+
}
|
|
90
|
+
function resolveJsonSchemaStrictSampling(tool, supportsStrictMode) {
|
|
91
|
+
const config = tool.constrainedSampling;
|
|
92
|
+
if (!config || config.type !== "json_schema") return;
|
|
93
|
+
if (supportsStrictMode) return true;
|
|
94
|
+
if (config.strict === "require") throw new Error(`Tool "${tool.name}" requires JSON-schema constrained sampling, but strict tools are unsupported.`);
|
|
95
|
+
}
|
|
96
|
+
function resolveGrammarConstrainedSampling(tool, supportsOpenAIGrammarTools) {
|
|
97
|
+
const config = tool.constrainedSampling;
|
|
98
|
+
if (!config || config.type !== "grammar") return;
|
|
99
|
+
if (!supportsOpenAIGrammarTools) return;
|
|
100
|
+
const larkDefinition = config.variants.openai_lark;
|
|
101
|
+
const regexDefinition = config.variants.openai_regex;
|
|
102
|
+
const hasLarkDefinition = typeof larkDefinition === "string" && larkDefinition.trim().length > 0;
|
|
103
|
+
const hasRegexDefinition = typeof regexDefinition === "string" && regexDefinition.trim().length > 0;
|
|
104
|
+
if (!hasLarkDefinition && !hasRegexDefinition) throw new Error(`Tool "${tool.name}" cannot use grammar constrained sampling: no supported grammar variant was provided.`);
|
|
105
|
+
try {
|
|
106
|
+
return {
|
|
107
|
+
format: hasLarkDefinition ? "lark" : "regex",
|
|
108
|
+
definition: hasLarkDefinition ? larkDefinition : regexDefinition,
|
|
109
|
+
inputProperty: inferGrammarInputProperty(tool)
|
|
110
|
+
};
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
113
|
+
throw new Error(`Tool "${tool.name}" cannot use grammar constrained sampling: ${message}.`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function createGrammarToolInputProperties(tools, supportsOpenAIGrammarTools) {
|
|
117
|
+
const properties = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const tool of tools ?? []) {
|
|
119
|
+
const grammar = resolveGrammarConstrainedSampling(tool, supportsOpenAIGrammarTools);
|
|
120
|
+
if (grammar) properties.set(tool.name, grammar.inputProperty);
|
|
121
|
+
}
|
|
122
|
+
return properties;
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/sanitize-unicode.js
|
|
126
|
+
/**
|
|
127
|
+
* Removes unpaired Unicode surrogate characters from a string.
|
|
128
|
+
*
|
|
129
|
+
* Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
|
|
130
|
+
* or vice versa) cause JSON serialization errors in many API providers.
|
|
131
|
+
*
|
|
132
|
+
* Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
|
|
133
|
+
* surrogates and will NOT be affected by this function.
|
|
134
|
+
*
|
|
135
|
+
* @param text - The text to sanitize
|
|
136
|
+
* @returns The sanitized text with unpaired surrogates removed
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* // Valid emoji (properly paired surrogates) are preserved
|
|
140
|
+
* sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
|
|
141
|
+
*
|
|
142
|
+
* // Unpaired high surrogate is removed
|
|
143
|
+
* const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
|
|
144
|
+
* sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
|
|
145
|
+
*/
|
|
146
|
+
function sanitizeSurrogates(text) {
|
|
147
|
+
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js
|
|
151
|
+
const NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
152
|
+
const NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
153
|
+
function replaceImagesWithPlaceholder(content, placeholder) {
|
|
154
|
+
const result = [];
|
|
155
|
+
let previousWasPlaceholder = false;
|
|
156
|
+
for (const block of content) {
|
|
157
|
+
if (block.type === "image") {
|
|
158
|
+
if (!previousWasPlaceholder) result.push({
|
|
159
|
+
type: "text",
|
|
160
|
+
text: placeholder
|
|
161
|
+
});
|
|
162
|
+
previousWasPlaceholder = true;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
result.push(block);
|
|
166
|
+
previousWasPlaceholder = block.text === placeholder;
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
function downgradeUnsupportedImages(messages, model) {
|
|
171
|
+
if (model.input.includes("image")) return messages;
|
|
172
|
+
return messages.map((msg) => {
|
|
173
|
+
if (msg.role === "user" && Array.isArray(msg.content)) return {
|
|
174
|
+
...msg,
|
|
175
|
+
content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER)
|
|
176
|
+
};
|
|
177
|
+
if (msg.role === "toolResult") return {
|
|
178
|
+
...msg,
|
|
179
|
+
content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER)
|
|
180
|
+
};
|
|
181
|
+
return msg;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Normalize tool call ID for cross-provider compatibility.
|
|
186
|
+
* OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
|
|
187
|
+
* Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
|
|
188
|
+
*/
|
|
189
|
+
function transformMessages(messages, model, normalizeToolCallId) {
|
|
190
|
+
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
191
|
+
const transformed = downgradeUnsupportedImages(messages.map((msg) => msg.content == null ? {
|
|
192
|
+
...msg,
|
|
193
|
+
content: []
|
|
194
|
+
} : msg), model).map((msg) => {
|
|
195
|
+
if (msg.role === "user") return msg;
|
|
196
|
+
if (msg.role === "toolResult") {
|
|
197
|
+
const normalizedId = toolCallIdMap.get(msg.toolCallId);
|
|
198
|
+
if (normalizedId && normalizedId !== msg.toolCallId) return {
|
|
199
|
+
...msg,
|
|
200
|
+
toolCallId: normalizedId
|
|
201
|
+
};
|
|
202
|
+
return msg;
|
|
203
|
+
}
|
|
204
|
+
if (msg.role === "assistant") {
|
|
205
|
+
const assistantMsg = msg;
|
|
206
|
+
const isSameModel = assistantMsg.provider === model.provider && assistantMsg.api === model.api && assistantMsg.model === model.id;
|
|
207
|
+
const transformedContent = assistantMsg.content.flatMap((block) => {
|
|
208
|
+
if (block.type === "thinking") {
|
|
209
|
+
if (block.redacted) return isSameModel ? block : [];
|
|
210
|
+
if (isSameModel && block.thinkingSignature) return block;
|
|
211
|
+
if (!block.thinking || block.thinking.trim() === "") return [];
|
|
212
|
+
if (isSameModel) return block;
|
|
213
|
+
return {
|
|
214
|
+
type: "text",
|
|
215
|
+
text: block.thinking
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
if (block.type === "text") {
|
|
219
|
+
if (isSameModel) return block;
|
|
220
|
+
return {
|
|
221
|
+
type: "text",
|
|
222
|
+
text: block.text
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (block.type === "toolCall") {
|
|
226
|
+
const toolCall = block;
|
|
227
|
+
let normalizedToolCall = toolCall;
|
|
228
|
+
if (!isSameModel && toolCall.thoughtSignature) {
|
|
229
|
+
normalizedToolCall = { ...toolCall };
|
|
230
|
+
delete normalizedToolCall.thoughtSignature;
|
|
231
|
+
}
|
|
232
|
+
if (!isSameModel && normalizeToolCallId) {
|
|
233
|
+
const normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);
|
|
234
|
+
if (normalizedId !== toolCall.id) {
|
|
235
|
+
toolCallIdMap.set(toolCall.id, normalizedId);
|
|
236
|
+
normalizedToolCall = {
|
|
237
|
+
...normalizedToolCall,
|
|
238
|
+
id: normalizedId
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return normalizedToolCall;
|
|
243
|
+
}
|
|
244
|
+
return block;
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
...assistantMsg,
|
|
248
|
+
content: transformedContent
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
return msg;
|
|
252
|
+
});
|
|
253
|
+
const result = [];
|
|
254
|
+
let pendingToolCalls = [];
|
|
255
|
+
let existingToolResultIds = /* @__PURE__ */ new Set();
|
|
256
|
+
const insertSyntheticToolResults = () => {
|
|
257
|
+
if (pendingToolCalls.length > 0) {
|
|
258
|
+
for (const tc of pendingToolCalls) if (!existingToolResultIds.has(tc.id)) result.push({
|
|
259
|
+
role: "toolResult",
|
|
260
|
+
toolCallId: tc.id,
|
|
261
|
+
toolName: tc.name,
|
|
262
|
+
content: [{
|
|
263
|
+
type: "text",
|
|
264
|
+
text: "No result provided"
|
|
265
|
+
}],
|
|
266
|
+
isError: true,
|
|
267
|
+
timestamp: Date.now()
|
|
268
|
+
});
|
|
269
|
+
pendingToolCalls = [];
|
|
270
|
+
existingToolResultIds = /* @__PURE__ */ new Set();
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
for (let i = 0; i < transformed.length; i++) {
|
|
274
|
+
const msg = transformed[i];
|
|
275
|
+
if (msg.role === "assistant") {
|
|
276
|
+
insertSyntheticToolResults();
|
|
277
|
+
const assistantMsg = msg;
|
|
278
|
+
if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") continue;
|
|
279
|
+
const toolCalls = assistantMsg.content.filter((b) => b.type === "toolCall");
|
|
280
|
+
if (toolCalls.length > 0) {
|
|
281
|
+
pendingToolCalls = toolCalls;
|
|
282
|
+
existingToolResultIds = /* @__PURE__ */ new Set();
|
|
283
|
+
}
|
|
284
|
+
result.push(msg);
|
|
285
|
+
} else if (msg.role === "toolResult") {
|
|
286
|
+
existingToolResultIds.add(msg.toolCallId);
|
|
287
|
+
result.push(msg);
|
|
288
|
+
} else if (msg.role === "user") {
|
|
289
|
+
insertSyntheticToolResults();
|
|
290
|
+
result.push(msg);
|
|
291
|
+
} else result.push(msg);
|
|
292
|
+
}
|
|
293
|
+
insertSyntheticToolResults();
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
//#endregion
|
|
297
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js
|
|
298
|
+
const CHARS_PER_TOKEN = 4;
|
|
299
|
+
const ESTIMATED_IMAGE_CHARS = 4800;
|
|
300
|
+
function calculateContextTokens(usage) {
|
|
301
|
+
return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
302
|
+
}
|
|
303
|
+
function safeJsonStringify(value) {
|
|
304
|
+
try {
|
|
305
|
+
return JSON.stringify(value) ?? "undefined";
|
|
306
|
+
} catch {
|
|
307
|
+
return "[unserializable]";
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function estimateTextAndImageContentChars(content) {
|
|
311
|
+
if (typeof content === "string") return content.length;
|
|
312
|
+
let chars = 0;
|
|
313
|
+
for (const block of content) chars += block.type === "text" ? block.text.length : ESTIMATED_IMAGE_CHARS;
|
|
314
|
+
return chars;
|
|
315
|
+
}
|
|
316
|
+
function estimateTextTokens(text) {
|
|
317
|
+
return Math.ceil(text.length / CHARS_PER_TOKEN);
|
|
318
|
+
}
|
|
319
|
+
function estimateTextAndImageContentTokens(content) {
|
|
320
|
+
return Math.ceil(estimateTextAndImageContentChars(content) / CHARS_PER_TOKEN);
|
|
321
|
+
}
|
|
322
|
+
function estimateMessageTokens(message) {
|
|
323
|
+
let chars = 0;
|
|
324
|
+
if (message.role === "user") return estimateTextAndImageContentTokens(message.content);
|
|
325
|
+
if (message.role === "toolResult") return estimateTextAndImageContentTokens(message.content);
|
|
326
|
+
for (const block of message.content) if (block.type === "text") chars += block.text.length;
|
|
327
|
+
else if (block.type === "thinking") chars += block.thinking.length;
|
|
328
|
+
else chars += block.name.length + safeJsonStringify(block.arguments).length;
|
|
329
|
+
return Math.ceil(chars / CHARS_PER_TOKEN);
|
|
330
|
+
}
|
|
331
|
+
function getLastAssistantUsageInfo(messages) {
|
|
332
|
+
let latestPrefixTimestamp = Number.NEGATIVE_INFINITY;
|
|
333
|
+
let usageInfo;
|
|
334
|
+
for (let i = 0; i < messages.length; i++) {
|
|
335
|
+
const message = messages[i];
|
|
336
|
+
if (message.role === "assistant") {
|
|
337
|
+
const assistant = message;
|
|
338
|
+
if (assistant.timestamp >= latestPrefixTimestamp && assistant.stopReason !== "aborted" && assistant.stopReason !== "error" && calculateContextTokens(assistant.usage) > 0) usageInfo = {
|
|
339
|
+
usage: assistant.usage,
|
|
340
|
+
index: i
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
latestPrefixTimestamp = Math.max(latestPrefixTimestamp, message.timestamp);
|
|
344
|
+
}
|
|
345
|
+
return usageInfo;
|
|
346
|
+
}
|
|
347
|
+
function estimateMessages(messages) {
|
|
348
|
+
const usageInfo = getLastAssistantUsageInfo(messages);
|
|
349
|
+
if (usageInfo) {
|
|
350
|
+
const usageTokens = calculateContextTokens(usageInfo.usage);
|
|
351
|
+
let trailingTokens = 0;
|
|
352
|
+
for (let i = usageInfo.index + 1; i < messages.length; i++) trailingTokens += estimateMessageTokens(messages[i]);
|
|
353
|
+
return {
|
|
354
|
+
tokens: usageTokens + trailingTokens,
|
|
355
|
+
usageTokens,
|
|
356
|
+
trailingTokens,
|
|
357
|
+
lastUsageIndex: usageInfo.index
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
let tokens = 0;
|
|
361
|
+
for (const message of messages) tokens += estimateMessageTokens(message);
|
|
362
|
+
return {
|
|
363
|
+
tokens,
|
|
364
|
+
usageTokens: 0,
|
|
365
|
+
trailingTokens: tokens,
|
|
366
|
+
lastUsageIndex: null
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function estimateToolsTokens(tools) {
|
|
370
|
+
if (!tools || tools.length === 0) return 0;
|
|
371
|
+
return estimateTextTokens(safeJsonStringify(tools));
|
|
372
|
+
}
|
|
373
|
+
function isMessageArray(value) {
|
|
374
|
+
return Array.isArray(value);
|
|
375
|
+
}
|
|
376
|
+
function estimateContextTokens(context) {
|
|
377
|
+
if (isMessageArray(context)) return estimateMessages(context);
|
|
378
|
+
const estimate = estimateMessages(context.messages);
|
|
379
|
+
if (estimate.lastUsageIndex !== null) {
|
|
380
|
+
const addedNames = new Set(context.messages.slice(estimate.lastUsageIndex + 1).filter((message) => message.role === "toolResult").flatMap((message) => message.addedToolNames ?? []));
|
|
381
|
+
const addedToolTokens = estimateToolsTokens(context.tools?.filter((tool) => addedNames.has(tool.name)));
|
|
382
|
+
return {
|
|
383
|
+
tokens: estimate.tokens + addedToolTokens,
|
|
384
|
+
usageTokens: estimate.usageTokens,
|
|
385
|
+
trailingTokens: estimate.trailingTokens + addedToolTokens,
|
|
386
|
+
lastUsageIndex: estimate.lastUsageIndex
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
const prefixTokens = (context.systemPrompt ? estimateTextTokens(context.systemPrompt) : 0) + estimateToolsTokens(context.tools);
|
|
390
|
+
return {
|
|
391
|
+
tokens: estimate.tokens + prefixTokens,
|
|
392
|
+
usageTokens: estimate.usageTokens,
|
|
393
|
+
trailingTokens: estimate.trailingTokens + prefixTokens,
|
|
394
|
+
lastUsageIndex: estimate.lastUsageIndex
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js
|
|
399
|
+
const CONTEXT_SAFETY_TOKENS = 4096;
|
|
400
|
+
const MIN_MAX_TOKENS = 1;
|
|
401
|
+
function clampMaxTokensToContext(model, context, maxTokens) {
|
|
402
|
+
if (model.contextWindow <= 0) return Math.max(MIN_MAX_TOKENS, maxTokens);
|
|
403
|
+
const available = model.contextWindow - estimateContextTokens(context).tokens - CONTEXT_SAFETY_TOKENS;
|
|
404
|
+
return Math.min(maxTokens, Math.max(MIN_MAX_TOKENS, available));
|
|
405
|
+
}
|
|
406
|
+
function buildBaseOptions(model, context, options, apiKey) {
|
|
407
|
+
const samplingParams = model.samplingParams || options?.samplingParams ? {
|
|
408
|
+
...model.samplingParams,
|
|
409
|
+
...options?.samplingParams
|
|
410
|
+
} : void 0;
|
|
411
|
+
return {
|
|
412
|
+
temperature: options?.temperature,
|
|
413
|
+
samplingParams,
|
|
414
|
+
maxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),
|
|
415
|
+
signal: options?.signal,
|
|
416
|
+
telemetryContext: options?.telemetryContext,
|
|
417
|
+
apiKey: apiKey || options?.apiKey,
|
|
418
|
+
fetch: options?.fetch,
|
|
419
|
+
transport: options?.transport,
|
|
420
|
+
cacheRetention: options?.cacheRetention,
|
|
421
|
+
sessionId: options?.sessionId,
|
|
422
|
+
headers: options?.headers,
|
|
423
|
+
onPayload: options?.onPayload,
|
|
424
|
+
onResponse: options?.onResponse,
|
|
425
|
+
timeoutMs: options?.timeoutMs,
|
|
426
|
+
websocketConnectTimeoutMs: options?.websocketConnectTimeoutMs,
|
|
427
|
+
maxRetries: options?.maxRetries,
|
|
428
|
+
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
429
|
+
metadata: options?.metadata,
|
|
430
|
+
env: options?.env
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
/** Tokens always left for the answer when a thinking budget shares the response ceiling. */
|
|
434
|
+
const MIN_ANSWER_TOKENS = 1024;
|
|
435
|
+
function clampReasoning(effort) {
|
|
436
|
+
return effort === "xhigh" || effort === "max" ? "high" : effort;
|
|
437
|
+
}
|
|
438
|
+
function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
|
|
439
|
+
let thinkingBudget = {
|
|
440
|
+
minimal: 1024,
|
|
441
|
+
low: 2048,
|
|
442
|
+
medium: 8192,
|
|
443
|
+
high: 16384,
|
|
444
|
+
...customBudgets
|
|
445
|
+
}[clampReasoning(reasoningLevel)];
|
|
446
|
+
const maxTokens = baseMaxTokens === void 0 ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
|
|
447
|
+
if (maxTokens <= thinkingBudget) thinkingBudget = Math.max(0, maxTokens - MIN_ANSWER_TOKENS);
|
|
448
|
+
return {
|
|
449
|
+
maxTokens,
|
|
450
|
+
thinkingBudget
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
//#endregion
|
|
454
|
+
export { clampReasoning as a, appendGrammarToolInputJsonDelta as c, resolveGrammarConstrainedSampling as d, resolveJsonSchemaStrictSampling as f, clampMaxTokensToContext as i, createGrammarToolInputProperties as l, clampThinkingLevel as m, adjustMaxTokensForThinking as n, transformMessages as o, calculateCost as p, buildBaseOptions as r, sanitizeSurrogates as s, MIN_ANSWER_TOKENS as t, getGrammarToolInput as u };
|
|
455
|
+
|
|
456
|
+
//# sourceMappingURL=simple-options-B_GO8FDE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-options-B_GO8FDE.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/models.js","../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js","../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/sanitize-unicode.js","../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js","../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js","../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/simple-options.js"],"sourcesContent":["import { lazyStream } from \"./api/lazy.js\";\nimport { defaultProviderAuthContext as defaultAuthContext } from \"./auth/context.js\";\nimport { InMemoryCredentialStore } from \"./auth/credential-store.js\";\nimport { ModelsError, resolveProviderAuth } from \"./auth/resolve.js\";\nimport { InMemoryModelsStore } from \"./models-store.js\";\nimport { operationSignal, raceWithAbortSignal } from \"./utils/abort.js\";\nexport { ModelsError } from \"./auth/resolve.js\";\nfunction mergeHeaders(base, override) {\n if (!base && !override)\n return undefined;\n const merged = { ...base };\n for (const [name, value] of Object.entries(override ?? {})) {\n const lowerName = name.toLowerCase();\n for (const existingName of Object.keys(merged)) {\n if (existingName.toLowerCase() === lowerName)\n delete merged[existingName];\n }\n merged[name] = value;\n }\n return merged;\n}\nclass ModelsImpl {\n providers = new Map();\n credentials;\n modelsStore;\n authContext;\n refreshGenerations = new Map();\n refreshControllers = new Map();\n publicationChains = new Map();\n constructor(options) {\n this.credentials = options?.credentials ?? new InMemoryCredentialStore();\n this.modelsStore = options?.modelsStore ?? new InMemoryModelsStore();\n this.authContext = options?.authContext ?? defaultAuthContext();\n }\n setProvider(provider) {\n this.supersedeProviderRefresh(provider.id);\n this.providers.set(provider.id, provider);\n }\n deleteProvider(id) {\n this.supersedeProviderRefresh(id);\n this.providers.delete(id);\n }\n clearProviders() {\n for (const id of new Set([...this.providers.keys(), ...this.refreshControllers.keys()])) {\n this.supersedeProviderRefresh(id);\n }\n this.providers.clear();\n }\n getProviders() {\n return Array.from(this.providers.values());\n }\n getProvider(id) {\n return this.providers.get(id);\n }\n getModels(provider) {\n if (provider !== undefined) {\n const entry = this.providers.get(provider);\n if (!entry)\n return [];\n try {\n return entry.getModels();\n }\n catch {\n return [];\n }\n }\n const models = [];\n for (const entry of this.providers.values()) {\n try {\n models.push(...entry.getModels());\n }\n catch {\n // Best-effort: ill-behaved providers yield no models.\n }\n }\n return models;\n }\n getModel(provider, id) {\n return this.getModels(provider).find((model) => model.id === id);\n }\n supersedeProviderRefresh(providerId) {\n const generation = (this.refreshGenerations.get(providerId) ?? 0) + 1;\n this.refreshGenerations.set(providerId, generation);\n const previous = this.refreshControllers.get(providerId);\n if (previous) {\n this.refreshControllers.delete(providerId);\n previous.abort();\n }\n return generation;\n }\n beginProviderRefresh(providerId) {\n const generation = this.supersedeProviderRefresh(providerId);\n const controller = new AbortController();\n this.refreshControllers.set(providerId, controller);\n return { generation, controller };\n }\n publishProviderModels(providerId, generation, signal, publication) {\n const previous = this.publicationChains.get(providerId) ?? Promise.resolve();\n const queued = (async () => {\n await previous.catch(() => { });\n if (signal.aborted || this.refreshGenerations.get(providerId) !== generation)\n return false;\n if (publication.persist === null) {\n await this.modelsStore.delete(providerId, { signal });\n }\n else if (publication.persist !== undefined) {\n await this.modelsStore.write(providerId, structuredClone(publication.persist), { signal });\n }\n if (signal.aborted || this.refreshGenerations.get(providerId) !== generation)\n return false;\n publication.update?.();\n return true;\n })();\n const tail = queued.catch(() => { });\n this.publicationChains.set(providerId, tail);\n void tail.then(() => {\n if (this.publicationChains.get(providerId) === tail)\n this.publicationChains.delete(providerId);\n });\n return raceWithAbortSignal(queued, signal);\n }\n async runProviderRefreshPhase(provider, credential, allowNetwork, force, generation, signal) {\n const stored = await this.modelsStore.read(provider.id, { signal });\n await provider.refreshModels({\n credential,\n stored: stored ? structuredClone(stored) : undefined,\n publish: (publication) => this.publishProviderModels(provider.id, generation, signal, publication),\n allowNetwork,\n force: allowNetwork ? force : undefined,\n signal,\n });\n }\n async refresh(options = {}) {\n const allowNetwork = options.allowNetwork ?? true;\n const callerSignal = operationSignal(options.signal);\n const errors = new Map();\n if (callerSignal.aborted)\n return { aborted: true, errors };\n const selected = options.providers ? new Set(options.providers) : undefined;\n const refreshable = Array.from(this.providers.values()).filter((provider) => provider.refreshModels !== undefined && (!selected || selected.has(provider.id)));\n const refresh = Promise.all(refreshable.map(async (provider) => {\n const { generation, controller } = this.beginProviderRefresh(provider.id);\n const signal = AbortSignal.any([callerSignal, controller.signal]);\n const operation = (async () => {\n let storedCredential;\n let credentialError;\n try {\n storedCredential = await this.readCredential(provider.id, signal);\n }\n catch (error) {\n credentialError = error;\n }\n // Restore cached provider state before auth resolution or network access.\n await this.runProviderRefreshPhase(provider, storedCredential, false, undefined, generation, signal);\n if (credentialError !== undefined)\n throw credentialError;\n if (!allowNetwork || signal.aborted)\n return;\n const credential = await this.resolveRefreshCredential(provider, storedCredential, signal);\n if (!credential)\n return;\n await this.runProviderRefreshPhase(provider, credential, true, options.force, generation, signal);\n })();\n try {\n await raceWithAbortSignal(operation, signal);\n }\n catch (error) {\n if (!signal.aborted) {\n errors.set(provider.id, error instanceof Error\n ? error\n : new ModelsError(\"model_source\", `Model refresh failed for ${provider.id}`, { cause: error }));\n }\n }\n finally {\n if (this.refreshControllers.get(provider.id) === controller) {\n this.refreshControllers.delete(provider.id);\n }\n }\n }));\n try {\n await raceWithAbortSignal(refresh, callerSignal);\n }\n catch (error) {\n if (!callerSignal.aborted)\n throw error;\n }\n return { aborted: callerSignal.aborted, errors: new Map(errors) };\n }\n async resolveRefreshCredential(provider, stored, signal) {\n if (stored?.type === \"oauth\") {\n const oauth = provider.auth.oauth;\n if (!oauth)\n return undefined;\n if (Date.now() < stored.expires)\n return stored;\n if (signal.aborted)\n return undefined;\n const post = await this.credentials.modify(provider.id, async (current) => {\n if (current?.type !== \"oauth\" || Date.now() < current.expires)\n return undefined;\n return oauth.refresh(current, signal);\n }, { signal });\n return post?.type === \"oauth\" ? post : undefined;\n }\n const apiKey = provider.auth.apiKey;\n if (!apiKey)\n return undefined;\n const credential = stored?.type === \"api_key\" ? stored : undefined;\n const result = await apiKey.resolve({ ctx: this.authContext, credential, signal });\n if (!result)\n return undefined;\n return { type: \"api_key\", key: result.auth.apiKey, env: result.env };\n }\n async readCredential(providerId, signal) {\n try {\n return await this.credentials.read(providerId, { signal });\n }\n catch (error) {\n throw new ModelsError(\"auth\", `Credential store read failed for ${providerId}`, { cause: error });\n }\n }\n async checkProviderAuth(provider, credential, signal) {\n if (credential?.type === \"oauth\") {\n return provider.auth.oauth ? { source: \"OAuth\", type: \"oauth\" } : undefined;\n }\n const apiKey = provider.auth.apiKey;\n if (!apiKey)\n return undefined;\n if (apiKey.check) {\n try {\n return await apiKey.check({\n ctx: this.authContext,\n credential: credential?.type === \"api_key\" ? credential : undefined,\n signal,\n });\n }\n catch (error) {\n throw new ModelsError(\"auth\", `API key auth check failed for provider ${provider.id}`, { cause: error });\n }\n }\n const resolution = await resolveProviderAuth(provider, this.credentials, this.authContext, { signal });\n return resolution ? { source: resolution.source, type: \"api_key\" } : undefined;\n }\n checkAuth(providerId, options) {\n const signal = operationSignal(options?.signal);\n const check = (async () => {\n signal.throwIfAborted();\n const provider = this.providers.get(providerId);\n if (!provider)\n return undefined;\n return this.checkProviderAuth(provider, await this.readCredential(providerId, signal), signal);\n })();\n return raceWithAbortSignal(check, signal);\n }\n getAvailable(providerId, options) {\n const signal = operationSignal(options?.signal);\n const available = (async () => {\n signal.throwIfAborted();\n const providers = providerId\n ? [this.providers.get(providerId)].filter((entry) => entry !== undefined)\n : this.getProviders();\n const checks = await Promise.all(providers.map(async (provider) => {\n const credential = await this.readCredential(provider.id, signal);\n return { provider, credential, auth: await this.checkProviderAuth(provider, credential, signal) };\n }));\n return checks.flatMap(({ provider, credential, auth }) => {\n if (!auth)\n return [];\n const models = provider.getModels();\n return provider.filterModels?.(models, credential) ?? models;\n });\n })();\n return raceWithAbortSignal(available, signal);\n }\n async getAuth(providerOrModel, overrides) {\n const signal = operationSignal(overrides?.signal);\n const providerId = typeof providerOrModel === \"string\" ? providerOrModel : providerOrModel.provider;\n const provider = this.providers.get(providerId);\n if (!provider)\n return undefined;\n const result = await resolveProviderAuth(provider, this.credentials, this.authContext, { ...overrides, signal });\n if (!result || typeof providerOrModel === \"string\" || !providerOrModel.headers)\n return result;\n return {\n ...result,\n auth: {\n ...result.auth,\n headers: mergeHeaders(result.auth.headers, providerOrModel.headers),\n },\n };\n }\n async login(providerId, type, interaction) {\n const signal = operationSignal(interaction.signal);\n signal.throwIfAborted();\n const provider = this.providers.get(providerId);\n if (!provider)\n throw new ModelsError(\"provider\", `Unknown provider: ${providerId}`);\n const method = type === \"oauth\" ? provider.auth.oauth : provider.auth.apiKey;\n if (!method?.login) {\n throw new ModelsError(\"auth\", `${provider.name} does not support ${type} login`);\n }\n const loginOperation = method.login({ ...interaction, signal });\n const credential = await raceWithAbortSignal(loginOperation, signal);\n let mutationStarted = false;\n let markMutationStarted;\n const started = new Promise((resolve) => {\n markMutationStarted = resolve;\n });\n const mutation = this.credentials.modify(providerId, async () => {\n mutationStarted = true;\n markMutationStarted?.();\n return credential;\n }, { signal });\n void mutation.catch(() => { });\n try {\n await new Promise((resolve, reject) => {\n const onAbort = () => {\n if (!mutationStarted)\n reject(signal.reason);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n void Promise.race([started, mutation]).then(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, (error) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n });\n if (signal.aborted)\n onAbort();\n });\n await mutation;\n }\n catch (error) {\n signal.throwIfAborted();\n throw new ModelsError(\"auth\", `Credential store modify failed for ${providerId}`, { cause: error });\n }\n return credential;\n }\n async logout(providerId, options) {\n const signal = operationSignal(options?.signal);\n signal.throwIfAborted();\n try {\n await this.credentials.delete(providerId, { signal });\n }\n catch (error) {\n signal.throwIfAborted();\n throw new ModelsError(\"auth\", `Credential store delete failed for ${providerId}`, { cause: error });\n }\n }\n requireProvider(model) {\n const provider = this.providers.get(model.provider);\n if (!provider) {\n throw new ModelsError(\"provider\", `Unknown provider: ${model.provider}`);\n }\n return provider;\n }\n async applyAuth(model, options) {\n this.requireProvider(model);\n const resolution = await this.getAuth(model, {\n apiKey: options?.apiKey,\n env: options?.env,\n signal: options?.signal,\n });\n if (!resolution) {\n throw new ModelsError(\"auth\", `Provider is not configured: ${model.provider}`);\n }\n const auth = resolution.auth;\n // Explicit request options win per-field; the Models-only transform runs last.\n const apiKey = options?.apiKey ?? auth.apiKey;\n let headers = mergeHeaders(auth.headers, options?.headers);\n if (options?.transformHeaders)\n headers = await options.transformHeaders(headers ?? {});\n const env = resolution.env || options?.env ? { ...(resolution.env ?? {}), ...(options?.env ?? {}) } : undefined;\n const requestModel = auth.baseUrl ? { ...model, baseUrl: auth.baseUrl } : model;\n const { transformHeaders: _transformHeaders, ...providerOptions } = options ?? {};\n const requestOptions = { ...providerOptions, apiKey, headers, env };\n return { requestModel, requestOptions };\n }\n stream(model, context, options) {\n return lazyStream(model, async () => {\n const provider = this.requireProvider(model);\n const { requestModel, requestOptions } = await this.applyAuth(model, options);\n return provider.stream(requestModel, context, requestOptions);\n });\n }\n async complete(model, context, options) {\n return this.stream(model, context, options).result();\n }\n streamSimple(model, context, options) {\n return lazyStream(model, async () => {\n const provider = this.requireProvider(model);\n const { requestModel, requestOptions } = await this.applyAuth(model, options);\n return provider.streamSimple(requestModel, context, requestOptions);\n });\n }\n async completeSimple(model, context, options) {\n return this.streamSimple(model, context, options).result();\n }\n async fetchDeferred(model, handle, options) {\n return lazyStream(model, async () => {\n const provider = this.requireProvider(model);\n if (!provider.fetchDeferred) {\n throw new ModelsError(\"provider\", `Provider ${model.provider} does not support deferred responses`);\n }\n const { requestModel, requestOptions } = await this.applyAuth(model, options);\n return provider.fetchDeferred(requestModel, handle, requestOptions);\n }).result();\n }\n async cancelDeferred(model, handle, options) {\n const provider = this.requireProvider(model);\n if (!provider.cancelDeferred) {\n throw new ModelsError(\"provider\", `Provider ${model.provider} does not support deferred responses`);\n }\n const { requestModel, requestOptions } = await this.applyAuth(model, options);\n await provider.cancelDeferred(requestModel, handle, requestOptions);\n }\n}\nexport function createModels(options) {\n return new ModelsImpl(options);\n}\n/**\n * Builds a provider from parts. Built-in provider factories and models.json\n * custom providers both go through this. A single `api` streams all models;\n * an `api` map dispatches on `model.api`, and a model whose api has no entry\n * produces a stream error.\n */\nexport function createProvider(input) {\n const baselineModels = input.models;\n let dynamicModels = [];\n const fetchModels = input.fetchModels;\n const currentModels = () => {\n const merged = [...baselineModels];\n for (const model of dynamicModels) {\n const index = merged.findIndex((entry) => entry.id === model.id);\n if (index >= 0)\n merged[index] = model;\n else\n merged.push(model);\n }\n return merged;\n };\n const single = typeof input.api.stream === \"function\" ? input.api : undefined;\n const byApi = single ? undefined : input.api;\n const apiFor = (model) => single ?? byApi?.[model.api];\n const dispatch = (model, run) => {\n const streams = apiFor(model);\n if (!streams) {\n return lazyStream(model, async () => {\n throw new ModelsError(\"stream\", `Provider ${input.id} has no API implementation for \"${model.api}\"`);\n });\n }\n return run(streams);\n };\n const provider = {\n id: input.id,\n name: input.name ?? input.id,\n baseUrl: input.baseUrl,\n headers: input.headers,\n auth: input.auth,\n getModels: currentModels,\n refreshModels: fetchModels\n ? async (context) => {\n if (context.stored) {\n const restored = context.stored.models\n .filter((model) => model.provider === input.id)\n .map((model) => model);\n if (!(await context.publish({\n update: () => {\n dynamicModels = restored;\n },\n }))) {\n return;\n }\n }\n if (!context.allowNetwork || context.signal.aborted)\n return;\n const refreshed = await fetchModels(context);\n if (context.signal.aborted)\n return;\n await context.publish({\n persist: { models: refreshed, checkedAt: Date.now() },\n update: () => {\n dynamicModels = refreshed;\n },\n });\n }\n : undefined,\n filterModels: input.filterModels,\n stream: (model, context, options) => dispatch(model, (streams) => streams.stream(model, context, options)),\n streamSimple: (model, context, options) => dispatch(model, (streams) => streams.streamSimple(model, context, options)),\n };\n const streams = single ? [single] : Object.values(byApi ?? {}).filter((entry) => entry !== undefined);\n if (streams.some((entry) => entry.fetchDeferred !== undefined)) {\n provider.fetchDeferred = (model, handle, options) => lazyStream(model, async () => {\n const implementation = apiFor(model);\n if (!implementation?.fetchDeferred) {\n throw new ModelsError(\"provider\", `Provider ${input.id} does not support deferred responses for \"${model.api}\"`);\n }\n return implementation.fetchDeferred(model, handle, options);\n });\n }\n if (streams.some((entry) => entry.cancelDeferred !== undefined)) {\n provider.cancelDeferred = async (model, handle, options) => {\n const implementation = apiFor(model);\n if (!implementation?.cancelDeferred) {\n throw new ModelsError(\"provider\", `Provider ${input.id} cannot cancel deferred responses for \"${model.api}\"`);\n }\n await implementation.cancelDeferred(model, handle, options);\n };\n }\n return provider;\n}\n/**\n * Runtime-checked narrowing for dynamically looked-up models:\n *\n * ```ts\n * const model = models.getModel(\"anthropic\", \"claude-opus-4-7\");\n * if (model && hasApi(model, \"anthropic-messages\")) {\n * // model: Model<\"anthropic-messages\">, stream options fully typed\n * }\n * ```\n */\nexport function hasApi(model, api) {\n return model.api === api;\n}\nexport function calculateCost(model, usage) {\n const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;\n let rates = model.cost;\n let matchedThreshold = -1;\n for (const tier of model.cost.tiers ?? []) {\n if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {\n rates = tier;\n matchedThreshold = tier.inputTokensAbove;\n }\n }\n // Anthropic charges 2x base input for 1h cache writes.\n const longWrite = usage.cacheWrite1h ?? 0;\n const shortWrite = usage.cacheWrite - longWrite;\n usage.cost.input = (rates.input / 1000000) * usage.input;\n usage.cost.output = (rates.output / 1000000) * usage.output;\n usage.cost.cacheRead = (rates.cacheRead / 1000000) * usage.cacheRead;\n usage.cost.cacheWrite = (rates.cacheWrite * shortWrite + rates.input * 2 * longWrite) / 1000000;\n usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n return usage.cost;\n}\nconst EXTENDED_THINKING_LEVELS = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"];\nexport function getSupportedThinkingLevels(model) {\n if (!model.reasoning)\n return [\"off\"];\n return EXTENDED_THINKING_LEVELS.filter((level) => {\n const mapped = model.thinkingLevelMap?.[level];\n if (mapped === null)\n return false;\n if (level === \"xhigh\" || level === \"max\")\n return mapped !== undefined;\n return true;\n });\n}\nexport function clampThinkingLevel(model, level) {\n const availableLevels = getSupportedThinkingLevels(model);\n if (availableLevels.includes(level))\n return level;\n const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);\n if (requestedIndex === -1)\n return availableLevels[0] ?? \"off\";\n for (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {\n const candidate = EXTENDED_THINKING_LEVELS[i];\n if (availableLevels.includes(candidate))\n return candidate;\n }\n for (let i = requestedIndex - 1; i >= 0; i--) {\n const candidate = EXTENDED_THINKING_LEVELS[i];\n if (availableLevels.includes(candidate))\n return candidate;\n }\n return availableLevels[0] ?? \"off\";\n}\n/**\n * Check if two models are equal by comparing both their id and provider.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual(a, b) {\n if (!a || !b)\n return false;\n return a.id === b.id && a.provider === b.provider;\n}\n//# sourceMappingURL=models.js.map","export function getGrammarToolInput(toolName, arguments_, inputProperty) {\n const input = arguments_[inputProperty];\n if (typeof input !== \"string\") {\n throw new Error(`Grammar tool call \"${toolName}\" requires argument \"${inputProperty}\" to be a string.`);\n }\n return input;\n}\nexport function appendGrammarToolInputJsonDelta(buffer, inputProperty, nextInput, close) {\n if (buffer.closed) {\n if (close && nextInput === buffer.input)\n return undefined;\n throw new Error(`grammar tool input for property \"${inputProperty}\" changed after it was closed`);\n }\n if (!nextInput.startsWith(buffer.input)) {\n throw new Error(`grammar tool input for property \"${inputProperty}\" changed non-monotonically`);\n }\n const inputDelta = nextInput.slice(buffer.input.length);\n if (!close && inputDelta.length === 0)\n return undefined;\n let delta = \"\";\n if (!buffer.started) {\n delta += `{${JSON.stringify(inputProperty)}:\"`;\n buffer.started = true;\n }\n delta += JSON.stringify(inputDelta).slice(1, -1);\n buffer.input = nextInput;\n if (close) {\n delta += '\"}';\n buffer.closed = true;\n }\n return delta;\n}\nfunction inferGrammarInputProperty(tool) {\n const schema = tool.parameters;\n if (schema.type !== \"object\") {\n throw new Error(\"grammar constrained sampling requires an object parameter schema\");\n }\n if (!Array.isArray(schema.required) || schema.required.length !== 1 || typeof schema.required[0] !== \"string\") {\n throw new Error(\"grammar constrained sampling requires exactly one required string property\");\n }\n const inputProperty = schema.required[0];\n if (!schema.properties?.[inputProperty]) {\n throw new Error(`grammar constrained sampling requires a properties entry for ${inputProperty}`);\n }\n if (schema.properties[inputProperty]?.type !== \"string\") {\n throw new Error(`grammar constrained sampling property ${inputProperty} must have type string`);\n }\n return inputProperty;\n}\nexport function resolveJsonSchemaStrictSampling(tool, supportsStrictMode) {\n const config = tool.constrainedSampling;\n if (!config || config.type !== \"json_schema\") {\n return undefined;\n }\n if (supportsStrictMode) {\n return true;\n }\n if (config.strict === \"require\") {\n throw new Error(`Tool \"${tool.name}\" requires JSON-schema constrained sampling, but strict tools are unsupported.`);\n }\n return undefined;\n}\nexport function resolveGrammarConstrainedSampling(tool, supportsOpenAIGrammarTools) {\n const config = tool.constrainedSampling;\n if (!config || config.type !== \"grammar\") {\n return undefined;\n }\n if (!supportsOpenAIGrammarTools) {\n return undefined;\n }\n const larkDefinition = config.variants.openai_lark;\n const regexDefinition = config.variants.openai_regex;\n const hasLarkDefinition = typeof larkDefinition === \"string\" && larkDefinition.trim().length > 0;\n const hasRegexDefinition = typeof regexDefinition === \"string\" && regexDefinition.trim().length > 0;\n if (!hasLarkDefinition && !hasRegexDefinition) {\n throw new Error(`Tool \"${tool.name}\" cannot use grammar constrained sampling: no supported grammar variant was provided.`);\n }\n try {\n return {\n format: hasLarkDefinition ? \"lark\" : \"regex\",\n definition: hasLarkDefinition ? larkDefinition : regexDefinition,\n inputProperty: inferGrammarInputProperty(tool),\n };\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Tool \"${tool.name}\" cannot use grammar constrained sampling: ${message}.`);\n }\n}\nexport function createGrammarToolInputProperties(tools, supportsOpenAIGrammarTools) {\n const properties = new Map();\n for (const tool of tools ?? []) {\n const grammar = resolveGrammarConstrainedSampling(tool, supportsOpenAIGrammarTools);\n if (grammar) {\n properties.set(tool.name, grammar.inputProperty);\n }\n }\n return properties;\n}\n//# sourceMappingURL=constrained-sampling.js.map","/**\n * Removes unpaired Unicode surrogate characters from a string.\n *\n * Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,\n * or vice versa) cause JSON serialization errors in many API providers.\n *\n * Valid emoji and other characters outside the Basic Multilingual Plane use properly paired\n * surrogates and will NOT be affected by this function.\n *\n * @param text - The text to sanitize\n * @returns The sanitized text with unpaired surrogates removed\n *\n * @example\n * // Valid emoji (properly paired surrogates) are preserved\n * sanitizeSurrogates(\"Hello 🙈 World\") // => \"Hello 🙈 World\"\n *\n * // Unpaired high surrogate is removed\n * const unpaired = String.fromCharCode(0xD83D); // high surrogate without low\n * sanitizeSurrogates(`Text ${unpaired} here`) // => \"Text here\"\n */\nexport function sanitizeSurrogates(text) {\n // Replace unpaired high surrogates (0xD800-0xDBFF not followed by low surrogate)\n // Replace unpaired low surrogates (0xDC00-0xDFFF not preceded by high surrogate)\n return text.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, \"\");\n}\n//# sourceMappingURL=sanitize-unicode.js.map","const NON_VISION_USER_IMAGE_PLACEHOLDER = \"(image omitted: model does not support images)\";\nconst NON_VISION_TOOL_IMAGE_PLACEHOLDER = \"(tool image omitted: model does not support images)\";\nfunction replaceImagesWithPlaceholder(content, placeholder) {\n const result = [];\n let previousWasPlaceholder = false;\n for (const block of content) {\n if (block.type === \"image\") {\n if (!previousWasPlaceholder) {\n result.push({ type: \"text\", text: placeholder });\n }\n previousWasPlaceholder = true;\n continue;\n }\n result.push(block);\n previousWasPlaceholder = block.text === placeholder;\n }\n return result;\n}\nfunction downgradeUnsupportedImages(messages, model) {\n if (model.input.includes(\"image\")) {\n return messages;\n }\n return messages.map((msg) => {\n if (msg.role === \"user\" && Array.isArray(msg.content)) {\n return {\n ...msg,\n content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER),\n };\n }\n if (msg.role === \"toolResult\") {\n return {\n ...msg,\n content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER),\n };\n }\n return msg;\n });\n}\n/**\n * Normalize tool call ID for cross-provider compatibility.\n * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.\n * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).\n */\nexport function transformMessages(messages, model, normalizeToolCallId) {\n // Build a map of original tool call IDs to normalized IDs\n const toolCallIdMap = new Map();\n // Normalize null/undefined content from untyped callers (custom tools, hand-built\n // histories, old session files) so downstream code can rely on the type contract.\n const normalizedMessages = messages.map((msg) => (msg.content == null ? { ...msg, content: [] } : msg));\n const imageAwareMessages = downgradeUnsupportedImages(normalizedMessages, model);\n // First pass: transform messages (unsupported image downgrade, thinking blocks, tool call ID normalization)\n const transformed = imageAwareMessages.map((msg) => {\n // User messages pass through unchanged\n if (msg.role === \"user\") {\n return msg;\n }\n // Handle toolResult messages - normalize toolCallId if we have a mapping\n if (msg.role === \"toolResult\") {\n const normalizedId = toolCallIdMap.get(msg.toolCallId);\n if (normalizedId && normalizedId !== msg.toolCallId) {\n return { ...msg, toolCallId: normalizedId };\n }\n return msg;\n }\n // Assistant messages need transformation check\n if (msg.role === \"assistant\") {\n const assistantMsg = msg;\n const isSameModel = assistantMsg.provider === model.provider &&\n assistantMsg.api === model.api &&\n assistantMsg.model === model.id;\n const transformedContent = assistantMsg.content.flatMap((block) => {\n if (block.type === \"thinking\") {\n // Redacted thinking is opaque encrypted content, only valid for the same model.\n // Drop it for cross-model to avoid API errors.\n if (block.redacted) {\n return isSameModel ? block : [];\n }\n // For same model: keep thinking blocks with signatures (needed for replay)\n // even if the thinking text is empty (OpenAI encrypted reasoning)\n if (isSameModel && block.thinkingSignature)\n return block;\n // Skip empty thinking blocks, convert others to plain text\n if (!block.thinking || block.thinking.trim() === \"\")\n return [];\n if (isSameModel)\n return block;\n return {\n type: \"text\",\n text: block.thinking,\n };\n }\n if (block.type === \"text\") {\n if (isSameModel)\n return block;\n return {\n type: \"text\",\n text: block.text,\n };\n }\n if (block.type === \"toolCall\") {\n const toolCall = block;\n let normalizedToolCall = toolCall;\n if (!isSameModel && toolCall.thoughtSignature) {\n normalizedToolCall = { ...toolCall };\n delete normalizedToolCall.thoughtSignature;\n }\n if (!isSameModel && normalizeToolCallId) {\n const normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);\n if (normalizedId !== toolCall.id) {\n toolCallIdMap.set(toolCall.id, normalizedId);\n normalizedToolCall = { ...normalizedToolCall, id: normalizedId };\n }\n }\n return normalizedToolCall;\n }\n return block;\n });\n return {\n ...assistantMsg,\n content: transformedContent,\n };\n }\n return msg;\n });\n // Second pass: insert synthetic empty tool results for orphaned tool calls\n // This preserves thinking signatures and satisfies API requirements\n const result = [];\n let pendingToolCalls = [];\n let existingToolResultIds = new Set();\n const insertSyntheticToolResults = () => {\n if (pendingToolCalls.length > 0) {\n for (const tc of pendingToolCalls) {\n if (!existingToolResultIds.has(tc.id)) {\n result.push({\n role: \"toolResult\",\n toolCallId: tc.id,\n toolName: tc.name,\n content: [{ type: \"text\", text: \"No result provided\" }],\n isError: true,\n timestamp: Date.now(),\n });\n }\n }\n pendingToolCalls = [];\n existingToolResultIds = new Set();\n }\n };\n for (let i = 0; i < transformed.length; i++) {\n const msg = transformed[i];\n if (msg.role === \"assistant\") {\n // If we have pending orphaned tool calls from a previous assistant, insert synthetic results now\n insertSyntheticToolResults();\n // Skip errored/aborted assistant messages entirely.\n // These are incomplete turns that shouldn't be replayed:\n // - May have partial content (reasoning without message, incomplete tool calls)\n // - Replaying them can cause API errors (e.g., OpenAI \"reasoning without following item\")\n // - The model should retry from the last valid state\n const assistantMsg = msg;\n if (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n continue;\n }\n // Track tool calls from this assistant message\n const toolCalls = assistantMsg.content.filter((b) => b.type === \"toolCall\");\n if (toolCalls.length > 0) {\n pendingToolCalls = toolCalls;\n existingToolResultIds = new Set();\n }\n result.push(msg);\n }\n else if (msg.role === \"toolResult\") {\n existingToolResultIds.add(msg.toolCallId);\n result.push(msg);\n }\n else if (msg.role === \"user\") {\n // User message interrupts tool flow - insert synthetic results for orphaned calls\n insertSyntheticToolResults();\n result.push(msg);\n }\n else {\n result.push(msg);\n }\n }\n // If the conversation ends with unresolved tool calls, synthesize results now.\n insertSyntheticToolResults();\n return result;\n}\n//# sourceMappingURL=transform-messages.js.map","const CHARS_PER_TOKEN = 4;\nconst ESTIMATED_IMAGE_CHARS = 4800;\nexport function calculateContextTokens(usage) {\n return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n}\nfunction safeJsonStringify(value) {\n try {\n return JSON.stringify(value) ?? \"undefined\";\n }\n catch {\n return \"[unserializable]\";\n }\n}\nfunction estimateTextAndImageContentChars(content) {\n if (typeof content === \"string\")\n return content.length;\n let chars = 0;\n for (const block of content)\n chars += block.type === \"text\" ? block.text.length : ESTIMATED_IMAGE_CHARS;\n return chars;\n}\nexport function estimateTextTokens(text) {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\nexport function estimateTextAndImageContentTokens(content) {\n return Math.ceil(estimateTextAndImageContentChars(content) / CHARS_PER_TOKEN);\n}\nexport function estimateMessageTokens(message) {\n let chars = 0;\n if (message.role === \"user\")\n return estimateTextAndImageContentTokens(message.content);\n if (message.role === \"toolResult\")\n return estimateTextAndImageContentTokens(message.content);\n for (const block of message.content) {\n if (block.type === \"text\") {\n chars += block.text.length;\n }\n else if (block.type === \"thinking\") {\n chars += block.thinking.length;\n }\n else {\n chars += block.name.length + safeJsonStringify(block.arguments).length;\n }\n }\n return Math.ceil(chars / CHARS_PER_TOKEN);\n}\nfunction getLastAssistantUsageInfo(messages) {\n let latestPrefixTimestamp = Number.NEGATIVE_INFINITY;\n let usageInfo;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (message.role === \"assistant\") {\n const assistant = message;\n // A newer prefix message was inserted after this response (for example, a\n // compaction summary), so its usage cannot describe the current prefix.\n const usageAppliesToPrefix = assistant.timestamp >= latestPrefixTimestamp;\n if (usageAppliesToPrefix &&\n assistant.stopReason !== \"aborted\" &&\n assistant.stopReason !== \"error\" &&\n calculateContextTokens(assistant.usage) > 0) {\n usageInfo = { usage: assistant.usage, index: i };\n }\n }\n latestPrefixTimestamp = Math.max(latestPrefixTimestamp, message.timestamp);\n }\n return usageInfo;\n}\nfunction estimateMessages(messages) {\n const usageInfo = getLastAssistantUsageInfo(messages);\n if (usageInfo) {\n const usageTokens = calculateContextTokens(usageInfo.usage);\n let trailingTokens = 0;\n for (let i = usageInfo.index + 1; i < messages.length; i++) {\n trailingTokens += estimateMessageTokens(messages[i]);\n }\n return { tokens: usageTokens + trailingTokens, usageTokens, trailingTokens, lastUsageIndex: usageInfo.index };\n }\n let tokens = 0;\n for (const message of messages)\n tokens += estimateMessageTokens(message);\n return { tokens, usageTokens: 0, trailingTokens: tokens, lastUsageIndex: null };\n}\nfunction estimateToolsTokens(tools) {\n if (!tools || tools.length === 0)\n return 0;\n return estimateTextTokens(safeJsonStringify(tools));\n}\nfunction isMessageArray(value) {\n return Array.isArray(value);\n}\nexport function estimateContextTokens(context) {\n if (isMessageArray(context))\n return estimateMessages(context);\n const estimate = estimateMessages(context.messages);\n if (estimate.lastUsageIndex !== null) {\n const addedNames = new Set(context.messages\n .slice(estimate.lastUsageIndex + 1)\n .filter((message) => message.role === \"toolResult\")\n .flatMap((message) => message.addedToolNames ?? []));\n const addedToolTokens = estimateToolsTokens(context.tools?.filter((tool) => addedNames.has(tool.name)));\n return {\n tokens: estimate.tokens + addedToolTokens,\n usageTokens: estimate.usageTokens,\n trailingTokens: estimate.trailingTokens + addedToolTokens,\n lastUsageIndex: estimate.lastUsageIndex,\n };\n }\n const prefixTokens = (context.systemPrompt ? estimateTextTokens(context.systemPrompt) : 0) + estimateToolsTokens(context.tools);\n return {\n tokens: estimate.tokens + prefixTokens,\n usageTokens: estimate.usageTokens,\n trailingTokens: estimate.trailingTokens + prefixTokens,\n lastUsageIndex: estimate.lastUsageIndex,\n };\n}\n//# sourceMappingURL=estimate.js.map","import { estimateContextTokens } from \"../utils/estimate.js\";\nconst CONTEXT_SAFETY_TOKENS = 4096;\nconst MIN_MAX_TOKENS = 1;\nexport function clampMaxTokensToContext(model, context, maxTokens) {\n if (model.contextWindow <= 0)\n return Math.max(MIN_MAX_TOKENS, maxTokens);\n const available = model.contextWindow - estimateContextTokens(context).tokens - CONTEXT_SAFETY_TOKENS;\n return Math.min(maxTokens, Math.max(MIN_MAX_TOKENS, available));\n}\nexport function buildBaseOptions(model, context, options, apiKey) {\n const samplingParams = model.samplingParams || options?.samplingParams\n ? { ...model.samplingParams, ...options?.samplingParams }\n : undefined;\n return {\n temperature: options?.temperature,\n samplingParams,\n maxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),\n signal: options?.signal,\n telemetryContext: options?.telemetryContext,\n apiKey: apiKey || options?.apiKey,\n fetch: options?.fetch,\n transport: options?.transport,\n cacheRetention: options?.cacheRetention,\n sessionId: options?.sessionId,\n headers: options?.headers,\n onPayload: options?.onPayload,\n onResponse: options?.onResponse,\n timeoutMs: options?.timeoutMs,\n websocketConnectTimeoutMs: options?.websocketConnectTimeoutMs,\n maxRetries: options?.maxRetries,\n maxRetryDelayMs: options?.maxRetryDelayMs,\n metadata: options?.metadata,\n env: options?.env,\n };\n}\n/** Tokens always left for the answer when a thinking budget shares the response ceiling. */\nexport const MIN_ANSWER_TOKENS = 1024;\nexport function clampReasoning(effort) {\n return effort === \"xhigh\" || effort === \"max\" ? \"high\" : effort;\n}\nexport function adjustMaxTokensForThinking(\n// Undefined means no explicit caller cap. Use the model cap and fit thinking inside it.\nbaseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {\n const defaultBudgets = {\n minimal: 1024,\n low: 2048,\n medium: 8192,\n high: 16384,\n };\n const budgets = { ...defaultBudgets, ...customBudgets };\n const level = clampReasoning(reasoningLevel);\n let thinkingBudget = budgets[level];\n const maxTokens = baseMaxTokens === undefined ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n if (maxTokens <= thinkingBudget) {\n thinkingBudget = Math.max(0, maxTokens - MIN_ANSWER_TOKENS);\n }\n return { maxTokens, thinkingBudget };\n}\n//# sourceMappingURL=simple-options.js.map"],"x_google_ignoreList":[0,1,2,3,4,5],"mappings":"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"}
|