|
27 | 27 | use Symfony\AI\Agent\Toolbox\Tool\Agent as AgentTool;
|
28 | 28 | use Symfony\AI\Agent\Toolbox\ToolFactory\ChainFactory;
|
29 | 29 | use Symfony\AI\Agent\Toolbox\ToolFactory\MemoryToolFactory;
|
30 |
| -use Symfony\AI\AiBundle\DependencyInjection\ModelCatalogCompilerPass; |
31 | 30 | use Symfony\AI\AiBundle\DependencyInjection\ProcessorCompilerPass;
|
32 | 31 | use Symfony\AI\AiBundle\Exception\InvalidArgumentException;
|
33 | 32 | use Symfony\AI\AiBundle\Profiler\TraceablePlatform;
|
|
48 | 47 | use Symfony\AI\Platform\Bridge\VertexAi\PlatformFactory as VertexAiPlatformFactory;
|
49 | 48 | use Symfony\AI\Platform\Bridge\Voyage\PlatformFactory as VoyagePlatformFactory;
|
50 | 49 | use Symfony\AI\Platform\Exception\RuntimeException;
|
| 50 | +use Symfony\AI\Platform\Capability; |
51 | 51 | use Symfony\AI\Platform\Model;
|
| 52 | +use Symfony\AI\Platform\ModelCatalog; |
52 | 53 | use Symfony\AI\Platform\ModelClientInterface;
|
53 | 54 | use Symfony\AI\Platform\Platform;
|
54 | 55 | use Symfony\AI\Platform\PlatformInterface;
|
@@ -99,7 +100,6 @@ public function build(ContainerBuilder $container): void
|
99 | 100 | parent::build($container);
|
100 | 101 |
|
101 | 102 | $container->addCompilerPass(new ProcessorCompilerPass());
|
102 |
| - $container->addCompilerPass(new ModelCatalogCompilerPass()); |
103 | 103 | }
|
104 | 104 |
|
105 | 105 | public function configure(DefinitionConfigurator $definition): void // @phpstan-ignore-line generics.notSubtype
|
@@ -132,12 +132,13 @@ public function loadExtension(array $config, ContainerConfigurator $container, C
|
132 | 132 | }
|
133 | 133 | }
|
134 | 134 |
|
135 |
| - foreach ($config['models'] ?? [] as $platformName => $models) { |
136 |
| - foreach ($models as $modelName => $model) { |
137 |
| - $this->processModelConfig($modelName, $model, $platformName, $builder); |
138 |
| - } |
| 135 | + foreach ($config['model'] ?? [] as $platformName => $models) { |
| 136 | + $this->processModelCatalogConfig($platformName, $models, $builder); |
139 | 137 | }
|
140 | 138 |
|
| 139 | + // Ensure default empty model catalogs exist for all platforms |
| 140 | + $this->ensureDefaultModelCatalogs($builder); |
| 141 | + |
141 | 142 | foreach ($config['agent'] as $agentName => $agent) {
|
142 | 143 | $this->processAgentConfig($agentName, $agent, $builder);
|
143 | 144 | }
|
@@ -350,6 +351,7 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
|
350 | 351 | new Reference($platform['http_client'], ContainerInterface::NULL_ON_INVALID_REFERENCE),
|
351 | 352 | new Reference('ai.platform.contract.openai'),
|
352 | 353 | $platform['region'] ?? null,
|
| 354 | + new Reference('ai.model_catalog.openai', ContainerInterface::NULL_ON_INVALID_REFERENCE), |
353 | 355 | ])
|
354 | 356 | ->addTag('ai.platform');
|
355 | 357 |
|
@@ -1162,20 +1164,58 @@ private function processIndexerConfig(int|string $name, array $config, Container
|
1162 | 1164 | }
|
1163 | 1165 |
|
1164 | 1166 | /**
|
1165 |
| - * @param array<string, mixed> $config |
| 1167 | + * @param array<string, mixed> $models |
1166 | 1168 | */
|
1167 |
| - private function processModelConfig(string $modelName, array $config, string $platformName, ContainerBuilder $container): void |
| 1169 | + private function processModelCatalogConfig(string $platformName, array $models, ContainerBuilder $container): void |
1168 | 1170 | {
|
1169 |
| - $platformServiceId = 'ai.platform.'.$platformName; |
1170 |
| - |
1171 |
| - $modelDefinition = new Definition($config['class']); |
1172 |
| - $modelDefinition->addTag('ai.model.catalog', [ |
1173 |
| - 'name' => $modelName, |
1174 |
| - 'class' => $config['class'], |
1175 |
| - 'platform' => $platformServiceId, |
1176 |
| - 'capabilities' => $config['capabilities'], |
1177 |
| - ]); |
| 1171 | + $modelDefinitions = []; |
| 1172 | + |
| 1173 | + foreach ($models as $modelName => $modelConfig) { |
| 1174 | + $capabilities = $modelConfig['capabilities'] ?? []; |
| 1175 | + |
| 1176 | + // If no capabilities provided, add all capabilities from Capability enum |
| 1177 | + if (empty($capabilities)) { |
| 1178 | + $capabilityEnums = Capability::cases(); |
| 1179 | + } else { |
| 1180 | + // Convert string capabilities to Capability enums |
| 1181 | + if (is_string($capabilities)) { |
| 1182 | + $capabilities = explode(',', $capabilities); |
| 1183 | + } |
| 1184 | + |
| 1185 | + $capabilityEnums = []; |
| 1186 | + foreach ($capabilities as $capability) { |
| 1187 | + $capability = trim($capability); |
| 1188 | + if ($capability !== '') { |
| 1189 | + $capabilityEnums[] = Capability::from($capability); |
| 1190 | + } |
| 1191 | + } |
| 1192 | + } |
| 1193 | + |
| 1194 | + $modelDefinitions[$modelName] = [ |
| 1195 | + 'class' => $modelConfig['class'], |
| 1196 | + 'platform' => $platformName, |
| 1197 | + 'capabilities' => $capabilityEnums, |
| 1198 | + ]; |
| 1199 | + } |
| 1200 | + |
| 1201 | + // Create platform-specific model catalog service |
| 1202 | + $catalogServiceId = 'ai.model_catalog.' . $platformName; |
| 1203 | + $catalogDefinition = new Definition(ModelCatalog::class, [$modelDefinitions]); |
| 1204 | + $container->setDefinition($catalogServiceId, $catalogDefinition); |
| 1205 | + } |
1178 | 1206 |
|
1179 |
| - $container->setDefinition('ai.model.catalog.'.$modelName, $modelDefinition); |
| 1207 | + private function ensureDefaultModelCatalogs(ContainerBuilder $container): void |
| 1208 | + { |
| 1209 | + $defaultPlatforms = ['openai', 'anthropic', 'gemini', 'azure', 'mistral', 'ollama', 'perplexity']; |
| 1210 | + |
| 1211 | + foreach ($defaultPlatforms as $platform) { |
| 1212 | + $catalogServiceId = 'ai.model_catalog.' . $platform; |
| 1213 | + |
| 1214 | + // Only create if it doesn't already exist |
| 1215 | + if (!$container->hasDefinition($catalogServiceId)) { |
| 1216 | + $catalogDefinition = new Definition(ModelCatalog::class, [[]]); |
| 1217 | + $container->setDefinition($catalogServiceId, $catalogDefinition); |
| 1218 | + } |
| 1219 | + } |
1180 | 1220 | }
|
1181 | 1221 | }
|
0 commit comments