1191 lines
37 KiB
JavaScript
1191 lines
37 KiB
JavaScript
// src/anthropic-provider.ts
|
|
import {
|
|
NoSuchModelError
|
|
} from "@ai-sdk/provider";
|
|
import {
|
|
loadApiKey,
|
|
withoutTrailingSlash
|
|
} from "@ai-sdk/provider-utils";
|
|
|
|
// src/anthropic-messages-language-model.ts
|
|
import {
|
|
UnsupportedFunctionalityError as UnsupportedFunctionalityError3
|
|
} from "@ai-sdk/provider";
|
|
import {
|
|
combineHeaders,
|
|
createEventSourceResponseHandler,
|
|
createJsonResponseHandler,
|
|
parseProviderOptions,
|
|
postJsonToApi,
|
|
resolve
|
|
} from "@ai-sdk/provider-utils";
|
|
import { z as z2 } from "zod";
|
|
|
|
// src/anthropic-error.ts
|
|
import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
|
|
import { z } from "zod";
|
|
var anthropicErrorDataSchema = z.object({
|
|
type: z.literal("error"),
|
|
error: z.object({
|
|
type: z.string(),
|
|
message: z.string()
|
|
})
|
|
});
|
|
var anthropicFailedResponseHandler = createJsonErrorResponseHandler({
|
|
errorSchema: anthropicErrorDataSchema,
|
|
errorToMessage: (data) => data.error.message
|
|
});
|
|
|
|
// src/anthropic-prepare-tools.ts
|
|
import {
|
|
UnsupportedFunctionalityError
|
|
} from "@ai-sdk/provider";
|
|
function prepareTools(mode) {
|
|
var _a;
|
|
const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
|
|
const toolWarnings = [];
|
|
const betas = /* @__PURE__ */ new Set();
|
|
if (tools == null) {
|
|
return { tools: void 0, tool_choice: void 0, toolWarnings, betas };
|
|
}
|
|
const anthropicTools2 = [];
|
|
for (const tool of tools) {
|
|
switch (tool.type) {
|
|
case "function":
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
description: tool.description,
|
|
input_schema: tool.parameters
|
|
});
|
|
break;
|
|
case "provider-defined":
|
|
switch (tool.id) {
|
|
case "anthropic.computer_20250124":
|
|
betas.add("computer-use-2025-01-24");
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
type: "computer_20250124",
|
|
display_width_px: tool.args.displayWidthPx,
|
|
display_height_px: tool.args.displayHeightPx,
|
|
display_number: tool.args.displayNumber
|
|
});
|
|
break;
|
|
case "anthropic.computer_20241022":
|
|
betas.add("computer-use-2024-10-22");
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
type: "computer_20241022",
|
|
display_width_px: tool.args.displayWidthPx,
|
|
display_height_px: tool.args.displayHeightPx,
|
|
display_number: tool.args.displayNumber
|
|
});
|
|
break;
|
|
case "anthropic.text_editor_20250124":
|
|
betas.add("computer-use-2025-01-24");
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
type: "text_editor_20250124"
|
|
});
|
|
break;
|
|
case "anthropic.text_editor_20241022":
|
|
betas.add("computer-use-2024-10-22");
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
type: "text_editor_20241022"
|
|
});
|
|
break;
|
|
case "anthropic.bash_20250124":
|
|
betas.add("computer-use-2025-01-24");
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
type: "bash_20250124"
|
|
});
|
|
break;
|
|
case "anthropic.bash_20241022":
|
|
betas.add("computer-use-2024-10-22");
|
|
anthropicTools2.push({
|
|
name: tool.name,
|
|
type: "bash_20241022"
|
|
});
|
|
break;
|
|
default:
|
|
toolWarnings.push({ type: "unsupported-tool", tool });
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
toolWarnings.push({ type: "unsupported-tool", tool });
|
|
break;
|
|
}
|
|
}
|
|
const toolChoice = mode.toolChoice;
|
|
if (toolChoice == null) {
|
|
return {
|
|
tools: anthropicTools2,
|
|
tool_choice: void 0,
|
|
toolWarnings,
|
|
betas
|
|
};
|
|
}
|
|
const type = toolChoice.type;
|
|
switch (type) {
|
|
case "auto":
|
|
return {
|
|
tools: anthropicTools2,
|
|
tool_choice: { type: "auto" },
|
|
toolWarnings,
|
|
betas
|
|
};
|
|
case "required":
|
|
return {
|
|
tools: anthropicTools2,
|
|
tool_choice: { type: "any" },
|
|
toolWarnings,
|
|
betas
|
|
};
|
|
case "none":
|
|
return { tools: void 0, tool_choice: void 0, toolWarnings, betas };
|
|
case "tool":
|
|
return {
|
|
tools: anthropicTools2,
|
|
tool_choice: { type: "tool", name: toolChoice.toolName },
|
|
toolWarnings,
|
|
betas
|
|
};
|
|
default: {
|
|
const _exhaustiveCheck = type;
|
|
throw new UnsupportedFunctionalityError({
|
|
functionality: `Unsupported tool choice type: ${_exhaustiveCheck}`
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// src/convert-to-anthropic-messages-prompt.ts
|
|
import {
|
|
UnsupportedFunctionalityError as UnsupportedFunctionalityError2
|
|
} from "@ai-sdk/provider";
|
|
import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
|
|
function convertToAnthropicMessagesPrompt({
|
|
prompt,
|
|
sendReasoning,
|
|
warnings
|
|
}) {
|
|
var _a, _b, _c, _d;
|
|
const betas = /* @__PURE__ */ new Set();
|
|
const blocks = groupIntoBlocks(prompt);
|
|
let system = void 0;
|
|
const messages = [];
|
|
function getCacheControl(providerMetadata) {
|
|
var _a2;
|
|
const anthropic2 = providerMetadata == null ? void 0 : providerMetadata.anthropic;
|
|
const cacheControlValue = (_a2 = anthropic2 == null ? void 0 : anthropic2.cacheControl) != null ? _a2 : anthropic2 == null ? void 0 : anthropic2.cache_control;
|
|
return cacheControlValue;
|
|
}
|
|
for (let i = 0; i < blocks.length; i++) {
|
|
const block = blocks[i];
|
|
const isLastBlock = i === blocks.length - 1;
|
|
const type = block.type;
|
|
switch (type) {
|
|
case "system": {
|
|
if (system != null) {
|
|
throw new UnsupportedFunctionalityError2({
|
|
functionality: "Multiple system messages that are separated by user/assistant messages"
|
|
});
|
|
}
|
|
system = block.messages.map(({ content, providerMetadata }) => ({
|
|
type: "text",
|
|
text: content,
|
|
cache_control: getCacheControl(providerMetadata)
|
|
}));
|
|
break;
|
|
}
|
|
case "user": {
|
|
const anthropicContent = [];
|
|
for (const message of block.messages) {
|
|
const { role, content } = message;
|
|
switch (role) {
|
|
case "user": {
|
|
for (let j = 0; j < content.length; j++) {
|
|
const part = content[j];
|
|
const isLastPart = j === content.length - 1;
|
|
const cacheControl = (_a = getCacheControl(part.providerMetadata)) != null ? _a : isLastPart ? getCacheControl(message.providerMetadata) : void 0;
|
|
switch (part.type) {
|
|
case "text": {
|
|
anthropicContent.push({
|
|
type: "text",
|
|
text: part.text,
|
|
cache_control: cacheControl
|
|
});
|
|
break;
|
|
}
|
|
case "image": {
|
|
anthropicContent.push({
|
|
type: "image",
|
|
source: part.image instanceof URL ? {
|
|
type: "url",
|
|
url: part.image.toString()
|
|
} : {
|
|
type: "base64",
|
|
media_type: (_b = part.mimeType) != null ? _b : "image/jpeg",
|
|
data: convertUint8ArrayToBase64(part.image)
|
|
},
|
|
cache_control: cacheControl
|
|
});
|
|
break;
|
|
}
|
|
case "file": {
|
|
if (part.mimeType !== "application/pdf") {
|
|
throw new UnsupportedFunctionalityError2({
|
|
functionality: "Non-PDF files in user messages"
|
|
});
|
|
}
|
|
betas.add("pdfs-2024-09-25");
|
|
anthropicContent.push({
|
|
type: "document",
|
|
source: part.data instanceof URL ? {
|
|
type: "url",
|
|
url: part.data.toString()
|
|
} : {
|
|
type: "base64",
|
|
media_type: "application/pdf",
|
|
data: part.data
|
|
},
|
|
cache_control: cacheControl
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case "tool": {
|
|
for (let i2 = 0; i2 < content.length; i2++) {
|
|
const part = content[i2];
|
|
const isLastPart = i2 === content.length - 1;
|
|
const cacheControl = (_c = getCacheControl(part.providerMetadata)) != null ? _c : isLastPart ? getCacheControl(message.providerMetadata) : void 0;
|
|
const toolResultContent = part.content != null ? part.content.map((part2) => {
|
|
var _a2;
|
|
switch (part2.type) {
|
|
case "text":
|
|
return {
|
|
type: "text",
|
|
text: part2.text,
|
|
cache_control: void 0
|
|
};
|
|
case "image":
|
|
return {
|
|
type: "image",
|
|
source: {
|
|
type: "base64",
|
|
media_type: (_a2 = part2.mimeType) != null ? _a2 : "image/jpeg",
|
|
data: part2.data
|
|
},
|
|
cache_control: void 0
|
|
};
|
|
}
|
|
}) : JSON.stringify(part.result);
|
|
anthropicContent.push({
|
|
type: "tool_result",
|
|
tool_use_id: part.toolCallId,
|
|
content: toolResultContent,
|
|
is_error: part.isError,
|
|
cache_control: cacheControl
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = role;
|
|
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
}
|
|
}
|
|
}
|
|
messages.push({ role: "user", content: anthropicContent });
|
|
break;
|
|
}
|
|
case "assistant": {
|
|
const anthropicContent = [];
|
|
for (let j = 0; j < block.messages.length; j++) {
|
|
const message = block.messages[j];
|
|
const isLastMessage = j === block.messages.length - 1;
|
|
const { content } = message;
|
|
for (let k = 0; k < content.length; k++) {
|
|
const part = content[k];
|
|
const isLastContentPart = k === content.length - 1;
|
|
const cacheControl = (_d = getCacheControl(part.providerMetadata)) != null ? _d : isLastContentPart ? getCacheControl(message.providerMetadata) : void 0;
|
|
switch (part.type) {
|
|
case "text": {
|
|
anthropicContent.push({
|
|
type: "text",
|
|
text: (
|
|
// trim the last text part if it's the last message in the block
|
|
// because Anthropic does not allow trailing whitespace
|
|
// in pre-filled assistant responses
|
|
isLastBlock && isLastMessage && isLastContentPart ? part.text.trim() : part.text
|
|
),
|
|
cache_control: cacheControl
|
|
});
|
|
break;
|
|
}
|
|
case "reasoning": {
|
|
if (sendReasoning) {
|
|
anthropicContent.push({
|
|
type: "thinking",
|
|
thinking: part.text,
|
|
signature: part.signature,
|
|
cache_control: cacheControl
|
|
});
|
|
} else {
|
|
warnings.push({
|
|
type: "other",
|
|
message: "sending reasoning content is disabled for this model"
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case "redacted-reasoning": {
|
|
anthropicContent.push({
|
|
type: "redacted_thinking",
|
|
data: part.data,
|
|
cache_control: cacheControl
|
|
});
|
|
break;
|
|
}
|
|
case "tool-call": {
|
|
anthropicContent.push({
|
|
type: "tool_use",
|
|
id: part.toolCallId,
|
|
name: part.toolName,
|
|
input: part.args,
|
|
cache_control: cacheControl
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
messages.push({ role: "assistant", content: anthropicContent });
|
|
break;
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = type;
|
|
throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
prompt: { system, messages },
|
|
betas
|
|
};
|
|
}
|
|
function groupIntoBlocks(prompt) {
|
|
const blocks = [];
|
|
let currentBlock = void 0;
|
|
for (const message of prompt) {
|
|
const { role } = message;
|
|
switch (role) {
|
|
case "system": {
|
|
if ((currentBlock == null ? void 0 : currentBlock.type) !== "system") {
|
|
currentBlock = { type: "system", messages: [] };
|
|
blocks.push(currentBlock);
|
|
}
|
|
currentBlock.messages.push(message);
|
|
break;
|
|
}
|
|
case "assistant": {
|
|
if ((currentBlock == null ? void 0 : currentBlock.type) !== "assistant") {
|
|
currentBlock = { type: "assistant", messages: [] };
|
|
blocks.push(currentBlock);
|
|
}
|
|
currentBlock.messages.push(message);
|
|
break;
|
|
}
|
|
case "user": {
|
|
if ((currentBlock == null ? void 0 : currentBlock.type) !== "user") {
|
|
currentBlock = { type: "user", messages: [] };
|
|
blocks.push(currentBlock);
|
|
}
|
|
currentBlock.messages.push(message);
|
|
break;
|
|
}
|
|
case "tool": {
|
|
if ((currentBlock == null ? void 0 : currentBlock.type) !== "user") {
|
|
currentBlock = { type: "user", messages: [] };
|
|
blocks.push(currentBlock);
|
|
}
|
|
currentBlock.messages.push(message);
|
|
break;
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = role;
|
|
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
}
|
|
}
|
|
}
|
|
return blocks;
|
|
}
|
|
|
|
// src/map-anthropic-stop-reason.ts
|
|
function mapAnthropicStopReason(finishReason) {
|
|
switch (finishReason) {
|
|
case "end_turn":
|
|
case "stop_sequence":
|
|
return "stop";
|
|
case "tool_use":
|
|
return "tool-calls";
|
|
case "max_tokens":
|
|
return "length";
|
|
default:
|
|
return "unknown";
|
|
}
|
|
}
|
|
|
|
// src/anthropic-messages-language-model.ts
|
|
var AnthropicMessagesLanguageModel = class {
|
|
constructor(modelId, settings, config) {
|
|
this.specificationVersion = "v1";
|
|
this.defaultObjectGenerationMode = "tool";
|
|
this.modelId = modelId;
|
|
this.settings = settings;
|
|
this.config = config;
|
|
}
|
|
supportsUrl(url) {
|
|
return url.protocol === "https:";
|
|
}
|
|
get provider() {
|
|
return this.config.provider;
|
|
}
|
|
get supportsImageUrls() {
|
|
return this.config.supportsImageUrls;
|
|
}
|
|
async getArgs({
|
|
mode,
|
|
prompt,
|
|
maxTokens = 4096,
|
|
// 4096: max model output tokens TODO update default in v5
|
|
temperature,
|
|
topP,
|
|
topK,
|
|
frequencyPenalty,
|
|
presencePenalty,
|
|
stopSequences,
|
|
responseFormat,
|
|
seed,
|
|
providerMetadata: providerOptions
|
|
}) {
|
|
var _a, _b, _c;
|
|
const type = mode.type;
|
|
const warnings = [];
|
|
if (frequencyPenalty != null) {
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "frequencyPenalty"
|
|
});
|
|
}
|
|
if (presencePenalty != null) {
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "presencePenalty"
|
|
});
|
|
}
|
|
if (seed != null) {
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "seed"
|
|
});
|
|
}
|
|
if (responseFormat != null && responseFormat.type !== "text") {
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "responseFormat",
|
|
details: "JSON response format is not supported."
|
|
});
|
|
}
|
|
const { prompt: messagesPrompt, betas: messagesBetas } = convertToAnthropicMessagesPrompt({
|
|
prompt,
|
|
sendReasoning: (_a = this.settings.sendReasoning) != null ? _a : true,
|
|
warnings
|
|
});
|
|
const anthropicOptions = parseProviderOptions({
|
|
provider: "anthropic",
|
|
providerOptions,
|
|
schema: anthropicProviderOptionsSchema
|
|
});
|
|
const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
|
|
const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
|
|
const baseArgs = {
|
|
// model id:
|
|
model: this.modelId,
|
|
// standardized settings:
|
|
max_tokens: maxTokens,
|
|
temperature,
|
|
top_k: topK,
|
|
top_p: topP,
|
|
stop_sequences: stopSequences,
|
|
// provider specific settings:
|
|
...isThinking && {
|
|
thinking: { type: "enabled", budget_tokens: thinkingBudget }
|
|
},
|
|
// prompt:
|
|
system: messagesPrompt.system,
|
|
messages: messagesPrompt.messages
|
|
};
|
|
if (isThinking) {
|
|
if (thinkingBudget == null) {
|
|
throw new UnsupportedFunctionalityError3({
|
|
functionality: "thinking requires a budget"
|
|
});
|
|
}
|
|
if (baseArgs.temperature != null) {
|
|
baseArgs.temperature = void 0;
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "temperature",
|
|
details: "temperature is not supported when thinking is enabled"
|
|
});
|
|
}
|
|
if (topK != null) {
|
|
baseArgs.top_k = void 0;
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "topK",
|
|
details: "topK is not supported when thinking is enabled"
|
|
});
|
|
}
|
|
if (topP != null) {
|
|
baseArgs.top_p = void 0;
|
|
warnings.push({
|
|
type: "unsupported-setting",
|
|
setting: "topP",
|
|
details: "topP is not supported when thinking is enabled"
|
|
});
|
|
}
|
|
baseArgs.max_tokens = maxTokens + thinkingBudget;
|
|
}
|
|
switch (type) {
|
|
case "regular": {
|
|
const {
|
|
tools,
|
|
tool_choice,
|
|
toolWarnings,
|
|
betas: toolsBetas
|
|
} = prepareTools(mode);
|
|
return {
|
|
args: { ...baseArgs, tools, tool_choice },
|
|
warnings: [...warnings, ...toolWarnings],
|
|
betas: /* @__PURE__ */ new Set([...messagesBetas, ...toolsBetas])
|
|
};
|
|
}
|
|
case "object-json": {
|
|
throw new UnsupportedFunctionalityError3({
|
|
functionality: "json-mode object generation"
|
|
});
|
|
}
|
|
case "object-tool": {
|
|
const { name, description, parameters } = mode.tool;
|
|
return {
|
|
args: {
|
|
...baseArgs,
|
|
tools: [{ name, description, input_schema: parameters }],
|
|
tool_choice: { type: "tool", name }
|
|
},
|
|
warnings,
|
|
betas: messagesBetas
|
|
};
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = type;
|
|
throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
|
|
}
|
|
}
|
|
}
|
|
async getHeaders({
|
|
betas,
|
|
headers
|
|
}) {
|
|
return combineHeaders(
|
|
await resolve(this.config.headers),
|
|
betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {},
|
|
headers
|
|
);
|
|
}
|
|
buildRequestUrl(isStreaming) {
|
|
var _a, _b, _c;
|
|
return (_c = (_b = (_a = this.config).buildRequestUrl) == null ? void 0 : _b.call(_a, this.config.baseURL, isStreaming)) != null ? _c : `${this.config.baseURL}/messages`;
|
|
}
|
|
transformRequestBody(args) {
|
|
var _a, _b, _c;
|
|
return (_c = (_b = (_a = this.config).transformRequestBody) == null ? void 0 : _b.call(_a, args)) != null ? _c : args;
|
|
}
|
|
async doGenerate(options) {
|
|
var _a, _b, _c, _d;
|
|
const { args, warnings, betas } = await this.getArgs(options);
|
|
const {
|
|
responseHeaders,
|
|
value: response,
|
|
rawValue: rawResponse
|
|
} = await postJsonToApi({
|
|
url: this.buildRequestUrl(false),
|
|
headers: await this.getHeaders({ betas, headers: options.headers }),
|
|
body: this.transformRequestBody(args),
|
|
failedResponseHandler: anthropicFailedResponseHandler,
|
|
successfulResponseHandler: createJsonResponseHandler(
|
|
anthropicMessagesResponseSchema
|
|
),
|
|
abortSignal: options.abortSignal,
|
|
fetch: this.config.fetch
|
|
});
|
|
const { messages: rawPrompt, ...rawSettings } = args;
|
|
let text = "";
|
|
for (const content of response.content) {
|
|
if (content.type === "text") {
|
|
text += content.text;
|
|
}
|
|
}
|
|
let toolCalls = void 0;
|
|
if (response.content.some((content) => content.type === "tool_use")) {
|
|
toolCalls = [];
|
|
for (const content of response.content) {
|
|
if (content.type === "tool_use") {
|
|
toolCalls.push({
|
|
toolCallType: "function",
|
|
toolCallId: content.id,
|
|
toolName: content.name,
|
|
args: JSON.stringify(content.input)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
const reasoning = response.content.filter(
|
|
(content) => content.type === "redacted_thinking" || content.type === "thinking"
|
|
).map(
|
|
(content) => content.type === "thinking" ? {
|
|
type: "text",
|
|
text: content.thinking,
|
|
signature: content.signature
|
|
} : {
|
|
type: "redacted",
|
|
data: content.data
|
|
}
|
|
);
|
|
return {
|
|
text,
|
|
reasoning: reasoning.length > 0 ? reasoning : void 0,
|
|
toolCalls,
|
|
finishReason: mapAnthropicStopReason(response.stop_reason),
|
|
usage: {
|
|
promptTokens: response.usage.input_tokens,
|
|
completionTokens: response.usage.output_tokens
|
|
},
|
|
rawCall: { rawPrompt, rawSettings },
|
|
rawResponse: {
|
|
headers: responseHeaders,
|
|
body: rawResponse
|
|
},
|
|
response: {
|
|
id: (_a = response.id) != null ? _a : void 0,
|
|
modelId: (_b = response.model) != null ? _b : void 0
|
|
},
|
|
warnings,
|
|
providerMetadata: {
|
|
anthropic: {
|
|
cacheCreationInputTokens: (_c = response.usage.cache_creation_input_tokens) != null ? _c : null,
|
|
cacheReadInputTokens: (_d = response.usage.cache_read_input_tokens) != null ? _d : null
|
|
}
|
|
},
|
|
request: { body: JSON.stringify(args) }
|
|
};
|
|
}
|
|
async doStream(options) {
|
|
const { args, warnings, betas } = await this.getArgs(options);
|
|
const body = { ...args, stream: true };
|
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
url: this.buildRequestUrl(true),
|
|
headers: await this.getHeaders({ betas, headers: options.headers }),
|
|
body: this.transformRequestBody(body),
|
|
failedResponseHandler: anthropicFailedResponseHandler,
|
|
successfulResponseHandler: createEventSourceResponseHandler(
|
|
anthropicMessagesChunkSchema
|
|
),
|
|
abortSignal: options.abortSignal,
|
|
fetch: this.config.fetch
|
|
});
|
|
const { messages: rawPrompt, ...rawSettings } = args;
|
|
let finishReason = "unknown";
|
|
const usage = {
|
|
promptTokens: Number.NaN,
|
|
completionTokens: Number.NaN
|
|
};
|
|
const toolCallContentBlocks = {};
|
|
let providerMetadata = void 0;
|
|
let blockType = void 0;
|
|
return {
|
|
stream: response.pipeThrough(
|
|
new TransformStream({
|
|
transform(chunk, controller) {
|
|
var _a, _b, _c, _d;
|
|
if (!chunk.success) {
|
|
controller.enqueue({ type: "error", error: chunk.error });
|
|
return;
|
|
}
|
|
const value = chunk.value;
|
|
switch (value.type) {
|
|
case "ping": {
|
|
return;
|
|
}
|
|
case "content_block_start": {
|
|
const contentBlockType = value.content_block.type;
|
|
blockType = contentBlockType;
|
|
switch (contentBlockType) {
|
|
case "text":
|
|
case "thinking": {
|
|
return;
|
|
}
|
|
case "redacted_thinking": {
|
|
controller.enqueue({
|
|
type: "redacted-reasoning",
|
|
data: value.content_block.data
|
|
});
|
|
return;
|
|
}
|
|
case "tool_use": {
|
|
toolCallContentBlocks[value.index] = {
|
|
toolCallId: value.content_block.id,
|
|
toolName: value.content_block.name,
|
|
jsonText: ""
|
|
};
|
|
return;
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = contentBlockType;
|
|
throw new Error(
|
|
`Unsupported content block type: ${_exhaustiveCheck}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
case "content_block_stop": {
|
|
if (toolCallContentBlocks[value.index] != null) {
|
|
const contentBlock = toolCallContentBlocks[value.index];
|
|
controller.enqueue({
|
|
type: "tool-call",
|
|
toolCallType: "function",
|
|
toolCallId: contentBlock.toolCallId,
|
|
toolName: contentBlock.toolName,
|
|
args: contentBlock.jsonText
|
|
});
|
|
delete toolCallContentBlocks[value.index];
|
|
}
|
|
blockType = void 0;
|
|
return;
|
|
}
|
|
case "content_block_delta": {
|
|
const deltaType = value.delta.type;
|
|
switch (deltaType) {
|
|
case "text_delta": {
|
|
controller.enqueue({
|
|
type: "text-delta",
|
|
textDelta: value.delta.text
|
|
});
|
|
return;
|
|
}
|
|
case "thinking_delta": {
|
|
controller.enqueue({
|
|
type: "reasoning",
|
|
textDelta: value.delta.thinking
|
|
});
|
|
return;
|
|
}
|
|
case "signature_delta": {
|
|
if (blockType === "thinking") {
|
|
controller.enqueue({
|
|
type: "reasoning-signature",
|
|
signature: value.delta.signature
|
|
});
|
|
}
|
|
return;
|
|
}
|
|
case "input_json_delta": {
|
|
const contentBlock = toolCallContentBlocks[value.index];
|
|
controller.enqueue({
|
|
type: "tool-call-delta",
|
|
toolCallType: "function",
|
|
toolCallId: contentBlock.toolCallId,
|
|
toolName: contentBlock.toolName,
|
|
argsTextDelta: value.delta.partial_json
|
|
});
|
|
contentBlock.jsonText += value.delta.partial_json;
|
|
return;
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = deltaType;
|
|
throw new Error(
|
|
`Unsupported delta type: ${_exhaustiveCheck}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
case "message_start": {
|
|
usage.promptTokens = value.message.usage.input_tokens;
|
|
usage.completionTokens = value.message.usage.output_tokens;
|
|
providerMetadata = {
|
|
anthropic: {
|
|
cacheCreationInputTokens: (_a = value.message.usage.cache_creation_input_tokens) != null ? _a : null,
|
|
cacheReadInputTokens: (_b = value.message.usage.cache_read_input_tokens) != null ? _b : null
|
|
}
|
|
};
|
|
controller.enqueue({
|
|
type: "response-metadata",
|
|
id: (_c = value.message.id) != null ? _c : void 0,
|
|
modelId: (_d = value.message.model) != null ? _d : void 0
|
|
});
|
|
return;
|
|
}
|
|
case "message_delta": {
|
|
usage.completionTokens = value.usage.output_tokens;
|
|
finishReason = mapAnthropicStopReason(value.delta.stop_reason);
|
|
return;
|
|
}
|
|
case "message_stop": {
|
|
controller.enqueue({
|
|
type: "finish",
|
|
finishReason,
|
|
usage,
|
|
providerMetadata
|
|
});
|
|
return;
|
|
}
|
|
case "error": {
|
|
controller.enqueue({ type: "error", error: value.error });
|
|
return;
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck = value;
|
|
throw new Error(`Unsupported chunk type: ${_exhaustiveCheck}`);
|
|
}
|
|
}
|
|
}
|
|
})
|
|
),
|
|
rawCall: { rawPrompt, rawSettings },
|
|
rawResponse: { headers: responseHeaders },
|
|
warnings,
|
|
request: { body: JSON.stringify(body) }
|
|
};
|
|
}
|
|
};
|
|
var anthropicMessagesResponseSchema = z2.object({
|
|
type: z2.literal("message"),
|
|
id: z2.string().nullish(),
|
|
model: z2.string().nullish(),
|
|
content: z2.array(
|
|
z2.discriminatedUnion("type", [
|
|
z2.object({
|
|
type: z2.literal("text"),
|
|
text: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("thinking"),
|
|
thinking: z2.string(),
|
|
signature: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("redacted_thinking"),
|
|
data: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("tool_use"),
|
|
id: z2.string(),
|
|
name: z2.string(),
|
|
input: z2.unknown()
|
|
})
|
|
])
|
|
),
|
|
stop_reason: z2.string().nullish(),
|
|
usage: z2.object({
|
|
input_tokens: z2.number(),
|
|
output_tokens: z2.number(),
|
|
cache_creation_input_tokens: z2.number().nullish(),
|
|
cache_read_input_tokens: z2.number().nullish()
|
|
})
|
|
});
|
|
var anthropicMessagesChunkSchema = z2.discriminatedUnion("type", [
|
|
z2.object({
|
|
type: z2.literal("message_start"),
|
|
message: z2.object({
|
|
id: z2.string().nullish(),
|
|
model: z2.string().nullish(),
|
|
usage: z2.object({
|
|
input_tokens: z2.number(),
|
|
output_tokens: z2.number(),
|
|
cache_creation_input_tokens: z2.number().nullish(),
|
|
cache_read_input_tokens: z2.number().nullish()
|
|
})
|
|
})
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("content_block_start"),
|
|
index: z2.number(),
|
|
content_block: z2.discriminatedUnion("type", [
|
|
z2.object({
|
|
type: z2.literal("text"),
|
|
text: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("thinking"),
|
|
thinking: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("tool_use"),
|
|
id: z2.string(),
|
|
name: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("redacted_thinking"),
|
|
data: z2.string()
|
|
})
|
|
])
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("content_block_delta"),
|
|
index: z2.number(),
|
|
delta: z2.discriminatedUnion("type", [
|
|
z2.object({
|
|
type: z2.literal("input_json_delta"),
|
|
partial_json: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("text_delta"),
|
|
text: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("thinking_delta"),
|
|
thinking: z2.string()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("signature_delta"),
|
|
signature: z2.string()
|
|
})
|
|
])
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("content_block_stop"),
|
|
index: z2.number()
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("error"),
|
|
error: z2.object({
|
|
type: z2.string(),
|
|
message: z2.string()
|
|
})
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("message_delta"),
|
|
delta: z2.object({ stop_reason: z2.string().nullish() }),
|
|
usage: z2.object({ output_tokens: z2.number() })
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("message_stop")
|
|
}),
|
|
z2.object({
|
|
type: z2.literal("ping")
|
|
})
|
|
]);
|
|
var anthropicProviderOptionsSchema = z2.object({
|
|
thinking: z2.object({
|
|
type: z2.union([z2.literal("enabled"), z2.literal("disabled")]),
|
|
budgetTokens: z2.number().optional()
|
|
}).optional()
|
|
});
|
|
|
|
// src/anthropic-tools.ts
|
|
import { z as z3 } from "zod";
|
|
var Bash20241022Parameters = z3.object({
|
|
command: z3.string(),
|
|
restart: z3.boolean().optional()
|
|
});
|
|
function bashTool_20241022(options = {}) {
|
|
return {
|
|
type: "provider-defined",
|
|
id: "anthropic.bash_20241022",
|
|
args: {},
|
|
parameters: Bash20241022Parameters,
|
|
execute: options.execute,
|
|
experimental_toToolResultContent: options.experimental_toToolResultContent
|
|
};
|
|
}
|
|
var Bash20250124Parameters = z3.object({
|
|
command: z3.string(),
|
|
restart: z3.boolean().optional()
|
|
});
|
|
function bashTool_20250124(options = {}) {
|
|
return {
|
|
type: "provider-defined",
|
|
id: "anthropic.bash_20250124",
|
|
args: {},
|
|
parameters: Bash20250124Parameters,
|
|
execute: options.execute,
|
|
experimental_toToolResultContent: options.experimental_toToolResultContent
|
|
};
|
|
}
|
|
var TextEditor20241022Parameters = z3.object({
|
|
command: z3.enum(["view", "create", "str_replace", "insert", "undo_edit"]),
|
|
path: z3.string(),
|
|
file_text: z3.string().optional(),
|
|
insert_line: z3.number().int().optional(),
|
|
new_str: z3.string().optional(),
|
|
old_str: z3.string().optional(),
|
|
view_range: z3.array(z3.number().int()).optional()
|
|
});
|
|
function textEditorTool_20241022(options = {}) {
|
|
return {
|
|
type: "provider-defined",
|
|
id: "anthropic.text_editor_20241022",
|
|
args: {},
|
|
parameters: TextEditor20241022Parameters,
|
|
execute: options.execute,
|
|
experimental_toToolResultContent: options.experimental_toToolResultContent
|
|
};
|
|
}
|
|
var TextEditor20250124Parameters = z3.object({
|
|
command: z3.enum(["view", "create", "str_replace", "insert", "undo_edit"]),
|
|
path: z3.string(),
|
|
file_text: z3.string().optional(),
|
|
insert_line: z3.number().int().optional(),
|
|
new_str: z3.string().optional(),
|
|
old_str: z3.string().optional(),
|
|
view_range: z3.array(z3.number().int()).optional()
|
|
});
|
|
function textEditorTool_20250124(options = {}) {
|
|
return {
|
|
type: "provider-defined",
|
|
id: "anthropic.text_editor_20250124",
|
|
args: {},
|
|
parameters: TextEditor20250124Parameters,
|
|
execute: options.execute,
|
|
experimental_toToolResultContent: options.experimental_toToolResultContent
|
|
};
|
|
}
|
|
var Computer20241022Parameters = z3.object({
|
|
action: z3.enum([
|
|
"key",
|
|
"type",
|
|
"mouse_move",
|
|
"left_click",
|
|
"left_click_drag",
|
|
"right_click",
|
|
"middle_click",
|
|
"double_click",
|
|
"screenshot",
|
|
"cursor_position"
|
|
]),
|
|
coordinate: z3.array(z3.number().int()).optional(),
|
|
text: z3.string().optional()
|
|
});
|
|
function computerTool_20241022(options) {
|
|
return {
|
|
type: "provider-defined",
|
|
id: "anthropic.computer_20241022",
|
|
args: {
|
|
displayWidthPx: options.displayWidthPx,
|
|
displayHeightPx: options.displayHeightPx,
|
|
displayNumber: options.displayNumber
|
|
},
|
|
parameters: Computer20241022Parameters,
|
|
execute: options.execute,
|
|
experimental_toToolResultContent: options.experimental_toToolResultContent
|
|
};
|
|
}
|
|
var Computer20250124Parameters = z3.object({
|
|
action: z3.enum([
|
|
"key",
|
|
"hold_key",
|
|
"type",
|
|
"cursor_position",
|
|
"mouse_move",
|
|
"left_mouse_down",
|
|
"left_mouse_up",
|
|
"left_click",
|
|
"left_click_drag",
|
|
"right_click",
|
|
"middle_click",
|
|
"double_click",
|
|
"triple_click",
|
|
"scroll",
|
|
"wait",
|
|
"screenshot"
|
|
]),
|
|
coordinate: z3.tuple([z3.number().int(), z3.number().int()]).optional(),
|
|
duration: z3.number().optional(),
|
|
scroll_amount: z3.number().optional(),
|
|
scroll_direction: z3.enum(["up", "down", "left", "right"]).optional(),
|
|
start_coordinate: z3.tuple([z3.number().int(), z3.number().int()]).optional(),
|
|
text: z3.string().optional()
|
|
});
|
|
function computerTool_20250124(options) {
|
|
return {
|
|
type: "provider-defined",
|
|
id: "anthropic.computer_20250124",
|
|
args: {
|
|
displayWidthPx: options.displayWidthPx,
|
|
displayHeightPx: options.displayHeightPx,
|
|
displayNumber: options.displayNumber
|
|
},
|
|
parameters: Computer20250124Parameters,
|
|
execute: options.execute,
|
|
experimental_toToolResultContent: options.experimental_toToolResultContent
|
|
};
|
|
}
|
|
var anthropicTools = {
|
|
bash_20241022: bashTool_20241022,
|
|
bash_20250124: bashTool_20250124,
|
|
textEditor_20241022: textEditorTool_20241022,
|
|
textEditor_20250124: textEditorTool_20250124,
|
|
computer_20241022: computerTool_20241022,
|
|
computer_20250124: computerTool_20250124
|
|
};
|
|
|
|
// src/anthropic-provider.ts
|
|
function createAnthropic(options = {}) {
|
|
var _a;
|
|
const baseURL = (_a = withoutTrailingSlash(options.baseURL)) != null ? _a : "https://api.anthropic.com/v1";
|
|
const getHeaders = () => ({
|
|
"anthropic-version": "2023-06-01",
|
|
"x-api-key": loadApiKey({
|
|
apiKey: options.apiKey,
|
|
environmentVariableName: "ANTHROPIC_API_KEY",
|
|
description: "Anthropic"
|
|
}),
|
|
...options.headers
|
|
});
|
|
const createChatModel = (modelId, settings = {}) => new AnthropicMessagesLanguageModel(modelId, settings, {
|
|
provider: "anthropic.messages",
|
|
baseURL,
|
|
headers: getHeaders,
|
|
fetch: options.fetch,
|
|
supportsImageUrls: true
|
|
});
|
|
const provider = function(modelId, settings) {
|
|
if (new.target) {
|
|
throw new Error(
|
|
"The Anthropic model function cannot be called with the new keyword."
|
|
);
|
|
}
|
|
return createChatModel(modelId, settings);
|
|
};
|
|
provider.languageModel = createChatModel;
|
|
provider.chat = createChatModel;
|
|
provider.messages = createChatModel;
|
|
provider.textEmbeddingModel = (modelId) => {
|
|
throw new NoSuchModelError({ modelId, modelType: "textEmbeddingModel" });
|
|
};
|
|
provider.tools = anthropicTools;
|
|
return provider;
|
|
}
|
|
var anthropic = createAnthropic();
|
|
export {
|
|
anthropic,
|
|
createAnthropic
|
|
};
|
|
//# sourceMappingURL=index.mjs.map
|