Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Doctrine Message Store Laravel Package

symfony/ai-doctrine-message-store

Doctrine DBAL message store integration for Symfony AI Chat. Persist and retrieve chat messages in a relational database using Doctrine DBAL, enabling durable conversation history and easy storage configuration within Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Dependencies

    composer require symfony/ai-doctrine-message-store doctrine/dbal symfony/ai
    
    • Laravel users: Use doctrine/dbal (v3.x) for DBAL compatibility.
  2. Register DBAL Connection Configure a DBAL connection in config/database.php (Laravel) or config/packages/doctrine.yaml (Symfony):

    // Laravel: config/database.php
    'connections' => [
        'ai_dbal' => [
            'driver' => 'pdo_mysql',
            'url' => env('DATABASE_URL'),
            'database' => env('DB_DATABASE'),
            'username' => env('DB_USERNAME'),
            'password' => env('DB_PASSWORD'),
            'host' => env('DB_HOST'),
            'port' => env('DB_PORT', '3306'),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
    ],
    
  3. First Use Case: Store a Chat Message

    // Laravel: Create a service to wrap the Symfony store
    use Symfony\AI\DoctrineMessageStore\DoctrineDBALMessageStore;
    use Symfony\Component\Messenger\Message\SentMessage;
    use Symfony\Component\Messenger\Envelope;
    
    class AiMessageStoreService
    {
        public function __construct()
        {
            $connection = \DB::connection('ai_dbal')->getDoctrineConnection();
            $this->store = new DoctrineDBALMessageStore($connection);
        }
    
        public function saveMessage(array $message)
        {
            $envelope = new Envelope(new SentMessage($message));
            $this->store->store($envelope);
        }
    }
    

    Usage:

    $store = new AiMessageStoreService();
    $store->saveMessage([
        'id' => 'chat_123',
        'content' => 'Hello, AI!',
        'metadata' => ['user_id' => 1, 'timestamp' => now()],
    ]);
    
  4. Retrieve Messages

    public function getMessages(string $conversationId)
    {
        return $this->store->find($conversationId);
    }
    

Implementation Patterns

Core Workflows

  1. Symfony AI Chat Integration

    • Use the store as a drop-in replacement for Symfony AI’s default message store.
    • Example: Persist conversation history for a chatbot:
      $conversationId = 'user_42_chat_session';
      $messages = [
          ['role' => 'user', 'content' => 'What is Laravel?'],
          ['role' => 'assistant', 'content' => 'A PHP framework...'],
      ];
      
      foreach ($messages as $message) {
          $this->store->saveMessage([
              'conversation_id' => $conversationId,
              'content' => $message['content'],
              'role' => $message['role'],
          ]);
      }
      
  2. Laravel-Specific Patterns

    • Service Provider Binding:
      // app/Providers/AppServiceProvider.php
      public function register()
      {
          $this->app->singleton('ai.message_store', function ($app) {
              $connection = $app['db']->connection('ai_dbal')->getDoctrineConnection();
              return new DoctrineDBALMessageStore($connection);
          });
      }
      
    • Event-Driven Storage: Listen to AI response events and auto-store them:
      use Illuminate\Support\Facades\Event;
      
      Event::listen(\App\Events\AIResponseGenerated::class, function ($event) {
          $store = app('ai.message_store');
          $store->saveMessage([
              'conversation_id' => $event->conversationId,
              'content' => $event->response,
              'role' => 'assistant',
          ]);
      });
      
  3. Schema Management

    • Laravel Migrations: Create a migration to match the expected schema (reverse-engineered from Symfony AI’s defaults):
      php artisan make:migration create_ai_messages_table
      
      public function up()
      {
          \DB::connection('ai_dbal')->getSchemaBuilder()->createTable('ai_messages', function (Blueprint $table) {
              $table->id();
              $table->string('conversation_id');
              $table->text('content');
              $table->string('role')->comment('user|assistant|system');
              $table->json('metadata')->nullable();
              $table->timestamps();
              $table->index(['conversation_id', 'created_at']);
          });
      }
      
    • Doctrine Migrations (Alternative): Use doctrine/doctrine-migrations-bundle for schema updates.
  4. Bulk Operations

    • Export/Import:
      // Export all messages for a conversation
      $messages = $this->store->find('conversation_123');
      $serialized = json_encode($messages);
      
      // Import (custom logic needed; not natively supported)
      $decoded = json_decode($serialized, true);
      foreach ($decoded as $message) {
          $this->store->saveMessage($message);
      }
      
  5. Hybrid Storage Combine with Redis for performance:

    use Symfony\Component\Cache\Adapter\RedisAdapter;
    
    $cache = new RedisAdapter();
    $cache->save('ai:conversation_123', $messages, 3600); // Cache for 1 hour
    

Integration Tips

  1. Avoid Symfony Bloat

    • Only install symfony/ai-doctrine-message-store and doctrine/dbal. Skip symfony/ai if using Laravel’s AI packages (e.g., laravel-ai).
  2. Leverage Laravel’s Query Builder For advanced queries, use DBAL’s query builder:

    $query = $connection->createQueryBuilder()
        ->select('*')
        ->from('ai_messages')
        ->where('conversation_id = :id')
        ->setParameter('id', 'user_42_chat')
        ->orderBy('created_at', 'ASC')
        ->execute();
    
  3. Transaction Management Wrap AI operations in transactions:

    \DB::connection('ai_dbal')->transaction(function () {
        $store->saveMessage($message);
        // Other DB operations...
    });
    
  4. Testing Use Laravel’s testing tools with a SQLite in-memory DB:

    public function testMessageStorage()
    {
        $connection = \DB::connection('sqlite_test')->getDoctrineConnection();
        $store = new DoctrineDBALMessageStore($connection);
    
        $store->saveMessage(['conversation_id' => 'test', 'content' => 'Hello']);
        $messages = $store->find('test');
    
        $this->assertCount(1, $messages);
    }
    

Gotchas and Tips

Pitfalls

  1. Schema Mismatch

    • Issue: The package expects a specific schema. If your migration differs, queries will fail.
    • Fix: Use the Symfony AI Chat schema as a reference. Example fields:
      -- Required columns
      id (PK), conversation_id, content, role, created_at, updated_at
      
    • Debug: Enable DBAL logging:
      $connection->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
      
  2. PSR-15 Incompatibility

    • Issue: Laravel lacks native PSR-15 support. The Symfony store expects PSR-15 envelopes.
    • Fix: Create a wrapper class:
      class LaravelMessageStore
      {
          public function __construct(private DoctrineDBALMessageStore $store) {}
      
          public function store(array $message)
          {
              $envelope = new Envelope(new SentMessage($message));
              $this->store->store($envelope);
          }
      
          public function find(string $conversationId)
          {
              return $this->store->find($conversationId);
          }
      }
      
  3. Connection Configuration

    • Issue: DBAL may fail silently if the connection isn’t properly configured.
    • Fix: Verify the connection in config/database.php:
      'ai_dbal' => [
          'driver' => 'pdo_mysql',
          'host' => env('DB_HOST', '127.0.0.1'),
          'port' => env('DB_PORT', '3306'),
          'database' => env('DB_DATABASE', 'forge'),
          'username' => env('DB_USERNAME', 'forge'),
          'password' => env('DB_PASSWORD', ''),
          'charset
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope