diff --git a/examples/openrouter/stream.php b/examples/openrouter/stream.php new file mode 100644 index 000000000..4077432a5 --- /dev/null +++ b/examples/openrouter/stream.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\AI\Platform\Bridge\OpenRouter\PlatformFactory; +use Symfony\AI\Platform\Message\Message; +use Symfony\AI\Platform\Message\MessageBag; + +require_once dirname(__DIR__).'/bootstrap.php'; + +$platform = PlatformFactory::create(env('OPENROUTER_KEY'), http_client()); + +$messages = new MessageBag(Message::ofUser('List the first 50 prime number?')); +$result = $platform->invoke('google/gemini-2.5-flash-lite', $messages, [ + 'stream' => true, +]); + +print_stream($result); diff --git a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php index 675468aad..29765a4a4 100644 --- a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php +++ b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php @@ -73,7 +73,7 @@ public function convert(RawResultInterface|RawHttpResult $result, array $options } if (isset($data['error'])) { - throw new RuntimeException(\sprintf('Error "%s"-%s (%s): "%s".', $data['error']['code'], $data['error']['type'], $data['error']['param'], $data['error']['message'])); + throw new RuntimeException(\sprintf('Error "%s"-%s (%s): "%s".', $data['error']['code'] ?? '-', $data['error']['type'] ?? '-', $data['error']['param'] ?? '-', $data['error']['message'] ?? '-')); } if (!isset($data['choices'])) { diff --git a/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php b/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php index c2dcfe52d..5b0d4d060 100644 --- a/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php +++ b/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php @@ -11,14 +11,10 @@ namespace Symfony\AI\Platform\Bridge\OpenRouter\Completions; -use Symfony\AI\Platform\Exception\AuthenticationException; -use Symfony\AI\Platform\Exception\BadRequestException; -use Symfony\AI\Platform\Exception\RateLimitExceededException; -use Symfony\AI\Platform\Exception\RuntimeException; +use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter as OpenAiResponseConverter; use Symfony\AI\Platform\Model; use Symfony\AI\Platform\Result\RawResultInterface; use Symfony\AI\Platform\Result\ResultInterface; -use Symfony\AI\Platform\Result\TextResult; use Symfony\AI\Platform\ResultConverterInterface; /** @@ -26,6 +22,11 @@ */ final class ResultConverter implements ResultConverterInterface { + public function __construct( + private readonly OpenAiResponseConverter $gptResponseConverter = new OpenAiResponseConverter(), + ) { + } + public function supports(Model $model): bool { return true; @@ -33,32 +34,6 @@ public function supports(Model $model): bool public function convert(RawResultInterface $result, array $options = []): ResultInterface { - $response = $result->getObject(); - $data = $result->getData(); - - if (401 === $response->getStatusCode()) { - $errorMessage = json_decode($response->getContent(false), true)['error']['message']; - throw new AuthenticationException($errorMessage); - } - - if (400 === $response->getStatusCode() || 404 === $response->getStatusCode()) { - $errorMessage = json_decode($response->getContent(false), true)['error']['message'] ?? 'Bad Request'; - throw new BadRequestException($errorMessage); - } - - if (429 === $response->getStatusCode()) { - $errorMessage = json_decode($response->getContent(false), true)['error']['message'] ?? 'Bad Request'; - throw new RateLimitExceededException($errorMessage); - } - - if (!isset($data['choices'][0]['message'])) { - throw new RuntimeException('Response does not contain message.'); - } - - if (!isset($data['choices'][0]['message']['content'])) { - throw new RuntimeException('Message does not contain content.'); - } - - return new TextResult($data['choices'][0]['message']['content']); + return $this->gptResponseConverter->convert($result, $options); } }