|
18 | 18 | use PHPUnit\Framework\Attributes\TestWith; |
19 | 19 | use PHPUnit\Framework\TestCase; |
20 | 20 | use Probots\Pinecone\Client as PineconeClient; |
| 21 | +use Psr\Log\LoggerInterface; |
| 22 | +use Psr\Log\NullLogger; |
21 | 23 | use Symfony\AI\Agent\AgentInterface; |
22 | 24 | use Symfony\AI\Agent\Memory\MemoryInputProcessor; |
23 | 25 | use Symfony\AI\Agent\Memory\StaticMemoryProvider; |
|
35 | 37 | use Symfony\AI\Platform\CachedPlatform; |
36 | 38 | use Symfony\AI\Platform\Capability; |
37 | 39 | use Symfony\AI\Platform\EventListener\TemplateRendererListener; |
| 40 | +use Symfony\AI\Platform\FailoverPlatform; |
38 | 41 | use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionLanguageTemplateRenderer; |
39 | 42 | use Symfony\AI\Platform\Message\TemplateRenderer\StringTemplateRenderer; |
40 | 43 | use Symfony\AI\Platform\Message\TemplateRenderer\TemplateRendererRegistry; |
@@ -4019,6 +4022,104 @@ public function testElevenLabsPlatformWithApiCatalogCanBeRegistered() |
4019 | 4022 | $this->assertSame([['interface' => ModelCatalogInterface::class]], $modelCatalogDefinition->getTag('proxy')); |
4020 | 4023 | } |
4021 | 4024 |
|
| 4025 | + public function testFailoverPlatformCanBeCreated() |
| 4026 | + { |
| 4027 | + $container = $this->buildContainer([ |
| 4028 | + 'ai' => [ |
| 4029 | + 'platform' => [ |
| 4030 | + 'ollama' => [ |
| 4031 | + 'host_url' => 'http://127.0.0.1:11434', |
| 4032 | + ], |
| 4033 | + 'openai' => [ |
| 4034 | + 'api_key' => 'sk-openai_key_full', |
| 4035 | + ], |
| 4036 | + 'failover' => [ |
| 4037 | + 'main' => [ |
| 4038 | + 'platforms' => [ |
| 4039 | + 'ai.platform.ollama', |
| 4040 | + 'ai.platform.openai', |
| 4041 | + ], |
| 4042 | + ], |
| 4043 | + ], |
| 4044 | + ], |
| 4045 | + ], |
| 4046 | + ]); |
| 4047 | + |
| 4048 | + $this->assertTrue($container->hasDefinition('ai.platform.failover.main')); |
| 4049 | + |
| 4050 | + $definition = $container->getDefinition('ai.platform.failover.main'); |
| 4051 | + |
| 4052 | + $this->assertTrue($definition->isLazy()); |
| 4053 | + $this->assertSame(FailoverPlatform::class, $definition->getClass()); |
| 4054 | + |
| 4055 | + $this->assertCount(4, $definition->getArguments()); |
| 4056 | + $this->assertCount(2, $definition->getArgument(0)); |
| 4057 | + $this->assertEquals([ |
| 4058 | + new Reference('ai.platform.ollama'), |
| 4059 | + new Reference('ai.platform.openai'), |
| 4060 | + ], $definition->getArgument(0)); |
| 4061 | + $this->assertInstanceOf(Reference::class, $definition->getArgument(1)); |
| 4062 | + $this->assertSame(ClockInterface::class, (string) $definition->getArgument(1)); |
| 4063 | + $this->assertSame(60, $definition->getArgument(2)); |
| 4064 | + $this->assertInstanceOf(Reference::class, $definition->getArgument(3)); |
| 4065 | + $this->assertSame(LoggerInterface::class, (string) $definition->getArgument(3)); |
| 4066 | + |
| 4067 | + $this->assertTrue($definition->hasTag('proxy')); |
| 4068 | + $this->assertSame([['interface' => PlatformInterface::class]], $definition->getTag('proxy')); |
| 4069 | + $this->assertTrue($definition->hasTag('ai.platform')); |
| 4070 | + $this->assertSame([['name' => 'failover']], $definition->getTag('ai.platform')); |
| 4071 | + |
| 4072 | + $this->assertTrue($container->hasAlias('Symfony\AI\Platform\PlatformInterface $main')); |
| 4073 | + |
| 4074 | + $container = $this->buildContainer([ |
| 4075 | + 'ai' => [ |
| 4076 | + 'platform' => [ |
| 4077 | + 'ollama' => [ |
| 4078 | + 'host_url' => 'http://127.0.0.1:11434', |
| 4079 | + ], |
| 4080 | + 'openai' => [ |
| 4081 | + 'api_key' => 'sk-openai_key_full', |
| 4082 | + ], |
| 4083 | + 'failover' => [ |
| 4084 | + 'main' => [ |
| 4085 | + 'platforms' => [ |
| 4086 | + 'ai.platform.ollama', |
| 4087 | + 'ai.platform.openai', |
| 4088 | + ], |
| 4089 | + 'retry_period' => 120, |
| 4090 | + ], |
| 4091 | + ], |
| 4092 | + ], |
| 4093 | + ], |
| 4094 | + ]); |
| 4095 | + |
| 4096 | + $this->assertTrue($container->hasDefinition('ai.platform.failover.main')); |
| 4097 | + |
| 4098 | + $definition = $container->getDefinition('ai.platform.failover.main'); |
| 4099 | + |
| 4100 | + $this->assertTrue($definition->isLazy()); |
| 4101 | + $this->assertSame(FailoverPlatform::class, $definition->getClass()); |
| 4102 | + |
| 4103 | + $this->assertCount(4, $definition->getArguments()); |
| 4104 | + $this->assertCount(2, $definition->getArgument(0)); |
| 4105 | + $this->assertEquals([ |
| 4106 | + new Reference('ai.platform.ollama'), |
| 4107 | + new Reference('ai.platform.openai'), |
| 4108 | + ], $definition->getArgument(0)); |
| 4109 | + $this->assertInstanceOf(Reference::class, $definition->getArgument(1)); |
| 4110 | + $this->assertSame(ClockInterface::class, (string) $definition->getArgument(1)); |
| 4111 | + $this->assertSame(120, $definition->getArgument(2)); |
| 4112 | + $this->assertInstanceOf(Reference::class, $definition->getArgument(3)); |
| 4113 | + $this->assertSame(LoggerInterface::class, (string) $definition->getArgument(3)); |
| 4114 | + |
| 4115 | + $this->assertTrue($definition->hasTag('proxy')); |
| 4116 | + $this->assertSame([['interface' => PlatformInterface::class]], $definition->getTag('proxy')); |
| 4117 | + $this->assertTrue($definition->hasTag('ai.platform')); |
| 4118 | + $this->assertSame([['name' => 'failover']], $definition->getTag('ai.platform')); |
| 4119 | + |
| 4120 | + $this->assertTrue($container->hasAlias('Symfony\AI\Platform\PlatformInterface $main')); |
| 4121 | + } |
| 4122 | + |
4022 | 4123 | public function testOpenAiPlatformWithDefaultRegion() |
4023 | 4124 | { |
4024 | 4125 | $container = $this->buildContainer([ |
@@ -7013,6 +7114,7 @@ private function buildContainer(array $configuration): ContainerBuilder |
7013 | 7114 | $container->setParameter('kernel.environment', 'dev'); |
7014 | 7115 | $container->setParameter('kernel.build_dir', 'public'); |
7015 | 7116 | $container->setDefinition(ClockInterface::class, new Definition(MonotonicClock::class)); |
| 7117 | + $container->setDefinition(LoggerInterface::class, new Definition(NullLogger::class)); |
7016 | 7118 |
|
7017 | 7119 | $extension = (new AiBundle())->getContainerExtension(); |
7018 | 7120 | $extension->load($configuration, $container); |
@@ -7068,6 +7170,21 @@ private function getFullConfig(): array |
7068 | 7170 | 'host' => 'https://api.elevenlabs.io/v1', |
7069 | 7171 | 'api_key' => 'elevenlabs_key_full', |
7070 | 7172 | ], |
| 7173 | + 'failover' => [ |
| 7174 | + 'main' => [ |
| 7175 | + 'platforms' => [ |
| 7176 | + 'ai.platform.ollama', |
| 7177 | + 'ai.platform.openai', |
| 7178 | + ], |
| 7179 | + ], |
| 7180 | + 'main_with_custom_retry_period' => [ |
| 7181 | + 'platforms' => [ |
| 7182 | + 'ai.platform.ollama', |
| 7183 | + 'ai.platform.openai', |
| 7184 | + ], |
| 7185 | + 'retry_period' => 120, |
| 7186 | + ], |
| 7187 | + ], |
7071 | 7188 | 'gemini' => [ |
7072 | 7189 | 'api_key' => 'gemini_key_full', |
7073 | 7190 | ], |
|
0 commit comments