@draht/ai 2026.10.20 → 2026.10.23
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/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +155 -111
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-config.d.ts +15 -0
- package/dist/api/azure-openai-config.d.ts.map +1 -0
- package/dist/api/azure-openai-config.js +76 -0
- package/dist/api/azure-openai-config.js.map +1 -0
- package/dist/api/azure-openai-responses.d.ts +3 -6
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +19 -83
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +86 -22
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/classifier-shared.d.ts +21 -0
- package/dist/api/classifier-shared.d.ts.map +1 -0
- package/dist/api/classifier-shared.js +99 -0
- package/dist/api/classifier-shared.js.map +1 -0
- package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.js +15 -9
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
- package/dist/api/google-generative-ai.js +4 -4
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +3 -1
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +9 -9
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +7 -2
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +28 -8
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/llama-cpp-classify.d.ts.map +1 -1
- package/dist/api/llama-cpp-classify.js +4 -1
- package/dist/api/llama-cpp-classify.js.map +1 -1
- package/dist/api/mistral-conversations.d.ts.map +1 -1
- package/dist/api/mistral-conversations.js +38 -18
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +21 -13
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +49 -38
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-decisions.d.ts +4 -0
- package/dist/api/openai-decisions.d.ts.map +1 -0
- package/dist/api/openai-decisions.js +162 -0
- package/dist/api/openai-decisions.js.map +1 -0
- package/dist/api/openai-decisions.lazy.d.ts +3 -0
- package/dist/api/openai-decisions.lazy.d.ts.map +1 -0
- package/dist/api/openai-decisions.lazy.js +4 -0
- package/dist/api/openai-decisions.lazy.js.map +1 -0
- package/dist/api/openai-responses-shared.d.ts +26 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +82 -16
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +47 -18
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.d.ts.map +1 -1
- package/dist/api/openrouter-images.js +4 -3
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +3 -3
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts +2 -1
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +12 -2
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/system-one-shared.d.ts +0 -1
- package/dist/api/system-one-shared.d.ts.map +1 -1
- package/dist/api/system-one-shared.js +5 -89
- package/dist/api/system-one-shared.js.map +1 -1
- package/dist/api/transform-messages.d.ts +16 -1
- package/dist/api/transform-messages.d.ts.map +1 -1
- package/dist/api/transform-messages.js +28 -15
- package/dist/api/transform-messages.js.map +1 -1
- package/dist/api/typesafe-system-one.d.ts.map +1 -1
- package/dist/api/typesafe-system-one.js +2 -1
- package/dist/api/typesafe-system-one.js.map +1 -1
- package/dist/auth/oauth/anthropic.d.ts.map +1 -1
- package/dist/auth/oauth/anthropic.js +65 -7
- package/dist/auth/oauth/anthropic.js.map +1 -1
- package/dist/auth/oauth/load.d.ts +2 -0
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +5 -0
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -1
- package/dist/auth/oauth/openai-chatgpt.js +11 -14
- package/dist/auth/oauth/openai-chatgpt.js.map +1 -1
- package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
- package/dist/auth/oauth/openai-codex.js +7 -5
- package/dist/auth/oauth/openai-codex.js.map +1 -1
- package/dist/auth/oauth/opencode-go.d.ts +3 -12
- package/dist/auth/oauth/opencode-go.d.ts.map +1 -1
- package/dist/auth/oauth/opencode-go.js +229 -34
- package/dist/auth/oauth/opencode-go.js.map +1 -1
- package/dist/auth/resolve.d.ts +16 -1
- package/dist/auth/resolve.d.ts.map +1 -1
- package/dist/auth/resolve.js +51 -27
- package/dist/auth/resolve.js.map +1 -1
- package/dist/auth/types.d.ts +5 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/bun-oauth.d.ts.map +1 -1
- package/dist/bun-oauth.js +2 -1
- package/dist/bun-oauth.js.map +1 -1
- package/dist/env-api-keys.js +1 -1
- package/dist/env-api-keys.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +9 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +4 -4
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +4 -4
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +26 -14
- package/dist/models.js.map +1 -1
- package/dist/providers/all.js +2 -2
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/azure.d.ts +3 -0
- package/dist/providers/azure.d.ts.map +1 -0
- package/dist/providers/azure.js +46 -0
- package/dist/providers/azure.js.map +1 -0
- package/dist/providers/azure.models.d.ts +6 -0
- package/dist/providers/azure.models.d.ts.map +1 -0
- package/dist/providers/azure.models.js +8 -0
- package/dist/providers/azure.models.js.map +1 -0
- package/dist/providers/compat-schema.d.ts +491 -0
- package/dist/providers/compat-schema.d.ts.map +1 -0
- package/dist/providers/compat-schema.js +386 -0
- package/dist/providers/compat-schema.js.map +1 -0
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/anthropic.json +1 -1
- package/dist/providers/data/azure.json +1 -0
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cerebras.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/google.json +1 -1
- package/dist/providers/data/groq.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/meta.json +1 -1
- package/dist/providers/data/minimax-cn.json +1 -1
- package/dist/providers/data/minimax.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/moonshotai-cn.json +1 -1
- package/dist/providers/data/nvidia.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/together.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/faux.d.ts.map +1 -1
- package/dist/providers/faux.js +25 -8
- package/dist/providers/faux.js.map +1 -1
- package/dist/providers/kimi-coding.d.ts +1 -1
- package/dist/providers/kimi-coding.js +3 -3
- package/dist/providers/kimi-coding.js.map +1 -1
- package/dist/providers/model-schema.d.ts +91 -0
- package/dist/providers/model-schema.d.ts.map +1 -0
- package/dist/providers/model-schema.js +57 -0
- package/dist/providers/model-schema.js.map +1 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +12 -3
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/opencode-go.d.ts +3 -1
- package/dist/providers/opencode-go.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +4 -3
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/providers/opencode.d.ts.map +1 -1
- package/dist/providers/opencode.js +10 -2
- package/dist/providers/opencode.js.map +1 -1
- package/dist/providers/openrouter-api.d.ts +40 -0
- package/dist/providers/openrouter-api.d.ts.map +1 -0
- package/dist/providers/openrouter-api.js +41 -0
- package/dist/providers/openrouter-api.js.map +1 -0
- package/dist/providers/openrouter.d.ts +11 -1
- package/dist/providers/openrouter.d.ts.map +1 -1
- package/dist/providers/openrouter.js +52 -1
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/radius.d.ts.map +1 -1
- package/dist/providers/radius.js +4 -12
- package/dist/providers/radius.js.map +1 -1
- package/dist/telemetry.d.ts +288 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +191 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +42 -310
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/estimate.js +1 -1
- package/dist/utils/estimate.js.map +1 -1
- package/dist/utils/event-stream.d.ts +10 -1
- package/dist/utils/event-stream.d.ts.map +1 -1
- package/dist/utils/event-stream.js +25 -0
- package/dist/utils/event-stream.js.map +1 -1
- package/dist/utils/identity.d.ts +65 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/identity.js +145 -0
- package/dist/utils/identity.js.map +1 -0
- package/dist/utils/json-parse.d.ts +10 -0
- package/dist/utils/json-parse.d.ts.map +1 -1
- package/dist/utils/json-parse.js +26 -1
- package/dist/utils/json-parse.js.map +1 -1
- package/dist/utils/model-operations.d.ts +3 -1
- package/dist/utils/model-operations.d.ts.map +1 -1
- package/dist/utils/model-operations.js +6 -0
- package/dist/utils/model-operations.js.map +1 -1
- package/dist/utils/overflow.d.ts +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +6 -1
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/provider-retry.d.ts +2 -0
- package/dist/utils/provider-retry.d.ts.map +1 -1
- package/dist/utils/provider-retry.js +2 -0
- package/dist/utils/provider-retry.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +30 -10
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/transcript.d.ts +27 -10
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +34 -20
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +3 -0
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +5 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +5 -5
- package/dist/providers/azure-openai-responses.d.ts +0 -3
- package/dist/providers/azure-openai-responses.d.ts.map +0 -1
- package/dist/providers/azure-openai-responses.js +0 -14
- package/dist/providers/azure-openai-responses.js.map +0 -1
- package/dist/providers/azure-openai-responses.models.d.ts +0 -6
- package/dist/providers/azure-openai-responses.models.d.ts.map +0 -1
- package/dist/providers/azure-openai-responses.models.js +0 -8
- package/dist/providers/azure-openai-responses.models.js.map +0 -1
- package/dist/providers/data/azure-openai-responses.json +0 -1
- package/dist/utils/assistant-message-frame.d.ts +0 -77
- package/dist/utils/assistant-message-frame.d.ts.map +0 -1
- package/dist/utils/assistant-message-frame.js +0 -425
- package/dist/utils/assistant-message-frame.js.map +0 -1
- package/dist/utils/draht-user-agent.d.ts +0 -2
- package/dist/utils/draht-user-agent.d.ts.map +0 -1
- package/dist/utils/draht-user-agent.js +0 -12
- package/dist/utils/draht-user-agent.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;AAoBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;AAoBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AAuJrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AA2ChE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AAoRD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA2WzE,CAAC;AA2BF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAgDlF,CAAC"}
|
|
@@ -2,19 +2,19 @@ import Anthropic, {} from "@anthropic-ai/sdk";
|
|
|
2
2
|
import { ANTHROPIC_FEDERATION_RULE_ID_ENV, ANTHROPIC_IDENTITY_TOKEN_FILE_ENV, ANTHROPIC_ORGANIZATION_ID_ENV, ANTHROPIC_SERVICE_ACCOUNT_ID_ENV, ANTHROPIC_WORKSPACE_ID_ENV, } from "../env-api-keys.js";
|
|
3
3
|
import { calculateCost } from "../models.js";
|
|
4
4
|
import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
|
|
5
|
-
import { getDrahtUserAgent } from "../utils/draht-user-agent.js";
|
|
6
5
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
7
6
|
import { headersToRecord } from "../utils/headers.js";
|
|
8
|
-
import {
|
|
7
|
+
import { getIdentityHeaders } from "../utils/identity.js";
|
|
8
|
+
import { parseJsonWithRepair, parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
|
|
9
9
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
10
10
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
11
11
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
12
12
|
import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
|
|
13
|
-
import { getCurrentTools,
|
|
13
|
+
import { getCurrentTools, getInitialSystemMessage, resolveTranscript, } from "../utils/transcript.js";
|
|
14
14
|
import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
15
15
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
|
|
16
16
|
import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
|
|
17
|
-
import { transformMessages } from "./transform-messages.js";
|
|
17
|
+
import { splitErrorToolResultImages, transformMessages } from "./transform-messages.js";
|
|
18
18
|
/**
|
|
19
19
|
* Resolve cache retention preference.
|
|
20
20
|
* Defaults to "short" and uses DRAHT_CACHE_RETENTION for backward compatibility.
|
|
@@ -75,6 +75,16 @@ const fromClaudeCodeName = (name, tools) => {
|
|
|
75
75
|
}
|
|
76
76
|
return name;
|
|
77
77
|
};
|
|
78
|
+
function convertImageBlock(image) {
|
|
79
|
+
return {
|
|
80
|
+
type: "image",
|
|
81
|
+
source: {
|
|
82
|
+
type: "base64",
|
|
83
|
+
media_type: image.mimeType,
|
|
84
|
+
data: image.data,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
78
88
|
/**
|
|
79
89
|
* Convert content blocks to Anthropic API format
|
|
80
90
|
*/
|
|
@@ -92,14 +102,7 @@ function convertContentBlocks(content) {
|
|
|
92
102
|
text: sanitizeSurrogates(block.text),
|
|
93
103
|
};
|
|
94
104
|
}
|
|
95
|
-
return
|
|
96
|
-
type: "image",
|
|
97
|
-
source: {
|
|
98
|
-
type: "base64",
|
|
99
|
-
media_type: block.mimeType,
|
|
100
|
-
data: block.data,
|
|
101
|
-
},
|
|
102
|
-
};
|
|
105
|
+
return convertImageBlock(block);
|
|
103
106
|
});
|
|
104
107
|
// If only images (no text), add placeholder text block
|
|
105
108
|
const hasText = blocks.some((b) => b.type === "text");
|
|
@@ -116,16 +119,16 @@ const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
|
116
119
|
const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
|
|
117
120
|
const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
|
|
118
121
|
const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
|
|
119
|
-
const
|
|
122
|
+
const INLINE_TOOLS_BETA = "inline-tools-2026-09-15";
|
|
120
123
|
/**
|
|
121
124
|
* Stable deferred tool declared whenever native tool changes are in use. Anthropic adds
|
|
122
|
-
* hidden prompt scaffolding
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
125
|
+
* hidden prompt scaffolding for mid-conversation tool changes; declaring this placeholder
|
|
126
|
+
* from the first request keeps that scaffolding in the cached prefix, so the first tool
|
|
127
|
+
* change does not invalidate the cache (measured: full miss without it). It is never
|
|
128
|
+
* activated and the model cannot see it.
|
|
126
129
|
*/
|
|
127
130
|
const DEFERRED_TOOL_PLACEHOLDER = {
|
|
128
|
-
name: "
|
|
131
|
+
name: "__draht_deferred_placeholder__",
|
|
129
132
|
description: "Reserved placeholder. Never available. Never call this.",
|
|
130
133
|
input_schema: { type: "object", properties: {}, required: [] },
|
|
131
134
|
defer_loading: true,
|
|
@@ -157,9 +160,6 @@ function mergeHeaders(...headerSources) {
|
|
|
157
160
|
}
|
|
158
161
|
return merged;
|
|
159
162
|
}
|
|
160
|
-
function mergeClientHeaders(...headerSources) {
|
|
161
|
-
return mergeHeaders({ "User-Agent": getDrahtUserAgent() }, ...headerSources);
|
|
162
|
-
}
|
|
163
163
|
function hasHeader(headers, name) {
|
|
164
164
|
if (!headers)
|
|
165
165
|
return false;
|
|
@@ -378,14 +378,12 @@ export const stream = (model, context, options) => {
|
|
|
378
378
|
const normalizedContext = resolveTranscript(context, getAnthropicCompat(model).supportsMidConvoSystemMessages);
|
|
379
379
|
const currentTools = getCurrentTools(normalizedContext.messages);
|
|
380
380
|
(async () => {
|
|
381
|
-
const providerThinkingLevel = model.compat?.supportsMidConvoEffort ? (options?.effort ?? "high") : undefined;
|
|
382
381
|
const output = {
|
|
383
382
|
role: "assistant",
|
|
384
383
|
content: [],
|
|
385
384
|
api: model.api,
|
|
386
385
|
provider: model.provider,
|
|
387
386
|
model: model.id,
|
|
388
|
-
...(providerThinkingLevel === undefined ? {} : { providerThinkingLevel }),
|
|
389
387
|
usage: {
|
|
390
388
|
input: 0,
|
|
391
389
|
output: 0,
|
|
@@ -421,25 +419,59 @@ export const stream = (model, context, options) => {
|
|
|
421
419
|
}
|
|
422
420
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
423
421
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
424
|
-
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
|
|
422
|
+
const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation, options?.identity);
|
|
425
423
|
client = created.client;
|
|
426
424
|
isOAuth = created.isOAuthToken;
|
|
427
425
|
}
|
|
428
|
-
let params = buildParams(model, normalizedContext, isOAuth, options);
|
|
429
|
-
const nextParams = await options?.onPayload?.(params, model);
|
|
430
|
-
if (nextParams !== undefined) {
|
|
431
|
-
params = { ...nextParams, stream: true };
|
|
432
|
-
}
|
|
433
426
|
const requestOptions = {
|
|
434
427
|
...(options?.signal ? { signal: options.signal } : {}),
|
|
435
428
|
...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
|
|
436
429
|
maxRetries: 0,
|
|
437
430
|
};
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
431
|
+
let disablePreferredStrictTools = false;
|
|
432
|
+
let response;
|
|
433
|
+
for (;;) {
|
|
434
|
+
options?.signal?.throwIfAborted();
|
|
435
|
+
const built = buildParams(model, normalizedContext, isOAuth, options, disablePreferredStrictTools);
|
|
436
|
+
if (built.providerThinkingLevel)
|
|
437
|
+
output.providerThinkingLevel = built.providerThinkingLevel;
|
|
438
|
+
let params = built.params;
|
|
439
|
+
const nextParams = await options?.onPayload?.(params, model);
|
|
440
|
+
if (nextParams !== undefined) {
|
|
441
|
+
params = { ...nextParams, stream: true };
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
response = await retryProviderRequest(() => client.beta.messages.create(params, requestOptions).asResponse(), {
|
|
445
|
+
maxRetries: options?.maxRetries,
|
|
446
|
+
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
447
|
+
signal: options?.signal,
|
|
448
|
+
});
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
// Only downgrade a rejected request, never an already-started stream.
|
|
453
|
+
if (options?.signal?.aborted ||
|
|
454
|
+
disablePreferredStrictTools ||
|
|
455
|
+
!built.hasPreferredStrictTools ||
|
|
456
|
+
!(error instanceof Anthropic.APIError) ||
|
|
457
|
+
error.status !== 400 ||
|
|
458
|
+
error.type !== "invalid_request_error" ||
|
|
459
|
+
![
|
|
460
|
+
"The compiled grammar is too large",
|
|
461
|
+
"Too many strict tools (",
|
|
462
|
+
"Schemas contains too many parameters with union types (",
|
|
463
|
+
].some((message) => error.message.includes(message))) {
|
|
464
|
+
throw error;
|
|
465
|
+
}
|
|
466
|
+
disablePreferredStrictTools = true;
|
|
467
|
+
appendAssistantMessageDiagnostic(output, {
|
|
468
|
+
type: "anthropic_strict_tools_fallback",
|
|
469
|
+
timestamp: Date.now(),
|
|
470
|
+
error: { message: error.message },
|
|
471
|
+
details: { reason: "strict_tool_limits_exceeded" },
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
443
475
|
await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
|
|
444
476
|
stream.push({ type: "start", partial: output });
|
|
445
477
|
const blocks = output.content;
|
|
@@ -593,7 +625,7 @@ export const stream = (model, context, options) => {
|
|
|
593
625
|
});
|
|
594
626
|
}
|
|
595
627
|
else if (block.type === "toolCall") {
|
|
596
|
-
block
|
|
628
|
+
Object.assign(block, parseToolCallArguments(block.partialJson));
|
|
597
629
|
// Finalize in-place and strip the scratch buffer so replay only
|
|
598
630
|
// carries parsed arguments.
|
|
599
631
|
delete block.partialJson;
|
|
@@ -748,7 +780,7 @@ export const streamSimple = (model, context, options) => {
|
|
|
748
780
|
function isOAuthToken(apiKey) {
|
|
749
781
|
return apiKey.includes("sk-ant-oat");
|
|
750
782
|
}
|
|
751
|
-
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
|
|
783
|
+
function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation, identity) {
|
|
752
784
|
// Copilot: Bearer auth.
|
|
753
785
|
if (model.provider === "github-copilot") {
|
|
754
786
|
const client = new PiAnthropic({
|
|
@@ -757,14 +789,14 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
757
789
|
baseURL: model.baseUrl,
|
|
758
790
|
dangerouslyAllowBrowser: true,
|
|
759
791
|
fetch,
|
|
760
|
-
defaultHeaders:
|
|
792
|
+
defaultHeaders: mergeHeaders(getIdentityHeaders(model, identity), {
|
|
761
793
|
accept: "application/json",
|
|
762
794
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
763
795
|
}, model.headers, dynamicHeaders, optionsHeaders),
|
|
764
796
|
});
|
|
765
797
|
return { client, isOAuthToken: false };
|
|
766
798
|
}
|
|
767
|
-
// OAuth: Bearer auth, Claude Code identity headers
|
|
799
|
+
// OAuth: Bearer auth, Claude Code identity headers instead of the client identity.
|
|
768
800
|
if (apiKey && isOAuthToken(apiKey)) {
|
|
769
801
|
const client = new PiAnthropic({
|
|
770
802
|
apiKey: null,
|
|
@@ -772,7 +804,7 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
772
804
|
baseURL: model.baseUrl,
|
|
773
805
|
dangerouslyAllowBrowser: true,
|
|
774
806
|
fetch,
|
|
775
|
-
defaultHeaders:
|
|
807
|
+
defaultHeaders: mergeHeaders({
|
|
776
808
|
accept: "application/json",
|
|
777
809
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
778
810
|
"user-agent": `claude-cli/${claudeCodeVersion}`,
|
|
@@ -788,7 +820,7 @@ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sess
|
|
|
788
820
|
const header = compat.sessionAffinityFormat === "openrouter" ? "x-session-id" : "x-session-affinity";
|
|
789
821
|
sessionAffinityHeaders[header] = sessionId;
|
|
790
822
|
}
|
|
791
|
-
const defaultHeaders =
|
|
823
|
+
const defaultHeaders = mergeHeaders(getIdentityHeaders(model, identity), {
|
|
792
824
|
accept: "application/json",
|
|
793
825
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
794
826
|
}, sessionAffinityHeaders, model.headers, optionsHeaders);
|
|
@@ -852,32 +884,42 @@ function getBetaFeatures(model, context, isOAuthToken, nativeToolChanges, option
|
|
|
852
884
|
features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
|
|
853
885
|
}
|
|
854
886
|
if (nativeToolChanges)
|
|
855
|
-
features.push(
|
|
887
|
+
features.push(INLINE_TOOLS_BETA);
|
|
856
888
|
return [...new Set(features)];
|
|
857
889
|
}
|
|
858
|
-
function buildParams(model, context, isOAuthToken, options) {
|
|
890
|
+
function buildParams(model, context, isOAuthToken, options, disablePreferredStrictTools = false) {
|
|
859
891
|
const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
|
|
860
892
|
const compat = getAnthropicCompat(model);
|
|
861
893
|
const initialSystemMessage = getInitialSystemMessage(context.messages);
|
|
862
894
|
const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
|
|
863
895
|
const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
|
|
864
896
|
const conversationMessages = initialSystemMessage ? transformedMessages.slice(1) : transformedMessages;
|
|
865
|
-
// Native tool changes
|
|
866
|
-
//
|
|
867
|
-
//
|
|
897
|
+
// Native tool changes keep the request-level tool list fixed and define every later tool
|
|
898
|
+
// by value in a `tool_addition` block, which also expresses same-name redefinitions.
|
|
899
|
+
// Anthropic rejects a tool list where every tool is deferred, so there must be an initial
|
|
900
|
+
// active tool to anchor the placeholder. Otherwise the current tool list is sent.
|
|
901
|
+
let hasPreferredStrictTools = false;
|
|
902
|
+
const convertToolDefinitions = (tools, toolCacheControl) => {
|
|
903
|
+
const definitions = convertTools(tools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl, disablePreferredStrictTools);
|
|
904
|
+
if (definitions.some((definition, index) => {
|
|
905
|
+
const config = tools[index].constrainedSampling;
|
|
906
|
+
return definition.strict === true && config && config.type === "json_schema" && config.strict === "prefer";
|
|
907
|
+
})) {
|
|
908
|
+
hasPreferredStrictTools = true;
|
|
909
|
+
}
|
|
910
|
+
return definitions;
|
|
911
|
+
};
|
|
868
912
|
const initialTools = initialSystemMessage?.toolsAdded ?? [];
|
|
869
|
-
const nativeToolChanges = compat.supportsMidConvoSystemMessages &&
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature,
|
|
913
|
+
const nativeToolChanges = compat.supportsMidConvoSystemMessages && compat.supportsMidConvoToolChanges && initialTools.length > 0;
|
|
914
|
+
const thinkingDisabled = model.reasoning && options?.thinkingEnabled === false && model.thinkingLevelMap?.off !== null;
|
|
915
|
+
// Effort cannot change between messages while thinking is disabled, so "off" sends no effort markers.
|
|
916
|
+
const effortMessages = model.compat?.supportsMidConvoEffort === true && !thinkingDisabled;
|
|
917
|
+
const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, effortMessages ? model.provider : undefined, nativeToolChanges ? convertToolDefinitions : undefined);
|
|
874
918
|
const activeEffort = options?.effort ?? "high";
|
|
875
919
|
const betaFeatures = getBetaFeatures(model, context, isOAuthToken, nativeToolChanges, options);
|
|
876
920
|
const params = {
|
|
877
921
|
model: model.id,
|
|
878
|
-
messages:
|
|
879
|
-
? insertThinkingLevelMessages(converted, activeEffort)
|
|
880
|
-
: converted.messages,
|
|
922
|
+
messages: effortMessages ? insertThinkingLevelMessages(converted, activeEffort) : converted.messages,
|
|
881
923
|
max_tokens: options?.maxTokens ?? model.maxTokens,
|
|
882
924
|
stream: true,
|
|
883
925
|
...(betaFeatures.length > 0 ? { betas: betaFeatures } : {}),
|
|
@@ -918,27 +960,26 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
918
960
|
}
|
|
919
961
|
const toolCacheControl = compat.supportsCacheControlOnTools ? cacheControl : undefined;
|
|
920
962
|
if (nativeToolChanges) {
|
|
921
|
-
// Initial tools stay active with the cache breakpoint on the last one
|
|
922
|
-
//
|
|
923
|
-
//
|
|
924
|
-
//
|
|
925
|
-
|
|
926
|
-
const laterTools = getDeclaredTools(context.messages).filter((tool) => !initialNames.has(tool.name));
|
|
927
|
-
params.tools = [
|
|
928
|
-
...convertTools(initialTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl),
|
|
929
|
-
DEFERRED_TOOL_PLACEHOLDER,
|
|
930
|
-
...convertTools(laterTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools).map((tool) => ({ ...tool, defer_loading: true })),
|
|
931
|
-
];
|
|
963
|
+
// Initial tools stay active with the cache breakpoint on the last one, followed by the
|
|
964
|
+
// placeholder. The list never changes afterwards: later tools are defined by value in
|
|
965
|
+
// `tool_addition` blocks and withdrawn by `tool_removal`, so the cached prefix survives
|
|
966
|
+
// every tool change.
|
|
967
|
+
params.tools = [...convertToolDefinitions(initialTools, toolCacheControl), DEFERRED_TOOL_PLACEHOLDER];
|
|
932
968
|
}
|
|
933
969
|
else {
|
|
934
970
|
const tools = getCurrentTools(context.messages);
|
|
935
971
|
if (tools.length > 0) {
|
|
936
|
-
params.tools =
|
|
972
|
+
params.tools = convertToolDefinitions(tools, toolCacheControl);
|
|
937
973
|
}
|
|
938
974
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
975
|
+
if (thinkingDisabled) {
|
|
976
|
+
// No effort is sent, so the model default applies. Anthropic rejects `block_binding`
|
|
977
|
+
// with disabled thinking.
|
|
978
|
+
params.thinking = { type: "disabled" };
|
|
979
|
+
}
|
|
980
|
+
else if (effortMessages) {
|
|
981
|
+
// Managed effort models use adaptive thinking so prefix mismatches can
|
|
982
|
+
// be dropped instead of surfacing as persistent 400 responses.
|
|
942
983
|
params.thinking = {
|
|
943
984
|
type: "adaptive",
|
|
944
985
|
display: options?.thinkingDisplay ?? "summarized",
|
|
@@ -946,29 +987,24 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
946
987
|
};
|
|
947
988
|
params.output_config = { effort: "high" };
|
|
948
989
|
}
|
|
949
|
-
else if (model.reasoning) {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
params.output_config = { effort: options.effort };
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
else {
|
|
962
|
-
// Budget-based thinking for older models
|
|
963
|
-
params.thinking = {
|
|
964
|
-
type: "enabled",
|
|
965
|
-
budget_tokens: options.thinkingBudgetTokens || 1024,
|
|
966
|
-
display,
|
|
967
|
-
};
|
|
990
|
+
else if (model.reasoning && options?.thinkingEnabled) {
|
|
991
|
+
// Default to "summarized" so Opus 4.7 and Mythos Preview behave like
|
|
992
|
+
// older Claude 4 models (whose API default is also "summarized").
|
|
993
|
+
const display = options.thinkingDisplay ?? "summarized";
|
|
994
|
+
if (model.compat?.forceAdaptiveThinking === true) {
|
|
995
|
+
// Adaptive thinking: Claude decides when and how much to think.
|
|
996
|
+
params.thinking = { type: "adaptive", display };
|
|
997
|
+
if (options.effort) {
|
|
998
|
+
params.output_config = { effort: options.effort };
|
|
968
999
|
}
|
|
969
1000
|
}
|
|
970
|
-
else
|
|
971
|
-
|
|
1001
|
+
else {
|
|
1002
|
+
// Budget-based thinking for older models
|
|
1003
|
+
params.thinking = {
|
|
1004
|
+
type: "enabled",
|
|
1005
|
+
budget_tokens: options.thinkingBudgetTokens || 1024,
|
|
1006
|
+
display,
|
|
1007
|
+
};
|
|
972
1008
|
}
|
|
973
1009
|
}
|
|
974
1010
|
if (options?.metadata) {
|
|
@@ -989,21 +1025,23 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
989
1025
|
if (allowedFallbackModels && allowedFallbackModels.length > 0) {
|
|
990
1026
|
params.fallbacks = allowedFallbackModels.map((fallback) => ({ model: fallback.model }));
|
|
991
1027
|
}
|
|
992
|
-
return params;
|
|
1028
|
+
return { params, hasPreferredStrictTools, providerThinkingLevel: effortMessages ? activeEffort : undefined };
|
|
993
1029
|
}
|
|
994
1030
|
// Normalize tool call IDs to match Anthropic's required pattern and length
|
|
995
1031
|
function normalizeToolCallId(id) {
|
|
996
1032
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
997
1033
|
}
|
|
998
|
-
function convertToolResult(msg) {
|
|
1034
|
+
function convertToolResult(msg, content = msg.content) {
|
|
999
1035
|
return {
|
|
1000
1036
|
type: "tool_result",
|
|
1001
1037
|
tool_use_id: msg.toolCallId,
|
|
1002
|
-
content: convertContentBlocks(
|
|
1038
|
+
content: convertContentBlocks(content),
|
|
1003
1039
|
is_error: msg.isError,
|
|
1004
1040
|
};
|
|
1005
1041
|
}
|
|
1006
|
-
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider,
|
|
1042
|
+
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider,
|
|
1043
|
+
/** Converts tool definitions for native `tool_addition` blocks; undefined when tool changes are not native. */
|
|
1044
|
+
convertToolDefinitions) {
|
|
1007
1045
|
const params = [];
|
|
1008
1046
|
const assistantLevels = new Map();
|
|
1009
1047
|
// Later system messages are held back and emitted directly before the next assistant
|
|
@@ -1025,18 +1063,20 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
1025
1063
|
const blocks = [];
|
|
1026
1064
|
if (text.length > 0)
|
|
1027
1065
|
blocks.push({ type: "text", text: sanitizeSurrogates(text) });
|
|
1028
|
-
if (
|
|
1066
|
+
if (convertToolDefinitions) {
|
|
1067
|
+
const added = msg.toolsAdded ?? [];
|
|
1068
|
+
const redefined = new Set(added.map((tool) => tool.name));
|
|
1029
1069
|
for (const tool of msg.toolsRemoved ?? []) {
|
|
1070
|
+
// A new definition under the same name replaces the old one, so no removal is needed.
|
|
1071
|
+
if (redefined.has(tool.name))
|
|
1072
|
+
continue;
|
|
1030
1073
|
blocks.push({
|
|
1031
1074
|
type: "tool_removal",
|
|
1032
1075
|
tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
|
|
1033
1076
|
});
|
|
1034
1077
|
}
|
|
1035
|
-
for (const
|
|
1036
|
-
blocks.push({
|
|
1037
|
-
type: "tool_addition",
|
|
1038
|
-
tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
|
|
1039
|
-
});
|
|
1078
|
+
for (const definition of convertToolDefinitions(added)) {
|
|
1079
|
+
blocks.push({ type: "tool_addition", tool: { type: "tool_definition", definition } });
|
|
1040
1080
|
}
|
|
1041
1081
|
}
|
|
1042
1082
|
if (blocks.length > 0)
|
|
@@ -1060,14 +1100,7 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
1060
1100
|
};
|
|
1061
1101
|
}
|
|
1062
1102
|
else {
|
|
1063
|
-
return
|
|
1064
|
-
type: "image",
|
|
1065
|
-
source: {
|
|
1066
|
-
type: "base64",
|
|
1067
|
-
media_type: item.mimeType,
|
|
1068
|
-
data: item.data,
|
|
1069
|
-
},
|
|
1070
|
-
};
|
|
1103
|
+
return convertImageBlock(item);
|
|
1071
1104
|
}
|
|
1072
1105
|
});
|
|
1073
1106
|
const filteredBlocks = blocks.filter((b) => {
|
|
@@ -1158,16 +1191,24 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
1158
1191
|
else if (msg.role === "toolResult") {
|
|
1159
1192
|
// Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
|
|
1160
1193
|
const toolResults = [];
|
|
1194
|
+
// Anthropic rejects error tool results that contain anything but text, so their images follow
|
|
1195
|
+
// all tool results of the turn, which must come first in the user message (#10794).
|
|
1196
|
+
const errorImages = [];
|
|
1161
1197
|
let j = i;
|
|
1162
1198
|
while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
|
|
1163
|
-
|
|
1199
|
+
const toolMsg = transformedMessages[j];
|
|
1200
|
+
const split = splitErrorToolResultImages(toolMsg);
|
|
1201
|
+
toolResults.push(convertToolResult(toolMsg, split?.content));
|
|
1202
|
+
if (split) {
|
|
1203
|
+
errorImages.push({ type: "text", text: split.caption }, ...split.images.map(convertImageBlock));
|
|
1204
|
+
}
|
|
1164
1205
|
j++;
|
|
1165
1206
|
}
|
|
1166
1207
|
// Skip the messages we've already processed.
|
|
1167
1208
|
i = j - 1;
|
|
1168
1209
|
params.push({
|
|
1169
1210
|
role: "user",
|
|
1170
|
-
content: toolResults,
|
|
1211
|
+
content: [...toolResults, ...errorImages],
|
|
1171
1212
|
});
|
|
1172
1213
|
}
|
|
1173
1214
|
}
|
|
@@ -1254,11 +1295,14 @@ const isAnthropicStrictUnsupportedKeyword = (key, value) => {
|
|
|
1254
1295
|
return typeof value !== "string" || !ANTHROPIC_STRICT_STRING_FORMATS.has(value);
|
|
1255
1296
|
return false;
|
|
1256
1297
|
};
|
|
1257
|
-
function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl) {
|
|
1298
|
+
function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl, disablePreferredStrictTools = false) {
|
|
1258
1299
|
if (!tools)
|
|
1259
1300
|
return [];
|
|
1260
1301
|
return tools.map((tool, index) => {
|
|
1261
|
-
const
|
|
1302
|
+
const config = tool.constrainedSampling;
|
|
1303
|
+
const strict = disablePreferredStrictTools && config && config.type === "json_schema" && config.strict === "prefer"
|
|
1304
|
+
? undefined
|
|
1305
|
+
: resolveJsonSchemaStrictSampling(tool, supportsStrictTools, isAnthropicStrictUnsupportedKeyword);
|
|
1262
1306
|
const parameters = getJsonSchemaToolParameters(tool, strict);
|
|
1263
1307
|
const schema = parameters;
|
|
1264
1308
|
const legacyInputSchema = {
|