Skip to content

Commit 18d48cf

Browse files
committed
Refactor streaming result conversion to improve metadata handling and replace StreamChunk with TextChunk
1 parent 9972cb7 commit 18d48cf

File tree

1 file changed

+23
-30
lines changed

1 file changed

+23
-30
lines changed

src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
use Symfony\AI\Platform\Exception\ContentFilterException;
1818
use Symfony\AI\Platform\Exception\RateLimitExceededException;
1919
use Symfony\AI\Platform\Exception\RuntimeException;
20-
use Symfony\AI\Platform\Metadata\TokenUsage;
20+
use Symfony\AI\Platform\Metadata\Metadata;
2121
use Symfony\AI\Platform\Model;
2222
use Symfony\AI\Platform\Result\ChoiceResult;
2323
use Symfony\AI\Platform\Result\RawHttpResult;
2424
use Symfony\AI\Platform\Result\RawResultInterface;
2525
use Symfony\AI\Platform\Result\ResultInterface;
26-
use Symfony\AI\Platform\Result\StreamChunk;
26+
use Symfony\AI\Platform\Result\TextChunk;
2727
use Symfony\AI\Platform\Result\StreamResult;
2828
use Symfony\AI\Platform\Result\TextResult;
2929
use Symfony\AI\Platform\Result\ToolCall;
@@ -90,50 +90,43 @@ public function convert(RawResultInterface|RawHttpResult $result, array $options
9090
private function convertStream(RawResultInterface|RawHttpResult $result): \Generator
9191
{
9292
$toolCalls = [];
93-
/** @var ToolCallResult|null $toolCallResult */
94-
$toolCallResult = null;
93+
$metadata = [];
9594
foreach ($result->getDataStream() as $data) {
95+
if (!$metadata) {
96+
$metadata['id'] = $data['id'];
97+
}
98+
99+
if (isset($data['usage'])) {
100+
$metadata['usage'] = $data['usage'];
101+
}
102+
103+
if (isset($data['choices'][0]['finish_reason'])) {
104+
$metadata['finish_reason'] = $data['choices'][0]['finish_reason'];
105+
}
106+
96107
if ($this->streamIsToolCall($data)) {
97108
$toolCalls = $this->convertStreamToToolCalls($toolCalls, $data);
98109
}
99110

100111
if ([] !== $toolCalls && $this->isToolCallsStreamFinished($data)) {
101112
$toolCallResult = new ToolCallResult(...array_map($this->convertToolCall(...), $toolCalls));
102-
// postpone yielding the tool call result until the usage is available
103-
continue;
104-
}
105-
106-
// Usage arrives after the tool calls are finished.
107-
if ($usage = $data['usage'] ?? null) {
108-
if ($toolCallResult) {
109-
$toolCallResult->getMetadata()->add('usage', $usage);
110-
yield $toolCallResult;
111-
$toolCallResult = null;
112-
} else {
113-
yield new TokenUsage(
114-
promptTokens: $usage['prompt_tokens'] ?? null,
115-
completionTokens: $usage['completion_tokens'] ?? null,
116-
thinkingTokens: $usage['completion_tokens_details']['reasoning_tokens'] ?? null,
117-
cachedTokens: $usage['prompt_tokens_details']['cached_tokens'] ?? null,
118-
totalTokens: $usage['total_tokens'] ?? null,
119-
);
120-
}
113+
$metadata['tool_calls'] = $toolCalls;
114+
$toolCallResult->getMetadata()->set($metadata);
115+
yield $toolCallResult;
121116
}
122117

123118
if (!isset($data['choices'][0]['delta']['content'])) {
124119
continue;
125120
}
126121

127-
$chunk = new StreamChunk($data['choices'][0]['delta']['content']);
128-
$chunk->setRawResult($result);
122+
$textChunk = new TextChunk($data['choices'][0]['delta']['content']);
123+
$textChunk->getMetadata()->set($metadata);
124+
$textChunk->setRawResult($result);
129125

130-
yield $chunk;
126+
yield $textChunk;
131127
}
132128

133-
// Yield the last tool call result if any.
134-
if ($toolCallResult) {
135-
yield $toolCallResult;
136-
}
129+
yield new Metadata($metadata);
137130
}
138131

139132
/**

0 commit comments

Comments
 (0)