Skip to content

Commit 2f65ed1

Browse files
lochmuellerchr-hertel
authored andcommitted
[Platform][OpenRouter] Allow streaming for OpenRouter based on ChatGPT ResultConverter
1 parent c06ad35 commit 2f65ed1

File tree

3 files changed

+33
-33
lines changed

3 files changed

+33
-33
lines changed

examples/openrouter/stream.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\AI\Platform\Bridge\OpenRouter\PlatformFactory;
13+
use Symfony\AI\Platform\Message\Message;
14+
use Symfony\AI\Platform\Message\MessageBag;
15+
16+
require_once dirname(__DIR__).'/bootstrap.php';
17+
18+
$platform = PlatformFactory::create(env('OPENROUTER_KEY'), http_client());
19+
20+
$messages = new MessageBag(Message::ofUser('List the first 50 prime number?'));
21+
$result = $platform->invoke('google/gemini-2.5-flash-lite', $messages, [
22+
'stream' => true,
23+
]);
24+
25+
print_stream($result);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function convert(RawResultInterface|RawHttpResult $result, array $options
7373
}
7474

7575
if (isset($data['error'])) {
76-
throw new RuntimeException(\sprintf('Error "%s"-%s (%s): "%s".', $data['error']['code'], $data['error']['type'], $data['error']['param'], $data['error']['message']));
76+
throw new RuntimeException(\sprintf('Error "%s"-%s (%s): "%s".', $data['error']['code'] ?? '-', $data['error']['type'] ?? '-', $data['error']['param'] ?? '-', $data['error']['message'] ?? '-'));
7777
}
7878

7979
if (!isset($data['choices'])) {

src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,54 +11,29 @@
1111

1212
namespace Symfony\AI\Platform\Bridge\OpenRouter\Completions;
1313

14-
use Symfony\AI\Platform\Exception\AuthenticationException;
15-
use Symfony\AI\Platform\Exception\BadRequestException;
16-
use Symfony\AI\Platform\Exception\RateLimitExceededException;
17-
use Symfony\AI\Platform\Exception\RuntimeException;
14+
use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter as OpenAiResponseConverter;
1815
use Symfony\AI\Platform\Model;
1916
use Symfony\AI\Platform\Result\RawResultInterface;
2017
use Symfony\AI\Platform\Result\ResultInterface;
21-
use Symfony\AI\Platform\Result\TextResult;
2218
use Symfony\AI\Platform\ResultConverterInterface;
2319

2420
/**
2521
* @author rglozman
2622
*/
2723
final class ResultConverter implements ResultConverterInterface
2824
{
25+
public function __construct(
26+
private readonly OpenAiResponseConverter $gptResponseConverter = new OpenAiResponseConverter(),
27+
) {
28+
}
29+
2930
public function supports(Model $model): bool
3031
{
3132
return true;
3233
}
3334

3435
public function convert(RawResultInterface $result, array $options = []): ResultInterface
3536
{
36-
$response = $result->getObject();
37-
$data = $result->getData();
38-
39-
if (401 === $response->getStatusCode()) {
40-
$errorMessage = json_decode($response->getContent(false), true)['error']['message'];
41-
throw new AuthenticationException($errorMessage);
42-
}
43-
44-
if (400 === $response->getStatusCode() || 404 === $response->getStatusCode()) {
45-
$errorMessage = json_decode($response->getContent(false), true)['error']['message'] ?? 'Bad Request';
46-
throw new BadRequestException($errorMessage);
47-
}
48-
49-
if (429 === $response->getStatusCode()) {
50-
$errorMessage = json_decode($response->getContent(false), true)['error']['message'] ?? 'Bad Request';
51-
throw new RateLimitExceededException($errorMessage);
52-
}
53-
54-
if (!isset($data['choices'][0]['message'])) {
55-
throw new RuntimeException('Response does not contain message.');
56-
}
57-
58-
if (!isset($data['choices'][0]['message']['content'])) {
59-
throw new RuntimeException('Message does not contain content.');
60-
}
61-
62-
return new TextResult($data['choices'][0]['message']['content']);
37+
return $this->gptResponseConverter->convert($result, $options);
6338
}
6439
}

0 commit comments

Comments
 (0)