Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/components/chat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ with a ``Symfony\AI\Agent\AgentInterface`` and a ``Symfony\AI\Chat\MessageStoreI

$chat->submit(Message::ofUser('Hello'));

You can find more advanced usage in combination with an Agent using the store for long-term context:

* `External services storage with Cache`_
* `Current session context storage with HttpFoundation session`_
* `Current process context storage with InMemory`_
* `Long-term context with Meilisearch`_

Supported Message stores
------------------------

* `Cache`_
* `HttpFoundation session`_
* `InMemory`_
* `Meilisearch`_

Implementing a Bridge
---------------------
Expand Down Expand Up @@ -105,3 +119,12 @@ store and ``bin/console ai:message-store:drop`` to clean up the message store:

$ php bin/console ai:message-store:setup symfonycon
$ php bin/console ai:message-store:drop symfonycon

.. _`External services storage with Cache`: https://github.com/symfony/ai/blob/main/examples/chat/persistent-chat-cache.php
.. _`Current session context storage with HttpFoundation session`: https://github.com/symfony/ai/blob/main/examples/chat/persistent-chat-session.php
.. _`Current process context storage with InMemory`: https://github.com/symfony/ai/blob/main/examples/chat/persistent-chat.php
.. _`Long-term context with Meilisearch`: https://github.com/symfony/ai/blob/main/examples/chat/persistent-chat-meilisearch.php
.. _`Cache`: https://symfony.com/doc/current/components/cache.html
.. _`InMemory`: https://www.php.net/manual/en/language.types.array.php
.. _`HttpFoundation session`: https://developers.cloudflare.com/vectorize/
.. _`Meilisearch`: https://www.meilisearch.com/
38 changes: 38 additions & 0 deletions examples/chat/persistent-chat-meilisearch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Symfony\AI\Agent\Agent;
use Symfony\AI\Chat\Bridge\Meilisearch\MessageStore;
use Symfony\AI\Chat\Chat;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
use Symfony\Component\Clock\MonotonicClock;

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

$platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client());

$store = new MessageStore(http_client(), env('MEILISEARCH_HOST'), env('MEILISEARCH_API_KEY'), new MonotonicClock());
$store->setup();

$agent = new Agent($platform, 'gpt-4o-mini');
$chat = new Chat($agent, $store);

$messages = new MessageBag(
Message::forSystem('You are a helpful assistant. You only answer with short sentences.'),
);

$chat->initiate($messages);
$chat->submit(Message::ofUser('My name is Christopher.'));
$message = $chat->submit(Message::ofUser('What is my name?'));

echo $message->getContent().\PHP_EOL;
9 changes: 9 additions & 0 deletions examples/commands/message-stores.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
use Symfony\AI\Chat\Bridge\HttpFoundation\SessionStore;
use Symfony\AI\Chat\Bridge\Local\CacheStore;
use Symfony\AI\Chat\Bridge\Local\InMemoryStore;
use Symfony\AI\Chat\Bridge\Meilisearch\MessageStore as MeilisearchMessageStore;
use Symfony\AI\Chat\Command\DropStoreCommand;
use Symfony\AI\Chat\Command\SetupStoreCommand;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Clock\MonotonicClock;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\ConsoleOutput;
Expand All @@ -28,6 +30,13 @@

$factories = [
'cache' => static fn (): CacheStore => new CacheStore(new ArrayAdapter(), cacheKey: 'symfony'),
'meilisearch' => static fn (): MeilisearchMessageStore => new MeilisearchMessageStore(
http_client(),
env('MEILISEARCH_HOST'),
env('MEILISEARCH_API_KEY'),
new MonotonicClock(),
'symfony',
),
'memory' => static fn (): InMemoryStore => new InMemoryStore('symfony'),
'session' => static function (): SessionStore {
$request = Request::create('/');
Expand Down
1 change: 1 addition & 0 deletions examples/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"symfony/ai-platform": "@dev",
"symfony/ai-store": "@dev",
"symfony/cache": "^7.3|^8.0",
"symfony/clock": "^7.3|^8.0",
"symfony/console": "^7.3|^8.0",
"symfony/css-selector": "^7.3|^8.0",
"symfony/dependency-injection": "^7.3|^8.0",
Expand Down
Empty file.
1 change: 1 addition & 0 deletions src/ai-bundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^11.5",
"symfony/clock": "^7.3|^8.0",
"symfony/expression-language": "^7.3|^8.0",
"symfony/security-core": "^7.3|^8.0",
"symfony/translation": "^7.3|^8.0"
Expand Down
10 changes: 10 additions & 0 deletions src/ai-bundle/config/options.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,16 @@
->end()
->end()
->end()
->arrayNode('meilisearch')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->stringNode('endpoint')->cannotBeEmpty()->end()
->stringNode('api_key')->cannotBeEmpty()->end()
->stringNode('index_name')->cannotBeEmpty()->end()
->end()
->end()
->end()
->arrayNode('session')
->useAttributeAsKey('name')
->arrayPrototype()
Expand Down
20 changes: 20 additions & 0 deletions src/ai-bundle/src/AiBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use Symfony\AI\AiBundle\Profiler\TraceableToolbox;
use Symfony\AI\AiBundle\Security\Attribute\IsGrantedTool;
use Symfony\AI\Chat\Bridge\HttpFoundation\SessionStore;
use Symfony\AI\Chat\Bridge\Meilisearch\MessageStore as MeilisearchMessageStore;
use Symfony\AI\Chat\MessageStoreInterface;
use Symfony\AI\Platform\Bridge\Anthropic\PlatformFactory as AnthropicPlatformFactory;
use Symfony\AI\Platform\Bridge\Azure\OpenAi\PlatformFactory as AzureOpenAiPlatformFactory;
Expand Down Expand Up @@ -82,6 +83,7 @@
use Symfony\AI\Store\Indexer;
use Symfony\AI\Store\IndexerInterface;
use Symfony\AI\Store\StoreInterface;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
use Symfony\Component\DependencyInjection\Attribute\Target;
use Symfony\Component\DependencyInjection\ChildDefinition;
Expand Down Expand Up @@ -1340,6 +1342,24 @@ private function processMessageStoreConfig(string $type, array $messageStores, C
}
}

if ('meilisearch' === $type) {
foreach ($messageStores as $name => $messageStore) {
$definition = new Definition(MeilisearchMessageStore::class);
$definition
->setArguments([
$messageStore['endpoint'],
$messageStore['api_key'],
new Reference(ClockInterface::class),
$messageStore['index_name'],
])
->addTag('ai.message_store');

$container->setDefinition('ai.message_store.'.$type.'.'.$name, $definition);
$container->registerAliasForArgument('ai.message_store.'.$type.'.'.$name, MessageStoreInterface::class, $name);
$container->registerAliasForArgument('ai.message_store.'.$type.'.'.$name, MessageStoreInterface::class, $type.'_'.$name);
}
}

if ('session' === $type) {
foreach ($messageStores as $name => $messageStore) {
$definition = new Definition(SessionStore::class);
Expand Down
7 changes: 7 additions & 0 deletions src/ai-bundle/tests/DependencyInjection/AiBundleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3035,6 +3035,13 @@ private function getFullConfig(): array
'identifier' => '_memory',
],
],
'meilisearch' => [
'my_meilisearch_store' => [
'endpoint' => 'http://127.0.0.1:7700',
'api_key' => 'foo',
'index_name' => 'test',
],
],
'session' => [
'my_session_message_store' => [
'identifier' => 'session',
Expand Down
2 changes: 1 addition & 1 deletion src/chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ https://github.com/symfony/ai to create issues or submit pull requests.

## Resources

- [Documentation](doc/index.rst)
- [Documentation](../../docs/components/chat.rst)
- [Report issues](https://github.com/symfony/ai/issues) and
[send Pull Requests](https://github.com/symfony/ai/pulls)
in the [main Symfony AI repository](https://github.com/symfony/ai)
4 changes: 4 additions & 0 deletions src/chat/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^11.5.13",
"symfony/dependency-injection": "^7.3|^8.0",
"symfony/clock": "^7.3|^8.0",
"symfony/console": "^7.3|^8.0",
"symfony/http-foundation": "^7.3|^8.0",
"psr/cache": "^3.0"
},
"suggest": {
"symfony/clock": "To use stores that requires waiting for actions like Meilisearch"
},
"autoload": {
"psr-4": {
"Symfony\\AI\\Chat\\": "src/"
Expand Down
Loading