Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 6, 2025

Q A
Bug fix? yes
New feature? no
Docs? no
Issues Fix #833
License MIT
  • Analyze the issue with sources metadata being null during streaming
  • Identify the root cause in ToolboxStreamResult
  • Implement fix to propagate metadata from inner result to outer result
  • Add test for streaming with sources
  • Fix trailing whitespace in test (code quality)
  • Fix "yield from" error with non-iterable content
  • Simplify content type check for better maintainability
  • Improve code comments and comparison consistency
  • Add safety check for non-iterable objects
  • Revert unnecessary .gitignore change
  • Apply Symfony code style conventions

Summary

Fixed issue where sources metadata was inaccessible when using streaming with the Agent. The problem was that metadata was set on the inner result but never propagated to the outer StreamResult object.

Changes:

  • Modified StreamResult::getContent() to capture and propagate metadata from inner result
  • Added comprehensive type checking to safely handle all content types
  • Added test testSourcesEndUpInResultMetadataWithStreaming() to verify the fix works correctly
  • Applied Symfony code style conventions (Yoda conditions, fully qualified function names)
Original prompt

This section details on the original issue you should resolve

<issue_title>[Agent] Unable to access sources metadata with streaming</issue_title>
<issue_description>I am implementing the Symfony AI Agent in combination with the ai-sdk. I want to display the used sources in the UI, so I want to dispatch these in an event stream using the ai-sdk Data Stream Protocol. However, during streaming, the metadata seems to reset and sources are always null. Without the stream option this works fine.

Should this be done in a different order? The sources are present at some point, but seem to reset while actually streaming the content back.

This is basically all that I am doing:

    public function __invoke(ChatRequest $request): StreamedResponse
    {
        $platform = PlatformFactory::create(env('OPENAI_API_KEY'), HttpClient::create());
        
        $toolBox = new ToolBox([
            new RandomTool(),
        ]);
        $processor = new AgentProcessor($toolBox, includeSources: true);
        $agent = new Agent($platform, 'gpt-4o-mini', [$processor], [$processor]);

        $messages = new MessageBag();
        foreach ($request->messages() as $message) {
            foreach ($message['parts'] as $part) {
                if ($part['type'] !== 'text') {
                    continue;
                }
                $messages->add(Message::ofUser($part['text']));
            }
        }

        $result = $agent->call($messages, [
            'stream' => true
        ]);

        $response = new StreamedResponse(function () use ($result) {
            $messageId = 'msg_' . bin2hex(random_bytes(16));
            $textBlockId = 'text_' . bin2hex(random_bytes(16));
            
            $this->sendSSE(['type' => 'start', 'messageId' => $messageId]);
            $this->sendSSE(['type' => 'text-start', 'id' => $textBlockId]);
            
            foreach ($result->getContent() as $chunk) {
                $text = (string)$chunk;
                if ($text !== '') {
                    $this->sendSSE([
                        'type' => 'text-delta',
                        'id' => $textBlockId,
                        'delta' => $text
                    ]);
                }
            }
            
            $this->sendSSE(['type' => 'text-end', 'id' => $textBlockId]);
            
            // This is always null
            $sources = $result->getMetadata()->get('sources', []);
            foreach ($sources as $source) {
                if (!$source instanceof Source) {
                    continue;
                }
                $this->sendSSE([
                    'type' => 'source-url',
                    'sourceId' => $source->getReference(),
                    'url' => $source->getReference(),
                    'title' => $source->getName()
                ]);
            }
            
            $this->sendSSE(['type' => 'finish']);
            
            echo "data: [DONE]\n\n";
            flush();
        });

        
        $response->headers->set('Content-Type', 'text/event-stream');
        $response->headers->set('Cache-Control', 'no-cache');
        $response->headers->set('Connection', 'keep-alive');
        $response->headers->set('X-Accel-Buffering', 'no');
        $response->headers->set('x-vercel-ai-ui-message-stream', 'v1');
        
        return $response;
    }

    private function sendSSE(array $data): void
    {
        echo 'data: ' . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n";
        flush();
    }

</issue_description>

<agent_instructions>Try to fix this issue. do it as minimal as possible</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@chr-hertel Sounds like a legit bug to me - didn't test that yet as well. PR ofc welcome :)

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Fix issue with sources metadata during streaming [Agent] Fix sources metadata unavailable during streaming Nov 6, 2025
Copilot AI requested a review from OskarStark November 6, 2025 22:16
Copilot finished work on behalf of OskarStark November 6, 2025 22:16
@carsonbot carsonbot changed the title [Agent] Fix sources metadata unavailable during streaming Fix sources metadata unavailable during streaming Nov 6, 2025
@OskarStark OskarStark marked this pull request as ready for review November 7, 2025 13:20
@carsonbot carsonbot added the Bug Something isn't working label Nov 7, 2025
@OskarStark
Copy link
Contributor

@copilot fix the CI

This comment was marked as outdated.

Copilot finished work on behalf of OskarStark November 7, 2025 13:28
@JorrinKievit
Copy link

I checked and this indeed fixed it! @OskarStark

@OskarStark

This comment was marked as outdated.

This comment was marked as outdated.

Copilot finished work on behalf of OskarStark November 7, 2025 15:21
Copilot AI changed the title Fix sources metadata unavailable during streaming Fix sources metadata unavailable during streaming Nov 9, 2025
Copilot finished work on behalf of chr-hertel November 9, 2025 23:09
Copilot AI requested a review from chr-hertel November 9, 2025 23:09
@chr-hertel chr-hertel added the Agent Issues & PRs about the AI Agent component label Nov 11, 2025
@carsonbot carsonbot changed the title Fix sources metadata unavailable during streaming [Agent] Fix sources metadata unavailable during streaming Nov 11, 2025
@OskarStark

This comment was marked as outdated.

This comment was marked as outdated.

Copilot finished work on behalf of OskarStark November 13, 2025 12:46
@OskarStark OskarStark closed this Nov 13, 2025
@OskarStark OskarStark reopened this Nov 13, 2025
@OskarStark OskarStark force-pushed the copilot/fix-streaming-sources-metadata branch from 14af474 to cfdc2d8 Compare November 14, 2025 07:33
@OskarStark OskarStark merged commit 34fd794 into main Nov 14, 2025
27 checks passed
OskarStark added a commit that referenced this pull request Nov 14, 2025
…skarStark)

This PR was merged into the main branch.

Discussion
----------

[Agent] Fix sources metadata unavailable during streaming

  | Q             | A
  | ------------- | ---
  | Bug fix?      | yes
  | New feature?  | no
  | Docs?         | no
  | Issues        | Fix #833
  | License       | MIT

Replaces
* #838

Commits
-------

aeb6e22 [Agent] Fix sources metadata unavailable during streaming
@nicolas-grekas nicolas-grekas deleted the copilot/fix-streaming-sources-metadata branch November 14, 2025 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Agent Issues & PRs about the AI Agent component Bug Something isn't working Status: Needs Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Agent] Unable to access sources metadata with streaming

5 participants