Skip to content

Commit d8519d2

Browse files
committed
bug #88 [AiBundle] Use model FQCN for indexer config, to allow any Symfony\AI\Platform\Model child class (welcoMattic)
This PR was merged into the main branch. Discussion ---------- [AiBundle] Use model FQCN for indexer config, to allow any `Symfony\AI\Platform\Model` child class | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Docs? | no <!-- required for new features --> | Issues | Fix #59 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT Before: ```yaml ai: indexer: default: platform: 'symfony_ai.platform.mistral' model: name: 'Embeddings' version: 'mistral-embed' ``` After ```yaml ai: indexer: default: platform: 'symfony_ai.platform.mistral' model: class: 'Symfony\AI\Platform\Bridge\Mistral\Embeddings' name: !php/const Symfony\AI\Platform\Bridge\Mistral\Embeddings::MISTRAL_EMBED ``` This way, any class extending `Symfony\AI\Platform\Model` can be used as embedder model, even one written by users themselves. Embeddings model of providers (OpenAI, Mistral, Gemini, ...) can be named `Embeddings` with no issue. --- Replace php-llm/llm-chain-bundle#99 Commits ------- 66b6cbc Use model FQCN for indexer config, to allow any Symfony\AI\Platform\Model child class
2 parents 1f91152 + 66b6cbc commit d8519d2

File tree

5 files changed

+47
-57
lines changed

5 files changed

+47
-57
lines changed

demo/config/packages/ai.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ ai:
66
blog:
77
# platform: 'symfony_ai.platform.anthropic'
88
model:
9-
name: 'GPT'
10-
version: 'gpt-4o-mini'
9+
class: 'Symfony\AI\Platform\Bridge\OpenAI\GPT'
10+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\GPT::GPT_4O_MINI
1111
tools:
1212
- 'Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch'
1313
- service: 'clock'
@@ -16,13 +16,13 @@ ai:
1616
method: 'now'
1717
youtube:
1818
model:
19-
name: 'GPT'
20-
version: 'gpt-4o-mini'
19+
class: 'Symfony\AI\Platform\Bridge\OpenAI\GPT'
20+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\GPT::GPT_4O_MINI
2121
tools: false
2222
wikipedia:
2323
model:
24-
name: 'GPT'
25-
version: 'gpt-4o-mini'
24+
class: 'Symfony\AI\Platform\Bridge\OpenAI\GPT'
25+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\GPT::GPT_4O_MINI
2626
options:
2727
temperature: 0.5
2828
system_prompt: 'Please answer the users question based on Wikipedia and provide a link to the article.'
@@ -31,8 +31,8 @@ ai:
3131
- 'Symfony\AI\Agent\Toolbox\Tool\Wikipedia'
3232
audio:
3333
model:
34-
name: 'GPT'
35-
version: 'gpt-4o-mini'
34+
class: 'Symfony\AI\Platform\Bridge\OpenAI\GPT'
35+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\GPT::GPT_4O_MINI
3636
system_prompt: 'You are a friendly chatbot that likes to have a conversation with users and asks them some questions.'
3737
tools:
3838
# Agent in agent 🤯
@@ -47,8 +47,8 @@ ai:
4747
indexer:
4848
default:
4949
model:
50-
name: 'Embeddings'
51-
version: 'text-embedding-ada-002'
50+
class: 'Symfony\AI\Platform\Bridge\OpenAI\Embeddings'
51+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\Embeddings::TEXT_ADA_002
5252

5353
services:
5454
_defaults:

src/ai-bundle/config/options.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@
7070
->end()
7171
->arrayNode('model')
7272
->children()
73-
->scalarNode('name')->isRequired()->end()
74-
->scalarNode('version')->defaultNull()->end()
73+
->scalarNode('class')->isRequired()->end()
74+
->scalarNode('name')->defaultNull()->end()
7575
->arrayNode('options')
7676
->variablePrototype()->end()
7777
->end()
@@ -196,8 +196,8 @@
196196
->end()
197197
->arrayNode('model')
198198
->children()
199-
->scalarNode('name')->isRequired()->end()
200-
->scalarNode('version')->defaultNull()->end()
199+
->scalarNode('class')->isRequired()->end()
200+
->scalarNode('name')->defaultNull()->end()
201201
->arrayNode('options')
202202
->variablePrototype()->end()
203203
->end()

src/ai-bundle/doc/index.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ Configuration
3131
agent:
3232
default:
3333
model:
34-
name: 'GPT'
34+
class: 'Symfony\AI\Platform\Bridge\OpenAI\GPT'
35+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\GPT::GPT_4O_MINI
3536
3637
**Advanced Example with Anthropic, Azure, Google and multiple agents**
3738

@@ -56,8 +57,8 @@ Configuration
5657
platform: 'symfony_ai.platform.azure.gpt_deployment'
5758
structured_output: false # Disables support for "output_structure" option, default is true
5859
model:
59-
name: 'GPT'
60-
version: 'gpt-4o-mini'
60+
class: 'Symfony\AI\Platform\Bridge\OpenAI\GPT'
61+
name: !php/const Symfony\AI\Platform\Bridge\OpenAI\GPT::GPT_4O_MINI
6162
system_prompt: 'You are a helpful assistant that can answer questions.' # The default system prompt of the agent
6263
include_tools: true # Include tool definitions at the end of the system prompt
6364
tools:
@@ -78,7 +79,8 @@ Configuration
7879
research:
7980
platform: 'symfony_ai.platform.anthropic'
8081
model:
81-
name: 'Claude'
82+
class: 'Symfony\AI\Platform\Bridge\Anthropic\Claude'
83+
name: !php/const Symfony\AI\Platform\Bridge\Anthropic\Claude::SONNET_37
8284
tools: # If undefined, all tools are injected into the agent, use "tools: false" to disable tools.
8385
- 'Symfony\AI\Agent\Toolbox\Tool\Wikipedia'
8486
fault_tolerant_toolbox: false # Disables fault tolerant toolbox, default is true
@@ -90,11 +92,11 @@ Configuration
9092
collection: 'my_collection'
9193
indexer:
9294
default:
93-
# platform: 'symfony_ai.platform.anthropic'
95+
# platform: 'symfony_ai.platform.mistral'
9496
# store: 'symfony_ai.store.chroma_db.default'
9597
model:
96-
name: 'Embeddings'
97-
version: 'text-embedding-ada-002'
98+
class: 'Symfony\AI\Platform\Bridge\Mistral\Embeddings'
99+
name: !php/const Symfony\AI\Platform\Bridge\Mistral\Embeddings::MISTRAL_EMBED
98100
99101
Usage
100102
-----

src/ai-bundle/src/AIBundle.php

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,12 @@
2727
use Symfony\AI\AIBundle\Profiler\DataCollector;
2828
use Symfony\AI\AIBundle\Profiler\TraceablePlatform;
2929
use Symfony\AI\AIBundle\Profiler\TraceableToolbox;
30-
use Symfony\AI\Platform\Bridge\Anthropic\Claude;
3130
use Symfony\AI\Platform\Bridge\Anthropic\PlatformFactory as AnthropicPlatformFactory;
3231
use Symfony\AI\Platform\Bridge\Azure\OpenAI\PlatformFactory as AzureOpenAIPlatformFactory;
33-
use Symfony\AI\Platform\Bridge\Google\Gemini;
3432
use Symfony\AI\Platform\Bridge\Google\PlatformFactory as GooglePlatformFactory;
35-
use Symfony\AI\Platform\Bridge\Meta\Llama;
36-
use Symfony\AI\Platform\Bridge\Mistral\Mistral;
3733
use Symfony\AI\Platform\Bridge\Mistral\PlatformFactory as MistralPlatformFactory;
38-
use Symfony\AI\Platform\Bridge\OpenAI\Embeddings;
39-
use Symfony\AI\Platform\Bridge\OpenAI\GPT;
4034
use Symfony\AI\Platform\Bridge\OpenAI\PlatformFactory as OpenAIPlatformFactory;
4135
use Symfony\AI\Platform\Bridge\OpenRouter\PlatformFactory as OpenRouterPlatformFactory;
42-
use Symfony\AI\Platform\Bridge\Voyage\Voyage;
4336
use Symfony\AI\Platform\Model;
4437
use Symfony\AI\Platform\ModelClientInterface;
4538
use Symfony\AI\Platform\Platform;
@@ -261,20 +254,15 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
261254
private function processAgentConfig(string $name, array $config, ContainerBuilder $container): void
262255
{
263256
// MODEL
264-
['name' => $modelName, 'version' => $version, 'options' => $options] = $config['model'];
265-
266-
$modelClass = match (strtolower((string) $modelName)) {
267-
'gpt' => GPT::class,
268-
'claude' => Claude::class,
269-
'llama' => Llama::class,
270-
'gemini' => Gemini::class,
271-
'mistral' => Mistral::class,
272-
'openrouter' => Model::class,
273-
default => throw new \InvalidArgumentException(\sprintf('Model "%s" is not supported.', $modelName)),
274-
};
257+
['class' => $modelClass, 'name' => $modelName, 'options' => $options] = $config['model'];
258+
259+
if (!is_a($modelClass, Model::class, true)) {
260+
throw new \InvalidArgumentException(\sprintf('"%s" class is not extending Symfony\AI\Platform\Model.', $modelClass));
261+
}
262+
275263
$modelDefinition = new Definition($modelClass);
276-
if (null !== $version) {
277-
$modelDefinition->setArgument('$name', $version);
264+
if (null !== $modelName) {
265+
$modelDefinition->setArgument('$name', $modelName);
278266
}
279267
if ([] !== $options) {
280268
$modelDefinition->setArgument('$options', $options);
@@ -473,20 +461,20 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
473461
*/
474462
private function processIndexerConfig(int|string $name, array $config, ContainerBuilder $container): void
475463
{
476-
['name' => $modelName, 'version' => $version, 'options' => $options] = $config['model'];
477-
478-
$modelClass = match (strtolower((string) $modelName)) {
479-
'embeddings' => Embeddings::class,
480-
'voyage' => Voyage::class,
481-
default => throw new \InvalidArgumentException(\sprintf('Model "%s" is not supported.', $modelName)),
482-
};
483-
$modelDefinition = (new Definition($modelClass));
484-
if (null !== $version) {
485-
$modelDefinition->setArgument('$name', $version);
464+
['class' => $modelClass, 'name' => $modelName, 'options' => $options] = $config['model'];
465+
466+
if (!is_a($modelClass, Model::class, true)) {
467+
throw new \InvalidArgumentException(\sprintf('"%s" class is not extending Symfony\AI\Platform\Model.', $modelClass));
468+
}
469+
470+
$modelDefinition = (new Definition((string) $modelClass));
471+
if (null !== $modelName) {
472+
$modelDefinition->setArgument('$name', $modelName);
486473
}
487474
if ([] !== $options) {
488475
$modelDefinition->setArgument('$options', $options);
489476
}
477+
490478
$modelDefinition->addTag('symfony_ai.model.embeddings_model');
491479
$container->setDefinition('symfony_ai.indexer.'.$name.'.model', $modelDefinition);
492480

src/ai-bundle/tests/AIBundleTest.php renamed to src/ai-bundle/tests/DependencyInjection/AIBundleTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ private function getFullConfig(): array
7777
'my_chat_agent' => [
7878
'platform' => 'openai_platform_service_id',
7979
'model' => [
80-
'name' => 'gpt',
81-
'version' => 'gpt-3.5-turbo',
80+
'class' => 'Symfony\AI\Platform\Bridge\OpenAI\GPT',
81+
'name' => 'gpt-3.5-turbo',
8282
'options' => [
8383
'temperature' => 0.7,
8484
'max_tokens' => 150,
@@ -98,7 +98,7 @@ private function getFullConfig(): array
9898
'fault_tolerant_toolbox' => false,
9999
],
100100
'another_agent' => [
101-
'model' => ['name' => 'claude', 'version' => 'claude-3-opus-20240229'],
101+
'model' => ['class' => 'Symfony\AI\Platform\Bridge\Anthropic\Claude', 'name' => 'claude-3-opus-20240229'],
102102
'system_prompt' => 'Be concise.',
103103
],
104104
],
@@ -137,10 +137,10 @@ private function getFullConfig(): array
137137
'indexer' => [
138138
'my_text_indexer' => [
139139
'store' => 'my_azure_search_store_service_id',
140-
'platform' => 'google_platform_service_id',
140+
'platform' => 'mistral_platform_service_id',
141141
'model' => [
142-
'name' => 'embeddings',
143-
'version' => 'text-embedding-004',
142+
'class' => 'Symfony\AI\Platform\Bridge\Mistral\Embeddings',
143+
'name' => 'mistral-embed',
144144
'options' => ['dimension' => 768],
145145
],
146146
],

0 commit comments

Comments
 (0)