@openclaw/ai 2026.7.2-beta.7 → 2026.7.34
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 +5 -6
- package/dist/{anthropic-CH4UUnZr.mjs → anthropic-Bcdbq-l5.mjs} +467 -100
- package/dist/{api-registry-DlMgPR39.d.mts → api-registry-BXYnCOIR.d.mts} +2 -1
- package/dist/{azure-openai-responses-CImcwB83.mjs → azure-openai-responses-2xhpNPWg.mjs} +13 -11
- package/dist/{azure-openai-responses-client-compat-C7K7QfUE.mjs → azure-openai-responses-client-compat-a_O_GVQV.mjs} +2 -23
- package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-CtMlqaQ4.mjs} +4 -5
- package/dist/{event-stream-YjaPW20U.d.mts → event-stream-0nZeBKl2.d.mts} +1 -1
- package/dist/{event-stream-D8n2uFee.mjs → event-stream-ReMmOTzX.mjs} +6 -14
- package/dist/event-stream.d.mts +1 -1
- package/dist/event-stream.mjs +1 -1
- package/dist/{github-copilot-headers-NCJtz9i0.mjs → github-copilot-headers-BsH5cqGj.mjs} +12 -1
- package/dist/{google-CtSg0iTS.mjs → google-C6P31moq.mjs} +5 -5
- package/dist/{google-shared-DNBz5rcD.mjs → google-shared-BeyXFAcf.mjs} +26 -34
- package/dist/{google-vertex-31f1uS9L.mjs → google-vertex--9_gT74B.mjs} +19 -6
- package/dist/host-4t713IeR.mjs +37 -0
- package/dist/{anthropic-SrGtwsJu.d.mts → index-CGDEoorl.d.mts} +2 -6
- package/dist/index.d.mts +50 -7
- package/dist/index.mjs +5 -5
- package/dist/internal/anthropic.d.mts +61 -21
- package/dist/internal/anthropic.mjs +4 -5
- package/dist/internal/openai.d.mts +89 -98
- package/dist/internal/openai.mjs +6 -8
- package/dist/internal/runtime.d.mts +34 -13
- package/dist/internal/runtime.mjs +14 -26
- package/dist/internal/shared.d.mts +9 -26
- package/dist/internal/shared.mjs +2 -6
- package/dist/{json-parse-BvXNt1-7.mjs → json-parse-DzNSIQBq.mjs} +6 -4
- package/dist/{llm-request-activity-BjtkplhG.mjs → llm-request-activity-CehVkZP-.mjs} +19 -1
- package/dist/{mistral-CWmpvWYh.mjs → mistral-CBm3OQWD.mjs} +39 -141
- package/dist/model-utils-Cn9KAz3z.mjs +69 -0
- package/dist/{openai-chatgpt-responses-B84Ibtrd.mjs → openai-chatgpt-responses-M2RVpycr.mjs} +154 -101
- package/dist/{openai-completions-DsOxhOD1.mjs → openai-completions-BUlMEeBc.mjs} +295 -81
- package/dist/{openai-responses-BT7A3sLu.mjs → openai-responses-DW61C22l.mjs} +9 -14
- package/dist/openai-responses-shared-BhYsVkwW.mjs +1949 -0
- package/dist/{openai-tool-projection-OhX64DoP.mjs → openai-tool-projection-g4HuxD26.mjs} +20 -31
- package/dist/providers.d.mts +2 -3
- package/dist/providers.mjs +10 -11
- package/dist/reasoning-tag-text-partitioner-axhAdUwg.mjs +394 -0
- package/dist/{src-QkygScBs.mjs → src-CjOfhrH3.mjs} +6 -17
- package/dist/{stream-first-event-timeout-BBys9hSb.mjs → stream-first-event-timeout-RjWszj8c.mjs} +22 -2
- package/dist/transform-messages-DoWx35pj.mjs +509 -0
- package/dist/{types-bzp5k29J.d.mts → types-DRgdPqaZ.d.mts} +0 -19
- package/dist/types.d.mts +5 -5
- package/dist/types.mjs +4 -4
- package/dist/{validation-B-j7cOYp.d.mts → validation-BDMWOr8d.d.mts} +1 -1
- package/dist/{validation-DAa_yFOM.mjs → validation-FrchoOlv.mjs} +7 -2
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/npm-shrinkwrap.json +645 -0
- package/package.json +11 -36
- package/dist/anthropic-usage-DWU-x8MI.mjs +0 -459
- package/dist/cache-retention-0x979a5V.mjs +0 -12
- package/dist/deferred-event-buffer-DAvyP7qA.mjs +0 -19
- package/dist/error-coercion-DgxlWC0n.mjs +0 -15
- package/dist/host-B9GUmcra.d.mts +0 -173
- package/dist/host-Dog2WQiR.mjs +0 -369
- package/dist/index-BVVgDSdq.d.mts +0 -1
- package/dist/internal/retry-after.d.mts +0 -5
- package/dist/internal/retry-after.mjs +0 -101
- package/dist/number-coercion-DvG7SNMg.mjs +0 -129
- package/dist/openai-completions-compat-DBWjXoMZ.d.mts +0 -43
- package/dist/openai-prompt-cache-2uo_1OR1.d.mts +0 -7
- package/dist/openai-prompt-cache-mZTCdRPo.mjs +0 -12
- package/dist/openai-reasoning-compat-YgeLncHw.mjs +0 -396
- package/dist/openai-responses-shared-pXl6Wd8S.mjs +0 -392
- package/dist/openai-responses-stream-internal-Cw5txaGW.mjs +0 -2964
- package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +0 -13
- package/dist/provider-error-CAEvRjry.mjs +0 -47
- package/dist/provider-options-D8bB3z9b.d.mts +0 -144
- package/dist/reasoning-tag-text-partitioner-CGDyLWUR.mjs +0 -12209
- package/dist/simple-options-9lhRrN73.mjs +0 -50
- package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
- package/dist/tls-certificate-errors-DXSpluKI.mjs +0 -93
- package/dist/tool-result-text-CTpIRbYd.mjs +0 -225
- package/dist/transform-messages-C8mBqZxF.mjs +0 -2
- package/dist/transport-stream-shared-D81p90xq.mjs +0 -297
- package/dist/transports.d.mts +0 -573
- package/dist/transports.mjs +0 -4110
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { n as getEnvApiKey, t as findEnvKeys } from "../env-api-keys-
|
|
1
|
+
import { n as getEnvApiKey, t as findEnvKeys } from "../env-api-keys-CtMlqaQ4.mjs";
|
|
2
2
|
import { n as createApiRegistry, t as createLlmRuntime } from "../stream-CREqxHgU.mjs";
|
|
3
|
+
import { a as modelsAreEqual, i as getSupportedThinkingLevels, n as calculateCost, r as clampThinkingLevel, t as applyProviderReportedUsageCost } from "../model-utils-Cn9KAz3z.mjs";
|
|
4
|
+
import { n as onLlmRequestActivity, r as createDeferredEventBuffer, t as notifyLlmRequestActivity } from "../llm-request-activity-CehVkZP-.mjs";
|
|
5
|
+
import { t as headersToRecord } from "../headers-B_e4-1J0.mjs";
|
|
6
|
+
import { n as parseStreamingJson, r as repairJson, t as parseJsonWithRepair } from "../json-parse-DzNSIQBq.mjs";
|
|
3
7
|
import { t as sanitizeSurrogates } from "../sanitize-unicode-DT5o51ur.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
6
|
-
import { n as parseStreamingJson, r as repairJson, t as parseJsonWithRepair } from "../json-parse-BvXNt1-7.mjs";
|
|
7
|
-
import { n as onLlmRequestActivity, t as notifyLlmRequestActivity } from "../llm-request-activity-BjtkplhG.mjs";
|
|
8
|
-
import { t as createReasoningTagTextPartitioner } from "../reasoning-tag-text-partitioner-CGDyLWUR.mjs";
|
|
9
|
-
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, n as createFirstStreamEventTimeoutError, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "../stream-first-event-timeout-BBys9hSb.mjs";
|
|
8
|
+
import { t as createReasoningTagTextPartitioner } from "../reasoning-tag-text-partitioner-axhAdUwg.mjs";
|
|
9
|
+
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, n as createFirstStreamEventTimeoutError, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "../stream-first-event-timeout-RjWszj8c.mjs";
|
|
10
10
|
import { t as shortHash } from "../hash-CHgqbJmD.mjs";
|
|
11
|
-
import { t as headersToRecord } from "../headers-B_e4-1J0.mjs";
|
|
12
11
|
import { i as registerSessionResourceCleanup, n as resolveOpenAICodexAccountId, r as cleanupSessionResources, t as decodeOpenAICodexJwtPayload } from "../openai-chatgpt-jwt-DhAAzLkj.mjs";
|
|
13
12
|
import { t as createSseByteGuard } from "../streaming-byte-guard-BrbkbwUu.mjs";
|
|
14
13
|
//#region packages/ai/src/internal/default-runtime.ts
|
|
@@ -27,10 +26,7 @@ function resolveDefaultRuntime() {
|
|
|
27
26
|
const defaultRuntime = resolveDefaultRuntime();
|
|
28
27
|
const defaultApiRegistry = defaultRuntime.registry;
|
|
29
28
|
const defaultLlmRuntime = defaultRuntime.runtime;
|
|
30
|
-
const { getApiProvider, getApiProviders } = defaultApiRegistry;
|
|
31
|
-
function clearApiProviders() {
|
|
32
|
-
defaultApiRegistry.clearApiProviders();
|
|
33
|
-
}
|
|
29
|
+
const { registerApiProvider, getApiProvider, getApiProviders, unregisterApiProviders, clearApiProviders } = defaultApiRegistry;
|
|
34
30
|
const { stream, complete, streamSimple, completeSimple } = defaultLlmRuntime;
|
|
35
31
|
//#endregion
|
|
36
32
|
//#region packages/ai/src/utils/overflow.ts
|
|
@@ -63,9 +59,7 @@ function isConfiguredContextSizeOverflowError(errorMessage) {
|
|
|
63
59
|
* - Kimi For Coding: "Your request exceeded model token limit: X (requested: Y)"
|
|
64
60
|
* - Cerebras: "400/413 status code (no body)"
|
|
65
61
|
* - Mistral: "Prompt contains X tokens ... too large for model with Y maximum context length"
|
|
66
|
-
* - z.ai:
|
|
67
|
-
* "Prompt exceeds max length" (code 1261), or accept overflow silently; handled via the
|
|
68
|
-
* error patterns or usage.input > contextWindow
|
|
62
|
+
* - z.ai: Does NOT error, accepts overflow silently - handled via usage.input > contextWindow
|
|
69
63
|
* - Xiaomi MiMo: Truncates input to fill contextWindow exactly, then returns finish_reason "length"
|
|
70
64
|
* with output=0 (no room left to generate). Detected via stopReason "length" + zero output +
|
|
71
65
|
* input filling the context window.
|
|
@@ -76,20 +70,17 @@ const OVERFLOW_PATTERNS = [
|
|
|
76
70
|
/request_too_large/i,
|
|
77
71
|
/input is too long for requested model/i,
|
|
78
72
|
/exceeds the context window/i,
|
|
79
|
-
/exceeds (?:the )?(?:model'?s )?maximum context length
|
|
73
|
+
/exceeds (?:the )?(?:model'?s )?maximum context length of [\d,]+ tokens?/i,
|
|
80
74
|
/input token count.*exceeds the maximum/i,
|
|
81
75
|
/maximum prompt length is \d+/i,
|
|
82
76
|
/reduce the length of the messages/i,
|
|
83
77
|
/maximum context length is \d+ tokens/i,
|
|
84
|
-
/exceeds (?:the )?maximum allowed input length of [\d,]+ tokens?/i,
|
|
85
78
|
/input \(\d+ tokens\) is longer than the model'?s context length \(\d+ tokens\)/i,
|
|
86
79
|
/exceeds the limit of \d+/i,
|
|
87
80
|
/exceeds the available context size/i,
|
|
88
81
|
/greater than the context length/i,
|
|
89
82
|
/context window exceeds limit/i,
|
|
90
83
|
/exceeded model token limit/i,
|
|
91
|
-
/tokens? in request more than max tokens? allowed/i,
|
|
92
|
-
/prompt exceeds max(?:imum)? length/i,
|
|
93
84
|
/too large for model with \d+ maximum context length/i,
|
|
94
85
|
CONFIGURED_CONTEXT_SIZE_OVERFLOW_RE,
|
|
95
86
|
/model_context_window_exceeded/i,
|
|
@@ -116,7 +107,7 @@ const NON_OVERFLOW_PATTERNS = [
|
|
|
116
107
|
function resolveContextInputTokens(message) {
|
|
117
108
|
if (message.usage.contextUsage?.state === "available") return message.usage.contextUsage.promptTokens;
|
|
118
109
|
if (message.usage.contextUsage?.state === "unavailable") return;
|
|
119
|
-
return message.usage.input + message.usage.cacheRead
|
|
110
|
+
return message.usage.input + message.usage.cacheRead;
|
|
120
111
|
}
|
|
121
112
|
/**
|
|
122
113
|
* Check if an assistant message represents a context overflow error.
|
|
@@ -142,12 +133,10 @@ function resolveContextInputTokens(message) {
|
|
|
142
133
|
* - llama.cpp: "exceeds the available context size"
|
|
143
134
|
* - LM Studio: "greater than the context length"
|
|
144
135
|
* - Kimi For Coding: "exceeded model token limit: X (requested: Y)"
|
|
145
|
-
* - z.ai: "tokens in request more than max tokens allowed" or "Prompt exceeds max length"
|
|
146
136
|
*
|
|
147
137
|
* **Unreliable detection:**
|
|
148
138
|
* - z.ai: Sometimes accepts overflow silently (detectable via usage.input > contextWindow),
|
|
149
|
-
* sometimes returns rate limit errors
|
|
150
|
-
* contextWindow param to detect silent overflow.
|
|
139
|
+
* sometimes returns rate limit errors. Pass contextWindow param to detect silent overflow.
|
|
151
140
|
* - Xiaomi MiMo: Truncates input to fit contextWindow then returns stopReason "length" with
|
|
152
141
|
* output=0. Pass contextWindow param to detect via the "filled context + zero output" signal.
|
|
153
142
|
* - Ollama: May truncate input silently for some setups, but may also return explicit
|
|
@@ -171,8 +160,7 @@ function resolveContextInputTokens(message) {
|
|
|
171
160
|
*/
|
|
172
161
|
function isContextOverflow(message, contextWindow) {
|
|
173
162
|
if (message.stopReason === "error" && message.errorMessage) {
|
|
174
|
-
|
|
175
|
-
if (!NON_OVERFLOW_PATTERNS.some((p) => p.test(errorMessage)) && OVERFLOW_PATTERNS.some((p) => p.test(errorMessage))) return true;
|
|
163
|
+
if (!NON_OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage)) && OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage))) return true;
|
|
176
164
|
}
|
|
177
165
|
if (contextWindow && message.stopReason === "stop") {
|
|
178
166
|
const inputTokens = resolveContextInputTokens(message);
|
|
@@ -185,4 +173,4 @@ function isContextOverflow(message, contextWindow) {
|
|
|
185
173
|
return false;
|
|
186
174
|
}
|
|
187
175
|
//#endregion
|
|
188
|
-
export { applyProviderReportedUsageCost, calculateCost, clampThinkingLevel, cleanupSessionResources, clearApiProviders, complete, completeSimple, createDeferredEventBuffer, createFirstStreamEventAbortController, createFirstStreamEventTimeoutError, createReasoningTagTextPartitioner, createSseByteGuard, decodeOpenAICodexJwtPayload, defaultApiRegistry, defaultLlmRuntime, findEnvKeys, getApiProvider, getApiProviders, getEnvApiKey, getFirstStreamEventTimeoutHandler, getFirstStreamEventTimeoutMs, getSupportedThinkingLevels, headersToRecord, isConfiguredContextSizeOverflowError, isContextOverflow, modelsAreEqual, notifyLlmRequestActivity, onLlmRequestActivity, parseJsonWithRepair, parseStreamingJson, registerSessionResourceCleanup, repairJson, resolveOpenAICodexAccountId, sanitizeSurrogates, shortHash, stream, streamSimple, withFirstStreamEventTimeout };
|
|
176
|
+
export { applyProviderReportedUsageCost, calculateCost, clampThinkingLevel, cleanupSessionResources, clearApiProviders, complete, completeSimple, createDeferredEventBuffer, createFirstStreamEventAbortController, createFirstStreamEventTimeoutError, createReasoningTagTextPartitioner, createSseByteGuard, decodeOpenAICodexJwtPayload, defaultApiRegistry, defaultLlmRuntime, findEnvKeys, getApiProvider, getApiProviders, getEnvApiKey, getFirstStreamEventTimeoutHandler, getFirstStreamEventTimeoutMs, getSupportedThinkingLevels, headersToRecord, isConfiguredContextSizeOverflowError, isContextOverflow, modelsAreEqual, notifyLlmRequestActivity, onLlmRequestActivity, parseJsonWithRepair, parseStreamingJson, registerApiProvider, registerSessionResourceCleanup, repairJson, resolveOpenAICodexAccountId, sanitizeSurrogates, shortHash, stream, streamSimple, unregisterApiProviders, withFirstStreamEventTimeout };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { E as Model, F as SimpleStreamOptions, H as ThinkingBudgets, T as Message, W as ThinkingLevel, i as AssistantMessage, n as Api, z as StreamOptions } from "../types-
|
|
1
|
+
import { E as Model, F as SimpleStreamOptions, H as ThinkingBudgets, T as Message, W as ThinkingLevel, i as AssistantMessage, n as Api, z as StreamOptions } from "../types-DRgdPqaZ.mjs";
|
|
2
2
|
import { t as sanitizeSurrogates } from "../sanitize-unicode-BZiVbGwK.mjs";
|
|
3
|
-
import { n as normalizeStructuredPromptSection, r as sortPromptCacheToolsByName, t as normalizePromptCapabilityIds } from "../prompt-cache-stability-Cwcjv_fx.mjs";
|
|
4
3
|
|
|
5
4
|
//#region packages/ai/src/providers/simple-options.d.ts
|
|
6
5
|
type FirstEventStreamOptions = {
|
|
@@ -8,9 +7,6 @@ type FirstEventStreamOptions = {
|
|
|
8
7
|
onFirstEventTimeout?: (reason: Error) => void;
|
|
9
8
|
};
|
|
10
9
|
declare function buildBaseOptions(model: Model, options?: SimpleStreamOptions, apiKey?: string): StreamOptions & FirstEventStreamOptions;
|
|
11
|
-
declare function clampMaxTokensToModel(model: Model, requestedMaxTokens: number): number;
|
|
12
|
-
declare function clampMaxTokensToModel(model: Model, requestedMaxTokens: number | undefined): number | undefined;
|
|
13
|
-
declare function clampReasoning(effort: ThinkingLevel): Exclude<ThinkingLevel, "xhigh">;
|
|
14
10
|
declare function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh"> | undefined;
|
|
15
11
|
declare function adjustMaxTokensForThinking(baseMaxTokens: number | undefined, modelMaxTokens: number, reasoningLevel: ThinkingLevel, customBudgets?: ThinkingBudgets): {
|
|
16
12
|
maxTokens: number;
|
|
@@ -18,20 +14,11 @@ declare function adjustMaxTokensForThinking(baseMaxTokens: number | undefined, m
|
|
|
18
14
|
};
|
|
19
15
|
//#endregion
|
|
20
16
|
//#region packages/ai/src/providers/tool-result-text.d.ts
|
|
21
|
-
/** Media metadata alone is not an attachment; provider emitters need inline bytes. */
|
|
22
|
-
declare function hasMediaPayload(block: unknown): block is Record<string, unknown> & {
|
|
23
|
-
data: string;
|
|
24
|
-
};
|
|
25
|
-
/** Image metadata alone is not an attachment; provider emitters need inline bytes. */
|
|
26
|
-
declare function isImageWithMediaPayload<T>(block: T): block is T & {
|
|
27
|
-
type: "image";
|
|
28
|
-
data: string;
|
|
29
|
-
};
|
|
30
17
|
declare function describeToolResultMediaPlaceholder(blocks: readonly unknown[]): string | undefined;
|
|
31
18
|
declare function extractToolResultBlockText(block: unknown): string | undefined;
|
|
32
19
|
declare function extractToolResultText(blocks: readonly unknown[]): string;
|
|
33
20
|
//#endregion
|
|
34
|
-
//#region packages/ai/src/
|
|
21
|
+
//#region packages/ai/src/providers/transform-messages.d.ts
|
|
35
22
|
/**
|
|
36
23
|
* Normalize tool call ID for cross-provider compatibility.
|
|
37
24
|
* OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
|
|
@@ -39,6 +26,12 @@ declare function extractToolResultText(blocks: readonly unknown[]): string;
|
|
|
39
26
|
*/
|
|
40
27
|
declare function transformMessages<TApi extends Api>(messages: Message[], model: Model<TApi>, normalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string): Message[];
|
|
41
28
|
//#endregion
|
|
29
|
+
//#region packages/ai/src/utils/prompt-cache-stability.d.ts
|
|
30
|
+
/** Normalize structured prompt text before hashing or snapshot comparison. */
|
|
31
|
+
declare function normalizeStructuredPromptSection(text: string): string;
|
|
32
|
+
/** Normalize, de-dupe, and sort capability ids for stable prompt payloads. */
|
|
33
|
+
declare function normalizePromptCapabilityIds(capabilities: ReadonlyArray<string>): string[];
|
|
34
|
+
//#endregion
|
|
42
35
|
//#region packages/ai/src/utils/system-prompt-cache-boundary.d.ts
|
|
43
36
|
declare const SYSTEM_PROMPT_CACHE_BOUNDARY = "\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n";
|
|
44
37
|
declare function stripSystemPromptCacheBoundary(text: string): string;
|
|
@@ -52,14 +45,4 @@ declare function prependSystemPromptAdditionAfterCacheBoundary(params: {
|
|
|
52
45
|
systemPromptAddition?: string;
|
|
53
46
|
}): string;
|
|
54
47
|
//#endregion
|
|
55
|
-
|
|
56
|
-
type TlsCertificateErrorKind = "certificate_invalid" | "hostname_mismatch";
|
|
57
|
-
type TlsCertificateErrorDetails = {
|
|
58
|
-
kind: TlsCertificateErrorKind;
|
|
59
|
-
code?: string;
|
|
60
|
-
message: string;
|
|
61
|
-
};
|
|
62
|
-
/** Classify deterministic Node/OpenSSL certificate validation failures. */
|
|
63
|
-
declare function inspectTlsCertificateError(error: unknown): TlsCertificateErrorDetails | null;
|
|
64
|
-
//#endregion
|
|
65
|
-
export { SYSTEM_PROMPT_CACHE_BOUNDARY, TlsCertificateErrorDetails, TlsCertificateErrorKind, adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToModel, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, hasMediaPayload, inspectTlsCertificateError, isImageWithMediaPayload, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, sortPromptCacheToolsByName, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
|
|
48
|
+
export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
|
package/dist/internal/shared.mjs
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import { i as transformMessages } from "../host-Dog2WQiR.mjs";
|
|
2
1
|
import { t as sanitizeSurrogates } from "../sanitize-unicode-DT5o51ur.mjs";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import "../transform-messages-C8mBqZxF.mjs";
|
|
6
|
-
import { t as inspectTlsCertificateError } from "../tls-certificate-errors-DXSpluKI.mjs";
|
|
7
|
-
export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToModel, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, hasMediaPayload, inspectTlsCertificateError, isImageWithMediaPayload, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, sortPromptCacheToolsByName, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
|
|
2
|
+
import { S as normalizeStructuredPromptSection, _ as ensureSystemPromptCacheBoundary, a as adjustMaxTokensForThinking, b as stripSystemPromptCacheBoundary, g as SYSTEM_PROMPT_CACHE_BOUNDARY, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as buildBaseOptions, r as extractToolResultBlockText, s as clampReasoning, t as transformMessages, v as prependSystemPromptAdditionAfterCacheBoundary, x as normalizePromptCapabilityIds, y as splitSystemPromptCacheBoundary } from "../transform-messages-DoWx35pj.mjs";
|
|
3
|
+
export { SYSTEM_PROMPT_CACHE_BOUNDARY, adjustMaxTokensForThinking, buildBaseOptions, clampReasoning, describeToolResultMediaPlaceholder, ensureSystemPromptCacheBoundary, extractToolResultBlockText, extractToolResultText, normalizePromptCapabilityIds, normalizeStructuredPromptSection, prependSystemPromptAdditionAfterCacheBoundary, sanitizeSurrogates, splitSystemPromptCacheBoundary, stripSystemPromptCacheBoundary, transformMessages };
|
|
@@ -42,7 +42,7 @@ function repairJson(json) {
|
|
|
42
42
|
let inString = false;
|
|
43
43
|
let stringValuePrefix = "";
|
|
44
44
|
for (let index = 0; index < json.length; index++) {
|
|
45
|
-
const char = json
|
|
45
|
+
const char = json[index];
|
|
46
46
|
if (!inString) {
|
|
47
47
|
repaired += char;
|
|
48
48
|
if (char === "\"") {
|
|
@@ -58,8 +58,8 @@ function repairJson(json) {
|
|
|
58
58
|
continue;
|
|
59
59
|
}
|
|
60
60
|
if (char === "\\") {
|
|
61
|
-
const nextChar = json
|
|
62
|
-
if (
|
|
61
|
+
const nextChar = json[index + 1];
|
|
62
|
+
if (nextChar === void 0) {
|
|
63
63
|
repaired += "\\\\";
|
|
64
64
|
continue;
|
|
65
65
|
}
|
|
@@ -96,7 +96,9 @@ function repairJson(json) {
|
|
|
96
96
|
return repaired;
|
|
97
97
|
}
|
|
98
98
|
function parseJsonWithRepair(json) {
|
|
99
|
-
|
|
99
|
+
const repairedJson = repairJson(json);
|
|
100
|
+
if (repairedJson !== json) return JSON.parse(repairedJson);
|
|
101
|
+
return JSON.parse(json);
|
|
100
102
|
}
|
|
101
103
|
function looksLikeWindowsPathPrefix(prefix) {
|
|
102
104
|
const tail = prefix.slice(-160);
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
//#region packages/ai/src/utils/deferred-event-buffer.ts
|
|
2
|
+
function createDeferredEventBuffer(sink, onBufferedEvent) {
|
|
3
|
+
let events = [];
|
|
4
|
+
return {
|
|
5
|
+
push(event) {
|
|
6
|
+
events.push(event);
|
|
7
|
+
onBufferedEvent?.();
|
|
8
|
+
},
|
|
9
|
+
flush() {
|
|
10
|
+
for (const event of events) sink.push(event);
|
|
11
|
+
events = [];
|
|
12
|
+
},
|
|
13
|
+
discard() {
|
|
14
|
+
events = [];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
1
19
|
//#region packages/ai/src/utils/llm-request-activity.ts
|
|
2
20
|
const requestActivityListeners = /* @__PURE__ */ new WeakMap();
|
|
3
21
|
function notifyLlmRequestActivity(signal) {
|
|
@@ -14,4 +32,4 @@ function onLlmRequestActivity(signal, listener) {
|
|
|
14
32
|
};
|
|
15
33
|
}
|
|
16
34
|
//#endregion
|
|
17
|
-
export { onLlmRequestActivity as n, notifyLlmRequestActivity as t };
|
|
35
|
+
export { onLlmRequestActivity as n, createDeferredEventBuffer as r, notifyLlmRequestActivity as t };
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { n as getEnvApiKey } from "./env-api-keys-
|
|
2
|
-
import { t as AssistantMessageEventStream } from "./event-stream-
|
|
3
|
-
import {
|
|
1
|
+
import { n as getEnvApiKey } from "./env-api-keys-CtMlqaQ4.mjs";
|
|
2
|
+
import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
|
|
3
|
+
import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
|
|
4
|
+
import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-Cn9KAz3z.mjs";
|
|
5
|
+
import { n as parseStreamingJson } from "./json-parse-DzNSIQBq.mjs";
|
|
4
6
|
import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { c as calculateCost, l as clampThinkingLevel } from "./number-coercion-DvG7SNMg.mjs";
|
|
7
|
-
import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
|
|
8
|
-
import { d as transportAbortError } from "./transport-stream-shared-D81p90xq.mjs";
|
|
7
|
+
import { b as stripSystemPromptCacheBoundary, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as buildBaseOptions, t as transformMessages } from "./transform-messages-DoWx35pj.mjs";
|
|
9
8
|
import { t as shortHash } from "./hash-CHgqbJmD.mjs";
|
|
10
|
-
import { n as buildBaseOptions, r as clampMaxTokensToModel } from "./simple-options-9lhRrN73.mjs";
|
|
11
|
-
import "./transform-messages-C8mBqZxF.mjs";
|
|
12
9
|
import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
|
|
13
|
-
import { randomUUID } from "node:crypto";
|
|
14
10
|
import { HTTPClient, Mistral } from "@mistralai/mistralai";
|
|
15
11
|
//#region packages/ai/src/providers/mistral.ts
|
|
16
12
|
const MISTRAL_TOOL_CALL_ID_LENGTH = 9;
|
|
@@ -74,21 +70,13 @@ const streamMistral = (model, context, options) => {
|
|
|
74
70
|
let payload = buildChatPayload(model, context, transformMessages(context.messages, model, (id) => normalizeMistralToolCallId(id)), options);
|
|
75
71
|
const nextPayload = await options?.onPayload?.(payload, model);
|
|
76
72
|
if (nextPayload !== void 0) payload = nextPayload;
|
|
77
|
-
const
|
|
78
|
-
...model.headers,
|
|
79
|
-
...options?.headers
|
|
80
|
-
};
|
|
81
|
-
if (resolveMistralPromptCacheKey(options) && options?.sessionId) headers["x-affinity"] ||= options.sessionId;
|
|
82
|
-
const mistralStream = await mistral.chat.stream(payload, {
|
|
83
|
-
headers,
|
|
84
|
-
signal: options?.signal
|
|
85
|
-
});
|
|
73
|
+
const mistralStream = await mistral.chat.stream(payload, buildRequestOptions(model, options));
|
|
86
74
|
stream.push({
|
|
87
75
|
type: "start",
|
|
88
76
|
partial: output
|
|
89
77
|
});
|
|
90
78
|
await consumeChatStream(model, output, stream, mistralStream);
|
|
91
|
-
if (options?.signal?.aborted) throw
|
|
79
|
+
if (options?.signal?.aborted) throw new Error("Request was aborted");
|
|
92
80
|
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error("An unknown error occurred");
|
|
93
81
|
stream.push({
|
|
94
82
|
type: "done",
|
|
@@ -116,10 +104,7 @@ const streamMistral = (model, context, options) => {
|
|
|
116
104
|
const streamSimpleMistral = (model, context, options) => {
|
|
117
105
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
|
|
118
106
|
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
119
|
-
const base =
|
|
120
|
-
...buildBaseOptions(model, options, apiKey),
|
|
121
|
-
maxTokens: clampMaxTokensToModel(model, options?.maxTokens)
|
|
122
|
-
};
|
|
107
|
+
const base = buildBaseOptions(model, options, apiKey);
|
|
123
108
|
const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
|
|
124
109
|
const reasoning = clampedReasoning === "off" ? void 0 : clampedReasoning;
|
|
125
110
|
const shouldUseReasoning = model.reasoning && reasoning !== void 0;
|
|
@@ -177,7 +162,7 @@ function deriveMistralToolCallId(id, attempt) {
|
|
|
177
162
|
const normalized = id.replace(/[^a-zA-Z0-9]/g, "");
|
|
178
163
|
if (attempt === 0 && normalized.length === MISTRAL_TOOL_CALL_ID_LENGTH) return normalized;
|
|
179
164
|
const seedBase = normalized || id;
|
|
180
|
-
return shortHash(attempt === 0 ? seedBase : `${seedBase}:${attempt}`).replace(/[^a-zA-Z0-9]/g, "").
|
|
165
|
+
return shortHash(attempt === 0 ? seedBase : `${seedBase}:${attempt}`).replace(/[^a-zA-Z0-9]/g, "").slice(0, MISTRAL_TOOL_CALL_ID_LENGTH);
|
|
181
166
|
}
|
|
182
167
|
function formatMistralError(error) {
|
|
183
168
|
if (error instanceof Error) {
|
|
@@ -192,8 +177,7 @@ function formatMistralError(error) {
|
|
|
192
177
|
}
|
|
193
178
|
function truncateErrorText(text, maxChars) {
|
|
194
179
|
if (text.length <= maxChars) return text;
|
|
195
|
-
|
|
196
|
-
return `${truncated}... [truncated ${text.length - truncated.length} chars]`;
|
|
180
|
+
return `${text.slice(0, maxChars)}... [truncated ${text.length - maxChars} chars]`;
|
|
197
181
|
}
|
|
198
182
|
function safeJsonStringify(value) {
|
|
199
183
|
try {
|
|
@@ -203,6 +187,16 @@ function safeJsonStringify(value) {
|
|
|
203
187
|
return String(value);
|
|
204
188
|
}
|
|
205
189
|
}
|
|
190
|
+
function buildRequestOptions(model, options) {
|
|
191
|
+
const requestOptions = { retries: { strategy: "none" } };
|
|
192
|
+
if (options?.signal) requestOptions.signal = options.signal;
|
|
193
|
+
const headers = {};
|
|
194
|
+
if (model.headers) Object.assign(headers, model.headers);
|
|
195
|
+
if (options?.headers) Object.assign(headers, options.headers);
|
|
196
|
+
if (options?.sessionId && !headers["x-affinity"]) headers["x-affinity"] = options.sessionId;
|
|
197
|
+
if (Object.keys(headers).length > 0) requestOptions.headers = headers;
|
|
198
|
+
return requestOptions;
|
|
199
|
+
}
|
|
206
200
|
function buildChatPayload(model, context, messages, options) {
|
|
207
201
|
const payload = {
|
|
208
202
|
model: model.id,
|
|
@@ -224,86 +218,17 @@ function buildChatPayload(model, context, messages, options) {
|
|
|
224
218
|
}
|
|
225
219
|
if (options?.promptMode) payload.promptMode = options.promptMode;
|
|
226
220
|
if (options?.reasoningEffort) payload.reasoningEffort = options.reasoningEffort;
|
|
227
|
-
const promptCacheKey = resolveMistralPromptCacheKey(options);
|
|
228
|
-
if (promptCacheKey) payload.promptCacheKey = promptCacheKey;
|
|
229
221
|
if (context.systemPrompt) payload.messages.unshift({
|
|
230
222
|
role: "system",
|
|
231
223
|
content: sanitizeSurrogates(stripSystemPromptCacheBoundary(context.systemPrompt))
|
|
232
224
|
});
|
|
233
225
|
return payload;
|
|
234
226
|
}
|
|
235
|
-
function resolveMistralPromptCacheKey(options) {
|
|
236
|
-
if (options?.cacheRetention === "none") return;
|
|
237
|
-
return options?.promptCacheKey?.trim() || options?.sessionId?.trim() || void 0;
|
|
238
|
-
}
|
|
239
|
-
function readMistralCachedPromptTokens(usage, promptTokens) {
|
|
240
|
-
const record = usage;
|
|
241
|
-
const rawCachedTokens = record.promptTokensDetails?.cachedTokens ?? record.prompt_tokens_details?.cached_tokens ?? record.cachedTokens ?? record.cached_tokens;
|
|
242
|
-
return Math.min(promptTokens, Math.max(0, typeof rawCachedTokens === "number" && Number.isFinite(rawCachedTokens) ? rawCachedTokens : 0));
|
|
243
|
-
}
|
|
244
227
|
async function consumeChatStream(model, output, stream, mistralStream) {
|
|
245
228
|
let currentBlock = null;
|
|
246
229
|
const blocks = output.content;
|
|
247
230
|
const blockIndex = () => blocks.length - 1;
|
|
248
|
-
const
|
|
249
|
-
const normalizeMissingToolCallId = createMistralToolCallIdNormalizer();
|
|
250
|
-
const missingToolCallIdScope = randomUUID();
|
|
251
|
-
const createMissingToolCallId = (contentIndex) => normalizeMissingToolCallId(`${missingToolCallIdScope}:toolcall:${contentIndex}`);
|
|
252
|
-
const findIdentityCandidates = (matches, excludedContentIndexes) => {
|
|
253
|
-
const candidates = /* @__PURE__ */ new Set();
|
|
254
|
-
for (const [contentIndex, identity] of toolBlockIdentities) if (!excludedContentIndexes?.has(contentIndex) && matches(identity)) candidates.add(contentIndex);
|
|
255
|
-
return candidates;
|
|
256
|
-
};
|
|
257
|
-
const intersectCandidates = (left, right) => new Set([...left].filter((contentIndex) => right.has(contentIndex)));
|
|
258
|
-
const requireSingleCandidate = (candidates) => {
|
|
259
|
-
if (candidates.size > 1) throw new Error("Mistral streamed tool-call continuation is ambiguous; refusing to merge arguments");
|
|
260
|
-
return candidates.values().next().value;
|
|
261
|
-
};
|
|
262
|
-
const requireExistingCandidate = (candidates) => {
|
|
263
|
-
const candidate = requireSingleCandidate(candidates);
|
|
264
|
-
if (candidate === void 0) throw new Error("Mistral streamed tool-call identities conflict; refusing to merge arguments");
|
|
265
|
-
return candidate;
|
|
266
|
-
};
|
|
267
|
-
const resolveToolBlockIndex = (params) => {
|
|
268
|
-
const explicitId = params.explicitId;
|
|
269
|
-
const functionName = params.functionName;
|
|
270
|
-
const toolCallIndex = params.index;
|
|
271
|
-
const idCandidates = explicitId ? findIdentityCandidates((identity) => identity.explicitIds.has(explicitId), params.usedContentIndexes) : /* @__PURE__ */ new Set();
|
|
272
|
-
const nameCandidates = functionName ? findIdentityCandidates((identity) => identity.functionNames.has(functionName), params.usedContentIndexes) : /* @__PURE__ */ new Set();
|
|
273
|
-
const indexCandidates = toolCallIndex === void 0 ? /* @__PURE__ */ new Set() : findIdentityCandidates((identity) => identity.indexes.has(toolCallIndex), params.usedContentIndexes);
|
|
274
|
-
if (idCandidates.size > 0) {
|
|
275
|
-
let candidates = idCandidates;
|
|
276
|
-
if (nameCandidates.size > 0) candidates = intersectCandidates(candidates, nameCandidates);
|
|
277
|
-
return requireExistingCandidate(candidates);
|
|
278
|
-
}
|
|
279
|
-
if (nameCandidates.size > 0) {
|
|
280
|
-
const idCompatibleCandidates = new Set([...nameCandidates].filter((contentIndex) => {
|
|
281
|
-
const identity = toolBlockIdentities.get(contentIndex);
|
|
282
|
-
if (!identity) return false;
|
|
283
|
-
return !explicitId || identity.explicitIds.size === 0;
|
|
284
|
-
}));
|
|
285
|
-
if (idCompatibleCandidates.size <= 1 && (toolCallIndex === void 0 || toolCallIndex === 0)) return requireSingleCandidate(idCompatibleCandidates);
|
|
286
|
-
const indexCompatibleCandidates = new Set([...idCompatibleCandidates].filter((contentIndex) => {
|
|
287
|
-
const identity = toolBlockIdentities.get(contentIndex);
|
|
288
|
-
if (!identity) return false;
|
|
289
|
-
return toolCallIndex === void 0 || identity.indexes.size === 0 || identity.indexes.has(toolCallIndex);
|
|
290
|
-
}));
|
|
291
|
-
if (indexCompatibleCandidates.size === 0) return;
|
|
292
|
-
return requireSingleCandidate(indexCompatibleCandidates);
|
|
293
|
-
}
|
|
294
|
-
if (functionName) {
|
|
295
|
-
const namelessCandidates = new Set([...indexCandidates].filter((contentIndex) => {
|
|
296
|
-
const identity = toolBlockIdentities.get(contentIndex);
|
|
297
|
-
return identity?.functionNames.size === 0 && (!explicitId || identity.explicitIds.size === 0);
|
|
298
|
-
}));
|
|
299
|
-
return requireSingleCandidate(namelessCandidates);
|
|
300
|
-
}
|
|
301
|
-
if (explicitId) {
|
|
302
|
-
const idlessCandidates = new Set([...indexCandidates].filter((contentIndex) => toolBlockIdentities.get(contentIndex)?.explicitIds.size === 0));
|
|
303
|
-
return requireSingleCandidate(idlessCandidates);
|
|
304
|
-
}
|
|
305
|
-
return requireSingleCandidate(indexCandidates);
|
|
306
|
-
};
|
|
231
|
+
const toolBlocksByKey = /* @__PURE__ */ new Map();
|
|
307
232
|
const finishCurrentBlock = (block) => {
|
|
308
233
|
if (!block) return;
|
|
309
234
|
if (block.type === "text") {
|
|
@@ -326,13 +251,11 @@ async function consumeChatStream(model, output, stream, mistralStream) {
|
|
|
326
251
|
const chunk = event.data;
|
|
327
252
|
output.responseId ||= chunk.id;
|
|
328
253
|
if (chunk.usage) {
|
|
329
|
-
|
|
330
|
-
const cachedPromptTokens = readMistralCachedPromptTokens(chunk.usage, promptTokens);
|
|
331
|
-
output.usage.input = Math.max(0, promptTokens - cachedPromptTokens);
|
|
254
|
+
output.usage.input = chunk.usage.promptTokens || 0;
|
|
332
255
|
output.usage.output = chunk.usage.completionTokens || 0;
|
|
333
|
-
output.usage.cacheRead =
|
|
256
|
+
output.usage.cacheRead = 0;
|
|
334
257
|
output.usage.cacheWrite = 0;
|
|
335
|
-
output.usage.totalTokens = chunk.usage.totalTokens || output.usage.input + output.usage.output
|
|
258
|
+
output.usage.totalTokens = chunk.usage.totalTokens || output.usage.input + output.usage.output;
|
|
336
259
|
calculateCost(model, output.usage);
|
|
337
260
|
}
|
|
338
261
|
const choice = chunk.choices[0];
|
|
@@ -417,77 +340,52 @@ async function consumeChatStream(model, output, stream, mistralStream) {
|
|
|
417
340
|
}
|
|
418
341
|
}
|
|
419
342
|
const toolCalls = delta.toolCalls || [];
|
|
420
|
-
const usedToolBlockIndexes = /* @__PURE__ */ new Set();
|
|
421
343
|
for (const toolCall of toolCalls) {
|
|
422
344
|
if (currentBlock) {
|
|
423
345
|
finishCurrentBlock(currentBlock);
|
|
424
346
|
currentBlock = null;
|
|
425
347
|
}
|
|
426
|
-
const
|
|
427
|
-
const
|
|
428
|
-
const
|
|
429
|
-
const existingIndex = resolveToolBlockIndex({
|
|
430
|
-
explicitId: providedCallId,
|
|
431
|
-
functionName,
|
|
432
|
-
index: toolCallIndex,
|
|
433
|
-
usedContentIndexes: usedToolBlockIndexes
|
|
434
|
-
});
|
|
348
|
+
const callId = toolCall.id && toolCall.id !== "null" ? toolCall.id : deriveMistralToolCallId(`toolcall:${toolCall.index ?? 0}`, 0);
|
|
349
|
+
const key = `${callId}:${toolCall.index || 0}`;
|
|
350
|
+
const existingIndex = toolBlocksByKey.get(key);
|
|
435
351
|
let block;
|
|
436
352
|
if (existingIndex !== void 0) {
|
|
437
353
|
const existing = output.content[existingIndex];
|
|
438
354
|
if (existing?.type === "toolCall") block = existing;
|
|
439
355
|
}
|
|
440
356
|
if (!block) {
|
|
441
|
-
const contentIndex = output.content.length;
|
|
442
357
|
block = {
|
|
443
358
|
type: "toolCall",
|
|
444
|
-
id:
|
|
445
|
-
name:
|
|
359
|
+
id: callId,
|
|
360
|
+
name: toolCall.function.name,
|
|
446
361
|
arguments: {},
|
|
447
362
|
partialArgs: ""
|
|
448
363
|
};
|
|
449
364
|
output.content.push(block);
|
|
450
|
-
|
|
451
|
-
explicitIds: new Set(providedCallId ? [providedCallId] : []),
|
|
452
|
-
functionNames: new Set(functionName ? [functionName] : []),
|
|
453
|
-
indexes: new Set(toolCallIndex === void 0 ? [] : [toolCallIndex])
|
|
454
|
-
});
|
|
365
|
+
toolBlocksByKey.set(key, output.content.length - 1);
|
|
455
366
|
stream.push({
|
|
456
367
|
type: "toolcall_start",
|
|
457
|
-
contentIndex,
|
|
368
|
+
contentIndex: output.content.length - 1,
|
|
458
369
|
partial: output
|
|
459
370
|
});
|
|
460
371
|
}
|
|
461
|
-
const contentIndex = output.content.indexOf(block);
|
|
462
|
-
const identity = toolBlockIdentities.get(contentIndex);
|
|
463
|
-
if (!identity) throw new Error("Mistral streamed tool-call identity is missing");
|
|
464
|
-
usedToolBlockIndexes.add(contentIndex);
|
|
465
|
-
if (providedCallId) {
|
|
466
|
-
block.id = providedCallId;
|
|
467
|
-
identity.explicitIds.add(providedCallId);
|
|
468
|
-
}
|
|
469
|
-
if (functionName) {
|
|
470
|
-
if (identity.functionNames.size > 0 && !identity.functionNames.has(functionName)) throw new Error("Mistral streamed tool-call continuation changed function name; refusing to merge arguments");
|
|
471
|
-
block.name = functionName;
|
|
472
|
-
identity.functionNames.add(functionName);
|
|
473
|
-
}
|
|
474
|
-
if (toolCallIndex !== void 0) identity.indexes.add(toolCallIndex);
|
|
475
372
|
const argsDelta = typeof toolCall.function.arguments === "string" ? toolCall.function.arguments : JSON.stringify(toolCall.function.arguments || {});
|
|
476
373
|
block.partialArgs = (block.partialArgs || "") + argsDelta;
|
|
477
374
|
block.arguments = parseStreamingJson(block.partialArgs);
|
|
478
375
|
stream.push({
|
|
479
376
|
type: "toolcall_delta",
|
|
480
|
-
contentIndex,
|
|
377
|
+
contentIndex: toolBlocksByKey.get(key),
|
|
481
378
|
delta: argsDelta,
|
|
482
379
|
partial: output
|
|
483
380
|
});
|
|
484
381
|
}
|
|
485
382
|
}
|
|
486
383
|
finishCurrentBlock(currentBlock);
|
|
487
|
-
for (const index of
|
|
488
|
-
const block = output.content
|
|
489
|
-
if (block
|
|
384
|
+
for (const index of toolBlocksByKey.values()) {
|
|
385
|
+
const block = output.content[index];
|
|
386
|
+
if (block.type !== "toolCall") continue;
|
|
490
387
|
const toolBlock = block;
|
|
388
|
+
toolBlock.arguments = parseStreamingJson(toolBlock.partialArgs);
|
|
491
389
|
delete toolBlock.partialArgs;
|
|
492
390
|
stream.push({
|
|
493
391
|
type: "toolcall_end",
|
|
@@ -595,14 +493,14 @@ function toChatMessages(messages, supportsImages) {
|
|
|
595
493
|
continue;
|
|
596
494
|
}
|
|
597
495
|
const toolContent = [];
|
|
598
|
-
const toolText = buildToolResultText(extractToolResultText(msg.content), describeToolResultMediaPlaceholder(msg.content), msg.content.some(
|
|
496
|
+
const toolText = buildToolResultText(extractToolResultText(msg.content), describeToolResultMediaPlaceholder(msg.content), msg.content.some((part) => part.type === "image"), supportsImages, msg.isError);
|
|
599
497
|
toolContent.push({
|
|
600
498
|
type: "text",
|
|
601
499
|
text: toolText
|
|
602
500
|
});
|
|
603
501
|
for (const part of msg.content) {
|
|
604
502
|
if (!supportsImages) continue;
|
|
605
|
-
if (
|
|
503
|
+
if (part.type !== "image") continue;
|
|
606
504
|
toolContent.push({
|
|
607
505
|
type: "image_url",
|
|
608
506
|
imageUrl: `data:${part.mimeType};base64,${part.data}`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { a as requiresClaudeMandatoryAdaptiveThinking, l as resolveClaudeNativeThinkingLevelMap } from "./src-CjOfhrH3.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
|
+
usage.cost.input = model.cost.input / 1e6 * usage.input;
|
|
6
|
+
usage.cost.output = model.cost.output / 1e6 * usage.output;
|
|
7
|
+
usage.cost.cacheRead = model.cost.cacheRead / 1e6 * usage.cacheRead;
|
|
8
|
+
usage.cost.cacheWrite = model.cost.cacheWrite / 1e6 * usage.cacheWrite;
|
|
9
|
+
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
10
|
+
return usage.cost;
|
|
11
|
+
}
|
|
12
|
+
/** Replaces the catalog estimate when the provider reports an authoritative billed total. */
|
|
13
|
+
function applyProviderReportedUsageCost(usage, reportedCost) {
|
|
14
|
+
if (typeof reportedCost !== "number" || !Number.isFinite(reportedCost) || reportedCost < 0) return;
|
|
15
|
+
usage.cost.total = reportedCost;
|
|
16
|
+
usage.cost.totalOrigin = "provider-billed";
|
|
17
|
+
}
|
|
18
|
+
const EXTENDED_THINKING_LEVELS = [
|
|
19
|
+
"off",
|
|
20
|
+
"minimal",
|
|
21
|
+
"low",
|
|
22
|
+
"medium",
|
|
23
|
+
"high",
|
|
24
|
+
"xhigh",
|
|
25
|
+
"max"
|
|
26
|
+
];
|
|
27
|
+
function resolveThinkingLevelMap(model) {
|
|
28
|
+
return model.api === "anthropic-messages" ? resolveClaudeNativeThinkingLevelMap(model) ?? model.thinkingLevelMap : model.thinkingLevelMap;
|
|
29
|
+
}
|
|
30
|
+
/** Returns thinking levels exposed by a reasoning-capable model. */
|
|
31
|
+
function getSupportedThinkingLevels(model) {
|
|
32
|
+
const mandatoryAdaptiveContract = model.api === "anthropic-messages" && requiresClaudeMandatoryAdaptiveThinking(model);
|
|
33
|
+
if (!model.reasoning && !mandatoryAdaptiveContract) return ["off"];
|
|
34
|
+
const thinkingLevelMap = resolveThinkingLevelMap(model);
|
|
35
|
+
return EXTENDED_THINKING_LEVELS.filter((level) => {
|
|
36
|
+
const mapped = thinkingLevelMap?.[level];
|
|
37
|
+
if (mapped === null) return false;
|
|
38
|
+
if (level === "xhigh" || level === "max") return mapped !== void 0;
|
|
39
|
+
return true;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** Clamps a requested thinking level to the closest supported level for a model. */
|
|
43
|
+
function clampThinkingLevel(model, level) {
|
|
44
|
+
const availableLevels = getSupportedThinkingLevels(model);
|
|
45
|
+
if (availableLevels.includes(level)) return level;
|
|
46
|
+
const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
|
|
47
|
+
if (requestedIndex === -1) return availableLevels[0] ?? "off";
|
|
48
|
+
const thinkingLevelMap = resolveThinkingLevelMap(model);
|
|
49
|
+
if ((level === "xhigh" || level === "max") && thinkingLevelMap?.[level] === null) for (let i = requestedIndex - 1; i >= 0; i--) {
|
|
50
|
+
const candidate = EXTENDED_THINKING_LEVELS[i];
|
|
51
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
52
|
+
}
|
|
53
|
+
for (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {
|
|
54
|
+
const candidate = EXTENDED_THINKING_LEVELS[i];
|
|
55
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
56
|
+
}
|
|
57
|
+
for (let i = requestedIndex - 1; i >= 0; i--) {
|
|
58
|
+
const candidate = EXTENDED_THINKING_LEVELS[i];
|
|
59
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
60
|
+
}
|
|
61
|
+
return availableLevels[0] ?? "off";
|
|
62
|
+
}
|
|
63
|
+
/** Compares model identity by provider and id. */
|
|
64
|
+
function modelsAreEqual(a, b) {
|
|
65
|
+
if (!a || !b) return false;
|
|
66
|
+
return a.id === b.id && a.provider === b.provider;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { modelsAreEqual as a, getSupportedThinkingLevels as i, calculateCost as n, clampThinkingLevel as r, applyProviderReportedUsageCost as t };
|