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

Commit 5f3712f

Browse files
committed
feat: Allow any normalizable result from a tool
1 parent 97982eb commit 5f3712f

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/Chain/Toolbox/ToolResultConverter.php

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,43 @@
44

55
namespace PhpLlm\LlmChain\Chain\Toolbox;
66

7+
use Symfony\Component\Serializer\Encoder\EncoderInterface;
8+
use Symfony\Component\Serializer\Encoder\JsonEncoder;
9+
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
10+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
11+
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
12+
use Symfony\Component\Serializer\Serializer;
13+
714
/**
815
* @author Christopher Hertel <[email protected]>
916
*/
1017
final readonly class ToolResultConverter
1118
{
12-
/**
13-
* @param \JsonSerializable|\Stringable|array<int|string, mixed>|float|string|null $result
14-
*/
15-
public function convert(\JsonSerializable|\Stringable|array|float|string|\DateTimeInterface|null $result): ?string
19+
public function __construct(
20+
private NormalizerInterface&EncoderInterface $serializer = new Serializer([new DateTimeNormalizer(), new ObjectNormalizer()], [new JsonEncoder()]),
21+
) {
22+
}
23+
24+
public function convert(mixed $result): ?string
1625
{
17-
if (null === $result) {
18-
return null;
26+
if (null === $result || \is_string($result)) {
27+
return $result;
1928
}
2029

2130
if ($result instanceof \JsonSerializable || \is_array($result)) {
2231
return json_encode($result, flags: \JSON_THROW_ON_ERROR);
2332
}
2433

25-
if (\is_float($result) || $result instanceof \Stringable) {
34+
if ($result instanceof \Stringable) {
2635
return (string) $result;
2736
}
2837

29-
if ($result instanceof \DateTimeInterface) {
30-
return $result->format(\DATE_ATOM);
38+
$normalized = $this->serializer->normalize($result, 'json');
39+
40+
if (\is_scalar($normalized)) {
41+
return (string) $normalized;
3142
}
3243

33-
return $result;
44+
return $this->serializer->encode($normalized, 'json');
3445
}
3546
}

tests/Chain/Toolbox/ToolResultConverterTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace PhpLlm\LlmChain\Tests\Chain\Toolbox;
66

77
use PhpLlm\LlmChain\Chain\Toolbox\ToolResultConverter;
8+
use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\UserWithConstructor;
89
use PHPUnit\Framework\Attributes\CoversClass;
910
use PHPUnit\Framework\Attributes\DataProvider;
1011
use PHPUnit\Framework\Attributes\Test;
@@ -55,5 +56,16 @@ public function jsonSerialize(): array
5556
},
5657
'{"key":"value"}',
5758
];
59+
60+
yield 'object' => [
61+
new UserWithConstructor(
62+
id: 123,
63+
name: 'John Doe',
64+
createdAt: new \DateTimeImmutable('2021-07-31 12:34:56'),
65+
isActive: true,
66+
age: 18,
67+
),
68+
'{"id":123,"name":"John Doe","createdAt":"2021-07-31T12:34:56+00:00","isActive":true,"age":18}',
69+
];
5870
}
5971
}

0 commit comments

Comments
 (0)