Skip to content

Commit 04f14a9

Browse files
fix code review and phpstan errors
1 parent f67c952 commit 04f14a9

File tree

11 files changed

+50
-73
lines changed

11 files changed

+50
-73
lines changed

examples/platform/message-templates.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
require_once dirname(__DIR__).'/bootstrap.php';
2222

23-
// Setup event dispatcher with template renderer
2423
$eventDispatcher = new EventDispatcher();
2524
$rendererRegistry = new TemplateRendererRegistry([
2625
new StringTemplateRenderer(),
@@ -63,16 +62,7 @@
6362
echo "Variables: ['topic' => 'PHP']\n";
6463
echo 'Response: '.$result->asText()."\n\n";
6564

66-
echo "Example 3: AssistantMessage with template\n";
67-
echo "==========================================\n\n";
68-
69-
$assistantTemplate = Template::string('The answer is {result}');
70-
$message = Message::ofAssistant($assistantTemplate);
71-
72-
echo "AssistantMessage template: The answer is {result}\n";
73-
echo "Note: AssistantMessage templates are useful for creating conversation history\n\n";
74-
75-
echo "Example 4: Multiple messages with templates\n";
65+
echo "Example 3: Multiple messages with templates\n";
7666
echo "============================================\n\n";
7767

7868
$systemTemplate = Template::string('You are a {role} assistant.');
@@ -95,7 +85,7 @@
9585
echo "Variables: ['role' => 'helpful', 'operation' => '2 + 2']\n";
9686
echo 'Response: '.$result->asText()."\n\n";
9787

98-
echo "Example 5: UserMessage with mixed content\n";
88+
echo "Example 4: UserMessage with mixed content\n";
9989
echo "==========================================\n\n";
10090

10191
$messages = new MessageBag(

src/ai-bundle/config/services.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
use Symfony\AI\Platform\Contract\JsonSchema\DescriptionParser;
6464
use Symfony\AI\Platform\Contract\JsonSchema\Factory as SchemaFactory;
6565
use Symfony\AI\Platform\EventListener\TemplateRendererListener;
66-
use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionTemplateRenderer;
66+
use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionLanguageTemplateRenderer;
6767
use Symfony\AI\Platform\Message\TemplateRenderer\StringTemplateRenderer;
6868
use Symfony\AI\Platform\Message\TemplateRenderer\TemplateRendererRegistry;
6969
use Symfony\AI\Platform\Serializer\StructuredOutputSerializer;
@@ -118,7 +118,7 @@
118118
// message templates
119119
->set('ai.platform.template_renderer.string', StringTemplateRenderer::class)
120120
->tag('ai.platform.template_renderer')
121-
->set('ai.platform.template_renderer.expression', ExpressionTemplateRenderer::class)
121+
->set('ai.platform.template_renderer.expression', ExpressionLanguageTemplateRenderer::class)
122122
->args([
123123
service('expression_language')->nullOnInvalid(),
124124
])

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
use Symfony\AI\Chat\MessageStoreInterface;
2929
use Symfony\AI\Platform\Bridge\Ollama\OllamaApiCatalog;
3030
use Symfony\AI\Platform\Capability;
31+
use Symfony\AI\Platform\EventListener\TemplateRendererListener;
32+
use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionLanguageTemplateRenderer;
33+
use Symfony\AI\Platform\Message\TemplateRenderer\StringTemplateRenderer;
34+
use Symfony\AI\Platform\Message\TemplateRenderer\TemplateRendererRegistry;
3135
use Symfony\AI\Platform\Model;
3236
use Symfony\AI\Store\Bridge\Azure\SearchStore as AzureStore;
3337
use Symfony\AI\Store\Bridge\ChromaDb\Store as ChromaDbStore;
@@ -4425,24 +4429,24 @@ public function testTemplateRendererServicesAreRegistered()
44254429
// Verify string template renderer is registered
44264430
$this->assertTrue($container->hasDefinition('ai.platform.template_renderer.string'));
44274431
$stringRendererDefinition = $container->getDefinition('ai.platform.template_renderer.string');
4428-
$this->assertSame(\Symfony\AI\Platform\Message\TemplateRenderer\StringTemplateRenderer::class, $stringRendererDefinition->getClass());
4432+
$this->assertSame(StringTemplateRenderer::class, $stringRendererDefinition->getClass());
44294433
$this->assertTrue($stringRendererDefinition->hasTag('ai.platform.template_renderer'));
44304434

44314435
// Verify expression template renderer is registered
44324436
$this->assertTrue($container->hasDefinition('ai.platform.template_renderer.expression'));
44334437
$expressionRendererDefinition = $container->getDefinition('ai.platform.template_renderer.expression');
4434-
$this->assertSame(\Symfony\AI\Platform\Message\TemplateRenderer\ExpressionTemplateRenderer::class, $expressionRendererDefinition->getClass());
4438+
$this->assertSame(ExpressionLanguageTemplateRenderer::class, $expressionRendererDefinition->getClass());
44354439
$this->assertTrue($expressionRendererDefinition->hasTag('ai.platform.template_renderer'));
44364440

44374441
// Verify template renderer registry is registered
44384442
$this->assertTrue($container->hasDefinition('ai.platform.template_renderer_registry'));
44394443
$registryDefinition = $container->getDefinition('ai.platform.template_renderer_registry');
4440-
$this->assertSame(\Symfony\AI\Platform\Message\TemplateRenderer\TemplateRendererRegistry::class, $registryDefinition->getClass());
4444+
$this->assertSame(TemplateRendererRegistry::class, $registryDefinition->getClass());
44414445

44424446
// Verify template renderer listener is registered as event subscriber
44434447
$this->assertTrue($container->hasDefinition('ai.platform.template_renderer_listener'));
44444448
$listenerDefinition = $container->getDefinition('ai.platform.template_renderer_listener');
4445-
$this->assertSame(\Symfony\AI\Platform\EventListener\TemplateRendererListener::class, $listenerDefinition->getClass());
4449+
$this->assertSame(TemplateRendererListener::class, $listenerDefinition->getClass());
44464450
$this->assertTrue($listenerDefinition->hasTag('kernel.event_subscriber'));
44474451
}
44484452

src/platform/AGENTS.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ composer update
6060

6161
### Message Templates
6262

63-
Templates support variable substitution with type-based rendering. All message types (SystemMessage, UserMessage, AssistantMessage) support templates.
63+
Templates support variable substitution with type-based rendering. SystemMessage and UserMessage support templates.
6464

6565
```php
6666
use Symfony\AI\Platform\Message\Message;
@@ -74,9 +74,6 @@ $message = Message::forSystem($template);
7474
// UserMessage with template
7575
$message = Message::ofUser(Template::string('Calculate {operation}'));
7676

77-
// AssistantMessage with template
78-
$message = Message::ofAssistant(Template::string('The answer is {result}'));
79-
8077
// Multiple messages with templates
8178
$messages = new MessageBag(
8279
Message::forSystem(Template::string('You are a {role} assistant.')),

src/platform/CLAUDE.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ The component supports multiple AI providers through Bridge implementations:
7373

7474
### Message Templates
7575

76-
Templates support variable substitution with type-based rendering. All message types (SystemMessage, UserMessage, AssistantMessage) support templates:
76+
Templates support variable substitution with type-based rendering. SystemMessage and UserMessage support templates:
7777

7878
```php
7979
use Symfony\AI\Platform\Message\Message;
@@ -87,9 +87,6 @@ $message = Message::forSystem($template);
8787
// UserMessage with template
8888
$message = Message::ofUser(Template::string('Calculate {operation}'));
8989

90-
// AssistantMessage with template
91-
$message = Message::ofAssistant(Template::string('The answer is {result}'));
92-
9390
// UserMessage with mixed content (text and template)
9491
$message = Message::ofUser(
9592
'Plain text',

src/platform/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"symfony/cache": "^7.3|^8.0",
7070
"symfony/console": "^7.3|^8.0",
7171
"symfony/dotenv": "^7.3|^8.0",
72+
"symfony/expression-language": "^7.3|^8.0",
7273
"symfony/finder": "^7.3|^8.0",
7374
"symfony/process": "^7.3|^8.0",
7475
"symfony/var-dumper": "^7.3|^8.0"

src/platform/src/EventListener/TemplateRendererListener.php

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\AI\Platform\EventListener;
1313

1414
use Symfony\AI\Platform\Event\InvocationEvent;
15-
use Symfony\AI\Platform\Message\AssistantMessage;
1615
use Symfony\AI\Platform\Message\Content\Text;
1716
use Symfony\AI\Platform\Message\MessageBag;
1817
use Symfony\AI\Platform\Message\MessageInterface;
@@ -34,13 +33,6 @@ public function __construct(
3433
) {
3534
}
3635

37-
public static function getSubscribedEvents(): array
38-
{
39-
return [
40-
InvocationEvent::class => '__invoke',
41-
];
42-
}
43-
4436
public function __invoke(InvocationEvent $event): void
4537
{
4638
$options = $event->getOptions();
@@ -66,6 +58,16 @@ public function __invoke(InvocationEvent $event): void
6658
$event->setOptions($options);
6759
}
6860

61+
public static function getSubscribedEvents(): array
62+
{
63+
return [
64+
InvocationEvent::class => '__invoke',
65+
];
66+
}
67+
68+
/**
69+
* @param array<string, mixed> $templateVars
70+
*/
6971
private function renderMessage(MessageInterface $message, array $templateVars): MessageInterface
7072
{
7173
if ($message instanceof SystemMessage) {
@@ -77,15 +79,6 @@ private function renderMessage(MessageInterface $message, array $templateVars):
7779
}
7880
}
7981

80-
if ($message instanceof AssistantMessage) {
81-
$content = $message->getContent();
82-
if ($content instanceof Template) {
83-
$renderedContent = $this->rendererRegistry->render($content, $templateVars);
84-
85-
return new AssistantMessage($renderedContent, $message->getToolCalls());
86-
}
87-
}
88-
8982
if ($message instanceof UserMessage) {
9083
$hasTemplate = false;
9184
$renderedContent = [];

src/platform/src/Message/TemplateRenderer/ExpressionTemplateRenderer.php renamed to src/platform/src/Message/TemplateRenderer/ExpressionLanguageTemplateRenderer.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
1717

1818
/**
19-
* Expression Language template renderer.
20-
*
2119
* @author Johannes Wachter <johannes@sulu.io>
2220
*/
23-
final readonly class ExpressionTemplateRenderer implements TemplateRendererInterface
21+
final readonly class ExpressionLanguageTemplateRenderer implements TemplateRendererInterface
2422
{
2523
private ExpressionLanguage $expressionLanguage;
2624

src/platform/tests/EventListener/TemplateRendererListenerTest.php

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ public function testRendersTemplateWhenTemplateVarsProvided(): void
4848

4949
($this->listener)($event);
5050

51-
$messages = $event->getInput()->getMessages();
51+
$input = $event->getInput();
52+
$this->assertInstanceOf(MessageBag::class, $input);
53+
$messages = $input->getMessages();
5254
$this->assertCount(1, $messages);
5355
$this->assertSame('Hello World!', $messages[0]->getContent());
5456
}
@@ -79,7 +81,9 @@ public function testDoesNothingWhenTemplateVarsNotProvided(): void
7981

8082
($this->listener)($event);
8183

82-
$messages = $event->getInput()->getMessages();
84+
$input = $event->getInput();
85+
$this->assertInstanceOf(MessageBag::class, $input);
86+
$messages = $input->getMessages();
8387
$this->assertCount(1, $messages);
8488
$this->assertInstanceOf(Template::class, $messages[0]->getContent());
8589
}
@@ -114,7 +118,9 @@ public function testRendersMultipleMessages(): void
114118

115119
($this->listener)($event);
116120

117-
$messages = $event->getInput()->getMessages();
121+
$input = $event->getInput();
122+
$this->assertInstanceOf(MessageBag::class, $input);
123+
$messages = $input->getMessages();
118124
$this->assertCount(2, $messages);
119125
$this->assertSame('System: assistant', $messages[0]->getContent());
120126
$this->assertSame('User: help', $messages[1]->getContent());
@@ -133,28 +139,14 @@ public function testDoesNotRenderNonTemplateMessages(): void
133139

134140
($this->listener)($event);
135141

136-
$messages = $event->getInput()->getMessages();
142+
$input = $event->getInput();
143+
$this->assertInstanceOf(MessageBag::class, $input);
144+
$messages = $input->getMessages();
137145
$this->assertCount(2, $messages);
138146
$this->assertSame('Plain string', $messages[0]->getContent());
139147
$this->assertSame('Hello World!', $messages[1]->getContent());
140148
}
141149

142-
public function testRendersAssistantMessageTemplate(): void
143-
{
144-
$template = Template::string('Response: {answer}');
145-
$messageBag = new MessageBag(Message::ofAssistant($template));
146-
147-
$event = new InvocationEvent($this->model, $messageBag, [
148-
'template_vars' => ['answer' => '42'],
149-
]);
150-
151-
($this->listener)($event);
152-
153-
$messages = $event->getInput()->getMessages();
154-
$this->assertCount(1, $messages);
155-
$this->assertSame('Response: 42', $messages[0]->getContent());
156-
}
157-
158150
public function testRendersUserMessageTemplate(): void
159151
{
160152
$template = Template::string('Question: {query}');
@@ -166,7 +158,9 @@ public function testRendersUserMessageTemplate(): void
166158

167159
($this->listener)($event);
168160

169-
$messages = $event->getInput()->getMessages();
161+
$input = $event->getInput();
162+
$this->assertInstanceOf(MessageBag::class, $input);
163+
$messages = $input->getMessages();
170164
$this->assertCount(1, $messages);
171165

172166
$content = $messages[0]->getContent();
@@ -188,7 +182,9 @@ public function testRendersUserMessageWithMixedContent(): void
188182

189183
($this->listener)($event);
190184

191-
$messages = $event->getInput()->getMessages();
185+
$input = $event->getInput();
186+
$this->assertInstanceOf(MessageBag::class, $input);
187+
$messages = $input->getMessages();
192188
$content = $messages[0]->getContent();
193189

194190
$this->assertCount(2, $content);

src/platform/tests/Message/TemplateRenderer/ExpressionTemplateRendererTest.php renamed to src/platform/tests/Message/TemplateRenderer/ExpressionLanguageTemplateRendererTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\AI\Platform\Exception\InvalidArgumentException;
1616
use Symfony\AI\Platform\Message\Template;
17-
use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionTemplateRenderer;
17+
use Symfony\AI\Platform\Message\TemplateRenderer\ExpressionLanguageTemplateRenderer;
1818
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
1919

20-
final class ExpressionTemplateRendererTest extends TestCase
20+
final class ExpressionLanguageTemplateRendererTest extends TestCase
2121
{
22-
private ExpressionTemplateRenderer $renderer;
22+
private ExpressionLanguageTemplateRenderer $renderer;
2323

2424
protected function setUp(): void
2525
{
2626
if (!class_exists(ExpressionLanguage::class)) {
2727
$this->markTestSkipped('symfony/expression-language is not installed');
2828
}
2929

30-
$this->renderer = new ExpressionTemplateRenderer();
30+
$this->renderer = new ExpressionLanguageTemplateRenderer();
3131
}
3232

3333
public function testSupportsExpressionType(): void
@@ -93,6 +93,6 @@ public function testConstructorThrowsExceptionWhenExpressionLanguageNotAvailable
9393
$this->expectException(InvalidArgumentException::class);
9494
$this->expectExceptionMessage('ExpressionTemplateRenderer requires "symfony/expression-language" package');
9595

96-
new ExpressionTemplateRenderer();
96+
new ExpressionLanguageTemplateRenderer();
9797
}
9898
}

0 commit comments

Comments
 (0)