mirror of
https://github.com/symfony/ai-generic-platform.git
synced 2026-03-23 23:42:22 +01:00
[Platform][Generic] Fix FallbackModelCatalog
This commit is contained in:
committed by
Christopher Hertel
parent
f2a6f0bb1d
commit
38fa438be9
46
FallbackModelCatalog.php
Normal file
46
FallbackModelCatalog.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\AI\Platform\Bridge\Generic;
|
||||
|
||||
use Symfony\AI\Platform\Capability;
|
||||
use Symfony\AI\Platform\Model;
|
||||
use Symfony\AI\Platform\ModelCatalog\AbstractModelCatalog;
|
||||
|
||||
/**
|
||||
* A fallback model catalog for the Generic bridge that creates the
|
||||
* appropriate model subclass based on the model name.
|
||||
*
|
||||
* The Generic bridge requires models to be instances of CompletionsModel
|
||||
* or EmbeddingsModel for the corresponding ModelClient to accept them.
|
||||
* This catalog uses a naming convention (model name contains "embed")
|
||||
* to determine the correct type when no explicit catalog is provided.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FallbackModelCatalog extends AbstractModelCatalog
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->models = [];
|
||||
}
|
||||
|
||||
public function getModel(string $modelName): Model
|
||||
{
|
||||
$parsed = self::parseModelName($modelName);
|
||||
|
||||
if (str_contains(strtolower($parsed['name']), 'embed')) {
|
||||
return new EmbeddingsModel($parsed['name'], Capability::cases(), $parsed['options']);
|
||||
}
|
||||
|
||||
return new CompletionsModel($parsed['name'], Capability::cases(), $parsed['options']);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ namespace Symfony\AI\Platform\Bridge\Generic;
|
||||
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\AI\Platform\Contract;
|
||||
use Symfony\AI\Platform\ModelCatalog\FallbackModelCatalog;
|
||||
use Symfony\AI\Platform\ModelCatalog\ModelCatalogInterface;
|
||||
use Symfony\AI\Platform\Platform;
|
||||
use Symfony\Component\HttpClient\EventSourceHttpClient;
|
||||
|
||||
89
Tests/FallbackModelCatalogTest.php
Normal file
89
Tests/FallbackModelCatalogTest.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\AI\Platform\Bridge\Generic\Tests;
|
||||
|
||||
use PHPUnit\Framework\Attributes\TestWith;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
|
||||
use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel;
|
||||
use Symfony\AI\Platform\Bridge\Generic\FallbackModelCatalog;
|
||||
use Symfony\AI\Platform\Capability;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
final class FallbackModelCatalogTest extends TestCase
|
||||
{
|
||||
#[TestWith(['gpt-4o'])]
|
||||
#[TestWith(['claude-3-5-sonnet-20241022'])]
|
||||
#[TestWith(['mistral-large'])]
|
||||
#[TestWith(['deepseek-chat'])]
|
||||
public function testCompletionsModel(string $modelName)
|
||||
{
|
||||
$catalog = new FallbackModelCatalog();
|
||||
$model = $catalog->getModel($modelName);
|
||||
|
||||
$this->assertInstanceOf(CompletionsModel::class, $model);
|
||||
$this->assertSame($modelName, $model->getName());
|
||||
}
|
||||
|
||||
#[TestWith(['text-embedding-3-small'])]
|
||||
#[TestWith(['text-embedding-ada-002'])]
|
||||
#[TestWith(['text-embedding-004'])]
|
||||
#[TestWith(['gemini-embedding-001'])]
|
||||
public function testEmbeddingsModel(string $modelName)
|
||||
{
|
||||
$catalog = new FallbackModelCatalog();
|
||||
$model = $catalog->getModel($modelName);
|
||||
|
||||
$this->assertInstanceOf(EmbeddingsModel::class, $model);
|
||||
$this->assertSame($modelName, $model->getName());
|
||||
}
|
||||
|
||||
public function testAllCapabilitiesArePresent()
|
||||
{
|
||||
$catalog = new FallbackModelCatalog();
|
||||
$model = $catalog->getModel('test-model');
|
||||
|
||||
foreach (Capability::cases() as $capability) {
|
||||
$this->assertTrue($model->supports($capability), \sprintf('Model should have capability %s', $capability->value));
|
||||
}
|
||||
}
|
||||
|
||||
public function testCompletionsModelWithOptions()
|
||||
{
|
||||
$catalog = new FallbackModelCatalog();
|
||||
$model = $catalog->getModel('gpt-4o?temperature=0.7&max_tokens=1000');
|
||||
|
||||
$this->assertInstanceOf(CompletionsModel::class, $model);
|
||||
$this->assertSame('gpt-4o', $model->getName());
|
||||
$this->assertSame(0.7, $model->getOptions()['temperature']);
|
||||
$this->assertSame(1000, $model->getOptions()['max_tokens']);
|
||||
}
|
||||
|
||||
public function testEmbeddingsModelWithOptions()
|
||||
{
|
||||
$catalog = new FallbackModelCatalog();
|
||||
$model = $catalog->getModel('text-embedding-3-small?dimensions=256');
|
||||
|
||||
$this->assertInstanceOf(EmbeddingsModel::class, $model);
|
||||
$this->assertSame('text-embedding-3-small', $model->getName());
|
||||
$this->assertSame(256, $model->getOptions()['dimensions']);
|
||||
}
|
||||
|
||||
public function testGetModelsReturnsEmptyArray()
|
||||
{
|
||||
$catalog = new FallbackModelCatalog();
|
||||
|
||||
$this->assertSame([], $catalog->getModels());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user