Skip to content

Commit a7a21be

Browse files
committed
feature #1058 [Platform][OpenRouter] Decouple OpenRouter bridge from OpenAI in favor of Generic bridge (chr-hertel)
This PR was merged into the main branch. Discussion ---------- [Platform][OpenRouter] Decouple OpenRouter bridge from OpenAI in favor of Generic bridge | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | Docs? | no | Issues | | License | MIT Follows #1052, cc `@lochmueller` - all tests and example are working, not sure tho about your use cases Commits ------- b906107 Decouple OpenRouter bridge from OpenAI in favor of Generic bridge
2 parents 8014018 + b906107 commit a7a21be

File tree

10 files changed

+400
-612
lines changed

10 files changed

+400
-612
lines changed

src/platform/src/Bridge/Generic/Embeddings/ResultConverter.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
namespace Symfony\AI\Platform\Bridge\Generic\Embeddings;
1313

1414
use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel;
15+
use Symfony\AI\Platform\Exception\AuthenticationException;
16+
use Symfony\AI\Platform\Exception\BadRequestException;
17+
use Symfony\AI\Platform\Exception\RateLimitExceededException;
1518
use Symfony\AI\Platform\Exception\RuntimeException;
1619
use Symfony\AI\Platform\Model;
1720
use Symfony\AI\Platform\Result\RawResultInterface;
@@ -23,6 +26,7 @@
2326
* This default result converter assumes the same response format as OpenAI's embeddings endpoint.
2427
*
2528
* @author Christopher Hertel <mail@christopher-hertel.de>
29+
* @author Tim Lochmüller <tim@fruit-lab.de>
2630
*/
2731
class ResultConverter implements ResultConverterInterface
2832
{
@@ -33,16 +37,32 @@ public function supports(Model $model): bool
3337

3438
public function convert(RawResultInterface $result, array $options = []): VectorResult
3539
{
40+
$response = $result->getObject();
3641
$data = $result->getData();
3742

38-
if (!isset($data['data'])) {
43+
if (401 === $response->getStatusCode()) {
44+
$errorMessage = json_decode($response->getContent(false), true)['error']['message'];
45+
throw new AuthenticationException($errorMessage);
46+
}
47+
48+
if (400 === $response->getStatusCode() || 404 === $response->getStatusCode()) {
49+
$errorMessage = json_decode($response->getContent(false), true)['error']['message'] ?? 'Bad Request';
50+
throw new BadRequestException($errorMessage);
51+
}
52+
53+
if (429 === $response->getStatusCode()) {
54+
$errorMessage = json_decode($response->getContent(false), true)['error']['message'] ?? 'Bad Request';
55+
throw new RateLimitExceededException($errorMessage);
56+
}
57+
58+
if (!isset($data['data'][0]['embedding'])) {
3959
throw new RuntimeException('Response does not contain data.');
4060
}
4161

4262
return new VectorResult(
4363
...array_map(
4464
static fn (array $item): Vector => new Vector($item['embedding']),
45-
$data['data']
65+
$data['data'],
4666
),
4767
);
4868
}

src/platform/src/Bridge/OpenRouter/AbstractOpenRouterModelCatalog.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

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

14+
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
1415
use Symfony\AI\Platform\Capability;
15-
use Symfony\AI\Platform\Model;
1616
use Symfony\AI\Platform\ModelCatalog\AbstractModelCatalog;
1717

1818
/**
@@ -35,11 +35,11 @@ public function __construct()
3535
{
3636
$this->models = [
3737
'openrouter/auto' => [
38-
'class' => Model::class,
38+
'class' => CompletionsModel::class,
3939
'capabilities' => Capability::cases(),
4040
],
4141
'@preset' => [
42-
'class' => Model::class,
42+
'class' => CompletionsModel::class,
4343
'capabilities' => Capability::cases(),
4444
],
4545
];

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

Lines changed: 0 additions & 54 deletions
This file was deleted.

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

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/platform/src/Bridge/OpenRouter/Embeddings.php

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/platform/src/Bridge/OpenRouter/Embeddings/ModelClient.php

Lines changed: 0 additions & 53 deletions
This file was deleted.

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

Lines changed: 0 additions & 66 deletions
This file was deleted.

src/platform/src/Bridge/OpenRouter/ModelApiCatalog.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

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

14+
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
15+
use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel;
1416
use Symfony\AI\Platform\Capability;
1517
use Symfony\AI\Platform\Exception\InvalidArgumentException;
1618
use Symfony\AI\Platform\Model;
@@ -100,21 +102,21 @@ protected function fetchRemoteModels(): iterable
100102
}
101103

102104
yield $model['id'] => [
103-
'class' => Model::class,
105+
'class' => CompletionsModel::class,
104106
'capabilities' => $capabilities,
105107
];
106108
}
107109
}
108110

109111
/**
110-
* @return iterable<string, array{class: class-string<Embeddings>, capabilities: list<Capability::*>}>
112+
* @return iterable<string, array{class: class-string<EmbeddingsModel>, capabilities: list<Capability::*>}>
111113
*/
112114
protected function fetchRemoteEmbeddings(): iterable
113115
{
114116
$responseEmbeddings = $this->httpClient->request('GET', 'https://openrouter.ai/api/v1/embeddings/models');
115117
foreach ($responseEmbeddings->toArray()['data'] as $embedding) {
116118
yield $embedding['id'] => [
117-
'class' => Embeddings::class,
119+
'class' => EmbeddingsModel::class,
118120
'capabilities' => [Capability::INPUT_TEXT, Capability::EMBEDDINGS],
119121
];
120122
}

0 commit comments

Comments
 (0)