@openclaw/ai 2026.7.2-beta.3 → 2026.7.2-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/{anthropic-D7SyZQ5v.mjs → anthropic-CQVj3le6.mjs} +174 -33
- package/dist/{index-BoTnz8cv.d.mts → anthropic-SrGtwsJu.d.mts} +27 -1
- package/dist/{api-registry-DXBIXISf.d.mts → api-registry-DlMgPR39.d.mts} +1 -2
- package/dist/{azure-openai-responses-BkZgyZ3I.mjs → azure-openai-responses-DIYgsqFM.mjs} +7 -11
- package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
- package/dist/error-coercion-DgxlWC0n.mjs +15 -0
- package/dist/{event-stream-BPemFrFW.d.mts → event-stream-YjaPW20U.d.mts} +1 -1
- package/dist/event-stream.d.mts +1 -1
- package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → github-copilot-headers-BCoBNmL7.mjs} +48 -1
- package/dist/{google-C_biGbV7.mjs → google-f-A8xrae.mjs} +4 -4
- package/dist/{google-shared-BK-NoHl8.mjs → google-shared-J6qvYINH.mjs} +5 -4
- package/dist/{google-vertex-CvdzF1U7.mjs → google-vertex-D3yMVXIY.mjs} +3 -3
- package/dist/host-B9GUmcra.d.mts +173 -0
- package/dist/host-XYGZcgO8.mjs +98 -0
- package/dist/index-BVVgDSdq.d.mts +1 -0
- package/dist/index.d.mts +7 -50
- package/dist/index.mjs +3 -3
- package/dist/internal/anthropic.d.mts +15 -11
- package/dist/internal/anthropic.mjs +4 -4
- package/dist/internal/openai.d.mts +3 -280
- package/dist/internal/openai.mjs +5 -7
- package/dist/internal/runtime.d.mts +13 -34
- package/dist/internal/runtime.mjs +19 -11
- package/dist/internal/shared.d.mts +13 -8
- package/dist/internal/shared.mjs +2 -2
- package/dist/{mistral-BdrQmDWp.mjs → mistral-CKV-TOQj.mjs} +7 -6
- package/dist/number-coercion-DvG7SNMg.mjs +129 -0
- package/dist/openai-BPor_3WI.d.mts +358 -0
- package/dist/{openai-responses-shared-CwnGU0KW.mjs → openai-D3PD6PE-.mjs} +1890 -705
- package/dist/{openai-chatgpt-responses-DP63Qt01.mjs → openai-chatgpt-responses-CedIj0hk.mjs} +54 -58
- package/dist/{openai-completions-zLDfebnN.mjs → openai-completions-CiSutyu0.mjs} +459 -104
- package/dist/openai-prompt-cache-2uo_1OR1.d.mts +7 -0
- package/dist/openai-prompt-cache-mZTCdRPo.mjs +12 -0
- package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +13 -0
- package/dist/{provider-error-LMfTEkfO.mjs → provider-error-apVOZI6G.mjs} +9 -2
- package/dist/providers.d.mts +3 -2
- package/dist/providers.mjs +10 -9
- package/dist/{transform-messages-eb6lxDLB.mjs → shared-CdjNZd35.mjs} +273 -161
- package/dist/{src-CXno1H5g.mjs → src-QkygScBs.mjs} +23 -4
- package/dist/stream-first-event-timeout-C3OgBjIk.mjs +12294 -0
- package/dist/stream-first-event-timeout-DvDeSucC.d.mts +29 -0
- package/dist/transport-stream-shared-BbMELSI4.mjs +297 -0
- package/dist/transports.d.mts +593 -0
- package/dist/transports.mjs +4069 -0
- package/dist/{types-CYORveZ7.d.mts → types-bzp5k29J.d.mts} +8 -0
- package/dist/types.d.mts +5 -5
- package/dist/types.mjs +2 -2
- package/dist/{validation-BX8euiDv.d.mts → validation-B-j7cOYp.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/package.json +36 -11
- package/dist/azure-openai-responses-client-compat-C7K7QfUE.mjs +0 -62
- package/dist/github-copilot-headers-BsH5cqGj.mjs +0 -48
- package/dist/host-4t713IeR.mjs +0 -37
- package/dist/model-utils-1GiZ2_rr.mjs +0 -64
- package/dist/openai-responses-ClspWt4I.mjs +0 -136
- package/dist/openai-tool-projection-WHf2nuOI.mjs +0 -200
- package/dist/reasoning-tag-text-partitioner-BlVe67g6.mjs +0 -400
- package/dist/stream-first-event-timeout-RjWszj8c.mjs +0 -106
- package/npm-shrinkwrap.json +0 -645
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region packages/ai/src/providers/openai-prompt-cache.d.ts
|
|
2
|
+
/** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
|
|
3
|
+
declare const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
|
|
4
|
+
/** Truncates a prompt cache key by Unicode code point count. */
|
|
5
|
+
declare function clampOpenAIPromptCacheKey(key: string | undefined): string | undefined;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { clampOpenAIPromptCacheKey as n, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region packages/ai/src/providers/openai-prompt-cache.ts
|
|
2
|
+
/** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
|
|
3
|
+
const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
|
|
4
|
+
/** Truncates a prompt cache key by Unicode code point count. */
|
|
5
|
+
function clampOpenAIPromptCacheKey(key) {
|
|
6
|
+
if (key === void 0) return;
|
|
7
|
+
const chars = Array.from(key);
|
|
8
|
+
if (chars.length <= 64) return key;
|
|
9
|
+
return chars.slice(0, 64).join("");
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { clampOpenAIPromptCacheKey as n, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region packages/ai/src/utils/prompt-cache-stability.d.ts
|
|
2
|
+
/** Canonicalizes provider tool order without relying on host locale settings. */
|
|
3
|
+
declare function sortPromptCacheToolsByName<T extends {
|
|
4
|
+
readonly name?: string;
|
|
5
|
+
readonly wireName?: string;
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
}>(tools: readonly T[]): T[];
|
|
8
|
+
/** Normalize structured prompt text before hashing or snapshot comparison. */
|
|
9
|
+
declare function normalizeStructuredPromptSection(text: string): string;
|
|
10
|
+
/** Normalize, de-dupe, and sort capability ids for stable prompt payloads. */
|
|
11
|
+
declare function normalizePromptCapabilityIds(capabilities: ReadonlyArray<string>): string[];
|
|
12
|
+
//#endregion
|
|
13
|
+
export { normalizeStructuredPromptSection as n, sortPromptCacheToolsByName as r, normalizePromptCapabilityIds as t };
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import { D as truncateUtf16Safe } from "./shared-CdjNZd35.mjs";
|
|
1
2
|
//#region packages/ai/src/utils/provider-error.ts
|
|
2
3
|
const MAX_ERROR_BODY_LENGTH = 4e3;
|
|
3
4
|
function stringify(value) {
|
|
5
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
4
6
|
try {
|
|
5
|
-
return JSON.stringify(value)
|
|
7
|
+
return JSON.stringify(value, (_key, candidate) => {
|
|
8
|
+
if (typeof candidate !== "object" || candidate === null) return candidate;
|
|
9
|
+
if (seen.has(candidate)) return "[Circular]";
|
|
10
|
+
seen.add(candidate);
|
|
11
|
+
return candidate;
|
|
12
|
+
}) ?? String(value);
|
|
6
13
|
} catch {
|
|
7
14
|
return String(value);
|
|
8
15
|
}
|
|
@@ -25,7 +32,7 @@ function readBody(error) {
|
|
|
25
32
|
if (value === void 0 || value === null) continue;
|
|
26
33
|
if (typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) continue;
|
|
27
34
|
const body = (typeof value === "string" ? value : stringify(value)).trim();
|
|
28
|
-
if (body.length > 0) return body.length <= MAX_ERROR_BODY_LENGTH ? body : `${body
|
|
35
|
+
if (body.length > 0) return body.length <= MAX_ERROR_BODY_LENGTH ? body : `${truncateUtf16Safe(body, MAX_ERROR_BODY_LENGTH)}... [truncated]`;
|
|
29
36
|
}
|
|
30
37
|
}
|
|
31
38
|
function formatProviderError(error) {
|
package/dist/providers.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { n as ApiRegistry } from "./api-registry-
|
|
1
|
+
import { n as ApiRegistry } from "./api-registry-DlMgPR39.mjs";
|
|
2
|
+
import { n as clampOpenAIPromptCacheKey, t as OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH } from "./openai-prompt-cache-2uo_1OR1.mjs";
|
|
2
3
|
|
|
3
4
|
//#region packages/ai/src/providers/register-builtins.d.ts
|
|
4
5
|
/** Source id used for built-in API provider registrations. */
|
|
@@ -8,4 +9,4 @@ declare function registerBuiltInApiProviders(registry: ApiRegistry): void;
|
|
|
8
9
|
/** Restores the built-in provider registry state for tests. */
|
|
9
10
|
declare function resetApiProviders(registry: ApiRegistry): void;
|
|
10
11
|
//#endregion
|
|
11
|
-
export { BUILT_IN_API_PROVIDER_SOURCE_ID, registerBuiltInApiProviders, resetApiProviders };
|
|
12
|
+
export { BUILT_IN_API_PROVIDER_SOURCE_ID, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, clampOpenAIPromptCacheKey, registerBuiltInApiProviders, resetApiProviders };
|
package/dist/providers.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
|
|
2
|
+
import { n as clampOpenAIPromptCacheKey, t as OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH } from "./openai-prompt-cache-mZTCdRPo.mjs";
|
|
2
3
|
//#region packages/ai/src/providers/register-builtins.ts
|
|
3
4
|
/** Source id used for built-in API provider registrations. */
|
|
4
5
|
const BUILT_IN_API_PROVIDER_SOURCE_ID = "core:built-in";
|
|
@@ -63,35 +64,35 @@ function createLazyRegistration(api, importModule, select) {
|
|
|
63
64
|
};
|
|
64
65
|
}
|
|
65
66
|
const registerBuiltIns = [
|
|
66
|
-
createLazyRegistration("anthropic-messages", () => import("./anthropic-
|
|
67
|
+
createLazyRegistration("anthropic-messages", () => import("./anthropic-CQVj3le6.mjs").then((n) => n.t), (module) => ({
|
|
67
68
|
stream: module.streamAnthropic,
|
|
68
69
|
streamSimple: module.streamSimpleAnthropic
|
|
69
70
|
})),
|
|
70
|
-
createLazyRegistration("openai-completions", () => import("./openai-completions-
|
|
71
|
+
createLazyRegistration("openai-completions", () => import("./openai-completions-CiSutyu0.mjs").then((n) => n.n), (module) => ({
|
|
71
72
|
stream: module.streamOpenAICompletions,
|
|
72
73
|
streamSimple: module.streamSimpleOpenAICompletions
|
|
73
74
|
})),
|
|
74
|
-
createLazyRegistration("mistral-conversations", () => import("./mistral-
|
|
75
|
+
createLazyRegistration("mistral-conversations", () => import("./mistral-CKV-TOQj.mjs"), (module) => ({
|
|
75
76
|
stream: module.streamMistral,
|
|
76
77
|
streamSimple: module.streamSimpleMistral
|
|
77
78
|
})),
|
|
78
|
-
createLazyRegistration("openai-responses", () => import("./openai-
|
|
79
|
+
createLazyRegistration("openai-responses", () => import("./openai-D3PD6PE-.mjs").then((n) => n.t), (module) => ({
|
|
79
80
|
stream: module.streamOpenAIResponses,
|
|
80
81
|
streamSimple: module.streamSimpleOpenAIResponses
|
|
81
82
|
})),
|
|
82
|
-
createLazyRegistration("azure-openai-responses", () => import("./azure-openai-responses-
|
|
83
|
+
createLazyRegistration("azure-openai-responses", () => import("./azure-openai-responses-DIYgsqFM.mjs"), (module) => ({
|
|
83
84
|
stream: module.streamAzureOpenAIResponses,
|
|
84
85
|
streamSimple: module.streamSimpleAzureOpenAIResponses
|
|
85
86
|
})),
|
|
86
|
-
createLazyRegistration("openai-chatgpt-responses", () => import("./openai-chatgpt-responses-
|
|
87
|
+
createLazyRegistration("openai-chatgpt-responses", () => import("./openai-chatgpt-responses-CedIj0hk.mjs"), (module) => ({
|
|
87
88
|
stream: module.streamOpenAICodexResponses,
|
|
88
89
|
streamSimple: module.streamSimpleOpenAICodexResponses
|
|
89
90
|
})),
|
|
90
|
-
createLazyRegistration("google-generative-ai", () => import("./google-
|
|
91
|
+
createLazyRegistration("google-generative-ai", () => import("./google-f-A8xrae.mjs"), (module) => ({
|
|
91
92
|
stream: module.streamGoogle,
|
|
92
93
|
streamSimple: module.streamSimpleGoogle
|
|
93
94
|
})),
|
|
94
|
-
createLazyRegistration("google-vertex", () => import("./google-vertex-
|
|
95
|
+
createLazyRegistration("google-vertex", () => import("./google-vertex-D3yMVXIY.mjs"), (module) => ({
|
|
95
96
|
stream: module.streamGoogleVertex,
|
|
96
97
|
streamSimple: module.streamSimpleGoogleVertex
|
|
97
98
|
}))
|
|
@@ -106,4 +107,4 @@ function resetApiProviders(registry) {
|
|
|
106
107
|
registerBuiltInApiProviders(registry);
|
|
107
108
|
}
|
|
108
109
|
//#endregion
|
|
109
|
-
export { BUILT_IN_API_PROVIDER_SOURCE_ID, registerBuiltInApiProviders, resetApiProviders };
|
|
110
|
+
export { BUILT_IN_API_PROVIDER_SOURCE_ID, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH, clampOpenAIPromptCacheKey, registerBuiltInApiProviders, resetApiProviders };
|
|
@@ -1,164 +1,6 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { n as getAiTransportHost } from "./host-
|
|
1
|
+
import { a as requiresClaudeMandatoryAdaptiveThinking, c as resolveClaudeMythos5ModelIdentity, d as resolveClaudeSonnet5ModelIdentity, i as requiresClaudeDefaultSampling, o as resolveClaudeFable5ModelIdentity, u as resolveClaudeOpus5ModelIdentity } from "./src-QkygScBs.mjs";
|
|
2
|
+
import { n as getAiTransportHost } from "./host-XYGZcgO8.mjs";
|
|
3
3
|
import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
|
|
4
|
-
//#region packages/normalization-core/src/string-coerce.ts
|
|
5
|
-
/** Trims string input and returns null for non-strings or empty strings. */
|
|
6
|
-
function normalizeNullableString(value) {
|
|
7
|
-
if (typeof value !== "string") return null;
|
|
8
|
-
const trimmed = value.trim();
|
|
9
|
-
return trimmed ? trimmed : null;
|
|
10
|
-
}
|
|
11
|
-
/** Trims string input and returns undefined for non-strings or empty strings. */
|
|
12
|
-
function normalizeOptionalString(value) {
|
|
13
|
-
return normalizeNullableString(value) ?? void 0;
|
|
14
|
-
}
|
|
15
|
-
/** Lowercases a normalized optional string. */
|
|
16
|
-
function normalizeOptionalLowercaseString(value) {
|
|
17
|
-
return normalizeOptionalString(value)?.toLowerCase();
|
|
18
|
-
}
|
|
19
|
-
/** Lowercases a normalized string or returns an empty string when absent. */
|
|
20
|
-
function normalizeLowercaseStringOrEmpty(value) {
|
|
21
|
-
return normalizeOptionalLowercaseString(value) ?? "";
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
//#region packages/ai/src/utils/prompt-cache-stability.ts
|
|
25
|
-
/**
|
|
26
|
-
* Prompt-cache normalization helpers. They keep generated prompt sections
|
|
27
|
-
* deterministic across platform newlines, trailing whitespace, and input
|
|
28
|
-
* ordering.
|
|
29
|
-
*/
|
|
30
|
-
/** Normalize structured prompt text before hashing or snapshot comparison. */
|
|
31
|
-
function normalizeStructuredPromptSection(text) {
|
|
32
|
-
return sanitizeSurrogates(text).replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "").trim();
|
|
33
|
-
}
|
|
34
|
-
/** Normalize, de-dupe, and sort capability ids for stable prompt payloads. */
|
|
35
|
-
function normalizePromptCapabilityIds(capabilities) {
|
|
36
|
-
const seen = /* @__PURE__ */ new Set();
|
|
37
|
-
const normalized = [];
|
|
38
|
-
for (const capability of capabilities) {
|
|
39
|
-
const value = normalizeLowercaseStringOrEmpty(normalizeStructuredPromptSection(capability));
|
|
40
|
-
if (!value || seen.has(value)) continue;
|
|
41
|
-
seen.add(value);
|
|
42
|
-
normalized.push(value);
|
|
43
|
-
}
|
|
44
|
-
return normalized.toSorted((left, right) => left.localeCompare(right));
|
|
45
|
-
}
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region packages/ai/src/utils/system-prompt-cache-boundary.ts
|
|
48
|
-
/**
|
|
49
|
-
* System prompt cache-boundary helpers.
|
|
50
|
-
*
|
|
51
|
-
* Keeps stable prompt prefixes separate from dynamic runtime additions for provider prompt caching.
|
|
52
|
-
*/
|
|
53
|
-
const SYSTEM_PROMPT_CACHE_BOUNDARY = "\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n";
|
|
54
|
-
function stripSystemPromptCacheBoundary(text) {
|
|
55
|
-
return text.replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY, "\n");
|
|
56
|
-
}
|
|
57
|
-
function ensureSystemPromptCacheBoundary(systemPrompt) {
|
|
58
|
-
if (systemPrompt.trim().length === 0) return systemPrompt;
|
|
59
|
-
return systemPrompt.includes("\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n") ? systemPrompt : `${systemPrompt}${SYSTEM_PROMPT_CACHE_BOUNDARY}`;
|
|
60
|
-
}
|
|
61
|
-
function splitSystemPromptCacheBoundary(text) {
|
|
62
|
-
const boundaryIndex = text.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
63
|
-
if (boundaryIndex === -1) return;
|
|
64
|
-
return {
|
|
65
|
-
stablePrefix: text.slice(0, boundaryIndex).trimEnd(),
|
|
66
|
-
dynamicSuffix: text.slice(boundaryIndex + 34).trimStart()
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
function prependSystemPromptAdditionAfterCacheBoundary(params) {
|
|
70
|
-
const systemPromptAddition = typeof params.systemPromptAddition === "string" ? normalizeStructuredPromptSection(params.systemPromptAddition) : "";
|
|
71
|
-
if (!systemPromptAddition) return params.systemPrompt;
|
|
72
|
-
if (params.systemPrompt.trim().length === 0) return systemPromptAddition;
|
|
73
|
-
const split = splitSystemPromptCacheBoundary(params.systemPrompt);
|
|
74
|
-
if (!split) return `${systemPromptAddition}\n\n${params.systemPrompt}`;
|
|
75
|
-
const dynamicSuffix = split.dynamicSuffix ? normalizeStructuredPromptSection(split.dynamicSuffix) : "";
|
|
76
|
-
if (!dynamicSuffix) return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}`;
|
|
77
|
-
return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}\n\n${dynamicSuffix}`;
|
|
78
|
-
}
|
|
79
|
-
//#endregion
|
|
80
|
-
//#region packages/ai/src/providers/anthropic-model-contract.ts
|
|
81
|
-
function normalizeModelId(modelId) {
|
|
82
|
-
const normalized = normalizeLowercaseStringOrEmpty(modelId);
|
|
83
|
-
return (normalized.startsWith("anthropic/") ? normalized.slice(10) : normalized).replace(/[._\s]+/g, "-");
|
|
84
|
-
}
|
|
85
|
-
function normalizeApi(api) {
|
|
86
|
-
const normalized = normalizeLowercaseStringOrEmpty(api);
|
|
87
|
-
return normalized === "openclaw-anthropic-messages-transport" ? "anthropic-messages" : normalized;
|
|
88
|
-
}
|
|
89
|
-
function hasConcreteResponseModel(ref) {
|
|
90
|
-
const responseModelId = normalizeModelId(ref.responseModelId);
|
|
91
|
-
return responseModelId.length > 0 && responseModelId !== normalizeModelId(ref.modelId);
|
|
92
|
-
}
|
|
93
|
-
function usesClaudeFable5MessagesContract(model) {
|
|
94
|
-
return normalizeApi(model.api) === "anthropic-messages" && resolveClaudeFable5ModelIdentity(model) !== void 0;
|
|
95
|
-
}
|
|
96
|
-
/** Return whether streamed output must wait for the terminal refusal decision. */
|
|
97
|
-
function usesClaudeStreamingRefusalContract(model) {
|
|
98
|
-
if (normalizeApi(model.api) !== "anthropic-messages") return false;
|
|
99
|
-
return resolveClaudeFable5ModelIdentity(model) !== void 0 || resolveClaudeMythos5ModelIdentity(model) !== void 0 || resolveClaudeSonnet5ModelIdentity(model) !== void 0;
|
|
100
|
-
}
|
|
101
|
-
function requiresClaudeAdaptiveThinking(model) {
|
|
102
|
-
if (normalizeApi(model.api) !== "anthropic-messages") return false;
|
|
103
|
-
return requiresClaudeMandatoryAdaptiveThinking(model);
|
|
104
|
-
}
|
|
105
|
-
/** Return whether omitted thinking should default to adaptive/high. */
|
|
106
|
-
function defaultsClaudeAdaptiveThinking(model) {
|
|
107
|
-
return requiresClaudeAdaptiveThinking(model) || normalizeApi(model.api) === "anthropic-messages" && resolveClaudeSonnet5ModelIdentity(model) !== void 0;
|
|
108
|
-
}
|
|
109
|
-
/** Remove Sonnet 5 assistant prefills while preserving completed tool-use turns. */
|
|
110
|
-
function prepareClaudeSonnet5RequestContext(model, context) {
|
|
111
|
-
if (!resolveClaudeSonnet5ModelIdentity(model)) return context;
|
|
112
|
-
let end = context.messages.length;
|
|
113
|
-
while (end > 0) {
|
|
114
|
-
const message = context.messages[end - 1];
|
|
115
|
-
if (message?.role !== "assistant" || Array.isArray(message.content) && message.content.some((block) => block.type === "toolCall")) break;
|
|
116
|
-
end -= 1;
|
|
117
|
-
}
|
|
118
|
-
return end === context.messages.length ? context : {
|
|
119
|
-
...context,
|
|
120
|
-
messages: context.messages.slice(0, end)
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function applyClaudeRequestContract(params, model) {
|
|
124
|
-
if (normalizeApi(model.api) !== "anthropic-messages") return;
|
|
125
|
-
const sonnet5 = resolveClaudeSonnet5ModelIdentity(model) !== void 0;
|
|
126
|
-
if (!requiresClaudeDefaultSampling(model) && !sonnet5) return;
|
|
127
|
-
delete params.temperature;
|
|
128
|
-
delete params.top_p;
|
|
129
|
-
delete params.top_k;
|
|
130
|
-
if (sonnet5) delete params.service_tier;
|
|
131
|
-
}
|
|
132
|
-
function resolveReplayModelBoundIdentity(ref) {
|
|
133
|
-
if (normalizeApi(ref.api) !== "anthropic-messages") return;
|
|
134
|
-
const modelRef = hasConcreteResponseModel(ref) ? { id: ref.responseModelId } : {
|
|
135
|
-
id: ref.modelId,
|
|
136
|
-
params: ref.modelParams
|
|
137
|
-
};
|
|
138
|
-
const fableIdentity = resolveClaudeFable5ModelIdentity(modelRef);
|
|
139
|
-
if (fableIdentity) return `fable:${fableIdentity}`;
|
|
140
|
-
const mythosIdentity = resolveClaudeMythos5ModelIdentity(modelRef);
|
|
141
|
-
if (mythosIdentity) return `mythos:${mythosIdentity}`;
|
|
142
|
-
const sonnetIdentity = resolveClaudeSonnet5ModelIdentity(modelRef);
|
|
143
|
-
return sonnetIdentity ? `sonnet:${sonnetIdentity}` : void 0;
|
|
144
|
-
}
|
|
145
|
-
function resolveModelBoundThinkingReplayMode(params) {
|
|
146
|
-
const sourceApi = normalizeApi(params.source.api);
|
|
147
|
-
const targetApi = normalizeApi(params.target.api);
|
|
148
|
-
const sourceIdentity = resolveReplayModelBoundIdentity(params.source);
|
|
149
|
-
const targetIdentity = resolveReplayModelBoundIdentity(params.target);
|
|
150
|
-
const sameRoute = normalizeLowercaseStringOrEmpty(params.source.provider) === normalizeLowercaseStringOrEmpty(params.target.provider) && sourceApi === targetApi && normalizeModelId(params.source.modelId) === normalizeModelId(params.target.modelId);
|
|
151
|
-
if (!sourceIdentity && !targetIdentity) return "default";
|
|
152
|
-
if (!sourceIdentity && !hasConcreteResponseModel(params.source) && targetIdentity && sameRoute) return "preserve";
|
|
153
|
-
return sourceApi === targetApi && sourceIdentity === targetIdentity ? "preserve" : "drop";
|
|
154
|
-
}
|
|
155
|
-
//#endregion
|
|
156
|
-
//#region packages/normalization-core/src/record-coerce.ts
|
|
157
|
-
/** Type guard for non-array object records at browser-safe boundaries. */
|
|
158
|
-
function isRecord(value) {
|
|
159
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
160
|
-
}
|
|
161
|
-
//#endregion
|
|
162
4
|
//#region packages/ai/src/providers/simple-options.ts
|
|
163
5
|
function buildBaseOptions(model, options, apiKey) {
|
|
164
6
|
const firstEventOptions = options;
|
|
@@ -208,6 +50,12 @@ function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLeve
|
|
|
208
50
|
};
|
|
209
51
|
}
|
|
210
52
|
//#endregion
|
|
53
|
+
//#region packages/normalization-core/src/record-coerce.ts
|
|
54
|
+
/** Type guard for non-array object records at browser-safe boundaries. */
|
|
55
|
+
function isRecord(value) {
|
|
56
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
211
59
|
//#region packages/normalization-core/src/utf16-slice.ts
|
|
212
60
|
function isHighSurrogate(codeUnit) {
|
|
213
61
|
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
@@ -365,6 +213,113 @@ function extractToolResultText(blocks) {
|
|
|
365
213
|
return sanitizeSurrogates(truncateProviderToolText(structuredTexts.join("\n")));
|
|
366
214
|
}
|
|
367
215
|
//#endregion
|
|
216
|
+
//#region packages/normalization-core/src/string-coerce.ts
|
|
217
|
+
/** Reads a value only when it is already a string, preserving whitespace. */
|
|
218
|
+
function readStringValue(value) {
|
|
219
|
+
return typeof value === "string" ? value : void 0;
|
|
220
|
+
}
|
|
221
|
+
/** Trims string input and returns null for non-strings or empty strings. */
|
|
222
|
+
function normalizeNullableString(value) {
|
|
223
|
+
if (typeof value !== "string") return null;
|
|
224
|
+
const trimmed = value.trim();
|
|
225
|
+
return trimmed ? trimmed : null;
|
|
226
|
+
}
|
|
227
|
+
/** Trims string input and returns undefined for non-strings or empty strings. */
|
|
228
|
+
function normalizeOptionalString(value) {
|
|
229
|
+
return normalizeNullableString(value) ?? void 0;
|
|
230
|
+
}
|
|
231
|
+
/** Lowercases a normalized optional string. */
|
|
232
|
+
function normalizeOptionalLowercaseString(value) {
|
|
233
|
+
return normalizeOptionalString(value)?.toLowerCase();
|
|
234
|
+
}
|
|
235
|
+
/** Lowercases a normalized string or returns an empty string when absent. */
|
|
236
|
+
function normalizeLowercaseStringOrEmpty(value) {
|
|
237
|
+
return normalizeOptionalLowercaseString(value) ?? "";
|
|
238
|
+
}
|
|
239
|
+
/** Type guard for strings that remain non-empty after trimming. */
|
|
240
|
+
function hasNonEmptyString(value) {
|
|
241
|
+
return normalizeOptionalString(value) !== void 0;
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region packages/ai/src/providers/anthropic-model-contract.ts
|
|
245
|
+
function normalizeModelId(modelId) {
|
|
246
|
+
const normalized = normalizeLowercaseStringOrEmpty(modelId);
|
|
247
|
+
return (normalized.startsWith("anthropic/") ? normalized.slice(10) : normalized).replace(/[._\s]+/g, "-");
|
|
248
|
+
}
|
|
249
|
+
function normalizeApi(api) {
|
|
250
|
+
const normalized = normalizeLowercaseStringOrEmpty(api);
|
|
251
|
+
return normalized === "openclaw-anthropic-messages-transport" ? "anthropic-messages" : normalized;
|
|
252
|
+
}
|
|
253
|
+
function hasConcreteResponseModel(ref) {
|
|
254
|
+
const responseModelId = normalizeModelId(ref.responseModelId);
|
|
255
|
+
return responseModelId.length > 0 && responseModelId !== normalizeModelId(ref.modelId);
|
|
256
|
+
}
|
|
257
|
+
function usesClaudeFable5MessagesContract(model) {
|
|
258
|
+
return normalizeApi(model.api) === "anthropic-messages" && resolveClaudeFable5ModelIdentity(model) !== void 0;
|
|
259
|
+
}
|
|
260
|
+
/** Return whether streamed output must wait for the terminal refusal decision. */
|
|
261
|
+
function usesClaudeStreamingRefusalContract(model) {
|
|
262
|
+
if (normalizeApi(model.api) !== "anthropic-messages") return false;
|
|
263
|
+
return resolveClaudeFable5ModelIdentity(model) !== void 0 || resolveClaudeMythos5ModelIdentity(model) !== void 0 || resolveClaudeOpus5ModelIdentity(model) !== void 0 || resolveClaudeSonnet5ModelIdentity(model) !== void 0;
|
|
264
|
+
}
|
|
265
|
+
function requiresClaudeAdaptiveThinking(model) {
|
|
266
|
+
if (normalizeApi(model.api) !== "anthropic-messages") return false;
|
|
267
|
+
return requiresClaudeMandatoryAdaptiveThinking(model);
|
|
268
|
+
}
|
|
269
|
+
/** Return whether omitted thinking should default to adaptive/high. */
|
|
270
|
+
function defaultsClaudeAdaptiveThinking(model) {
|
|
271
|
+
return requiresClaudeAdaptiveThinking(model) || normalizeApi(model.api) === "anthropic-messages" && (resolveClaudeOpus5ModelIdentity(model) !== void 0 || resolveClaudeSonnet5ModelIdentity(model) !== void 0);
|
|
272
|
+
}
|
|
273
|
+
/** Remove unsupported assistant prefills while preserving completed tool-use turns. */
|
|
274
|
+
function prepareClaudeNoPrefillRequestContext(model, context) {
|
|
275
|
+
if (!resolveClaudeOpus5ModelIdentity(model) && !resolveClaudeSonnet5ModelIdentity(model)) return context;
|
|
276
|
+
let end = context.messages.length;
|
|
277
|
+
while (end > 0) {
|
|
278
|
+
const message = context.messages[end - 1];
|
|
279
|
+
if (message?.role !== "assistant" || Array.isArray(message.content) && message.content.some((block) => block.type === "toolCall")) break;
|
|
280
|
+
end -= 1;
|
|
281
|
+
}
|
|
282
|
+
return end === context.messages.length ? context : {
|
|
283
|
+
...context,
|
|
284
|
+
messages: context.messages.slice(0, end)
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function applyClaudeRequestContract(params, model) {
|
|
288
|
+
if (normalizeApi(model.api) !== "anthropic-messages") return;
|
|
289
|
+
const opus5 = resolveClaudeOpus5ModelIdentity(model) !== void 0;
|
|
290
|
+
const sonnet5 = resolveClaudeSonnet5ModelIdentity(model) !== void 0;
|
|
291
|
+
if (!requiresClaudeDefaultSampling(model) && !opus5 && !sonnet5) return;
|
|
292
|
+
delete params.temperature;
|
|
293
|
+
delete params.top_p;
|
|
294
|
+
delete params.top_k;
|
|
295
|
+
if (opus5 || sonnet5) delete params.service_tier;
|
|
296
|
+
}
|
|
297
|
+
function resolveReplayModelBoundIdentity(ref) {
|
|
298
|
+
if (normalizeApi(ref.api) !== "anthropic-messages") return;
|
|
299
|
+
const modelRef = hasConcreteResponseModel(ref) ? { id: ref.responseModelId } : {
|
|
300
|
+
id: ref.modelId,
|
|
301
|
+
params: ref.modelParams
|
|
302
|
+
};
|
|
303
|
+
const fableIdentity = resolveClaudeFable5ModelIdentity(modelRef);
|
|
304
|
+
if (fableIdentity) return `fable:${fableIdentity}`;
|
|
305
|
+
const mythosIdentity = resolveClaudeMythos5ModelIdentity(modelRef);
|
|
306
|
+
if (mythosIdentity) return `mythos:${mythosIdentity}`;
|
|
307
|
+
const opusIdentity = resolveClaudeOpus5ModelIdentity(modelRef);
|
|
308
|
+
if (opusIdentity) return `opus:${opusIdentity}`;
|
|
309
|
+
const sonnetIdentity = resolveClaudeSonnet5ModelIdentity(modelRef);
|
|
310
|
+
return sonnetIdentity ? `sonnet:${sonnetIdentity}` : void 0;
|
|
311
|
+
}
|
|
312
|
+
function resolveModelBoundThinkingReplayMode(params) {
|
|
313
|
+
const sourceApi = normalizeApi(params.source.api);
|
|
314
|
+
const targetApi = normalizeApi(params.target.api);
|
|
315
|
+
const sourceIdentity = resolveReplayModelBoundIdentity(params.source);
|
|
316
|
+
const targetIdentity = resolveReplayModelBoundIdentity(params.target);
|
|
317
|
+
const sameRoute = normalizeLowercaseStringOrEmpty(params.source.provider) === normalizeLowercaseStringOrEmpty(params.target.provider) && sourceApi === targetApi && normalizeModelId(params.source.modelId) === normalizeModelId(params.target.modelId);
|
|
318
|
+
if (!sourceIdentity && !targetIdentity) return "default";
|
|
319
|
+
if (!sourceIdentity && !hasConcreteResponseModel(params.source) && targetIdentity && sameRoute) return "preserve";
|
|
320
|
+
return sourceApi === targetApi && sourceIdentity === targetIdentity ? "preserve" : "drop";
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
368
323
|
//#region packages/ai/src/providers/transform-messages.ts
|
|
369
324
|
const NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
370
325
|
const NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
@@ -519,4 +474,161 @@ function transformMessages(messages, model, normalizeToolCallId) {
|
|
|
519
474
|
return result;
|
|
520
475
|
}
|
|
521
476
|
//#endregion
|
|
522
|
-
|
|
477
|
+
//#region packages/ai/src/utils/prompt-cache-stability.ts
|
|
478
|
+
/**
|
|
479
|
+
* Prompt-cache normalization helpers. They keep generated prompt sections
|
|
480
|
+
* deterministic across platform newlines, trailing whitespace, and input
|
|
481
|
+
* ordering.
|
|
482
|
+
*/
|
|
483
|
+
/** Canonicalizes provider tool order without relying on host locale settings. */
|
|
484
|
+
function sortPromptCacheToolsByName(tools) {
|
|
485
|
+
const compareText = (left, right) => {
|
|
486
|
+
const leftText = left ?? "";
|
|
487
|
+
const rightText = right ?? "";
|
|
488
|
+
return leftText < rightText ? -1 : leftText > rightText ? 1 : 0;
|
|
489
|
+
};
|
|
490
|
+
return tools.toSorted((left, right) => compareText(left.wireName ?? left.name, right.wireName ?? right.name) || compareText(left.description, right.description));
|
|
491
|
+
}
|
|
492
|
+
/** Normalize structured prompt text before hashing or snapshot comparison. */
|
|
493
|
+
function normalizeStructuredPromptSection(text) {
|
|
494
|
+
return sanitizeSurrogates(text).replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "").trim();
|
|
495
|
+
}
|
|
496
|
+
/** Normalize, de-dupe, and sort capability ids for stable prompt payloads. */
|
|
497
|
+
function normalizePromptCapabilityIds(capabilities) {
|
|
498
|
+
const seen = /* @__PURE__ */ new Set();
|
|
499
|
+
const normalized = [];
|
|
500
|
+
for (const capability of capabilities) {
|
|
501
|
+
const value = normalizeLowercaseStringOrEmpty(normalizeStructuredPromptSection(capability));
|
|
502
|
+
if (!value || seen.has(value)) continue;
|
|
503
|
+
seen.add(value);
|
|
504
|
+
normalized.push(value);
|
|
505
|
+
}
|
|
506
|
+
return normalized.toSorted((left, right) => left.localeCompare(right));
|
|
507
|
+
}
|
|
508
|
+
//#endregion
|
|
509
|
+
//#region packages/ai/src/utils/system-prompt-cache-boundary.ts
|
|
510
|
+
/**
|
|
511
|
+
* System prompt cache-boundary helpers.
|
|
512
|
+
*
|
|
513
|
+
* Keeps stable prompt prefixes separate from dynamic runtime additions for provider prompt caching.
|
|
514
|
+
*/
|
|
515
|
+
const SYSTEM_PROMPT_CACHE_BOUNDARY = "\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n";
|
|
516
|
+
function stripSystemPromptCacheBoundary(text) {
|
|
517
|
+
return text.replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY, "\n");
|
|
518
|
+
}
|
|
519
|
+
function ensureSystemPromptCacheBoundary(systemPrompt) {
|
|
520
|
+
if (systemPrompt.trim().length === 0) return systemPrompt;
|
|
521
|
+
return systemPrompt.includes("\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n") ? systemPrompt : `${systemPrompt}${SYSTEM_PROMPT_CACHE_BOUNDARY}`;
|
|
522
|
+
}
|
|
523
|
+
function splitSystemPromptCacheBoundary(text) {
|
|
524
|
+
const boundaryIndex = text.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
525
|
+
if (boundaryIndex === -1) return;
|
|
526
|
+
return {
|
|
527
|
+
stablePrefix: text.slice(0, boundaryIndex).trimEnd(),
|
|
528
|
+
dynamicSuffix: text.slice(boundaryIndex + 34).trimStart()
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
function prependSystemPromptAdditionAfterCacheBoundary(params) {
|
|
532
|
+
const systemPromptAddition = typeof params.systemPromptAddition === "string" ? normalizeStructuredPromptSection(params.systemPromptAddition) : "";
|
|
533
|
+
if (!systemPromptAddition) return params.systemPrompt;
|
|
534
|
+
if (params.systemPrompt.trim().length === 0) return systemPromptAddition;
|
|
535
|
+
const split = splitSystemPromptCacheBoundary(params.systemPrompt);
|
|
536
|
+
if (!split) return `${systemPromptAddition}\n\n${params.systemPrompt}`;
|
|
537
|
+
const dynamicSuffix = split.dynamicSuffix ? normalizeStructuredPromptSection(split.dynamicSuffix) : "";
|
|
538
|
+
if (!dynamicSuffix) return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}`;
|
|
539
|
+
return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}\n\n${dynamicSuffix}`;
|
|
540
|
+
}
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region packages/ai/src/utils/tls-certificate-errors.ts
|
|
543
|
+
const HOSTNAME_MISMATCH_CODES = /* @__PURE__ */ new Set(["ERR_TLS_CERT_ALTNAME_INVALID", "HOSTNAME_MISMATCH"]);
|
|
544
|
+
const CERTIFICATE_INVALID_CODES = /* @__PURE__ */ new Set([
|
|
545
|
+
"CERT_CHAIN_TOO_LONG",
|
|
546
|
+
"CERT_HAS_EXPIRED",
|
|
547
|
+
"CERT_NOT_YET_VALID",
|
|
548
|
+
"CERT_REJECTED",
|
|
549
|
+
"CERT_REVOKED",
|
|
550
|
+
"CERT_SIGNATURE_FAILURE",
|
|
551
|
+
"CERT_UNTRUSTED",
|
|
552
|
+
"CRL_HAS_EXPIRED",
|
|
553
|
+
"CRL_NOT_YET_VALID",
|
|
554
|
+
"CRL_SIGNATURE_FAILURE",
|
|
555
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
556
|
+
"ERROR_IN_CERT_NOT_AFTER_FIELD",
|
|
557
|
+
"ERROR_IN_CERT_NOT_BEFORE_FIELD",
|
|
558
|
+
"ERROR_IN_CRL_LAST_UPDATE_FIELD",
|
|
559
|
+
"ERROR_IN_CRL_NEXT_UPDATE_FIELD",
|
|
560
|
+
"INVALID_CA",
|
|
561
|
+
"INVALID_PURPOSE",
|
|
562
|
+
"PATH_LENGTH_EXCEEDED",
|
|
563
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
564
|
+
"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY",
|
|
565
|
+
"UNABLE_TO_DECRYPT_CERT_SIGNATURE",
|
|
566
|
+
"UNABLE_TO_DECRYPT_CRL_SIGNATURE",
|
|
567
|
+
"UNABLE_TO_GET_CRL",
|
|
568
|
+
"UNABLE_TO_GET_ISSUER_CERT",
|
|
569
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
570
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE"
|
|
571
|
+
]);
|
|
572
|
+
const HOSTNAME_MISMATCH_PATTERNS = [
|
|
573
|
+
/hostname\/ip does not match certificate(?:'s)? altnames/i,
|
|
574
|
+
/hostname mismatch/i,
|
|
575
|
+
/host: .+ is not in the cert(?:ificate)?(?:'s)? altnames/i
|
|
576
|
+
];
|
|
577
|
+
const CERTIFICATE_INVALID_PATTERNS = [
|
|
578
|
+
/certificate has expired/i,
|
|
579
|
+
/certificate is not yet valid/i,
|
|
580
|
+
/self[- ]signed certificate/i,
|
|
581
|
+
/unable to get local issuer certificate/i,
|
|
582
|
+
/unable to verify the first certificate/i
|
|
583
|
+
];
|
|
584
|
+
const MAX_TLS_ERROR_DEPTH = 8;
|
|
585
|
+
function classifyCode(code) {
|
|
586
|
+
if (HOSTNAME_MISMATCH_CODES.has(code)) return "hostname_mismatch";
|
|
587
|
+
return CERTIFICATE_INVALID_CODES.has(code) ? "certificate_invalid" : null;
|
|
588
|
+
}
|
|
589
|
+
function classifyMessage(message) {
|
|
590
|
+
if (HOSTNAME_MISMATCH_PATTERNS.some((pattern) => pattern.test(message))) return "hostname_mismatch";
|
|
591
|
+
return CERTIFICATE_INVALID_PATTERNS.some((pattern) => pattern.test(message)) ? "certificate_invalid" : null;
|
|
592
|
+
}
|
|
593
|
+
function inspectTlsCertificateErrorInternal(error, seen, depth) {
|
|
594
|
+
if (depth > MAX_TLS_ERROR_DEPTH) return null;
|
|
595
|
+
if (typeof error === "string") {
|
|
596
|
+
const kind = classifyMessage(error);
|
|
597
|
+
return kind ? {
|
|
598
|
+
kind,
|
|
599
|
+
message: error
|
|
600
|
+
} : null;
|
|
601
|
+
}
|
|
602
|
+
if (!error || typeof error !== "object" || seen.has(error)) return null;
|
|
603
|
+
seen.add(error);
|
|
604
|
+
const candidate = error;
|
|
605
|
+
const code = typeof candidate.code === "string" ? candidate.code.trim().toUpperCase() : void 0;
|
|
606
|
+
const message = typeof candidate.message === "string" && candidate.message.trim() ? candidate.message : void 0;
|
|
607
|
+
const codeKind = code ? classifyCode(code) : null;
|
|
608
|
+
if (code && codeKind) return {
|
|
609
|
+
kind: codeKind,
|
|
610
|
+
code,
|
|
611
|
+
message: message ?? code
|
|
612
|
+
};
|
|
613
|
+
const nestedErrors = Array.isArray(candidate.errors) ? candidate.errors : [];
|
|
614
|
+
for (const nested of [
|
|
615
|
+
candidate.cause,
|
|
616
|
+
candidate.error,
|
|
617
|
+
...nestedErrors
|
|
618
|
+
]) {
|
|
619
|
+
if (nested === void 0 || nested === error) continue;
|
|
620
|
+
const details = inspectTlsCertificateErrorInternal(nested, seen, depth + 1);
|
|
621
|
+
if (details) return details;
|
|
622
|
+
}
|
|
623
|
+
const messageKind = message ? classifyMessage(message) : null;
|
|
624
|
+
return messageKind && message ? {
|
|
625
|
+
kind: messageKind,
|
|
626
|
+
message
|
|
627
|
+
} : null;
|
|
628
|
+
}
|
|
629
|
+
/** Classify deterministic Node/OpenSSL certificate validation failures. */
|
|
630
|
+
function inspectTlsCertificateError(error) {
|
|
631
|
+
return inspectTlsCertificateErrorInternal(error, /* @__PURE__ */ new Set(), 0);
|
|
632
|
+
}
|
|
633
|
+
//#endregion
|
|
634
|
+
export { buildBaseOptions as A, extractToolResultBlockText as C, truncateUtf16Safe as D, isImageWithMediaPayload as E, clampReasoning as M, isRecord as O, describeToolResultMediaPlaceholder as S, hasMediaPayload as T, usesClaudeStreamingRefusalContract as _, splitSystemPromptCacheBoundary as a, normalizeOptionalString as b, normalizeStructuredPromptSection as c, applyClaudeRequestContract as d, defaultsClaudeAdaptiveThinking as f, usesClaudeFable5MessagesContract as g, resolveModelBoundThinkingReplayMode as h, prependSystemPromptAdditionAfterCacheBoundary as i, clampMaxTokensToModel as j, adjustMaxTokensForThinking as k, sortPromptCacheToolsByName as l, requiresClaudeAdaptiveThinking as m, SYSTEM_PROMPT_CACHE_BOUNDARY as n, stripSystemPromptCacheBoundary as o, prepareClaudeNoPrefillRequestContext as p, ensureSystemPromptCacheBoundary as r, normalizePromptCapabilityIds as s, inspectTlsCertificateError as t, transformMessages as u, hasNonEmptyString as v, extractToolResultText as w, readStringValue as x, normalizeLowercaseStringOrEmpty as y };
|
|
@@ -31,6 +31,7 @@ const CLAUDE_SONNET_5_THINKING_PROFILE = {
|
|
|
31
31
|
],
|
|
32
32
|
defaultLevel: "high"
|
|
33
33
|
};
|
|
34
|
+
const CLAUDE_OPUS_5_THINKING_PROFILE = CLAUDE_SONNET_5_THINKING_PROFILE;
|
|
34
35
|
/** Resolve the canonical normalized Claude model id for one runtime model ref. */
|
|
35
36
|
function resolveClaudeModelIdentity(ref) {
|
|
36
37
|
const normalized = normalizeClaudeModelId((typeof ref.params?.canonicalModelId === "string" ? ref.params.canonicalModelId : void 0) ?? ref.id);
|
|
@@ -63,20 +64,38 @@ function resolveClaudeSonnet5ModelIdentity(ref) {
|
|
|
63
64
|
if (!match) return;
|
|
64
65
|
return normalized.slice((match.index ?? 0) + (match[0].startsWith("-") ? 1 : 0));
|
|
65
66
|
}
|
|
67
|
+
/** Resolve Claude Opus 5 through aliases, direct ids, cloud ids, or deployment metadata. */
|
|
68
|
+
function resolveClaudeOpus5ModelIdentity(ref) {
|
|
69
|
+
const normalized = resolveClaudeModelIdentity(ref);
|
|
70
|
+
if (normalized === "opus" || normalized === "opus-5") return "claude-opus-5";
|
|
71
|
+
const match = /(?:^|-)claude-opus-5(?=$|[^a-z0-9])/.exec(normalized);
|
|
72
|
+
if (!match) return;
|
|
73
|
+
return normalized.slice((match.index ?? 0) + (match[0].startsWith("-") ? 1 : 0));
|
|
74
|
+
}
|
|
66
75
|
/** Return whether a Claude model supports adaptive thinking. */
|
|
67
76
|
function supportsClaudeAdaptiveThinking(ref) {
|
|
68
77
|
const modelId = resolveClaudeModelIdentity(ref);
|
|
69
|
-
return /(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(modelId);
|
|
78
|
+
return resolveClaudeOpus5ModelIdentity(ref) !== void 0 || /(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(modelId);
|
|
79
|
+
}
|
|
80
|
+
/** Return whether a Claude model has a native 1M-token context window. */
|
|
81
|
+
function supportsClaude1MContext(ref) {
|
|
82
|
+
const modelId = resolveClaudeModelIdentity(ref);
|
|
83
|
+
return resolveClaudeOpus5ModelIdentity(ref) !== void 0 || /(?:^|-)claude-(?:fable-5|mythos-(?:5|preview)|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(modelId);
|
|
84
|
+
}
|
|
85
|
+
/** Return whether a Claude model supports Anthropic's native fast mode. */
|
|
86
|
+
function supportsClaudeFastMode(ref) {
|
|
87
|
+
const modelId = resolveClaudeModelIdentity(ref);
|
|
88
|
+
return resolveClaudeOpus5ModelIdentity(ref) !== void 0 || /(?:^|-)claude-opus-4-8(?=$|[^a-z0-9])/.test(modelId);
|
|
70
89
|
}
|
|
71
90
|
/** Return whether a Claude model supports native max effort. */
|
|
72
91
|
function supportsClaudeNativeMaxEffort(ref) {
|
|
73
92
|
const modelId = resolveClaudeModelIdentity(ref);
|
|
74
|
-
return /(?:^|-)claude-(?:fable-5|mythos-5|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(modelId);
|
|
93
|
+
return resolveClaudeOpus5ModelIdentity(ref) !== void 0 || /(?:^|-)claude-(?:fable-5|mythos-5|opus-4-(?:6|7|8)|sonnet-(?:5|4-6))(?=$|[^a-z0-9])/.test(modelId);
|
|
75
94
|
}
|
|
76
95
|
/** Return whether a Claude model supports native xhigh effort. */
|
|
77
96
|
function supportsClaudeNativeXhighEffort(ref) {
|
|
78
97
|
const modelId = resolveClaudeModelIdentity(ref);
|
|
79
|
-
return /(?:^|-)claude-(?:fable-5|mythos-5|opus-4-(?:7|8)|sonnet-5)(?=$|[^a-z0-9])/.test(modelId);
|
|
98
|
+
return resolveClaudeOpus5ModelIdentity(ref) !== void 0 || /(?:^|-)claude-(?:fable-5|mythos-5|opus-4-(?:7|8)|sonnet-5)(?=$|[^a-z0-9])/.test(modelId);
|
|
80
99
|
}
|
|
81
100
|
/** Return whether a Claude model rejects caller-selected sampling parameters. */
|
|
82
101
|
function requiresClaudeDefaultSampling(ref) {
|
|
@@ -96,4 +115,4 @@ function resolveClaudeNativeThinkingLevelMap(ref) {
|
|
|
96
115
|
};
|
|
97
116
|
}
|
|
98
117
|
//#endregion
|
|
99
|
-
export {
|
|
118
|
+
export { requiresClaudeMandatoryAdaptiveThinking as a, resolveClaudeMythos5ModelIdentity as c, resolveClaudeSonnet5ModelIdentity as d, supportsClaude1MContext as f, supportsClaudeNativeXhighEffort as g, supportsClaudeNativeMaxEffort as h, requiresClaudeDefaultSampling as i, resolveClaudeNativeThinkingLevelMap as l, supportsClaudeFastMode as m, CLAUDE_OPUS_5_THINKING_PROFILE as n, resolveClaudeFable5ModelIdentity as o, supportsClaudeAdaptiveThinking as p, CLAUDE_SONNET_5_THINKING_PROFILE as r, resolveClaudeModelIdentity as s, CLAUDE_FABLE_5_THINKING_PROFILE as t, resolveClaudeOpus5ModelIdentity as u };
|