Skip to content

Commit f9c28e0

Browse files
committed
feature #583 [AI Bundle] Add memory provider configuration support (OskarStark)
This PR was squashed before being merged into the main branch. Discussion ---------- [AI Bundle] Add memory provider configuration support | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Docs? | yes | Issues | Follows #117 | License | MIT This PR introduces comprehensive memory provider configuration capabilities for AI agents, enabling both simple static memory and advanced dynamic memory scenarios. ## 🚀 Key Features ### Smart Detection Logic The system automatically detects the intent: - If the value matches an existing service/alias → uses that service directly - If no matching service exists → creates `StaticMemoryProvider` with the string as static content ### Memory as System Prompt - When only `memory` is provided (no `prompt`), memory serves as the system prompt - When both `memory` and `prompt` are provided, memory is prepended to the prompt ### Configuration Examples **Static Memory (Most Common):** ```yaml ai: agent: my_agent: model: class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt' name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI memory: 'You have access to user preferences and conversation history' prompt: text: 'You are a helpful assistant.' ``` **Dynamic Memory (Advanced):** ```yaml ai: agent: my_agent: model: class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt' name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI memory: 'my_custom_memory_service' # References existing service prompt: text: 'You are a helpful assistant.' ``` **Memory as System Prompt:** ```yaml ai: agent: my_agent: model: class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt' name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI memory: 'You are a helpful assistant with access to user context.' # No prompt needed - memory serves as system prompt ``` This enhancement significantly improves the developer experience while maintaining full backward compatibility and adding powerful new memory capabilities for AI agents. cc `@DZunke` Commits ------- f4ac5b6 [AI Bundle] Add memory provider configuration support
2 parents d8dfb30 + f4ac5b6 commit f9c28e0

File tree

5 files changed

+651
-30
lines changed

5 files changed

+651
-30
lines changed

src/ai-bundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add Symfony bundle for integrating Platform, Agent, and Store components
8+
* Add memory provider configuration support for agents. Symfony AI was bootstrapped by Christopher Hertel and Oskar Stark
89
* Add Perplexity platform support with API key configuration
910
* Add service configuration:
1011
- Agent services with configurable platforms and system prompts

src/ai-bundle/config/options.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@
130130
->end()
131131
->end()
132132
->booleanNode('structured_output')->defaultTrue()->end()
133+
->scalarNode('memory')
134+
->info('Plain string or service name of the memory provider implementing MemoryProviderInterface')
135+
->defaultNull()
136+
->validate()
137+
->ifTrue(function ($v) { return \is_string($v) && '' === $v; })
138+
->thenInvalid('Memory cannot be empty.')
139+
->end()
140+
->end()
133141
->arrayNode('prompt')
134142
->info('The system prompt configuration')
135143
->beforeNormalization()

src/ai-bundle/doc/index.rst

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Configuration
7171
model:
7272
class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt'
7373
name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI
74+
memory: 'You have access to conversation history and user preferences' # Optional: static memory or service reference
7475
prompt: # The system prompt configuration
7576
text: 'You are a helpful assistant that can answer questions.' # The prompt text
7677
include_tools: true # Include tool definitions at the end of the system prompt
@@ -181,6 +182,108 @@ The array format supports these options:
181182
* ``text`` (string, required): The system prompt text that will be sent to the AI model
182183
* ``include_tools`` (boolean, optional): When set to ``true``, tool definitions will be appended to the system prompt
183184

185+
Memory Provider Configuration
186+
-----------------------------
187+
188+
Memory providers allow agents to access and utilize conversation history and context from previous interactions.
189+
This enables agents to maintain context across conversations and provide more personalized responses.
190+
191+
**Static Memory (Simple)**
192+
193+
The simplest way to add memory is to provide a string that will be used as static context:
194+
195+
.. code-block:: yaml
196+
197+
ai:
198+
agent:
199+
my_agent:
200+
model:
201+
class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt'
202+
name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI
203+
memory: 'You have access to user preferences and conversation history'
204+
prompt:
205+
text: 'You are a helpful assistant.'
206+
207+
This static memory content is consistently available to the agent across all conversations.
208+
209+
**Dynamic Memory (Advanced)**
210+
211+
For more sophisticated scenarios, you can reference an existing service that implements dynamic memory:
212+
213+
.. code-block:: yaml
214+
215+
ai:
216+
agent:
217+
my_agent:
218+
model:
219+
class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt'
220+
name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI
221+
memory: 'my_memory_service' # References an existing service
222+
prompt:
223+
text: 'You are a helpful assistant.'
224+
225+
**Memory as System Prompt**
226+
227+
Memory can work independently or alongside the system prompt:
228+
229+
- **Memory only**: If no prompt is provided, memory becomes the system prompt
230+
- **Memory + Prompt**: If both are provided, memory is prepended to the prompt
231+
232+
.. code-block:: yaml
233+
234+
ai:
235+
agent:
236+
# Agent with memory only (memory becomes system prompt)
237+
memory_only_agent:
238+
model:
239+
class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt'
240+
memory: 'You are a helpful assistant with conversation history'
241+
242+
# Agent with both memory and prompt (memory prepended to prompt)
243+
memory_and_prompt_agent:
244+
model:
245+
class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt'
246+
memory: 'Previous conversation context...'
247+
prompt:
248+
text: 'You are a helpful assistant.'
249+
250+
**Custom Memory Provider Requirements**
251+
252+
When using a service reference, the memory service must implement the ``Symfony\AI\Agent\Memory\MemoryProviderInterface``::
253+
254+
use Symfony\AI\Agent\Input;
255+
use Symfony\AI\Agent\Memory\Memory;
256+
use Symfony\AI\Agent\Memory\MemoryProviderInterface;
257+
258+
final class MyMemoryProvider implements MemoryProviderInterface
259+
{
260+
public function loadMemory(Input $input): array
261+
{
262+
// Return an array of Memory objects containing relevant conversation history
263+
return [
264+
new Memory('Previous conversation context...'),
265+
new Memory('User preferences: prefers concise answers'),
266+
];
267+
}
268+
}
269+
270+
**How Memory Works**
271+
272+
The system automatically detects whether to use static or dynamic memory:
273+
274+
**Static Memory Processing:**
275+
1. When you provide a string that doesn't match any service name
276+
2. The system creates a ``StaticMemoryProvider`` automatically
277+
3. Content is formatted as "## Static Memory" with the provided text
278+
4. This memory is consistently available across all conversations
279+
280+
**Dynamic Memory Processing:**
281+
1. When the string matches an existing service in the container
282+
2. The ``MemoryInputProcessor`` uses that service directly
283+
3. The service's ``loadMemory()`` method is called before processing user input
284+
4. Dynamic memory content is injected based on the current context
285+
286+
In both cases, memory content is prepended to the system message, allowing the agent to utilize the context effectively.
184287

185288
Usage
186289
-----

src/ai-bundle/src/AiBundle.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use Symfony\AI\Agent\Attribute\AsOutputProcessor;
2020
use Symfony\AI\Agent\InputProcessor\SystemPromptInputProcessor;
2121
use Symfony\AI\Agent\InputProcessorInterface;
22+
use Symfony\AI\Agent\Memory\MemoryInputProcessor;
23+
use Symfony\AI\Agent\Memory\StaticMemoryProvider;
2224
use Symfony\AI\Agent\OutputProcessorInterface;
2325
use Symfony\AI\Agent\Toolbox\Attribute\AsTool;
2426
use Symfony\AI\Agent\Toolbox\FaultTolerantToolbox;
@@ -618,6 +620,31 @@ private function processAgentConfig(string $name, array $config, ContainerBuilde
618620
$container->setDefinition('ai.agent.'.$name.'.system_prompt_processor', $systemPromptInputProcessorDefinition);
619621
}
620622

623+
// MEMORY PROVIDER
624+
if (isset($config['memory'])) {
625+
$memoryValue = $config['memory'];
626+
627+
// Check if the value refers to an existing service
628+
if ($container->hasDefinition($memoryValue) || $container->hasAlias($memoryValue)) {
629+
// Use existing service as memory provider
630+
$memoryProviderReference = new Reference($memoryValue);
631+
} else {
632+
// Create StaticMemoryProvider with the string as static content
633+
$staticMemoryProviderDefinition = (new Definition(StaticMemoryProvider::class))
634+
->setArguments([$memoryValue]);
635+
636+
$staticMemoryServiceId = 'ai.agent.'.$name.'.static_memory_provider';
637+
$container->setDefinition($staticMemoryServiceId, $staticMemoryProviderDefinition);
638+
$memoryProviderReference = new Reference($staticMemoryServiceId);
639+
}
640+
641+
$memoryInputProcessorDefinition = (new Definition(MemoryInputProcessor::class))
642+
->setArguments([$memoryProviderReference])
643+
->addTag('ai.agent.input_processor', ['agent' => $agentId, 'priority' => -40]);
644+
645+
$container->setDefinition('ai.agent.'.$name.'.memory_input_processor', $memoryInputProcessorDefinition);
646+
}
647+
621648
$agentDefinition
622649
->setArgument(2, []) // placeholder until ProcessorCompilerPass process.
623650
->setArgument(3, []) // placeholder until ProcessorCompilerPass process.

0 commit comments

Comments
 (0)