Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit 99336fe

Browse files
authored
refactor: message content file handling [BC BREAK] (#285)
Preparation for #279 * Introducing a base File that centralizes mime type, base64 handling, etc. * Image split into ImageUrl and Image based on File => i usually know what i need in user land * `new Image('https://...')` => `new ImageUrl('https://...)` * `new Image('data:image/jpeg;base64,...')` => `Image::fromDataUrl('data:image/jpeg;base64,...')` * `new Image('/path/to/jpeg.jpg')` => `Image::fromFile('/path/to/jpeg.jpg')` * removing `File` class of Whisper bridge in favor of `Audio`
1 parent 54e13cb commit 99336fe

26 files changed

+317
-165
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,9 @@ $messages = new MessageBag(
552552
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
553553
Message::ofUser(
554554
'Describe the image as a comedian would do it.',
555-
new Image(dirname(__DIR__).'/tests/Fixture/image.jpg'), // Path to an image file
556-
new Image('https://foo.com/bar.png'), // URL to an image
557-
new Image('data:image/png;base64,...'), // Data URL of an image
555+
Image::fromFile(dirname(__DIR__).'/tests/Fixture/image.jpg'), // Path to an image file
556+
Image::fromDataUrl('data:image/png;base64,...'), // Data URL of an image
557+
new ImageUrl('https://foo.com/bar.png'), // URL to an image
558558
),
559559
);
560560
$response = $chain->call($messages);
@@ -579,7 +579,7 @@ use PhpLlm\LlmChain\Model\Message\MessageBag;
579579
$messages = new MessageBag(
580580
Message::ofUser(
581581
'What is this recording about?',
582-
Audio:fromFile(dirname(__DIR__).'/tests/Fixture/audio.mp3'), // Path to an audio file
582+
Audio::fromFile(dirname(__DIR__).'/tests/Fixture/audio.mp3'), // Path to an audio file
583583
),
584584
);
585585
$response = $chain->call($messages);

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
],
1616
"require": {
1717
"php": ">=8.2",
18+
"ext-fileinfo": "*",
1819
"oskarstark/enum-helper": "^1.5",
1920
"phpdocumentor/reflection-docblock": "^5.4",
2021
"phpstan/phpdoc-parser": "^2.1",

examples/audio-transcript-whisper.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use PhpLlm\LlmChain\Bridge\OpenAI\PlatformFactory;
44
use PhpLlm\LlmChain\Bridge\OpenAI\Whisper;
5-
use PhpLlm\LlmChain\Bridge\OpenAI\Whisper\File;
5+
use PhpLlm\LlmChain\Model\Message\Content\Audio;
66
use Symfony\Component\Dotenv\Dotenv;
77

88
require_once dirname(__DIR__).'/vendor/autoload.php';
@@ -15,7 +15,7 @@
1515

1616
$platform = PlatformFactory::create($_ENV['OPENAI_API_KEY']);
1717
$model = new Whisper();
18-
$file = new File(dirname(__DIR__).'/tests/Fixture/audio.mp3');
18+
$file = Audio::fromFile(dirname(__DIR__).'/tests/Fixture/audio.mp3');
1919

2020
$response = $platform->request($model, $file);
2121

examples/image-describer-binary-gemini.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
2525
Message::ofUser(
2626
'Describe the image as a comedian would do it.',
27-
new Image(dirname(__DIR__).'/tests/Fixture/image.jpg'),
27+
Image::fromFile(dirname(__DIR__).'/tests/Fixture/image.jpg'),
2828
),
2929
);
3030
$response = $chain->call($messages);

examples/image-describer-binary.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
2525
Message::ofUser(
2626
'Describe the image as a comedian would do it.',
27-
new Image(dirname(__DIR__).'/tests/Fixture/image.jpg'),
27+
Image::fromFile(dirname(__DIR__).'/tests/Fixture/image.jpg'),
2828
),
2929
);
3030
$response = $chain->call($messages);

examples/image-describer-url.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use PhpLlm\LlmChain\Bridge\OpenAI\GPT;
44
use PhpLlm\LlmChain\Bridge\OpenAI\PlatformFactory;
55
use PhpLlm\LlmChain\Chain;
6-
use PhpLlm\LlmChain\Model\Message\Content\Image;
6+
use PhpLlm\LlmChain\Model\Message\Content\ImageUrl;
77
use PhpLlm\LlmChain\Model\Message\Message;
88
use PhpLlm\LlmChain\Model\Message\MessageBag;
99
use Symfony\Component\Dotenv\Dotenv;
@@ -24,7 +24,7 @@
2424
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
2525
Message::ofUser(
2626
'Describe the image as a comedian would do it.',
27-
new Image('https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Webysther_20160423_-_Elephpant.svg/350px-Webysther_20160423_-_Elephpant.svg.png'),
27+
new ImageUrl('https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Webysther_20160423_-_Elephpant.svg/350px-Webysther_20160423_-_Elephpant.svg.png'),
2828
),
2929
);
3030
$response = $chain->call($messages);

src/Bridge/Azure/OpenAI/WhisperModelClient.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace PhpLlm\LlmChain\Bridge\Azure\OpenAI;
66

77
use PhpLlm\LlmChain\Bridge\OpenAI\Whisper;
8-
use PhpLlm\LlmChain\Bridge\OpenAI\Whisper\File;
8+
use PhpLlm\LlmChain\Model\Message\Content\Audio;
99
use PhpLlm\LlmChain\Model\Model;
1010
use PhpLlm\LlmChain\Platform\ModelClient;
1111
use Symfony\Component\HttpClient\EventSourceHttpClient;
@@ -34,12 +34,12 @@ public function __construct(
3434

3535
public function supports(Model $model, object|array|string $input): bool
3636
{
37-
return $model instanceof Whisper && $input instanceof File;
37+
return $model instanceof Whisper && $input instanceof Audio;
3838
}
3939

4040
public function request(Model $model, object|array|string $input, array $options = []): ResponseInterface
4141
{
42-
assert($input instanceof File);
42+
assert($input instanceof Audio);
4343

4444
$url = sprintf('https://%s/openai/deployments/%s/audio/translations', $this->baseUrl, $this->deployment);
4545

@@ -51,7 +51,7 @@ public function request(Model $model, object|array|string $input, array $options
5151
'query' => ['api-version' => $this->apiVersion],
5252
'body' => array_merge($options, $model->getOptions(), [
5353
'model' => $model->getName(),
54-
'file' => fopen($input->path, 'r'),
54+
'file' => $input->asResource(),
5555
]),
5656
]);
5757
}

src/Bridge/Google/GooglePromptConverter.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
use PhpLlm\LlmChain\Model\Message\Role;
1313
use PhpLlm\LlmChain\Model\Message\UserMessage;
1414

15-
use function Symfony\Component\String\u;
16-
1715
final class GooglePromptConverter
1816
{
1917
/**
@@ -63,8 +61,8 @@ private function convertMessage(MessageInterface $message): array
6361
}
6462
if ($content instanceof Image) {
6563
$parts[] = ['inline_data' => [
66-
'mime_type' => u($content->url)->after('data:')->before(';')->toString(),
67-
'data' => u($content->url)->after('base64,')->toString(),
64+
'mime_type' => $content->getFormat(),
65+
'data' => $content->asBase64(),
6866
]];
6967
}
7068
}

src/Bridge/Meta/LlamaPromptConverter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use PhpLlm\LlmChain\Exception\RuntimeException;
88
use PhpLlm\LlmChain\Model\Message\AssistantMessage;
9-
use PhpLlm\LlmChain\Model\Message\Content\Image;
9+
use PhpLlm\LlmChain\Model\Message\Content\ImageUrl;
1010
use PhpLlm\LlmChain\Model\Message\Content\Text;
1111
use PhpLlm\LlmChain\Model\Message\MessageBagInterface;
1212
use PhpLlm\LlmChain\Model\Message\SystemMessage;
@@ -60,7 +60,7 @@ public function convertMessage(UserMessage|SystemMessage|AssistantMessage $messa
6060
$contentParts[] = $value->text;
6161
}
6262

63-
if ($value instanceof Image) {
63+
if ($value instanceof ImageUrl) {
6464
$contentParts[] = $value->url;
6565
}
6666
}
@@ -70,7 +70,7 @@ public function convertMessage(UserMessage|SystemMessage|AssistantMessage $messa
7070
$contentParts[] = $value->text;
7171
}
7272

73-
if ($value instanceof Image) {
73+
if ($value instanceof ImageUrl) {
7474
$contentParts[] = $value->url;
7575
}
7676
} else {

src/Bridge/OpenAI/Whisper/File.php

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)