diff --git a/src/platform/src/Bridge/Generic/Embeddings/ResultConverter.php b/src/platform/src/Bridge/Generic/Embeddings/ResultConverter.php index d48d8ae0b..26869d0ac 100644 --- a/src/platform/src/Bridge/Generic/Embeddings/ResultConverter.php +++ b/src/platform/src/Bridge/Generic/Embeddings/ResultConverter.php @@ -12,6 +12,9 @@ namespace Symfony\AI\Platform\Bridge\Generic\Embeddings; use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel; +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\Model; use Symfony\AI\Platform\Result\RawResultInterface; @@ -23,6 +26,7 @@ * This default result converter assumes the same response format as OpenAI's embeddings endpoint. * * @author Christopher Hertel + * @author Tim Lochmüller */ class ResultConverter implements ResultConverterInterface { @@ -33,16 +37,32 @@ public function supports(Model $model): bool public function convert(RawResultInterface $result, array $options = []): VectorResult { + $response = $result->getObject(); $data = $result->getData(); - if (!isset($data['data'])) { + 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['data'][0]['embedding'])) { throw new RuntimeException('Response does not contain data.'); } return new VectorResult( ...array_map( static fn (array $item): Vector => new Vector($item['embedding']), - $data['data'] + $data['data'], ), ); } diff --git a/src/platform/src/Bridge/OpenRouter/AbstractOpenRouterModelCatalog.php b/src/platform/src/Bridge/OpenRouter/AbstractOpenRouterModelCatalog.php index 0aacf07d6..4f9b6285b 100644 --- a/src/platform/src/Bridge/OpenRouter/AbstractOpenRouterModelCatalog.php +++ b/src/platform/src/Bridge/OpenRouter/AbstractOpenRouterModelCatalog.php @@ -11,8 +11,8 @@ namespace Symfony\AI\Platform\Bridge\OpenRouter; +use Symfony\AI\Platform\Bridge\Generic\CompletionsModel; use Symfony\AI\Platform\Capability; -use Symfony\AI\Platform\Model; use Symfony\AI\Platform\ModelCatalog\AbstractModelCatalog; /** @@ -35,11 +35,11 @@ public function __construct() { $this->models = [ 'openrouter/auto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => Capability::cases(), ], '@preset' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => Capability::cases(), ], ]; diff --git a/src/platform/src/Bridge/OpenRouter/Completions/ModelClient.php b/src/platform/src/Bridge/OpenRouter/Completions/ModelClient.php deleted file mode 100644 index ed4c19ddd..000000000 --- a/src/platform/src/Bridge/OpenRouter/Completions/ModelClient.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenRouter\Completions; - -use Symfony\AI\Platform\Exception\InvalidArgumentException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\ModelClientInterface; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\Component\HttpClient\EventSourceHttpClient; -use Symfony\Contracts\HttpClient\HttpClientInterface; - -/** - * @author rglozman - */ -final class ModelClient implements ModelClientInterface -{ - private readonly EventSourceHttpClient $httpClient; - - public function __construct( - HttpClientInterface $httpClient, - #[\SensitiveParameter] private readonly string $apiKey, - ) { - $this->httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient); - - if ('' === $apiKey) { - throw new InvalidArgumentException('The API key must not be empty.'); - } - if (!str_starts_with($apiKey, 'sk-')) { - throw new InvalidArgumentException('The API key must start with "sk-".'); - } - } - - public function supports(Model $model): bool - { - return true; - } - - public function request(Model $model, array|string $payload, array $options = []): RawHttpResult - { - return new RawHttpResult($this->httpClient->request('POST', 'https://openrouter.ai/api/v1/chat/completions', [ - 'auth_bearer' => $this->apiKey, - 'json' => array_merge($options, $payload), - ])); - } -} diff --git a/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php b/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php deleted file mode 100644 index 5b0d4d060..000000000 --- a/src/platform/src/Bridge/OpenRouter/Completions/ResultConverter.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenRouter\Completions; - -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\ResultConverterInterface; - -/** - * @author rglozman - */ -final class ResultConverter implements ResultConverterInterface -{ - public function __construct( - private readonly OpenAiResponseConverter $gptResponseConverter = new OpenAiResponseConverter(), - ) { - } - - public function supports(Model $model): bool - { - return true; - } - - public function convert(RawResultInterface $result, array $options = []): ResultInterface - { - return $this->gptResponseConverter->convert($result, $options); - } -} diff --git a/src/platform/src/Bridge/OpenRouter/Embeddings.php b/src/platform/src/Bridge/OpenRouter/Embeddings.php deleted file mode 100644 index dd5c16fd6..000000000 --- a/src/platform/src/Bridge/OpenRouter/Embeddings.php +++ /dev/null @@ -1,18 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenRouter; - -use Symfony\AI\Platform\Model; - -class Embeddings extends Model -{ -} diff --git a/src/platform/src/Bridge/OpenRouter/Embeddings/ModelClient.php b/src/platform/src/Bridge/OpenRouter/Embeddings/ModelClient.php deleted file mode 100644 index 688797d7e..000000000 --- a/src/platform/src/Bridge/OpenRouter/Embeddings/ModelClient.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenRouter\Embeddings; - -use Symfony\AI\Platform\Bridge\OpenRouter\Embeddings; -use Symfony\AI\Platform\Exception\InvalidArgumentException; -use Symfony\AI\Platform\Model; -use Symfony\AI\Platform\ModelClientInterface; -use Symfony\AI\Platform\Result\RawHttpResult; -use Symfony\Contracts\HttpClient\HttpClientInterface; - -/** - * @author Tim Lochmüller - */ -final class ModelClient implements ModelClientInterface -{ - public function __construct( - private readonly HttpClientInterface $httpClient, - #[\SensitiveParameter] private readonly string $apiKey, - ) { - if ('' === $apiKey) { - throw new InvalidArgumentException('The API key must not be empty.'); - } - if (!str_starts_with($apiKey, 'sk-')) { - throw new InvalidArgumentException('The API key must start with "sk-".'); - } - } - - public function supports(Model $model): bool - { - return $model instanceof Embeddings; - } - - public function request(Model $model, array|string $payload, array $options = []): RawHttpResult - { - return new RawHttpResult($this->httpClient->request('POST', 'https://openrouter.ai/api/v1/embeddings', [ - 'auth_bearer' => $this->apiKey, - 'json' => [ - 'model' => $model->getName(), - 'input' => $payload, - ], - ])); - } -} diff --git a/src/platform/src/Bridge/OpenRouter/Embeddings/ResultConverter.php b/src/platform/src/Bridge/OpenRouter/Embeddings/ResultConverter.php deleted file mode 100644 index 27e1b0d64..000000000 --- a/src/platform/src/Bridge/OpenRouter/Embeddings/ResultConverter.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Platform\Bridge\OpenRouter\Embeddings; - -use Symfony\AI\Platform\Bridge\OpenRouter\Embeddings; -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\Model; -use Symfony\AI\Platform\Result\RawResultInterface; -use Symfony\AI\Platform\Result\VectorResult; -use Symfony\AI\Platform\ResultConverterInterface; -use Symfony\AI\Platform\Vector\Vector; - -/** - * @author Tim Lochmüller - */ -final class ResultConverter implements ResultConverterInterface -{ - public function supports(Model $model): bool - { - return $model instanceof Embeddings; - } - - public function convert(RawResultInterface $result, array $options = []): VectorResult - { - $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['data'][0]['embedding'])) { - throw new RuntimeException('Response does not contain data.'); - } - - return new VectorResult( - ...array_map( - static fn (array $item): Vector => new Vector($item['embedding']), - $data['data'], - ), - ); - } -} diff --git a/src/platform/src/Bridge/OpenRouter/ModelApiCatalog.php b/src/platform/src/Bridge/OpenRouter/ModelApiCatalog.php index 36bda17e1..4802ba630 100644 --- a/src/platform/src/Bridge/OpenRouter/ModelApiCatalog.php +++ b/src/platform/src/Bridge/OpenRouter/ModelApiCatalog.php @@ -11,6 +11,8 @@ namespace Symfony\AI\Platform\Bridge\OpenRouter; +use Symfony\AI\Platform\Bridge\Generic\CompletionsModel; +use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel; use Symfony\AI\Platform\Capability; use Symfony\AI\Platform\Exception\InvalidArgumentException; use Symfony\AI\Platform\Model; @@ -100,21 +102,21 @@ protected function fetchRemoteModels(): iterable } yield $model['id'] => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => $capabilities, ]; } } /** - * @return iterable, capabilities: list}> + * @return iterable, capabilities: list}> */ protected function fetchRemoteEmbeddings(): iterable { $responseEmbeddings = $this->httpClient->request('GET', 'https://openrouter.ai/api/v1/embeddings/models'); foreach ($responseEmbeddings->toArray()['data'] as $embedding) { yield $embedding['id'] => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [Capability::INPUT_TEXT, Capability::EMBEDDINGS], ]; } diff --git a/src/platform/src/Bridge/OpenRouter/ModelCatalog.php b/src/platform/src/Bridge/OpenRouter/ModelCatalog.php index 54bda0b5c..dccf514a2 100644 --- a/src/platform/src/Bridge/OpenRouter/ModelCatalog.php +++ b/src/platform/src/Bridge/OpenRouter/ModelCatalog.php @@ -11,6 +11,8 @@ namespace Symfony\AI\Platform\Bridge\OpenRouter; +use Symfony\AI\Platform\Bridge\Generic\CompletionsModel; +use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel; use Symfony\AI\Platform\Capability; use Symfony\AI\Platform\Exception\InvalidArgumentException; use Symfony\AI\Platform\Model; @@ -35,7 +37,7 @@ public function __construct( $defaultModels = [ // Models 'x-ai/grok-4.1-fast' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -43,7 +45,7 @@ public function __construct( ], ], 'google/gemini-3-pro-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -54,14 +56,14 @@ public function __construct( ], ], 'deepcogito/cogito-v2.1-671b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-5.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -70,7 +72,7 @@ public function __construct( ], ], 'openai/gpt-5.1-chat' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_PDF, Capability::INPUT_IMAGE, @@ -79,7 +81,7 @@ public function __construct( ], ], 'openai/gpt-5.1-codex' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -87,7 +89,7 @@ public function __construct( ], ], 'openai/gpt-5.1-codex-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -95,28 +97,28 @@ public function __construct( ], ], 'kwaipilot/kat-coder-pro:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'moonshotai/kimi-linear-48b-a3b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'moonshotai/kimi-k2-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'amazon/nova-premier-v1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -124,7 +126,7 @@ public function __construct( ], ], 'perplexity/sonar-pro-search' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -132,7 +134,7 @@ public function __construct( ], ], 'mistralai/voxtral-small-24b-2507' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_AUDIO, @@ -140,14 +142,14 @@ public function __construct( ], ], 'openai/gpt-oss-safeguard-20b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nvidia/nemotron-nano-12b-v2-vl:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -156,7 +158,7 @@ public function __construct( ], ], 'nvidia/nemotron-nano-12b-v2-vl' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -165,42 +167,42 @@ public function __construct( ], ], 'minimax/minimax-m2' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'liquid/lfm2-8b-a1b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'liquid/lfm-2.2-6b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'ibm-granite/granite-4.0-h-micro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepcogito/cogito-v2-preview-llama-405b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-5-image-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_PDF, Capability::INPUT_IMAGE, @@ -210,7 +212,7 @@ public function __construct( ], ], 'anthropic/claude-haiku-4.5' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -218,7 +220,7 @@ public function __construct( ], ], 'qwen/qwen3-vl-8b-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -226,7 +228,7 @@ public function __construct( ], ], 'qwen/qwen3-vl-8b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -234,7 +236,7 @@ public function __construct( ], ], 'openai/gpt-5-image' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -244,7 +246,7 @@ public function __construct( ], ], 'openai/o3-deep-research' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -253,7 +255,7 @@ public function __construct( ], ], 'openai/o4-mini-deep-research' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_PDF, Capability::INPUT_IMAGE, @@ -262,21 +264,21 @@ public function __construct( ], ], 'nvidia/llama-3.3-nemotron-super-49b-v1.5' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'baidu/ernie-4.5-21b-a3b-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.5-flash-image' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -285,7 +287,7 @@ public function __construct( ], ], 'qwen/qwen3-vl-30b-a3b-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -293,7 +295,7 @@ public function __construct( ], ], 'qwen/qwen3-vl-30b-a3b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -301,7 +303,7 @@ public function __construct( ], ], 'openai/gpt-5-pro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -310,21 +312,21 @@ public function __construct( ], ], 'z-ai/glm-4.6' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'z-ai/glm-4.6:exacto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'anthropic/claude-sonnet-4.5' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -333,28 +335,28 @@ public function __construct( ], ], 'deepseek/deepseek-v3.2-exp' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'thedrummer/cydonia-24b-v4.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'relace/relace-apply-3' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.5-flash-preview-09-2025' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_PDF, @@ -365,7 +367,7 @@ public function __construct( ], ], 'google/gemini-2.5-flash-lite-preview-09-2025' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -376,7 +378,7 @@ public function __construct( ], ], 'qwen/qwen3-vl-235b-a22b-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -384,7 +386,7 @@ public function __construct( ], ], 'qwen/qwen3-vl-235b-a22b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -392,21 +394,21 @@ public function __construct( ], ], 'qwen/qwen3-max' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-coder-plus' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-5-codex' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -414,21 +416,21 @@ public function __construct( ], ], 'deepseek/deepseek-v3.1-terminus' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-v3.1-terminus:exacto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'x-ai/grok-4-fast' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -436,35 +438,35 @@ public function __construct( ], ], 'alibaba/tongyi-deepresearch-30b-a3b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'alibaba/tongyi-deepresearch-30b-a3b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-coder-flash' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'arcee-ai/afm-4.5b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'opengvlab/internvl3-78b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -472,84 +474,84 @@ public function __construct( ], ], 'qwen/qwen3-next-80b-a3b-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-next-80b-a3b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meituan/longcat-flash-chat:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meituan/longcat-flash-chat' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-plus-2025-07-28' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-plus-2025-07-28:thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nvidia/nemotron-nano-9b-v2:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nvidia/nemotron-nano-9b-v2' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'moonshotai/kimi-k2-0905' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'moonshotai/kimi-k2-0905:exacto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepcogito/cogito-v2-preview-llama-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepcogito/cogito-v2-preview-llama-109b-moe' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -557,14 +559,14 @@ public function __construct( ], ], 'deepcogito/cogito-v2-preview-deepseek-671b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'stepfun-ai/step3' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -572,35 +574,35 @@ public function __construct( ], ], 'qwen/qwen3-30b-a3b-thinking-2507' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'x-ai/grok-code-fast-1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nousresearch/hermes-4-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nousresearch/hermes-4-405b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.5-flash-image-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -609,14 +611,14 @@ public function __construct( ], ], 'deepseek/deepseek-chat-v3.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4o-audio-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_AUDIO, Capability::INPUT_TEXT, @@ -624,7 +626,7 @@ public function __construct( ], ], 'mistralai/mistral-medium-3.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -632,14 +634,14 @@ public function __construct( ], ], 'baidu/ernie-4.5-21b-a3b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'baidu/ernie-4.5-vl-28b-a3b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -647,7 +649,7 @@ public function __construct( ], ], 'z-ai/glm-4.5v' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -655,21 +657,21 @@ public function __construct( ], ], 'ai21/jamba-mini-1.7' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'ai21/jamba-large-1.7' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-5-chat' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_PDF, Capability::INPUT_IMAGE, @@ -678,7 +680,7 @@ public function __construct( ], ], 'openai/gpt-5' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -687,7 +689,7 @@ public function __construct( ], ], 'openai/gpt-5-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -696,7 +698,7 @@ public function __construct( ], ], 'openai/gpt-5-nano' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -705,35 +707,35 @@ public function __construct( ], ], 'openai/gpt-oss-120b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-oss-120b:exacto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-oss-20b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-oss-20b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'anthropic/claude-opus-4.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -742,84 +744,84 @@ public function __construct( ], ], 'mistralai/codestral-2508' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-coder-30b-a3b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-30b-a3b-instruct-2507' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'z-ai/glm-4.5' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'z-ai/glm-4.5-air:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'z-ai/glm-4.5-air' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-235b-a22b-thinking-2507' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'z-ai/glm-4-32b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-coder:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-coder' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-coder:exacto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'bytedance/ui-tars-1.5-7b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -827,7 +829,7 @@ public function __construct( ], ], 'google/gemini-2.5-flash-lite' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -838,35 +840,35 @@ public function __construct( ], ], 'qwen/qwen3-235b-a22b-2507' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'switchpoint/router' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'moonshotai/kimi-k2:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'moonshotai/kimi-k2' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'thudm/glm-4.1v-9b-thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -874,28 +876,28 @@ public function __construct( ], ], 'mistralai/devstral-medium' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/devstral-small' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'cognitivecomputations/dolphin-mistral-24b-venice-edition:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'x-ai/grok-4' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -903,49 +905,49 @@ public function __construct( ], ], 'google/gemma-3n-e2b-it:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'tencent/hunyuan-a13b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'tngtech/deepseek-r1t2-chimera:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'tngtech/deepseek-r1t2-chimera' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'morph/morph-v3-large' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'morph/morph-v3-fast' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'baidu/ernie-4.5-vl-424b-a47b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -953,28 +955,28 @@ public function __construct( ], ], 'baidu/ernie-4.5-300b-a47b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'thedrummer/anubis-70b-v1.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'inception/mercury' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-small-3.2-24b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -982,7 +984,7 @@ public function __construct( ], ], 'mistralai/mistral-small-3.2-24b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -990,14 +992,14 @@ public function __construct( ], ], 'minimax/minimax-m1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.5-flash' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_PDF, Capability::INPUT_IMAGE, @@ -1008,7 +1010,7 @@ public function __construct( ], ], 'google/gemini-2.5-pro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1019,14 +1021,14 @@ public function __construct( ], ], 'moonshotai/kimi-dev-72b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/o3-pro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_PDF, @@ -1035,42 +1037,42 @@ public function __construct( ], ], 'x-ai/grok-3-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'x-ai/grok-3' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/magistral-small-2506' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/magistral-medium-2506:thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/magistral-medium-2506' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.5-pro-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_PDF, Capability::INPUT_IMAGE, @@ -1080,35 +1082,35 @@ public function __construct( ], ], 'deepseek/deepseek-r1-0528-qwen3-8b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1-0528-qwen3-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1-0528:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1-0528' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'anthropic/claude-opus-4' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1117,7 +1119,7 @@ public function __construct( ], ], 'anthropic/claude-sonnet-4' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1126,28 +1128,28 @@ public function __construct( ], ], 'mistralai/devstral-small-2505' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemma-3n-e4b-it:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemma-3n-e4b-it' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/codex-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1155,14 +1157,14 @@ public function __construct( ], ], 'nousresearch/deephermes-3-mistral-24b-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-medium-3' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1170,7 +1172,7 @@ public function __construct( ], ], 'google/gemini-2.5-pro-preview-05-06' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1181,7 +1183,7 @@ public function __construct( ], ], 'arcee-ai/spotlight' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1189,56 +1191,56 @@ public function __construct( ], ], 'arcee-ai/maestro-reasoning' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'arcee-ai/virtuoso-large' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'arcee-ai/coder-large' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/phi-4-reasoning-plus' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'inception/mercury-coder' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-4b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-prover-v2' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-guard-4-12b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1246,91 +1248,91 @@ public function __construct( ], ], 'qwen/qwen3-30b-a3b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-30b-a3b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-14b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-14b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-32b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-235b-a22b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen3-235b-a22b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'tngtech/deepseek-r1t-chimera:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'tngtech/deepseek-r1t-chimera' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/mai-ds-r1:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/mai-ds-r1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/o4-mini-high' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1339,7 +1341,7 @@ public function __construct( ], ], 'openai/o3' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1348,7 +1350,7 @@ public function __construct( ], ], 'openai/o4-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1357,14 +1359,14 @@ public function __construct( ], ], 'qwen/qwen2.5-coder-7b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1373,7 +1375,7 @@ public function __construct( ], ], 'openai/gpt-4.1-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1382,7 +1384,7 @@ public function __construct( ], ], 'openai/gpt-4.1-nano' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_IMAGE, Capability::INPUT_TEXT, @@ -1391,56 +1393,56 @@ public function __construct( ], ], 'eleutherai/llemma_7b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'alfredpros/codellama-7b-instruct-solidity' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'arliai/qwq-32b-arliai-rpr-v1:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'arliai/qwq-32b-arliai-rpr-v1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'x-ai/grok-3-mini-beta' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'x-ai/grok-3-beta' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nvidia/llama-3.1-nemotron-ultra-253b-v1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-4-maverick' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1448,7 +1450,7 @@ public function __construct( ], ], 'meta-llama/llama-4-scout' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1456,7 +1458,7 @@ public function __construct( ], ], 'qwen/qwen2.5-vl-32b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1464,7 +1466,7 @@ public function __construct( ], ], 'qwen/qwen2.5-vl-32b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1472,21 +1474,21 @@ public function __construct( ], ], 'deepseek/deepseek-chat-v3-0324:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-chat-v3-0324' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/o1-pro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1495,7 +1497,7 @@ public function __construct( ], ], 'mistralai/mistral-small-3.1-24b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1503,7 +1505,7 @@ public function __construct( ], ], 'mistralai/mistral-small-3.1-24b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1511,14 +1513,14 @@ public function __construct( ], ], 'allenai/olmo-2-0325-32b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemma-3-4b-it:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1526,7 +1528,7 @@ public function __construct( ], ], 'google/gemma-3-4b-it' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1534,7 +1536,7 @@ public function __construct( ], ], 'google/gemma-3-12b-it:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1542,7 +1544,7 @@ public function __construct( ], ], 'google/gemma-3-12b-it' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1550,28 +1552,28 @@ public function __construct( ], ], 'cohere/command-a' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4o-mini-search-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4o-search-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemma-3-27b-it:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1579,7 +1581,7 @@ public function __construct( ], ], 'google/gemma-3-27b-it' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1587,14 +1589,14 @@ public function __construct( ], ], 'thedrummer/skyfall-36b-v2' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/phi-4-multimodal-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1602,7 +1604,7 @@ public function __construct( ], ], 'perplexity/sonar-reasoning-pro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1610,7 +1612,7 @@ public function __construct( ], ], 'perplexity/sonar-pro' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1618,21 +1620,21 @@ public function __construct( ], ], 'perplexity/sonar-deep-research' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwq-32b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.0-flash-lite-001' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1643,7 +1645,7 @@ public function __construct( ], ], 'anthropic/claude-3.7-sonnet:thinking' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1652,7 +1654,7 @@ public function __construct( ], ], 'anthropic/claude-3.7-sonnet' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1661,21 +1663,21 @@ public function __construct( ], ], 'mistralai/mistral-saba' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-guard-3-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/o3-mini-high' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_PDF, @@ -1683,7 +1685,7 @@ public function __construct( ], ], 'google/gemini-2.0-flash-001' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1694,7 +1696,7 @@ public function __construct( ], ], 'qwen/qwen-vl-plus' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1702,28 +1704,28 @@ public function __construct( ], ], 'aion-labs/aion-1.0' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'aion-labs/aion-1.0-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'aion-labs/aion-rp-llama-3.1-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-vl-max' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1731,14 +1733,14 @@ public function __construct( ], ], 'qwen/qwen-turbo' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen2.5-vl-72b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1746,21 +1748,21 @@ public function __construct( ], ], 'qwen/qwen-plus' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-max' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/o3-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_PDF, @@ -1768,42 +1770,42 @@ public function __construct( ], ], 'mistralai/mistral-small-24b-instruct-2501:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-small-24b-instruct-2501' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1-distill-qwen-32b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1-distill-qwen-14b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'perplexity/sonar-reasoning' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'perplexity/sonar' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1811,35 +1813,35 @@ public function __construct( ], ], 'deepseek/deepseek-r1-distill-llama-70b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1-distill-llama-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-r1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'minimax/minimax-01' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1847,42 +1849,42 @@ public function __construct( ], ], 'mistralai/codestral-2501' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/phi-4' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'sao10k/l3.1-70b-hanami-x1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'deepseek/deepseek-chat' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'sao10k/l3.3-euryale-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/o1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1891,14 +1893,14 @@ public function __construct( ], ], 'cohere/command-r7b-12-2024' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemini-2.0-flash-exp:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1906,21 +1908,21 @@ public function __construct( ], ], 'meta-llama/llama-3.3-70b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.3-70b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'amazon/nova-lite-v1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1928,14 +1930,14 @@ public function __construct( ], ], 'amazon/nova-micro-v1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'amazon/nova-pro-v1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1943,7 +1945,7 @@ public function __construct( ], ], 'openai/gpt-4o-2024-11-20' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1952,21 +1954,21 @@ public function __construct( ], ], 'mistralai/mistral-large-2411' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-large-2407' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/pixtral-large-2411' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -1974,35 +1976,35 @@ public function __construct( ], ], 'qwen/qwen-2.5-coder-32b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-2.5-coder-32b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'raifle/sorcererlm-8x22b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'thedrummer/unslopnemo-12b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'anthropic/claude-3.5-haiku-20241022' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2011,7 +2013,7 @@ public function __construct( ], ], 'anthropic/claude-3.5-haiku' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2019,14 +2021,14 @@ public function __construct( ], ], 'anthracite-org/magnum-v4-72b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'anthropic/claude-3.5-sonnet' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2035,70 +2037,70 @@ public function __construct( ], ], 'mistralai/ministral-3b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/ministral-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-2.5-7b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nvidia/llama-3.1-nemotron-70b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'inflection/inflection-3-pi' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'inflection/inflection-3-productivity' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'thedrummer/rocinante-12b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.2-3b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.2-3b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.2-90b-vision-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2106,14 +2108,14 @@ public function __construct( ], ], 'meta-llama/llama-3.2-1b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.2-11b-vision-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2121,28 +2123,28 @@ public function __construct( ], ], 'qwen/qwen-2.5-72b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-2.5-72b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'neversleep/llama-3.1-lumimaid-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/pixtral-12b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2150,21 +2152,21 @@ public function __construct( ], ], 'cohere/command-r-08-2024' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'cohere/command-r-plus-08-2024' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'qwen/qwen-2.5-vl-7b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2172,42 +2174,42 @@ public function __construct( ], ], 'sao10k/l3.1-euryale-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/phi-3.5-mini-128k-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nousresearch/hermes-3-llama-3.1-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nousresearch/hermes-3-llama-3.1-405b:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nousresearch/hermes-3-llama-3.1-405b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/chatgpt-4o-latest' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2215,14 +2217,14 @@ public function __construct( ], ], 'sao10k/l3-lunaris-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4o-2024-08-06' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2231,49 +2233,49 @@ public function __construct( ], ], 'meta-llama/llama-3.1-405b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.1-70b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.1-405b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3.1-8b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-nemo:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-nemo' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4o-mini' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2282,7 +2284,7 @@ public function __construct( ], ], 'openai/gpt-4o-mini-2024-07-18' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2291,70 +2293,70 @@ public function __construct( ], ], 'google/gemma-2-27b-it' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'google/gemma-2-9b-it' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'sao10k/l3-euryale-70b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-7b-instruct-v0.3' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'nousresearch/hermes-2-pro-llama-3-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-7b-instruct:free' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-7b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/phi-3-mini-128k-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/phi-3-medium-128k-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4o' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2363,7 +2365,7 @@ public function __construct( ], ], 'openai/gpt-4o:extended' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2372,7 +2374,7 @@ public function __construct( ], ], 'openai/gpt-4o-2024-05-13' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2381,42 +2383,42 @@ public function __construct( ], ], 'meta-llama/llama-guard-2-8b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3-70b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'meta-llama/llama-3-8b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mixtral-8x22b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'microsoft/wizardlm-2-8x22b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4-turbo' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2424,7 +2426,7 @@ public function __construct( ], ], 'anthropic/claude-3-haiku' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2432,7 +2434,7 @@ public function __construct( ], ], 'anthropic/claude-3-opus' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::INPUT_IMAGE, @@ -2440,140 +2442,140 @@ public function __construct( ], ], 'mistralai/mistral-large' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4-turbo-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-3.5-turbo-0613' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-small' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-tiny' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-7b-instruct-v0.2' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mixtral-8x7b-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'neversleep/noromaid-20b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'alpindale/goliath-120b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openrouter/auto' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4-1106-preview' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-3.5-turbo-instruct' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mistralai/mistral-7b-instruct-v0.1' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-3.5-turbo-16k' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'mancer/weaver' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'undi95/remm-slerp-l2-13b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'gryphe/mythomax-l2-13b' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4-0314' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-3.5-turbo' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, ], ], 'openai/gpt-4' => [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::OUTPUT_TEXT, @@ -2582,147 +2584,147 @@ public function __construct( // Embeddings 'thenlper/gte-base' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'thenlper/gte-large' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'intfloat/e5-large-v2' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'intfloat/e5-base-v2' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'intfloat/multilingual-e5-large' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'sentence-transformers/paraphrase-minilm-l6-v2' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'sentence-transformers/all-minilm-l12-v2' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'baai/bge-base-en-v1.5' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'sentence-transformers/multi-qa-mpnet-base-dot-v1' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'baai/bge-large-en-v1.5' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'baai/bge-m3' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'sentence-transformers/all-mpnet-base-v2' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'sentence-transformers/all-minilm-l6-v2' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'mistralai/mistral-embed-2312' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'google/gemini-embedding-001' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'openai/text-embedding-ada-002' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'mistralai/codestral-embed-2505' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'openai/text-embedding-3-large' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'openai/text-embedding-3-small' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'qwen/qwen3-embedding-8b' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, ], ], 'qwen/qwen3-embedding-4b' => [ - 'class' => Embeddings::class, + 'class' => EmbeddingsModel::class, 'capabilities' => [ Capability::INPUT_TEXT, Capability::EMBEDDINGS, @@ -2751,7 +2753,7 @@ public function getModel(string $modelName): Model if (!isset($this->models[$catalogKey])) { // Add model to the list as default model $this->models[$catalogKey] = [ - 'class' => Model::class, + 'class' => CompletionsModel::class, 'capabilities' => [], ]; } @@ -2765,7 +2767,7 @@ public function getModel(string $modelName): Model $model = new $modelClass($actualModelName, $modelConfig['capabilities'], $options); if (!$model instanceof Model) { - throw new InvalidArgumentException(\sprintf('Model class "%s" must extend "%s".', $modelClass, Model::class)); + throw new InvalidArgumentException(\sprintf('Model class "%s" must extend "%s".', $modelClass, CompletionsModel::class)); } return $model; diff --git a/src/platform/src/Bridge/OpenRouter/PlatformFactory.php b/src/platform/src/Bridge/OpenRouter/PlatformFactory.php index 9261a7cce..e700e7bd7 100644 --- a/src/platform/src/Bridge/OpenRouter/PlatformFactory.php +++ b/src/platform/src/Bridge/OpenRouter/PlatformFactory.php @@ -12,13 +12,8 @@ namespace Symfony\AI\Platform\Bridge\OpenRouter; use Psr\EventDispatcher\EventDispatcherInterface; -use Symfony\AI\Platform\Bridge\Gemini\Contract\AssistantMessageNormalizer; -use Symfony\AI\Platform\Bridge\Gemini\Contract\MessageBagNormalizer; -use Symfony\AI\Platform\Bridge\Gemini\Contract\UserMessageNormalizer; -use Symfony\AI\Platform\Bridge\OpenRouter\Completions\ModelClient as CompletionsModelClient; -use Symfony\AI\Platform\Bridge\OpenRouter\Completions\ResultConverter as CompletionsResultConverter; -use Symfony\AI\Platform\Bridge\OpenRouter\Embeddings\ModelClient as EmbeddingsModelClient; -use Symfony\AI\Platform\Bridge\OpenRouter\Embeddings\ResultConverter as EmbeddingsResultConverter; +use Symfony\AI\Platform\Bridge\Generic\Completions; +use Symfony\AI\Platform\Bridge\Generic\Embeddings; use Symfony\AI\Platform\Contract; use Symfony\AI\Platform\ModelCatalog\ModelCatalogInterface; use Symfony\AI\Platform\Platform; @@ -40,14 +35,13 @@ public static function create( $httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient); return new Platform( - [new EmbeddingsModelClient($httpClient, $apiKey), new CompletionsModelClient($httpClient, $apiKey)], - [new EmbeddingsResultConverter(), new CompletionsResultConverter()], + [ + new Embeddings\ModelClient($httpClient, 'https://openrouter.ai', $apiKey, '/api/v1/embeddings'), + new Completions\ModelClient($httpClient, 'https://openrouter.ai', $apiKey, '/api/v1/chat/completions'), + ], + [new Embeddings\ResultConverter(), new Completions\ResultConverter()], $modelCatalog, - $contract ?? Contract::create( - new AssistantMessageNormalizer(), - new MessageBagNormalizer(), - new UserMessageNormalizer(), - ), + $contract ?? Contract::create(), $eventDispatcher, ); }