Skip to content

Commit 86b5a69

Browse files
committed
feature #1157 [Platform] Improvements on CachedPlatform (Guikingone)
This PR was squashed before being merged into the main branch. Discussion ---------- [Platform] Improvements on `CachedPlatform` | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | yes | Issues | Extracted from #1122 | License | MIT Summary: - Add `MonotonicClock` as the default implementation for `ClockInterface` argument in `CachedPlatform` to ease tests and improve precision instead of `DatetimeImmutable()` - Add an alias for `CachedPlatform` - Add missing `.` in the `name` tag of `CachedPlatform` definition - Improvements on tests for arguments / tags Commits ------- 149ff59 [Platform] Improvements on `CachedPlatform`
2 parents c707381 + 149ff59 commit 86b5a69

File tree

5 files changed

+46
-15
lines changed

5 files changed

+46
-15
lines changed

examples/misc/agent-with-cache.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
require_once dirname(__DIR__).'/bootstrap.php';
2121

2222
$platform = PlatformFactory::create(env('OLLAMA_HOST_URL'), http_client());
23-
$cachedPlatform = new CachedPlatform($platform, new TagAwareAdapter(new ArrayAdapter()));
23+
$cachedPlatform = new CachedPlatform($platform, cache: new TagAwareAdapter(new ArrayAdapter()));
2424

2525
$agent = new Agent($cachedPlatform, 'qwen3:0.6b-q4_K_M');
2626
$messages = new MessageBag(

src/ai-bundle/src/AiBundle.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,13 +402,15 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
402402
->setLazy(true)
403403
->setArguments([
404404
new Reference($cachedPlatformConfig['platform']),
405+
new Reference(ClockInterface::class),
405406
new Reference($cachedPlatformConfig['service'], ContainerInterface::NULL_ON_INVALID_REFERENCE),
406407
$cachedPlatformConfig['cache_key'] ?? $name,
407408
])
408409
->addTag('proxy', ['interface' => PlatformInterface::class])
409-
->addTag('ai.platform', ['name' => 'cache'.$name]);
410+
->addTag('ai.platform', ['name' => 'cache.'.$name]);
410411

411412
$container->setDefinition('ai.platform.cache.'.$name, $definition);
413+
$container->registerAliasForArgument('ai.platform.'.$type, PlatformInterface::class, $type.'_'.$name);
412414
}
413415

414416
return;

src/ai-bundle/tests/DependencyInjection/AiBundleTest.php

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use Symfony\AI\Platform\Bridge\ElevenLabs\ModelCatalog as ElevenLabsModelCatalog;
3333
use Symfony\AI\Platform\Bridge\ElevenLabs\PlatformFactory as ElevenLabsPlatformFactory;
3434
use Symfony\AI\Platform\Bridge\Ollama\OllamaApiCatalog;
35+
use Symfony\AI\Platform\CachedPlatform;
3536
use Symfony\AI\Platform\Capability;
3637
use Symfony\AI\Platform\EventListener\TemplateRendererListener;
3738
use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionLanguageTemplateRenderer;
@@ -74,6 +75,8 @@
7475
use Symfony\AI\Store\ManagedStoreInterface;
7576
use Symfony\AI\Store\RetrieverInterface;
7677
use Symfony\AI\Store\StoreInterface;
78+
use Symfony\Component\Clock\ClockInterface;
79+
use Symfony\Component\Clock\MonotonicClock;
7780
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
7881
use Symfony\Component\DependencyInjection\ContainerBuilder;
7982
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -6225,18 +6228,29 @@ public function testCachedPlatformCanBeUsed()
62256228
$this->assertTrue($container->hasDefinition('ai.platform.cache.ollama'));
62266229

62276230
$definition = $container->getDefinition('ai.platform.cache.ollama');
6231+
6232+
$this->assertSame(CachedPlatform::class, $definition->getClass());
62286233
$this->assertTrue($definition->isLazy());
6229-
$this->assertCount(3, $definition->getArguments());
6234+
$this->assertCount(4, $definition->getArguments());
62306235

62316236
$this->assertInstanceOf(Reference::class, $definition->getArgument(0));
62326237
$platformArgument = $definition->getArgument(0);
62336238
$this->assertSame('ai.platform.ollama', (string) $platformArgument);
6234-
6239+
$this->assertSame(ClockInterface::class, (string) $definition->getArgument(1));
62356240
$this->assertInstanceOf(Reference::class, $definition->getArgument(1));
6236-
$cacheArgument = $definition->getArgument(1);
6237-
$this->assertSame('cache.app', (string) $cacheArgument);
6241+
$this->assertSame('cache.app', (string) $definition->getArgument(2));
6242+
$this->assertSame('ollama', $definition->getArgument(3));
6243+
6244+
$this->assertSame([
6245+
['interface' => PlatformInterface::class],
6246+
], $definition->getTag('proxy'));
6247+
$this->assertTrue($definition->hasTag('ai.platform'));
6248+
$this->assertSame([
6249+
['name' => 'cache.ollama'],
6250+
], $definition->getTag('ai.platform'));
62386251

6239-
$this->assertSame('ollama', $definition->getArgument(2));
6252+
$this->assertTrue($container->hasAlias('.Symfony\AI\Platform\PlatformInterface $cache_ollama'));
6253+
$this->assertTrue($container->hasAlias('Symfony\AI\Platform\PlatformInterface $cacheOllama'));
62406254
}
62416255

62426256
public function testCachedPlatformCanBeUsedWithoutCustomCacheKey()
@@ -6260,18 +6274,29 @@ public function testCachedPlatformCanBeUsedWithoutCustomCacheKey()
62606274
$this->assertTrue($container->hasDefinition('ai.platform.cache.ollama'));
62616275

62626276
$definition = $container->getDefinition('ai.platform.cache.ollama');
6277+
6278+
$this->assertSame(CachedPlatform::class, $definition->getClass());
62636279
$this->assertTrue($definition->isLazy());
6264-
$this->assertCount(3, $definition->getArguments());
6280+
$this->assertCount(4, $definition->getArguments());
62656281

62666282
$this->assertInstanceOf(Reference::class, $definition->getArgument(0));
62676283
$platformArgument = $definition->getArgument(0);
62686284
$this->assertSame('ai.platform.ollama', (string) $platformArgument);
6269-
6285+
$this->assertSame(ClockInterface::class, (string) $definition->getArgument(1));
62706286
$this->assertInstanceOf(Reference::class, $definition->getArgument(1));
6271-
$cacheArgument = $definition->getArgument(1);
6272-
$this->assertSame('cache.app', (string) $cacheArgument);
6287+
$this->assertSame('cache.app', (string) $definition->getArgument(2));
6288+
$this->assertSame('ollama', $definition->getArgument(3));
6289+
6290+
$this->assertSame([
6291+
['interface' => PlatformInterface::class],
6292+
], $definition->getTag('proxy'));
6293+
$this->assertTrue($definition->hasTag('ai.platform'));
6294+
$this->assertSame([
6295+
['name' => 'cache.ollama'],
6296+
], $definition->getTag('ai.platform'));
62736297

6274-
$this->assertSame('ollama', $definition->getArgument(2));
6298+
$this->assertTrue($container->hasAlias('.Symfony\AI\Platform\PlatformInterface $cache_ollama'));
6299+
$this->assertTrue($container->hasAlias('Symfony\AI\Platform\PlatformInterface $cacheOllama'));
62756300
}
62766301

62776302
public function testCacheMessageStoreCanBeConfiguredWithCustomKey()
@@ -6987,6 +7012,7 @@ private function buildContainer(array $configuration): ContainerBuilder
69877012
$container->setParameter('kernel.debug', true);
69887013
$container->setParameter('kernel.environment', 'dev');
69897014
$container->setParameter('kernel.build_dir', 'public');
7015+
$container->setDefinition(ClockInterface::class, new Definition(MonotonicClock::class));
69907016

69917017
$extension = (new AiBundle())->getContainerExtension();
69927018
$extension->load($configuration, $container);

src/platform/src/CachedPlatform.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Symfony\AI\Platform\ModelCatalog\ModelCatalogInterface;
1515
use Symfony\AI\Platform\Result\DeferredResult;
1616
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
17+
use Symfony\Component\Clock\ClockInterface;
18+
use Symfony\Component\Clock\MonotonicClock;
1719
use Symfony\Contracts\Cache\CacheInterface;
1820
use Symfony\Contracts\Cache\ItemInterface;
1921

@@ -24,6 +26,7 @@ final class CachedPlatform implements PlatformInterface
2426
{
2527
public function __construct(
2628
private readonly PlatformInterface $platform,
29+
private readonly ClockInterface $clock = new MonotonicClock(),
2730
private readonly (CacheInterface&TagAwareAdapterInterface)|null $cache = null,
2831
private readonly ?string $cacheKey = null,
2932
) {
@@ -38,7 +41,7 @@ public function invoke(string $model, array|string|object $input, array $options
3841

3942
unset($options['prompt_cache_key']);
4043

41-
return $this->cache->get($cacheKey, static function (ItemInterface $item) use ($invokeCall, $model, $input, $options, $cacheKey): DeferredResult {
44+
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($invokeCall, $model, $input, $options, $cacheKey): DeferredResult {
4245
$item->tag($model);
4346

4447
$result = $invokeCall($model, $input, $options);
@@ -52,7 +55,7 @@ public function invoke(string $model, array|string|object $input, array $options
5255
$result->getMetadata()->set([
5356
'cached' => true,
5457
'cache_key' => $cacheKey,
55-
'cached_at' => (new \DateTimeImmutable())->getTimestamp(),
58+
'cached_at' => $this->clock->now()->getTimestamp(),
5659
]);
5760

5861
return $result;

src/platform/tests/CachedPlatformTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function testPlatformCanReturnCachedResultWhenCalledTwice()
4040

4141
$cachedPlatform = new CachedPlatform(
4242
$platform,
43-
new TagAwareAdapter(new ArrayAdapter()),
43+
cache: new TagAwareAdapter(new ArrayAdapter()),
4444
);
4545

4646
$deferredResult = $cachedPlatform->invoke('foo', 'bar', [

0 commit comments

Comments
 (0)