From 2eed829f8bf5eb998956a3d61a21f2604fe79fa3 Mon Sep 17 00:00:00 2001 From: Narendranath Gogineni Date: Wed, 30 Apr 2025 19:19:54 +0530 Subject: [PATCH 1/3] add support for anthropic pdf --- src/providers/anthropic/chatComplete.ts | 73 ++++++++++++++++++++++++- src/types/requestBody.ts | 12 ++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/providers/anthropic/chatComplete.ts b/src/providers/anthropic/chatComplete.ts index 405e3316f..2defba1a8 100644 --- a/src/providers/anthropic/chatComplete.ts +++ b/src/providers/anthropic/chatComplete.ts @@ -63,11 +63,40 @@ interface AnthropicTextContentItem { text: string; } +interface AnthropicUrlPdfContentItem { + type: 'document'; + source: { + type: 'url'; + url: string; + }; +} + +interface AnthropicBase64PdfContentItem { + type: 'document'; + source: { + type: 'base64'; + data: string; + media_type: string; + }; +} + +interface AnthropicPlainTextContentItem { + type: 'document'; + source: { + type: 'text'; + data: string; + media_type: string; + }; +} + type AnthropicMessageContentItem = | AnthropicToolResultContentItem | AnthropicBase64ImageContentItem | AnthropicUrlImageContentItem - | AnthropicTextContentItem; + | AnthropicTextContentItem + | AnthropicUrlPdfContentItem + | AnthropicBase64PdfContentItem + | AnthropicPlainTextContentItem; interface AnthropicMessage extends Message, PromptCache { content: AnthropicMessageContentItem[]; @@ -166,6 +195,46 @@ const transformAndAppendImageContentItem = ( } }; +const transformAndAppendFileContentItem = ( + item: ContentType, + transformedMessage: AnthropicMessage +) => { + const mimeType = + (item.file?.mime_type as keyof typeof fileExtensionMimeTypeMap) || + fileExtensionMimeTypeMap.pdf; + if (item.file?.file_url) { + transformedMessage.content.push({ + type: 'document', + source: { + type: 'url', + url: item.file.file_url, + }, + }); + } else if (item.file?.file_data) { + const contentType = + mimeType === fileExtensionMimeTypeMap.txt ? 'text' : 'base64'; + if (contentType === 'text') { + transformedMessage.content.push({ + type: 'document', + source: { + type: contentType, + data: item.file.file_data, + media_type: mimeType, + }, + }); + } else { + transformedMessage.content.push({ + type: 'document', + source: { + type: contentType, + data: item.file.file_data, + media_type: mimeType, + }, + }); + } + } +}; + export const AnthropicChatCompleteConfig: ProviderConfig = { model: { param: 'model', @@ -205,6 +274,8 @@ export const AnthropicChatCompleteConfig: ProviderConfig = { }); } else if (item.type === 'image_url') { transformAndAppendImageContentItem(item, transformedMessage); + } else if (item.type === 'file') { + transformAndAppendFileContentItem(item, transformedMessage); } }); messages.push(transformedMessage as AnthropicMessage); diff --git a/src/types/requestBody.ts b/src/types/requestBody.ts index 2a4b74345..4a0d6cb62 100644 --- a/src/types/requestBody.ts +++ b/src/types/requestBody.ts @@ -216,6 +216,7 @@ export interface Config { } /** + * TODO: make this a union type * A message content type. * @interface */ @@ -230,6 +231,17 @@ export interface ContentType extends PromptCache { mime_type?: string; }; data?: string; + file?: { + file_data?: string; + file_id?: string; + file_name?: string; + file_url?: string; + mime_type?: string; + }; + input_audio?: { + data: string; + format: string; //defaults to auto + }; } export interface ToolCall { From 646d3b92b8426951fd05fddf560b2acf02fc7f9a Mon Sep 17 00:00:00 2001 From: Narendranath Gogineni Date: Wed, 30 Apr 2025 19:56:45 +0530 Subject: [PATCH 2/3] file content part in request body for bedrock --- src/providers/bedrock/chatComplete.ts | 38 +++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/providers/bedrock/chatComplete.ts b/src/providers/bedrock/chatComplete.ts index b09c3ea03..146af77f4 100644 --- a/src/providers/bedrock/chatComplete.ts +++ b/src/providers/bedrock/chatComplete.ts @@ -1,4 +1,9 @@ -import { BEDROCK, documentMimeTypes, imagesMimeTypes } from '../../globals'; +import { + BEDROCK, + documentMimeTypes, + fileExtensionMimeTypeMap, + imagesMimeTypes, +} from '../../globals'; import { Message, Params, @@ -176,6 +181,32 @@ const getMessageContent = (message: Message) => { }, }); } + } else if (item.type === 'file') { + const mimeType = item.file?.mime_type || fileExtensionMimeTypeMap.pdf; + const fileFormat = mimeType.split('/')[1]; + if (item.file?.file_url) { + out.push({ + document: { + format: fileFormat, + name: crypto.randomUUID(), + source: { + s3Location: { + uri: item.file.file_url, + }, + }, + }, + }); + } else if (item.file?.file_data) { + out.push({ + document: { + format: fileFormat, + name: crypto.randomUUID(), + source: { + bytes: item.file.file_data, + }, + }, + }); + } } if (item.cache_control) { @@ -377,7 +408,10 @@ type BedrockContentItem = { format: string; name: string; source: { - bytes: string; + bytes?: string; + s3Location?: { + uri: string; + }; }; }; cachePoint?: { From bd40d8118699d71ec706550850845959e9bf7a8e Mon Sep 17 00:00:00 2001 From: Narendranath Gogineni Date: Tue, 6 May 2025 20:05:14 +0530 Subject: [PATCH 3/3] changes per comments --- src/providers/anthropic/chatComplete.ts | 39 +++++++++---------------- src/providers/bedrock/chatComplete.ts | 4 +-- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/providers/anthropic/chatComplete.ts b/src/providers/anthropic/chatComplete.ts index 2defba1a8..665d392f4 100644 --- a/src/providers/anthropic/chatComplete.ts +++ b/src/providers/anthropic/chatComplete.ts @@ -64,26 +64,26 @@ interface AnthropicTextContentItem { } interface AnthropicUrlPdfContentItem { - type: 'document'; + type: string; source: { - type: 'url'; + type: string; url: string; }; } interface AnthropicBase64PdfContentItem { - type: 'document'; + type: string; source: { - type: 'base64'; + type: string; data: string; media_type: string; }; } interface AnthropicPlainTextContentItem { - type: 'document'; + type: string; source: { - type: 'text'; + type: string; data: string; media_type: string; }; @@ -213,25 +213,14 @@ const transformAndAppendFileContentItem = ( } else if (item.file?.file_data) { const contentType = mimeType === fileExtensionMimeTypeMap.txt ? 'text' : 'base64'; - if (contentType === 'text') { - transformedMessage.content.push({ - type: 'document', - source: { - type: contentType, - data: item.file.file_data, - media_type: mimeType, - }, - }); - } else { - transformedMessage.content.push({ - type: 'document', - source: { - type: contentType, - data: item.file.file_data, - media_type: mimeType, - }, - }); - } + transformedMessage.content.push({ + type: 'document', + source: { + type: contentType, + data: item.file.file_data, + media_type: mimeType, + }, + }); } }; diff --git a/src/providers/bedrock/chatComplete.ts b/src/providers/bedrock/chatComplete.ts index 146af77f4..7ab77621d 100644 --- a/src/providers/bedrock/chatComplete.ts +++ b/src/providers/bedrock/chatComplete.ts @@ -188,7 +188,7 @@ const getMessageContent = (message: Message) => { out.push({ document: { format: fileFormat, - name: crypto.randomUUID(), + name: item.file.file_name || crypto.randomUUID(), source: { s3Location: { uri: item.file.file_url, @@ -200,7 +200,7 @@ const getMessageContent = (message: Message) => { out.push({ document: { format: fileFormat, - name: crypto.randomUUID(), + name: item.file.file_name || crypto.randomUUID(), source: { bytes: item.file.file_data, },