Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/chilly-bees-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@ai-sdk/anthropic': patch
'@example/ai-core': patch
---

Adds url-based pdf support for tool results
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { generateText, stepCountIs, tool } from 'ai';
import { run } from '../lib/run';
import { z } from 'zod';
import { anthropic } from '@ai-sdk/anthropic';

run(async () => {
const readPDFDocument = tool({
description: `Read and return a PDF document`,
inputSchema: z.object({}),
execute: async () => {
try {
return {
success: true,
description: 'Successfully loaded PDF document',
pdfUrl: 'https://arxiv.org/pdf/2001.08361', // Scaling Laws Paper
};
} catch (error) {
throw new Error(`Failed to analyze PDF: ${error}`);
}
},
toModelOutput(result) {
return {
type: 'content',
value: [
{
type: 'text',
text: result.description,
},
{
type: 'media',
data: result.pdfUrl,
mediaType: 'application/pdf',
},
],
};
},
});

const result = await generateText({
model: anthropic('claude-sonnet-4-0'),
prompt:
'Please read the pdf document using the tool provided and return the summary of that pdf',
tools: {
readPDFDocument,
},
stopWhen: stepCountIs(4),
});

console.log(`Assisstant response : ${JSON.stringify(result.text, null, 2)}`);
});
2 changes: 1 addition & 1 deletion packages/anthropic/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@ai-sdk/anthropic",
"name": "@flatfile/anthropic",
"version": "3.0.0-beta.24",
"license": "Apache-2.0",
"sideEffects": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ describe('tool messages', () => {
`);
});

it('should handle tool result with PDF content', async () => {
it('should handle tool result with base64 PDF content', async () => {
const result = await convertToAnthropicMessagesPrompt({
prompt: [
{
Expand Down Expand Up @@ -563,6 +563,78 @@ describe('tool messages', () => {
}
`);
});

it('should handle tool result with url-based PDF content', async () => {
const result = await convertToAnthropicMessagesPrompt({
prompt: [
{
role: 'tool',
content: [
{
type: 'tool-result',
toolName: 'image-generator',
toolCallId: 'image-gen-1',
output: {
type: 'content',
value: [
{
type: 'media',
data: 'https://example.com/document.pdf',
mediaType: 'application/pdf',
},
{
type: 'text',
text: 'Document loaded successfully',
},
],
},
},
],
},
],
sendReasoning: true,
warnings: [],
});

expect(result).toMatchInlineSnapshot(`
{
"betas": Set {
"pdfs-2024-09-25",
},
"prompt": {
"messages": [
{
"content": [
{
"cache_control": undefined,
"content": [
{
"cache_control": undefined,
"source": {
"type": "url",
"url": "https://example.com/document.pdf",
},
"type": "document",
},
{
"cache_control": undefined,
"text": "Document loaded successfully",
"type": "text",
},
],
"is_error": undefined,
"tool_use_id": "image-gen-1",
"type": "tool_result",
},
],
"role": "user",
},
],
"system": undefined,
},
}
`);
});
});

describe('assistant messages', () => {
Expand Down
30 changes: 30 additions & 0 deletions packages/anthropic/src/convert-to-anthropic-messages-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ function convertToString(data: LanguageModelV3DataContent): string {
});
}

function isValidUrl(string: string): boolean {
try {
new URL(string);
return true;
} catch {
return false;
}
}

export async function convertToAnthropicMessagesPrompt({
prompt,
sendReasoning,
Expand Down Expand Up @@ -268,6 +277,16 @@ export async function convertToAnthropicMessagesPrompt({
};
case 'media': {
if (contentPart.mediaType.startsWith('image/')) {
if (isValidUrl(contentPart.data)) {
return {
type: 'image',
source: {
type: 'url',
url: contentPart.data,
},
cache_control: undefined,
};
}
return {
type: 'image',
source: {
Expand All @@ -282,6 +301,17 @@ export async function convertToAnthropicMessagesPrompt({
if (contentPart.mediaType === 'application/pdf') {
betas.add('pdfs-2024-09-25');

if (isValidUrl(contentPart.data)) {
return {
type: 'document',
source: {
type: 'url',
url: contentPart.data,
},
cache_control: undefined,
};
}

return {
type: 'document',
source: {
Expand Down