Skip to content

Commit 9f160db

Browse files
CopilotOskarStark
andcommitted
Fix: Propagate metadata (sources) in streaming responses
Co-authored-by: OskarStark <995707+OskarStark@users.noreply.github.com>
1 parent 9f00cf2 commit 9f160db

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

src/agent/.phpunit.result.cache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":1,"defects":{"Symfony\\AI\\Agent\\Tests\\Toolbox\\AgentProcessorTest::testSourcesEndUpInResultMetadataWithStreaming":4},"times":{"Symfony\\AI\\Agent\\Tests\\Toolbox\\AgentProcessorTest::testSourcesEndUpInResultMetadataWithStreaming":0}}

src/agent/src/Toolbox/StreamResult.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@ public function getContent(): \Generator
3131
$streamedResult = '';
3232
foreach ($this->generator as $value) {
3333
if ($value instanceof ToolCallResult) {
34-
yield from ($this->handleToolCallsCallback)($value, Message::ofAssistant($streamedResult))->getContent();
34+
$innerResult = ($this->handleToolCallsCallback)($value, Message::ofAssistant($streamedResult));
35+
36+
// Propagate metadata from inner result to this result
37+
foreach ($innerResult->getMetadata()->all() as $key => $metadataValue) {
38+
$this->getMetadata()->add($key, $metadataValue);
39+
}
40+
41+
yield from $innerResult->getContent();
3542

3643
break;
3744
}

src/agent/tests/Toolbox/AgentProcessorTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Symfony\AI\Platform\PlatformInterface;
2727
use Symfony\AI\Platform\Result\DeferredResult;
2828
use Symfony\AI\Platform\Result\InMemoryRawResult;
29+
use Symfony\AI\Platform\Result\StreamResult as GenericStreamResult;
2930
use Symfony\AI\Platform\Result\TextResult;
3031
use Symfony\AI\Platform\Result\ToolCall;
3132
use Symfony\AI\Platform\Result\ToolCallResult;
@@ -233,4 +234,52 @@ public function testSourcesGetCollectedAcrossConsecutiveToolCalls()
233234
$this->assertCount(2, $metadata->get('sources'));
234235
$this->assertSame([$source1, $source2], $metadata->get('sources'));
235236
}
237+
238+
public function testSourcesEndUpInResultMetadataWithStreaming()
239+
{
240+
$toolCall = new ToolCall('call_1234', 'tool_sources', ['arg1' => 'value1']);
241+
$source1 = new Source('Relevant Article 1', 'http://example.com/article1', 'Content of article about the topic');
242+
$source2 = new Source('Relevant Article 2', 'http://example.com/article2', 'More content of article about the topic');
243+
$toolbox = $this->createMock(ToolboxInterface::class);
244+
$toolbox
245+
->expects($this->once())
246+
->method('execute')
247+
->willReturn(new ToolResult($toolCall, 'Response based on the two articles.', [$source1, $source2]));
248+
249+
$messageBag = new MessageBag();
250+
251+
// Create a generator that yields chunks and then a ToolCallResult
252+
$generator = (function () use ($toolCall) {
253+
yield 'chunk1';
254+
yield 'chunk2';
255+
yield new ToolCallResult($toolCall);
256+
})();
257+
258+
$result = new GenericStreamResult($generator);
259+
260+
$agent = $this->createMock(AgentInterface::class);
261+
$agent
262+
->expects($this->once())
263+
->method('call')
264+
->willReturn(new TextResult('Final response based on the two articles.'));
265+
266+
$processor = new AgentProcessor($toolbox, includeSources: true);
267+
$processor->setAgent($agent);
268+
269+
$output = new Output('gpt-4', $result, $messageBag);
270+
271+
$processor->processOutput($output);
272+
273+
// Consume the stream
274+
$content = '';
275+
foreach ($output->getResult()->getContent() as $chunk) {
276+
$content .= $chunk;
277+
}
278+
279+
// After consuming the stream, metadata should be available
280+
$metadata = $output->getResult()->getMetadata();
281+
$this->assertTrue($metadata->has('sources'));
282+
$this->assertCount(2, $metadata->get('sources'));
283+
$this->assertSame([$source1, $source2], $metadata->get('sources'));
284+
}
236285
}

0 commit comments

Comments
 (0)