Skip to content

Commit 499a3d9

Browse files
committed
feature #51 feat: allow any normalizable result from a tool (valtzu)
This PR was merged into the main branch. Discussion ---------- feat: allow any normalizable result from a tool | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Docs? | | Issues | | License | MIT Cherry picking php-llm/llm-chain#355 Commits ------- 006732d feat: allow any normalizable result from a tool (#355)
2 parents bb1e00a + 006732d commit 499a3d9

File tree

2 files changed

+30
-17
lines changed

2 files changed

+30
-17
lines changed

src/agent/src/Toolbox/ToolResultConverter.php

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,33 @@
1111

1212
namespace Symfony\AI\Agent\Toolbox;
1313

14+
use Symfony\Component\Serializer\Encoder\JsonEncoder;
15+
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
16+
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
17+
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
18+
use Symfony\Component\Serializer\Serializer;
19+
use Symfony\Component\Serializer\SerializerInterface;
20+
1421
/**
1522
* @author Christopher Hertel <[email protected]>
1623
*/
1724
final readonly class ToolResultConverter
1825
{
19-
/**
20-
* @param \JsonSerializable|\Stringable|array<int|string, mixed>|float|string|\DateTimeInterface|null $result
21-
*/
22-
public function convert(\JsonSerializable|\Stringable|array|float|string|\DateTimeInterface|null $result): ?string
23-
{
24-
if (null === $result) {
25-
return null;
26-
}
26+
public function __construct(
27+
private SerializerInterface $serializer = new Serializer([new JsonSerializableNormalizer(), new DateTimeNormalizer(), new ObjectNormalizer()], [new JsonEncoder()]),
28+
) {
29+
}
2730

28-
if ($result instanceof \JsonSerializable || \is_array($result)) {
29-
return json_encode($result, flags: \JSON_THROW_ON_ERROR);
31+
public function convert(mixed $result): ?string
32+
{
33+
if (null === $result || \is_string($result)) {
34+
return $result;
3035
}
3136

32-
if (\is_float($result) || $result instanceof \Stringable) {
37+
if ($result instanceof \Stringable) {
3338
return (string) $result;
3439
}
3540

36-
if ($result instanceof \DateTimeInterface) {
37-
return $result->format(\DATE_ATOM);
38-
}
39-
40-
return $result;
41+
return $this->serializer->serialize($result, 'json');
4142
}
4243
}

src/agent/tests/Toolbox/ToolResultConverterTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPUnit\Framework\Attributes\Test;
1717
use PHPUnit\Framework\TestCase;
1818
use Symfony\AI\Agent\Toolbox\ToolResultConverter;
19+
use Symfony\AI\Fixtures\StructuredOutput\UserWithConstructor;
1920

2021
#[CoversClass(ToolResultConverter::class)]
2122
final class ToolResultConverterTest extends TestCase
@@ -41,7 +42,7 @@ public static function provideResults(): \Generator
4142

4243
yield 'string' => ['plain string', 'plain string'];
4344

44-
yield 'datetime' => [new \DateTimeImmutable('2021-07-31 12:34:56'), '2021-07-31T12:34:56+00:00'];
45+
yield 'datetime' => [new \DateTimeImmutable('2021-07-31 12:34:56'), '"2021-07-31T12:34:56+00:00"'];
4546

4647
yield 'stringable' => [
4748
new class implements \Stringable {
@@ -62,5 +63,16 @@ public function jsonSerialize(): array
6263
},
6364
'{"key":"value"}',
6465
];
66+
67+
yield 'object' => [
68+
new UserWithConstructor(
69+
id: 123,
70+
name: 'John Doe',
71+
createdAt: new \DateTimeImmutable('2021-07-31 12:34:56'),
72+
isActive: true,
73+
age: 18,
74+
),
75+
'{"id":123,"name":"John Doe","createdAt":"2021-07-31T12:34:56+00:00","isActive":true,"age":18}',
76+
];
6577
}
6678
}

0 commit comments

Comments
 (0)