@@ -648,6 +648,200 @@ public function testPerplexityPlatformConfiguration()
648
648
$ this ->assertSame ('ai.platform.contract.perplexity ' , (string ) $ arguments [2 ]);
649
649
}
650
650
651
+ #[TestDox('System prompt with array structure works correctly ' )]
652
+ public function testSystemPromptWithArrayStructure ()
653
+ {
654
+ $ container = $ this ->buildContainer ([
655
+ 'ai ' => [
656
+ 'agent ' => [
657
+ 'test_agent ' => [
658
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
659
+ 'system_prompt ' => [
660
+ 'prompt ' => 'You are a helpful assistant. ' ,
661
+ ],
662
+ 'tools ' => [
663
+ ['service ' => 'some_tool ' , 'description ' => 'Test tool ' ],
664
+ ],
665
+ ],
666
+ ],
667
+ ],
668
+ ]);
669
+
670
+ $ this ->assertTrue ($ container ->hasDefinition ('ai.agent.test_agent.system_prompt_processor ' ));
671
+ $ definition = $ container ->getDefinition ('ai.agent.test_agent.system_prompt_processor ' );
672
+ $ arguments = $ definition ->getArguments ();
673
+
674
+ $ this ->assertSame ('You are a helpful assistant. ' , $ arguments [0 ]);
675
+ $ this ->assertNull ($ arguments [1 ]); // include_tools is false, so null reference
676
+ }
677
+
678
+ #[TestDox('System prompt with include_tools enabled works correctly ' )]
679
+ public function testSystemPromptWithIncludeToolsEnabled ()
680
+ {
681
+ $ container = $ this ->buildContainer ([
682
+ 'ai ' => [
683
+ 'agent ' => [
684
+ 'test_agent ' => [
685
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
686
+ 'system_prompt ' => [
687
+ 'prompt ' => 'You are a helpful assistant. ' ,
688
+ 'include_tools ' => true ,
689
+ ],
690
+ 'tools ' => [
691
+ ['service ' => 'some_tool ' , 'description ' => 'Test tool ' ],
692
+ ],
693
+ ],
694
+ ],
695
+ ],
696
+ ]);
697
+
698
+ $ this ->assertTrue ($ container ->hasDefinition ('ai.agent.test_agent.system_prompt_processor ' ));
699
+ $ definition = $ container ->getDefinition ('ai.agent.test_agent.system_prompt_processor ' );
700
+ $ arguments = $ definition ->getArguments ();
701
+
702
+ $ this ->assertSame ('You are a helpful assistant. ' , $ arguments [0 ]);
703
+ $ this ->assertInstanceOf (Reference::class, $ arguments [1 ]);
704
+ $ this ->assertSame ('ai.toolbox.test_agent ' , (string ) $ arguments [1 ]);
705
+ }
706
+
707
+ #[TestDox('System prompt with only prompt key defaults include_tools to false ' )]
708
+ public function testSystemPromptWithOnlyPromptKey ()
709
+ {
710
+ $ container = $ this ->buildContainer ([
711
+ 'ai ' => [
712
+ 'agent ' => [
713
+ 'test_agent ' => [
714
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
715
+ 'system_prompt ' => [
716
+ 'prompt ' => 'You are a helpful assistant. ' ,
717
+ ],
718
+ 'tools ' => [
719
+ ['service ' => 'some_tool ' , 'description ' => 'Test tool ' ],
720
+ ],
721
+ ],
722
+ ],
723
+ ],
724
+ ]);
725
+
726
+ $ this ->assertTrue ($ container ->hasDefinition ('ai.agent.test_agent.system_prompt_processor ' ));
727
+ $ definition = $ container ->getDefinition ('ai.agent.test_agent.system_prompt_processor ' );
728
+ $ arguments = $ definition ->getArguments ();
729
+
730
+ $ this ->assertSame ('You are a helpful assistant. ' , $ arguments [0 ]);
731
+ $ this ->assertNull ($ arguments [1 ]); // include_tools defaults to false
732
+ }
733
+
734
+ #[TestDox('Agent without system prompt does not create processor ' )]
735
+ public function testAgentWithoutSystemPrompt ()
736
+ {
737
+ $ container = $ this ->buildContainer ([
738
+ 'ai ' => [
739
+ 'agent ' => [
740
+ 'test_agent ' => [
741
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
742
+ ],
743
+ ],
744
+ ],
745
+ ]);
746
+
747
+ $ this ->assertFalse ($ container ->hasDefinition ('ai.agent.test_agent.system_prompt_processor ' ));
748
+ }
749
+
750
+ #[TestDox('Valid system prompt creates processor correctly ' )]
751
+ public function testValidSystemPromptCreatesProcessor ()
752
+ {
753
+ // This test verifies that valid system prompts work correctly with new structure
754
+ $ container = $ this ->buildContainer ([
755
+ 'ai ' => [
756
+ 'agent ' => [
757
+ 'test_agent ' => [
758
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
759
+ 'system_prompt ' => [
760
+ 'prompt ' => 'Valid prompt ' ,
761
+ 'include_tools ' => true ,
762
+ ],
763
+ 'tools ' => [
764
+ ['service ' => 'some_tool ' , 'description ' => 'Test tool ' ],
765
+ ],
766
+ ],
767
+ ],
768
+ ],
769
+ ]);
770
+
771
+ $ this ->assertTrue ($ container ->hasDefinition ('ai.agent.test_agent.system_prompt_processor ' ));
772
+ $ definition = $ container ->getDefinition ('ai.agent.test_agent.system_prompt_processor ' );
773
+ $ arguments = $ definition ->getArguments ();
774
+
775
+ $ this ->assertSame ('Valid prompt ' , $ arguments [0 ]);
776
+ $ this ->assertInstanceOf (Reference::class, $ arguments [1 ]);
777
+ $ this ->assertSame ('ai.toolbox.test_agent ' , (string ) $ arguments [1 ]);
778
+ }
779
+
780
+ #[TestDox('Empty prompt in array structure throws configuration exception ' )]
781
+ public function testEmptyPromptInArrayThrowsException ()
782
+ {
783
+ $ this ->expectException (InvalidConfigurationException::class);
784
+ $ this ->expectExceptionMessage ('The "prompt" cannot be empty. ' );
785
+
786
+ $ this ->buildContainer ([
787
+ 'ai ' => [
788
+ 'agent ' => [
789
+ 'test_agent ' => [
790
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
791
+ 'system_prompt ' => [
792
+ 'prompt ' => '' ,
793
+ ],
794
+ ],
795
+ ],
796
+ ],
797
+ ]);
798
+ }
799
+
800
+ #[TestDox('System prompt array without prompt key throws configuration exception ' )]
801
+ public function testSystemPromptArrayWithoutPromptKeyThrowsException ()
802
+ {
803
+ $ this ->expectException (InvalidConfigurationException::class);
804
+ $ this ->expectExceptionMessage ('The "prompt" cannot be empty. ' );
805
+
806
+ $ this ->buildContainer ([
807
+ 'ai ' => [
808
+ 'agent ' => [
809
+ 'test_agent ' => [
810
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
811
+ 'system_prompt ' => [
812
+ 'include_tools ' => true ,
813
+ ],
814
+ ],
815
+ ],
816
+ ],
817
+ ]);
818
+ }
819
+
820
+ #[TestDox('System prompt with string format works correctly ' )]
821
+ public function testSystemPromptWithStringFormat ()
822
+ {
823
+ $ container = $ this ->buildContainer ([
824
+ 'ai ' => [
825
+ 'agent ' => [
826
+ 'test_agent ' => [
827
+ 'model ' => ['class ' => 'Symfony\AI\Platform\Bridge\OpenAi\Gpt ' ],
828
+ 'system_prompt ' => 'You are a helpful assistant. ' ,
829
+ 'tools ' => [
830
+ ['service ' => 'some_tool ' , 'description ' => 'Test tool ' ],
831
+ ],
832
+ ],
833
+ ],
834
+ ],
835
+ ]);
836
+
837
+ $ this ->assertTrue ($ container ->hasDefinition ('ai.agent.test_agent.system_prompt_processor ' ));
838
+ $ definition = $ container ->getDefinition ('ai.agent.test_agent.system_prompt_processor ' );
839
+ $ arguments = $ definition ->getArguments ();
840
+
841
+ $ this ->assertSame ('You are a helpful assistant. ' , $ arguments [0 ]);
842
+ $ this ->assertNull ($ arguments [1 ]); // include_tools not enabled with string format
843
+ }
844
+
651
845
public function testVectorizerConfiguration ()
652
846
{
653
847
$ container = $ this ->buildContainer ([
@@ -1076,8 +1270,10 @@ private function getFullConfig(): array
1076
1270
],
1077
1271
'structured_output ' => false ,
1078
1272
'track_token_usage ' => true ,
1079
- 'system_prompt ' => 'You are a helpful assistant. ' ,
1080
- 'include_tools ' => true ,
1273
+ 'system_prompt ' => [
1274
+ 'prompt ' => 'You are a helpful assistant. ' ,
1275
+ 'include_tools ' => true ,
1276
+ ],
1081
1277
'tools ' => [
1082
1278
'enabled ' => true ,
1083
1279
'services ' => [
0 commit comments