1414use Google \Auth \ApplicationDefaultCredentials ;
1515use Symfony \AI \Agent \Agent ;
1616use Symfony \AI \Agent \AgentInterface ;
17+ use Symfony \AI \Agent \Attribute \AsInputProcessor ;
18+ use Symfony \AI \Agent \Attribute \AsOutputProcessor ;
1719use Symfony \AI \Agent \InputProcessor \SystemPromptInputProcessor ;
1820use Symfony \AI \Agent \InputProcessorInterface ;
1921use Symfony \AI \Agent \OutputProcessorInterface ;
2224use Symfony \AI \Agent \Toolbox \Tool \Agent as AgentTool ;
2325use Symfony \AI \Agent \Toolbox \ToolFactory \ChainFactory ;
2426use Symfony \AI \Agent \Toolbox \ToolFactory \MemoryToolFactory ;
27+ use Symfony \AI \AiBundle \DependencyInjection \ProcessorCompilerPass ;
2528use Symfony \AI \AiBundle \Exception \InvalidArgumentException ;
2629use Symfony \AI \AiBundle \Profiler \TraceablePlatform ;
2730use Symfony \AI \AiBundle \Profiler \TraceableToolbox ;
8386 */
8487final class AiBundle extends AbstractBundle
8588{
89+ public function build (ContainerBuilder $ container )
90+ {
91+ parent ::build ($ container );
92+
93+ $ container ->addCompilerPass (new ProcessorCompilerPass ());
94+ }
95+
8696 public function configure (DefinitionConfigurator $ definition ): void
8797 {
8898 $ definition ->import ('../config/options.php ' );
@@ -143,10 +153,25 @@ public function loadExtension(array $config, ContainerConfigurator $container, C
143153 ]);
144154 });
145155
156+ $ builder ->registerAttributeForAutoconfiguration (AsInputProcessor::class, static function (ChildDefinition $ definition , AsInputProcessor $ attribute ): void {
157+ $ definition ->addTag ('ai.agent.input_processor ' , [
158+ 'agent ' => $ attribute ->agent ,
159+ 'priority ' => $ attribute ->priority ,
160+ ]);
161+ });
162+
163+ $ builder ->registerAttributeForAutoconfiguration (AsOutputProcessor::class, static function (ChildDefinition $ definition , AsOutputProcessor $ attribute ): void {
164+ $ definition ->addTag ('ai.agent.output_processor ' , [
165+ 'agent ' => $ attribute ->agent ,
166+ 'priority ' => $ attribute ->priority ,
167+ ]);
168+ });
169+
146170 $ builder ->registerForAutoconfiguration (InputProcessorInterface::class)
147- ->addTag ('ai.agent.input_processor ' );
171+ ->addTag ('ai.agent.input_processor ' , [ ' tagged_by ' => ' interface ' ] );
148172 $ builder ->registerForAutoconfiguration (OutputProcessorInterface::class)
149- ->addTag ('ai.agent.output_processor ' );
173+ ->addTag ('ai.agent.output_processor ' , ['tagged_by ' => 'interface ' ]);
174+
150175 $ builder ->registerForAutoconfiguration (ModelClientInterface::class)
151176 ->addTag ('ai.platform.model_client ' );
152177 $ builder ->registerForAutoconfiguration (ResultConverterInterface::class)
@@ -436,9 +461,6 @@ private function processAgentConfig(string $name, array $config, ContainerBuilde
436461 ->setArgument (0 , new Reference ($ config ['platform ' ]))
437462 ->setArgument (1 , new Reference ('ai.agent. ' .$ name .'.model ' ));
438463
439- $ inputProcessors = [];
440- $ outputProcessors = [];
441-
442464 // TOOL & PROCESSOR
443465 if ($ config ['tools ' ]['enabled ' ]) {
444466 // Create specific toolbox and process if tools are explicitly defined
@@ -492,26 +514,28 @@ private function processAgentConfig(string $name, array $config, ContainerBuilde
492514
493515 $ toolProcessorDefinition = (new ChildDefinition ('ai.tool.agent_processor.abstract ' ))
494516 ->replaceArgument (0 , new Reference ('ai.toolbox. ' .$ name ));
495- $ container ->setDefinition ('ai.tool.agent_processor. ' .$ name , $ toolProcessorDefinition );
496517
497- $ inputProcessors [] = new Reference ('ai.tool.agent_processor. ' .$ name );
498- $ outputProcessors [] = new Reference ('ai.tool.agent_processor. ' .$ name );
518+ $ container ->setDefinition ('ai.tool.agent_processor. ' .$ name , $ toolProcessorDefinition )
519+ ->addTag ('ai.agent.input_processor ' , ['agent ' => $ name , 'priority ' => -10 ])
520+ ->addTag ('ai.agent.output_processor ' , ['agent ' => $ name , 'priority ' => -10 ]);
499521 } else {
500522 if ($ config ['fault_tolerant_toolbox ' ] && !$ container ->hasDefinition ('ai.fault_tolerant_toolbox ' )) {
501523 $ container ->setDefinition ('ai.fault_tolerant_toolbox ' , new Definition (FaultTolerantToolbox::class))
502524 ->setArguments ([new Reference ('.inner ' )])
503525 ->setDecoratedService ('ai.toolbox ' );
504526 }
505527
506- $ inputProcessors [] = new Reference ('ai.tool.agent_processor ' );
507- $ outputProcessors [] = new Reference ('ai.tool.agent_processor ' );
528+ $ container ->getDefinition ('ai.tool.agent_processor ' )
529+ ->addTag ('ai.agent.input_processor ' , ['agent ' => $ name , 'priority ' => -10 ])
530+ ->addTag ('ai.agent.output_processor ' , ['agent ' => $ name , 'priority ' => -10 ]);
508531 }
509532 }
510533
511534 // STRUCTURED OUTPUT
512535 if ($ config ['structured_output ' ]) {
513- $ inputProcessors [] = new Reference ('ai.agent.structured_output_processor ' );
514- $ outputProcessors [] = new Reference ('ai.agent.structured_output_processor ' );
536+ $ container ->getDefinition ('ai.agent.structured_output_processor ' )
537+ ->addTag ('ai.agent.input_processor ' , ['agent ' => $ name , 'priority ' => -20 ])
538+ ->addTag ('ai.agent.output_processor ' , ['agent ' => $ name , 'priority ' => -20 ]);
515539 }
516540
517541 // TOKEN USAGE TRACKING
@@ -530,25 +554,28 @@ private function processAgentConfig(string $name, array $config, ContainerBuilde
530554 }
531555
532556 if ($ container ->hasDefinition ('ai.platform.token_usage_processor. ' .$ platform )) {
533- $ outputProcessors [] = new Reference ('ai.platform.token_usage_processor. ' .$ platform );
557+ $ container ->getDefinition ('ai.platform.token_usage_processor. ' .$ platform )
558+ ->addTag ('ai.agent.output_processor ' , ['agent ' => $ name , 'priority ' => -30 ]);
534559 }
535560 }
536561 }
537562
538563 // SYSTEM PROMPT
539564 if (\is_string ($ config ['system_prompt ' ])) {
540- $ systemPromptInputProcessorDefinition = new Definition (SystemPromptInputProcessor::class, [
541- $ config ['system_prompt ' ],
542- $ config ['include_tools ' ] ? new Reference ('ai.toolbox. ' .$ name ) : null ,
543- new Reference ('logger ' , ContainerInterface::IGNORE_ON_INVALID_REFERENCE ),
544- ]);
565+ $ systemPromptInputProcessorDefinition = (new Definition (SystemPromptInputProcessor::class))
566+ ->setArguments ([
567+ $ config ['system_prompt ' ],
568+ $ config ['include_tools ' ] ? new Reference ('ai.toolbox. ' .$ name ) : null ,
569+ new Reference ('logger ' , ContainerInterface::IGNORE_ON_INVALID_REFERENCE ),
570+ ])
571+ ->addTag ('ai.agent.input_processor ' , ['agent ' => $ name , 'priority ' => -30 ]);
545572
546- $ inputProcessors [] = $ systemPromptInputProcessorDefinition ;
573+ $ container -> setDefinition ( ' ai.agent. ' . $ name . ' .system_prompt_processor ' , $ systemPromptInputProcessorDefinition) ;
547574 }
548575
549576 $ agentDefinition
550- ->setArgument (2 , $ inputProcessors )
551- ->setArgument (3 , $ outputProcessors )
577+ ->setArgument (2 , []) // placeholder until ProcessorCompilerPass process.
578+ ->setArgument (3 , []) // placeholder until ProcessorCompilerPass process.
552579 ->setArgument (4 , new Reference ('logger ' , ContainerInterface::IGNORE_ON_INVALID_REFERENCE ))
553580 ;
554581
0 commit comments