Skip to content

Commit e3fd191

Browse files
committed
feat: extend Claude support for images and pdf input
1 parent 8e6a7d0 commit e3fd191

File tree

11 files changed

+191
-7
lines changed

11 files changed

+191
-7
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -821,3 +821,4 @@ For testing multi-modal features, the repository contains binary media content,
821821

822822
* `tests/Fixture/image.jpg`: Chris F., Creative Commons, see [pexels.com](https://www.pexels.com/photo/blauer-und-gruner-elefant-mit-licht-1680755/)
823823
* `tests/Fixture/audio.mp3`: davidbain, Creative Commons, see [freesound.org](https://freesound.org/people/davidbain/sounds/136777/)
824+
* `tests/Ficture/document.pdf`: Chem8240ja, Public Domain, see [Wikipedia](https://en.m.wikipedia.org/wiki/File:Re_example.pdf)
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
4+
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory;
5+
use PhpLlm\LlmChain\Chain;
6+
use PhpLlm\LlmChain\Model\Message\Content\Image;
7+
use PhpLlm\LlmChain\Model\Message\Message;
8+
use PhpLlm\LlmChain\Model\Message\MessageBag;
9+
use Symfony\Component\Dotenv\Dotenv;
10+
11+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
12+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
13+
14+
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
15+
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;
16+
exit(1);
17+
}
18+
19+
$platform = PlatformFactory::create($_ENV['ANTHROPIC_API_KEY']);
20+
$llm = new Claude(Claude::SONNET_37);
21+
22+
$chain = new Chain($platform, $llm);
23+
$messages = new MessageBag(
24+
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
25+
Message::ofUser(
26+
Image::fromFile(dirname(__DIR__, 2).'/tests/Fixture/image.jpg'),
27+
'Describe this image.',
28+
),
29+
);
30+
$response = $chain->call($messages);
31+
32+
echo $response->getContent().PHP_EOL;
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
4+
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory;
5+
use PhpLlm\LlmChain\Chain;
6+
use PhpLlm\LlmChain\Model\Message\Content\ImageUrl;
7+
use PhpLlm\LlmChain\Model\Message\Message;
8+
use PhpLlm\LlmChain\Model\Message\MessageBag;
9+
use Symfony\Component\Dotenv\Dotenv;
10+
11+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
12+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
13+
14+
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
15+
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;
16+
exit(1);
17+
}
18+
19+
$platform = PlatformFactory::create($_ENV['ANTHROPIC_API_KEY']);
20+
$llm = new Claude(Claude::SONNET_37);
21+
22+
$chain = new Chain($platform, $llm);
23+
$messages = new MessageBag(
24+
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
25+
Message::ofUser(
26+
new ImageUrl('https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg'),
27+
'Describe this image.',
28+
),
29+
);
30+
$response = $chain->call($messages);
31+
32+
echo $response->getContent().PHP_EOL;
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
4+
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory;
5+
use PhpLlm\LlmChain\Chain;
6+
use PhpLlm\LlmChain\Model\Message\Content\Document;
7+
use PhpLlm\LlmChain\Model\Message\Message;
8+
use PhpLlm\LlmChain\Model\Message\MessageBag;
9+
use Symfony\Component\Dotenv\Dotenv;
10+
11+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
12+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
13+
14+
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
15+
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;
16+
exit(1);
17+
}
18+
19+
$platform = PlatformFactory::create($_ENV['ANTHROPIC_API_KEY']);
20+
$llm = new Claude(Claude::SONNET_37);
21+
22+
$chain = new Chain($platform, $llm);
23+
$messages = new MessageBag(
24+
Message::ofUser(
25+
Document::fromFile(dirname(__DIR__, 2).'/tests/Fixture/document.pdf'),
26+
'What is this document about?',
27+
),
28+
);
29+
$response = $chain->call($messages);
30+
31+
echo $response->getContent().PHP_EOL;

examples/anthropic/pdf-input-url.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
4+
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory;
5+
use PhpLlm\LlmChain\Chain;
6+
use PhpLlm\LlmChain\Model\Message\Content\DocumentUrl;
7+
use PhpLlm\LlmChain\Model\Message\Message;
8+
use PhpLlm\LlmChain\Model\Message\MessageBag;
9+
use Symfony\Component\Dotenv\Dotenv;
10+
11+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
12+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
13+
14+
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
15+
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;
16+
exit(1);
17+
}
18+
19+
$platform = PlatformFactory::create($_ENV['ANTHROPIC_API_KEY']);
20+
$llm = new Claude(Claude::SONNET_37);
21+
22+
$chain = new Chain($platform, $llm);
23+
$messages = new MessageBag(
24+
Message::ofUser(
25+
new DocumentUrl('https://upload.wikimedia.org/wikipedia/commons/2/20/Re_example.pdf'),
26+
'What is this document about?',
27+
),
28+
);
29+
$response = $chain->call($messages);
30+
31+
echo $response->getContent().PHP_EOL;

src/Bridge/Anthropic/Claude.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function supportsAudioInput(): bool
4242

4343
public function supportsImageInput(): bool
4444
{
45-
return false; // it does, but implementation here is still open.
45+
return true;
4646
}
4747

4848
public function supportsStreaming(): bool
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpLlm\LlmChain\Model\Message\Content;
6+
7+
final readonly class Document extends File implements Content
8+
{
9+
/**
10+
* @return array{type: 'document', source: array{type: 'base64', media_type: string, data: string}}
11+
*/
12+
public function jsonSerialize(): array
13+
{
14+
return [
15+
'type' => 'document',
16+
'source' => [
17+
'type' => 'base64',
18+
'media_type' => $this->getFormat(),
19+
'data' => $this->asBase64(),
20+
],
21+
];
22+
}
23+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpLlm\LlmChain\Model\Message\Content;
6+
7+
final readonly class DocumentUrl implements Content
8+
{
9+
public function __construct(
10+
public string $url,
11+
) {
12+
}
13+
14+
/**
15+
* @return array{type: 'document', source: array{type: 'url', url: string}}
16+
*/
17+
public function jsonSerialize(): array
18+
{
19+
return [
20+
'type' => 'document',
21+
'source' => [
22+
'type' => 'url',
23+
'url' => $this->url,
24+
],
25+
];
26+
}
27+
}

src/Model/Message/Content/Image.php

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77
final readonly class Image extends File implements Content
88
{
99
/**
10-
* @return array{type: 'image_url', image_url: array{url: string}}
10+
* @return array{type: 'image', source: array{type: 'base64', media_type: string, data: string}}
1111
*/
1212
public function jsonSerialize(): array
1313
{
1414
return [
15-
'type' => 'image_url',
16-
'image_url' => ['url' => $this->asDataUrl()],
15+
'type' => 'image',
16+
'source' => [
17+
'type' => 'base64',
18+
'media_type' => $this->getFormat(),
19+
'data' => $this->asBase64(),
20+
],
1721
];
1822
}
1923
}

src/Model/Message/Content/ImageUrl.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ public function __construct(
1212
}
1313

1414
/**
15-
* @return array{type: 'image_url', image_url: array{url: string}}
15+
* @return array{type: 'image', source: array{type: 'url', url: string}}
1616
*/
1717
public function jsonSerialize(): array
1818
{
1919
return [
20-
'type' => 'image_url',
21-
'image_url' => ['url' => $this->url],
20+
'type' => 'image',
21+
'source' => [
22+
'type' => 'url',
23+
'url' => $this->url,
24+
],
2225
];
2326
}
2427
}

tests/Fixture/document.pdf

18 KB
Binary file not shown.

0 commit comments

Comments
 (0)