Skip to content

Commit 74955b6

Browse files
committed
bug #1199 [AI Bundle][Profiler] avoid serializing closures for files and images (uerka)
This PR was squashed before being merged into the main branch. Discussion ---------- [AI Bundle][Profiler] avoid serializing closures for files and images | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | no | Issues | | License | MIT Currently when agent call includes images/files profiler throws exception 'Serialization of 'Closure' is not allowed' and therefore cannot store profile. Added __serialize() methods to File class and also displaying of files/images in profiler. Commits ------- 90ced03 [AI Bundle][Profiler] avoid serializing closures for files and images
2 parents c131b97 + 90ced03 commit 74955b6

File tree

5 files changed

+85
-2
lines changed

5 files changed

+85
-2
lines changed

src/ai-bundle/templates/data_collector.html.twig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,10 @@
119119
{% for item in message.content %}
120120
{% if item.text is defined %}
121121
{{ item.text|nl2br }}
122-
{% else %}
123-
<img src="{{ item.url }}" />
122+
{% elseif item.format is defined and item.format starts with 'image/' %}
123+
<img src="{{ item.asDataUrl }}" style="max-width: 100%;"/>
124+
{% elseif item.asDataUrl %}
125+
<a href="{{ item.asDataUrl }}" download="{{ item.filename ?? 'View File' }}">{{ item.filename ?? 'View File' }}</a>
124126
{% endif %}
125127
{% endfor %}
126128
{% else %}

src/platform/src/Message/Content/File.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ final public function __construct(
2828
) {
2929
}
3030

31+
/**
32+
* @return array{data: string, path: string|null, format: string}
33+
*/
34+
public function __serialize(): array
35+
{
36+
return [
37+
'data' => $this->data instanceof \Closure ? ($this->data)() : $this->data,
38+
'format' => $this->format,
39+
'path' => $this->path,
40+
];
41+
}
42+
3143
public static function fromDataUrl(string $dataUrl): static
3244
{
3345
if (!str_starts_with($dataUrl, 'data:')) {

src/platform/tests/Message/Content/AudioTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,14 @@ public function testFromFileWithInvalidPath()
5656

5757
Audio::fromFile('foo.mp3');
5858
}
59+
60+
public function testCanBeSerialized()
61+
{
62+
$audio = Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
63+
64+
$serialized = serialize($audio);
65+
$unserialized = unserialize($serialized);
66+
$this->assertInstanceOf(Audio::class, $unserialized);
67+
$this->assertSame('audio.mp3', $unserialized->getFilename());
68+
}
5969
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Platform\Tests\Message\Content;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\AI\Platform\Message\Content\File;
16+
17+
final class FileTest extends TestCase
18+
{
19+
public function testConstructWithValidDataUrl()
20+
{
21+
$image = File::fromDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKklEQVR42mNk+A8AAwMhIv9n+X');
22+
23+
$this->assertStringStartsWith('data:image/png;base64', $image->asDataUrl());
24+
}
25+
26+
public function testWithValidFile()
27+
{
28+
$image = File::fromFile(\dirname(__DIR__, 5).'/fixtures/image.jpg');
29+
30+
$this->assertStringStartsWith('data:image/jpeg;base64,', $image->asDataUrl());
31+
}
32+
33+
public function testFromBinaryWithInvalidFile()
34+
{
35+
$this->expectExceptionMessage('The file "foo.jpg" does not exist or is not readable.');
36+
37+
File::fromFile('foo.jpg');
38+
}
39+
40+
public function testCanBeSerialized()
41+
{
42+
$audio = File::fromFile(\dirname(__DIR__, 5).'/fixtures/image.jpg');
43+
44+
$serialized = serialize($audio);
45+
$unserialized = unserialize($serialized);
46+
$this->assertInstanceOf(File::class, $unserialized);
47+
$this->assertSame('image.jpg', $unserialized->getFilename());
48+
}
49+
}

src/platform/tests/Message/Content/ImageTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,14 @@ public function testFromBinaryWithInvalidFile()
3636

3737
Image::fromFile('foo.jpg');
3838
}
39+
40+
public function testCanBeSerialized()
41+
{
42+
$audio = Image::fromFile(\dirname(__DIR__, 5).'/fixtures/image.jpg');
43+
44+
$serialized = serialize($audio);
45+
$unserialized = unserialize($serialized);
46+
$this->assertInstanceOf(Image::class, $unserialized);
47+
$this->assertSame('image.jpg', $unserialized->getFilename());
48+
}
3949
}

0 commit comments

Comments
 (0)