UNPKG

@genkit-ai/anthropic

Version:

Genkit AI framework plugin for Anthropic APIs.

377 lines 11.9 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var beta_exports = {}; __export(beta_exports, { BetaRunner: () => BetaRunner }); module.exports = __toCommonJS(beta_exports); var import_logging = require("genkit/logging"); var import_utils = require("../utils.js"); var import_base = require("./base.js"); var import_beta = require("./converters/beta.js"); var import_shared = require("./converters/shared.js"); const BETA_APIS = [ // 'message-batches-2024-09-24', // 'prompt-caching-2024-07-31', // 'computer-use-2025-01-24', // 'pdfs-2024-09-25', // 'token-counting-2024-11-01', // 'token-efficient-tools-2025-02-19', // 'output-128k-2025-02-19', "files-api-2025-04-14", // 'mcp-client-2025-04-04', // 'dev-full-thinking-2025-05-14', // 'interleaved-thinking-2025-05-14', // 'code-execution-2025-05-22', // 'extended-cache-ttl-2025-04-11', // 'context-1m-2025-08-07', // 'context-management-2025-06-27', // 'model-context-window-exceeded-2025-08-26', // 'skills-2025-10-02', "effort-2025-11-24", // 'advanced-tool-use-2025-11-20', "structured-outputs-2025-11-13", "task-budgets-2026-03-13" ]; function toAnthropicSchema(schema) { const out = structuredClone(schema); delete out.$schema; if (out.type === "object") { out.additionalProperties = false; } for (const key in out) { if (typeof out[key] === "object" && out[key] !== null) { out[key] = toAnthropicSchema(out[key]); } } return out; } class BetaRunner extends import_base.BaseRunner { constructor(params) { super(params); } /** * Map a Genkit Part -> Anthropic beta content block param. * Supports: text, images (base64 data URLs), PDFs (document source), * tool_use (client tool request), tool_result (client tool response). */ toAnthropicMessageContent(part) { if (part.reasoning) { const signature = this.getThinkingSignature(part); if (!signature) { throw new Error( "Anthropic thinking parts require a signature when sending back to the API. Preserve the `metadata.thoughtSignature` value from the original response." ); } return { type: "thinking", thinking: part.reasoning, signature }; } const redactedThinking = this.getRedactedThinkingData(part); if (redactedThinking !== void 0) { return { type: "redacted_thinking", data: redactedThinking }; } if (part.text) { return { type: "text", text: part.text }; } if (part.custom?.anthropicDocument) { return (0, import_beta.toBetaDocumentBlock)( part.custom.anthropicDocument ); } if (part.media) { if (part.media.contentType === "anthropic/file") { return { type: "document", source: { type: "file", file_id: part.media.url } }; } if (part.media.contentType === "anthropic/image") { return { type: "image", source: { type: "file", file_id: part.media.url } }; } if (part.media.contentType === "application/pdf") { return { type: "document", source: this.toPdfDocumentSource(part.media) }; } const source = this.toImageSource(part.media); if (source.kind === "base64") { return { type: "image", source: { type: "base64", data: source.data, media_type: source.mediaType } }; } return { type: "image", source: { type: "url", url: source.url } }; } if (part.toolRequest) { if (!part.toolRequest.ref) { throw new Error( `Tool request ref is required for Anthropic API. Part: ${JSON.stringify( part.toolRequest )}` ); } return { type: "tool_use", id: part.toolRequest.ref, name: part.toolRequest.name, input: part.toolRequest.input }; } if (part.toolResponse) { if (!part.toolResponse.ref) { throw new Error( `Tool response ref is required for Anthropic API. Part: ${JSON.stringify( part.toolResponse )}` ); } const betaResult = { type: "tool_result", tool_use_id: part.toolResponse.ref, content: [this.toAnthropicToolResponseContent(part)] }; return betaResult; } throw new Error( `Unsupported genkit part fields encountered for current message role: ${JSON.stringify( part )}.` ); } createMessage(body, abortSignal) { return this.client.beta.messages.create(body, { signal: abortSignal }); } streamMessages(body, abortSignal) { return this.client.beta.messages.stream(body, { signal: abortSignal }); } /** * Build non-streaming request body. */ toAnthropicRequestBody(modelName, request) { const { system, messages } = this.toAnthropicMessages(request.messages); const mappedModelName = request.config?.version ?? (0, import_utils.checkModelName)(modelName); const thinkingConfig = this.toAnthropicThinkingConfig( request.config?.thinking ); const { topP, topK, apiVersion: _1, thinking: _2, maxOutputTokens, stopSequences, version, apiKey, ...restConfig } = request.config ?? {}; const body = { model: mappedModelName, max_tokens: maxOutputTokens ?? this.DEFAULT_MAX_OUTPUT_TOKENS, messages, system, stop_sequences: stopSequences, temperature: request.config?.temperature, top_k: topK, top_p: topP, tool_choice: request.config?.tool_choice, metadata: request.config?.metadata, tools: request.tools?.map((tool) => this.toAnthropicTool(tool)), thinking: thinkingConfig, output_format: this.isStructuredOutputEnabled(request) ? { type: "json_schema", schema: toAnthropicSchema(request.output.schema) } : void 0, betas: Array.isArray(request.config?.betas) ? [...request.config?.betas ?? []] : [...BETA_APIS], ...restConfig }; return (0, import_utils.removeUndefinedProperties)(body); } /** * Build streaming request body. */ toAnthropicStreamingRequestBody(modelName, request) { const { system, messages } = this.toAnthropicMessages(request.messages); const mappedModelName = request.config?.version ?? (0, import_utils.checkModelName)(modelName); const thinkingConfig = this.toAnthropicThinkingConfig( request.config?.thinking ); const { topP, topK, apiVersion: _1, thinking: _2, maxOutputTokens, stopSequences, version, apiKey, ...restConfig } = request.config ?? {}; const body = { model: mappedModelName, max_tokens: maxOutputTokens ?? this.DEFAULT_MAX_OUTPUT_TOKENS, messages, stream: true, system, stop_sequences: stopSequences, temperature: request.config?.temperature, top_k: topK, top_p: topP, tool_choice: request.config?.tool_choice, metadata: request.config?.metadata, tools: request.tools?.map((tool) => this.toAnthropicTool(tool)), thinking: thinkingConfig, output_format: this.isStructuredOutputEnabled(request) ? { type: "json_schema", schema: toAnthropicSchema(request.output.schema) } : void 0, betas: Array.isArray(request.config?.betas) ? [...request.config?.betas ?? []] : [...BETA_APIS], ...restConfig }; return (0, import_utils.removeUndefinedProperties)(body); } toGenkitResponse(message) { return { candidates: [ { index: 0, finishReason: this.fromBetaStopReason(message.stop_reason), message: { role: "model", content: message.content.map( (block) => this.fromBetaContentBlock(block) ) } } ], usage: { inputTokens: message.usage.input_tokens, outputTokens: message.usage.output_tokens }, custom: message, raw: message }; } toGenkitPart(event) { if (event.type === "content_block_start") { return this.fromBetaContentBlock(event.content_block); } if (event.type === "content_block_delta") { if (event.delta.type === "text_delta") { return (0, import_shared.textDeltaToPart)(event.delta); } if (event.delta.type === "thinking_delta") { return (0, import_shared.thinkingDeltaToPart)(event.delta); } if (event.delta.type === "citations_delta") { return (0, import_shared.citationsDeltaToPart)(event.delta); } return void 0; } return void 0; } fromBetaContentBlock(contentBlock) { switch (contentBlock.type) { case "text": return (0, import_shared.textBlockToPart)(contentBlock); case "tool_use": return (0, import_shared.toolUseBlockToPart)({ id: contentBlock.id, name: contentBlock.name ?? "unknown_tool", input: contentBlock.input }); case "thinking": return (0, import_shared.thinkingBlockToPart)(contentBlock); case "redacted_thinking": return (0, import_shared.redactedThinkingBlockToPart)(contentBlock); case "server_tool_use": return (0, import_beta.betaServerToolUseBlockToPart)(contentBlock); case "web_search_tool_result": return (0, import_shared.webSearchToolResultBlockToPart)(contentBlock); // Unsupported beta server tool types case "mcp_tool_use": case "mcp_tool_result": case "web_fetch_tool_result": case "code_execution_tool_result": case "bash_code_execution_tool_result": case "text_editor_code_execution_tool_result": case "container_upload": case "tool_search_tool_result": throw new Error((0, import_beta.unsupportedServerToolError)(contentBlock.type)); default: { const unknownType = contentBlock.type; import_logging.logger.warn( `Unexpected Anthropic beta content block type: ${unknownType}. Returning empty text. Content block: ${JSON.stringify(contentBlock)}` ); return { text: "" }; } } } fromBetaStopReason(reason) { switch (reason) { case "max_tokens": case "model_context_window_exceeded": return "length"; case "end_turn": case "stop_sequence": case "tool_use": case "pause_turn": return "stop"; case null: return "unknown"; case "refusal": return "other"; default: return "other"; } } isStructuredOutputEnabled(request) { return !!(request.output?.schema && request.output.constrained && request.output.format === "json"); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { BetaRunner }); //# sourceMappingURL=beta.js.map