Skip to content

Commit 7a005cb

Browse files
committed
[AIBundle] Wire & configure services explicitly
1 parent 24797e3 commit 7a005cb

File tree

4 files changed

+169
-107
lines changed

4 files changed

+169
-107
lines changed

src/ai-bundle/config/options.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
namespace Symfony\Component\Config\Definition\Configurator;
1313

14+
use Codewithkyrian\ChromaDB\Client as ChromaDBClient;
15+
use MongoDB\Client as MongoDBClient;
16+
use Probots\Pinecone\Client as PineconeClient;
1417
use Symfony\AI\Platform\PlatformInterface;
1518
use Symfony\AI\Store\StoreInterface;
1619

@@ -154,6 +157,7 @@
154157
->useAttributeAsKey('name')
155158
->arrayPrototype()
156159
->children()
160+
->scalarNode('client')->cannotBeEmpty()->defaultValue(ChromaDBClient::class)->end()
157161
->scalarNode('collection')->isRequired()->end()
158162
->end()
159163
->end()
@@ -163,6 +167,7 @@
163167
->useAttributeAsKey('name')
164168
->arrayPrototype()
165169
->children()
170+
->scalarNode('client')->cannotBeEmpty()->defaultValue(MongoDBClient::class)->end()
166171
->scalarNode('database')->isRequired()->end()
167172
->scalarNode('collection')->isRequired()->end()
168173
->scalarNode('index_name')->isRequired()->end()
@@ -176,6 +181,7 @@
176181
->useAttributeAsKey('name')
177182
->arrayPrototype()
178183
->children()
184+
->scalarNode('client')->cannotBeEmpty()->defaultValue(PineconeClient::class)->end()
179185
->scalarNode('namespace')->end()
180186
->arrayNode('filter')
181187
->scalarPrototype()->end()

src/ai-bundle/config/services.php

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,66 +18,108 @@
1818
use Symfony\AI\Agent\Toolbox\Toolbox;
1919
use Symfony\AI\Agent\Toolbox\ToolboxInterface;
2020
use Symfony\AI\Agent\Toolbox\ToolCallArgumentResolver;
21+
use Symfony\AI\Agent\Toolbox\ToolFactory\AbstractToolFactory;
2122
use Symfony\AI\Agent\Toolbox\ToolFactory\ReflectionToolFactory;
22-
use Symfony\AI\Agent\Toolbox\ToolFactoryInterface;
2323
use Symfony\AI\Agent\Toolbox\ToolResultConverter;
2424
use Symfony\AI\AIBundle\Profiler\DataCollector;
2525
use Symfony\AI\AIBundle\Profiler\TraceableToolbox;
2626
use Symfony\AI\AIBundle\Security\EventListener\IsGrantedToolAttributeListener;
27+
use Symfony\AI\Platform\Bridge\Anthropic\Contract\AnthropicContract;
28+
use Symfony\AI\Platform\Bridge\Google\Contract\GoogleContract;
29+
use Symfony\AI\Platform\Contract;
30+
use Symfony\AI\Platform\Contract\JsonSchema\DescriptionParser;
31+
use Symfony\AI\Platform\Contract\JsonSchema\Factory as SchemaFactory;
2732

2833
return static function (ContainerConfigurator $container): void {
2934
$container->services()
30-
->defaults()
31-
->autowire()
32-
35+
->set('ai.platform.contract.default', Contract::class)
36+
->factory([Contract::class, 'create'])
37+
->set('ai.platform.contract.anthropic', Contract::class)
38+
->factory([AnthropicContract::class, 'create'])
39+
->set('ai.platform.contract.google', Contract::class)
40+
->factory([GoogleContract::class, 'create'])
3341
// structured output
34-
->set(ResponseFormatFactory::class)
35-
->alias(ResponseFormatFactoryInterface::class, ResponseFormatFactory::class)
36-
->set(StructureOutputProcessor::class)
42+
->set('ai.agent.response_format_factory', ResponseFormatFactory::class)
43+
->args([
44+
service('ai.platform.json_schema_factory'),
45+
])
46+
->set('ai.platform.json_schema.description_parser', DescriptionParser::class)
47+
->set('ai.platform.json_schema_factory', SchemaFactory::class)
48+
->args([
49+
service('ai.platform.json_schema.description_parser'),
50+
service('type_info.resolver')->nullOnInvalid(),
51+
])
52+
->alias(ResponseFormatFactoryInterface::class, 'ai.agent.response_format_factory')
53+
->set('ai.agent.structured_output_processor', StructureOutputProcessor::class)
54+
->args([
55+
service('ai.agent.response_format_factory'),
56+
service('serializer'),
57+
])
3758
->tag('ai.agent.input_processor')
3859
->tag('ai.agent.output_processor')
3960

4061
// tools
41-
->set('ai.toolbox.abstract')
42-
->class(Toolbox::class)
43-
->autowire()
62+
->set('ai.toolbox.abstract', Toolbox::class)
4463
->abstract()
4564
->args([
46-
'$toolFactory' => service(ToolFactoryInterface::class),
47-
'$tools' => abstract_arg('Collection of tools'),
65+
service('ai.tool_factory'),
66+
abstract_arg('Collection of tools'),
67+
service('ai.tool_call_argument_resolver'),
68+
service('logger')->ignoreOnInvalid(),
69+
service('event_dispatcher')->nullOnInvalid(),
4870
])
49-
->set(Toolbox::class)
71+
->set('ai.toolbox', Toolbox::class)
5072
->parent('ai.toolbox.abstract')
73+
->arg('index_1', tagged_iterator('ai.tool'))
74+
->alias(ToolboxInterface::class, 'ai.toolbox')
75+
->set('ai.tool_factory.abstract', AbstractToolFactory::class)
76+
->abstract()
77+
->args([
78+
service('ai.platform.json_schema_factory'),
79+
])
80+
->set('ai.tool_factory', ReflectionToolFactory::class)
81+
->parent('ai.tool_factory.abstract')
82+
->set('ai.tool_result_converter', ToolResultConverter::class)
83+
->args([
84+
service('serializer'),
85+
])
86+
->set('ai.tool_call_argument_resolver', ToolCallArgumentResolver::class)
5187
->args([
52-
'$tools' => tagged_iterator('ai.tool'),
88+
service('serializer'),
5389
])
54-
->alias(ToolboxInterface::class, Toolbox::class)
55-
->set(ReflectionToolFactory::class)
56-
->alias(ToolFactoryInterface::class, ReflectionToolFactory::class)
57-
->set(ToolResultConverter::class)
58-
->set(ToolCallArgumentResolver::class)
59-
->set('ai.tool.agent_processor.abstract')
60-
->class(ToolProcessor::class)
90+
->set('ai.tool.agent_processor.abstract', ToolProcessor::class)
6191
->abstract()
6292
->args([
63-
'$toolbox' => abstract_arg('Toolbox'),
93+
abstract_arg('Toolbox'),
94+
service('ai.tool_result_converter'),
95+
service('event_dispatcher')->nullOnInvalid(),
96+
false,
6497
])
65-
->set(ToolProcessor::class)
98+
->set('ai.tool.agent_processor', ToolProcessor::class)
6699
->parent('ai.tool.agent_processor.abstract')
67100
->tag('ai.agent.input_processor')
68101
->tag('ai.agent.output_processor')
102+
->arg('index_0', service('ai.toolbox'))
103+
->set('ai.security.is_granted_attribute_listener', IsGrantedToolAttributeListener::class)
69104
->args([
70-
'$toolbox' => service(ToolboxInterface::class),
71-
'$eventDispatcher' => service('event_dispatcher')->nullOnInvalid(),
105+
service('security.authorization_checker'),
106+
service('expression_language')->nullOnInvalid(),
72107
])
73-
->set('ai.security.is_granted_attribute_listener', IsGrantedToolAttributeListener::class)
74108
->tag('kernel.event_listener')
75109

76110
// profiler
77-
->set(DataCollector::class)
111+
->set('ai.data_collector', DataCollector::class)
112+
->args([
113+
tagged_iterator('ai.traceable_platform'),
114+
service('ai.toolbox'),
115+
tagged_iterator('ai.traceable_toolbox'),
116+
])
78117
->tag('data_collector')
79-
->set(TraceableToolbox::class)
80-
->decorate(ToolboxInterface::class)
118+
->set('ai.traceable_toolbox', TraceableToolbox::class)
119+
->decorate('ai.toolbox')
120+
->args([
121+
service('.inner'),
122+
])
81123
->tag('ai.traceable_toolbox')
82124
;
83125
};

0 commit comments

Comments
 (0)