@genkit-ai/anthropic
Version:
Genkit AI framework plugin for Anthropic APIs.
1 lines • 9.81 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/runner/converters/shared.ts"],"sourcesContent":["/**\n * Copyright 2025 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Shared utilities for converting Anthropic content blocks to Genkit Parts.\n * Uses structural typing so both stable and beta API types work with these functions.\n */\n\nimport type { Part } from 'genkit';\nimport type {\n AnthropicCitation,\n AnthropicDocumentOptions,\n} from '../../types.mjs';\nimport { MEDIA_TYPES, MediaTypeSchema } from '../../types.mjs';\nimport {\n fromAnthropicCitation,\n type AnthropicCitationInput,\n} from './citations.mjs';\n\n// Re-export citation utilities for backward compatibility\nexport {\n fromAnthropicCitation,\n type AnthropicCitationInput,\n} from './citations.mjs';\n\n/**\n * Converts a text block to a Genkit Part, including citations if present.\n * Uses structural typing for compatibility with both stable and beta APIs.\n */\nexport function textBlockToPart(block: {\n text: string;\n citations?: AnthropicCitationInput[] | null;\n}): Part {\n if (block.citations && block.citations.length > 0) {\n const citations = block.citations\n .map((c) => fromAnthropicCitation(c))\n .filter((c): c is AnthropicCitation => c !== undefined);\n if (citations.length > 0) {\n return {\n text: block.text,\n metadata: { citations },\n };\n }\n }\n return { text: block.text };\n}\n\n/**\n * Converts a tool_use block to a Genkit Part.\n */\nexport function toolUseBlockToPart(block: {\n id: string;\n name: string;\n input: unknown;\n}): Part {\n return {\n toolRequest: {\n ref: block.id,\n name: block.name,\n input: block.input,\n },\n };\n}\n\n/**\n * Converts a thinking block to a Genkit Part, including signature metadata if present.\n */\nexport function thinkingBlockToPart(block: {\n thinking: string;\n signature?: string;\n}): Part {\n if (block.signature !== undefined) {\n return {\n reasoning: block.thinking,\n metadata: { thoughtSignature: block.signature },\n };\n }\n return { reasoning: block.thinking };\n}\n\n/**\n * Converts a redacted thinking block to a Genkit Part.\n */\nexport function redactedThinkingBlockToPart(block: { data: string }): Part {\n return { custom: { redactedThinking: block.data } };\n}\n\n/**\n * Converts a web_search_tool_result block to a Genkit Part.\n */\nexport function webSearchToolResultBlockToPart(block: {\n tool_use_id: string;\n content: unknown;\n}): Part {\n return {\n text: `[Anthropic server tool result ${block.tool_use_id}] ${JSON.stringify(block.content)}`,\n metadata: {\n anthropicServerToolResult: {\n type: 'web_search_tool_result',\n toolUseId: block.tool_use_id,\n content: block.content,\n },\n },\n };\n}\n\n// --- Delta converters for streaming ---\n\n/**\n * Converts a text_delta to a Genkit Part.\n */\nexport function textDeltaToPart(delta: { text: string }): Part {\n return { text: delta.text };\n}\n\n/**\n * Converts a thinking_delta to a Genkit Part.\n */\nexport function thinkingDeltaToPart(delta: { thinking: string }): Part {\n return { reasoning: delta.thinking };\n}\n\n/**\n * Converts a citations_delta to a Genkit Part for streaming.\n * Returns a text part with empty text and citation data in metadata.\n * Empty text is intentional: genkit's `.text` getter concatenates all text parts,\n * so empty strings contribute nothing to the final text while preserving the citation\n * in the parts array for consumers who need to access citation metadata.\n */\nexport function citationsDeltaToPart(delta: {\n type: 'citations_delta';\n citation: AnthropicCitationInput;\n}): Part | undefined {\n const citation = fromAnthropicCitation(delta.citation);\n if (citation) {\n return {\n text: '',\n metadata: { citations: [citation] },\n };\n }\n return undefined;\n}\n\n// --- Document block converters (shared between stable and beta APIs) ---\n\n/**\n * Document block type constraint for generics.\n */\ntype DocumentBlockBase = {\n type: 'document';\n source: unknown;\n title?: string | null;\n context?: string | null;\n citations?: { enabled?: boolean } | null;\n};\n\n/**\n * Converts AnthropicDocumentOptions to Anthropic's document block format.\n * Works for both stable and beta APIs via generics.\n */\nexport function createDocumentBlock<T extends DocumentBlockBase>(\n options: AnthropicDocumentOptions,\n sourceConverter: (source: AnthropicDocumentOptions['source']) => T['source']\n): T {\n return {\n type: 'document' as const,\n source: sourceConverter(options.source),\n ...(options.title && { title: options.title }),\n ...(options.context && { context: options.context }),\n ...(options.citations && { citations: options.citations }),\n } as T;\n}\n\n/**\n * Converts document source options to Anthropic's source format.\n * Works for both stable and beta APIs via a file handler callback.\n * The file handler is called for 'file' type sources, allowing different\n * behavior (error for stable, conversion for beta).\n */\nexport function convertDocumentSource<T>(\n source: AnthropicDocumentOptions['source'],\n fileHandler: (fileId: string) => T\n): T {\n switch (source.type) {\n case 'text':\n return {\n type: 'text',\n media_type: (source.mediaType ?? 'text/plain') as 'text/plain',\n data: source.data,\n } as T;\n case 'base64':\n return {\n type: 'base64',\n media_type: source.mediaType as 'application/pdf',\n data: source.data,\n } as T;\n case 'file':\n return fileHandler(source.fileId);\n case 'content':\n return {\n type: 'content',\n content: source.content.map((item) => {\n if (item.type === 'text') {\n return item;\n }\n // Validate media type with Zod\n const mediaTypeResult = MediaTypeSchema.safeParse(\n item.source.mediaType\n );\n if (!mediaTypeResult.success) {\n throw new Error(\n `Unsupported image media type for Anthropic document content: ${item.source.mediaType}. Supported types: ${Object.values(MEDIA_TYPES).join(', ')}`\n );\n }\n return {\n type: 'image' as const,\n source: {\n type: 'base64' as const,\n media_type: mediaTypeResult.data,\n data: item.source.data,\n },\n };\n }),\n } as T;\n case 'url':\n return {\n type: 'url',\n url: source.url,\n } as T;\n default:\n throw new Error(\n `Unsupported document source type: ${(source as { type: string }).type}`\n );\n }\n}\n"],"mappings":"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","names":["fromAnthropicCitation"]}