Skip to content

Commit d5a7cc5

Browse files
committed
bug #1143 [Platform] Keep metadata set by result converters instead of overwriting in DeferredResult (chr-hertel)
This PR was merged into the main branch. Discussion ---------- [Platform] Keep metadata set by result converters instead of overwriting in DeferredResult | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | no | Issues | | License | MIT Currently, metadata that gets set by result converters is overwritten in `DeferredResult` which is unfortunate since it completely eliminates the option for that layer to work with that `Metadata` object. should work after this PR tho. Commits ------- f0b26a5 Keep metadata set by result converters instead of overwriting in DeferredResult
2 parents 5811a24 + f0b26a5 commit d5a7cc5

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

src/platform/src/Metadata/Metadata.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ public function set(array $metadata): void
4848
$this->metadata = $metadata;
4949
}
5050

51+
/**
52+
* @param array<string, mixed> $metadata
53+
*/
54+
public function merge(array $metadata): void
55+
{
56+
$this->metadata = array_merge($this->metadata, $metadata);
57+
}
58+
5159
public function add(string $key, mixed $value): void
5260
{
5361
$this->metadata[$key] = $value;

src/platform/src/Result/DeferredResult.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function getResult(): ResultInterface
5050
$this->convertedResult->setRawResult($this->rawResult);
5151
}
5252

53-
$this->convertedResult->getMetadata()->set($this->getMetadata()->all());
53+
$this->convertedResult->getMetadata()->merge($this->getMetadata()->all());
5454

5555
if (null !== $tokenUsageExtractor = $this->resultConverter->getTokenUsageExtractor()) {
5656
if (null !== $tokenUsage = $tokenUsageExtractor->extract($this->rawResult, $this->options)) {

src/platform/tests/Metadata/MetadataTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ public function testItCanSetEntireMetadataArray()
7676
$this->assertSame(['key2' => 'value2', 'key3' => 'value3'], $metadata->all());
7777
}
7878

79+
public function testItCanMergeMetadataArrays()
80+
{
81+
$metadata = new Metadata(['key0' => 'value0', 'key1' => 'value1']);
82+
$metadata->merge(['key2' => 'value2', 'key1' => 'newValue1']);
83+
84+
$this->assertTrue($metadata->has('key0'));
85+
$this->assertTrue($metadata->has('key1'));
86+
$this->assertTrue($metadata->has('key2'));
87+
$this->assertSame('value0', $metadata->get('key0'));
88+
$this->assertSame('newValue1', $metadata->get('key1'));
89+
$this->assertSame('value2', $metadata->get('key2'));
90+
}
91+
7992
public function testItImplementsJsonSerializable()
8093
{
8194
$metadata = new Metadata(['key' => 'value']);

src/platform/tests/Result/DeferredResultTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\AI\Platform\Result\BaseResult;
1616
use Symfony\AI\Platform\Result\DeferredResult;
17+
use Symfony\AI\Platform\Result\InMemoryRawResult;
1718
use Symfony\AI\Platform\Result\RawHttpResult;
1819
use Symfony\AI\Platform\Result\RawResultInterface;
1920
use Symfony\AI\Platform\Result\ResultInterface;
2021
use Symfony\AI\Platform\Result\TextResult;
2122
use Symfony\AI\Platform\ResultConverterInterface;
23+
use Symfony\AI\Platform\Test\PlainConverter;
2224
use Symfony\Contracts\HttpClient\ResponseInterface as SymfonyHttpResponse;
2325

2426
final class DeferredResultTest extends TestCase
@@ -119,6 +121,21 @@ public function testItPassesOptionsToConverter()
119121
$deferredResult->getResult();
120122
}
121123

124+
public function testItKeepsResultMetadata()
125+
{
126+
$result = new TextResult('Hello World');
127+
$result->getMetadata()->add('foo', 'bar');
128+
$converter = new PlainConverter($result);
129+
130+
$deferredResult = new DeferredResult($converter, new InMemoryRawResult());
131+
$deferredResult->getMetadata()->add('key', 'value');
132+
133+
$unwrappedResult = $deferredResult->getResult();
134+
135+
$this->assertSame('bar', $unwrappedResult->getMetadata()->get('foo'));
136+
$this->assertSame('value', $unwrappedResult->getMetadata()->get('key'));
137+
}
138+
122139
/**
123140
* Workaround for low deps because mocking the ResponseInterface leads to an exception with
124141
* mock creation "Type Traversable|object|array|string|null contains both object and a class type"

0 commit comments

Comments
 (0)