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 Cache Message Store Laravel Package

symfony/ai-cache-message-store

PSR-6 cache-backed message store for Symfony AI Chat. Persist and retrieve chat messages using any PSR-6 cache pool for lightweight conversation history across requests. Part of the Symfony AI ecosystem.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package Add the package to your Laravel project via Composer:

    composer require symfony/ai-cache-message-store
    
  2. Ensure PSR-6 Cache Compatibility Laravel’s built-in Cache facade is PSR-6 compliant. Verify your cache driver (e.g., Redis, database, file) is properly configured in .env:

    CACHE_DRIVER=redis
    
  3. Integrate with Symfony AI Chat If using Symfony AI Chat, replace the default MessageStore with CacheMessageStore in your configuration or service provider:

    use Symfony\Component\AI\Chat\MessageStoreInterface;
    use Symfony\Component\AI\Chat\CacheMessageStore;
    use Symfony\Contracts\Cache\CacheInterface;
    
    $this->app->bind(MessageStoreInterface::class, function ($app) {
        return new CacheMessageStore(
            $app->make(CacheInterface::class)
        );
    });
    
  4. First Use Case: Persisting Chat History Use the cache-backed message store to persist and retrieve chat messages across requests:

    use Symfony\Component\AI\Chat\Message;
    use Symfony\Component\AI\Chat\MessageStoreInterface;
    
    $messageStore = $this->app->make(MessageStoreInterface::class);
    
    // Save a message
    $message = new Message('user', 'Hello, AI!');
    $messageStore->save($message);
    
    // Retrieve messages for a chat
    $messages = $messageStore->findAll('chat_id_123');
    

Implementation Patterns

Usage Patterns

  1. Cache Driver Selection

    • Redis/Memcached: Best for high-performance, distributed environments.
    • Database: Use if you need persistence and don’t want to manage cache eviction.
    • File: Suitable for development or low-traffic environments.

    Configure in config/cache.php or .env:

    CACHE_DRIVER=redis
    REDIS_HOST=127.0.0.1
    REDIS_PASSWORD=null
    REDIS_PORT=6379
    
  2. TTL Management Set appropriate Time-To-Live (TTL) values for chat messages based on use case:

    • Short-lived chats (e.g., customer support): 1 hour (3600 seconds).
    • Persistent sessions (e.g., user dashboards): 24 hours (86400 seconds).
    • No TTL: Use null for indefinite caching (not recommended for transient data).

    Example with custom TTL:

    $messageStore = new CacheMessageStore(
        $app->make(CacheInterface::class),
        'chat_messages', // Cache key prefix
        3600             // TTL in seconds
    );
    
  3. Key Naming Strategy Use a consistent key naming convention to avoid collisions:

    // Example: chat_{chat_id}_{user_id}
    $key = 'chat_' . $chatId . '_' . $userId;
    $messageStore->save($message, $key);
    
  4. Hybrid Storage Combine cache with a database for critical data:

    $messageStore = new HybridMessageStore(
        $app->make(CacheInterface::class), // Primary cache store
        $app->make(DatabaseMessageStore::class) // Fallback
    );
    

Workflows

  1. Saving and Retrieving Messages

    // Save a message
    $messageStore->save($message, 'chat_123_user_456');
    
    // Retrieve all messages for a chat
    $messages = $messageStore->findAll('chat_123_*'); // Use wildcards for prefix matching
    
    // Delete a message
    $messageStore->delete('chat_123_user_456');
    
  2. Batching Operations For high-throughput scenarios, batch save/retrieve operations:

    $messages = [
        new Message('user', 'First message'),
        new Message('ai', 'Response 1'),
    ];
    
    foreach ($messages as $message) {
        $messageStore->save($message, 'chat_123_user_456_' . uniqid());
    }
    
  3. Integration with Laravel Events Listen for cache events (e.g., CacheItemPool::clear or custom events) to invalidate messages:

    use Symfony\Component\Cache\CacheItemPoolInterface;
    
    $cachePool = $app->make(CacheItemPoolInterface::class);
    $cachePool->clear('chat_*'); // Invalidate all chat messages
    

Integration Tips

  1. Laravel Service Provider Bind the CacheMessageStore to Laravel’s container:

    use Illuminate\Support\ServiceProvider;
    use Symfony\Component\AI\Chat\CacheMessageStore;
    use Symfony\Contracts\Cache\CacheInterface;
    
    class AiServiceProvider extends ServiceProvider
    {
        public function register()
        {
            $this->app->bind(
                \Symfony\Component\AI\Chat\MessageStoreInterface::class,
                function ($app) {
                    return new CacheMessageStore(
                        $app->make(CacheInterface::class),
                        'chat_messages',
                        3600
                    );
                }
            );
        }
    }
    
  2. Custom Message Serialization If messages contain complex data, customize serialization:

    use Symfony\Component\Serializer\SerializerInterface;
    
    $serializer = $app->make(SerializerInterface::class);
    $messageStore = new CacheMessageStore(
        $app->make(CacheInterface::class),
        'chat_messages',
        3600,
        $serializer
    );
    
  3. Cache Tagging Use cache tags for granular invalidation (requires PSR-6 cache support):

    $messageStore->save($message, 'chat_123_user_456', ['chat_123', 'user_456']);
    $cachePool->invalidateTags(['chat_123']); // Invalidate all tags for chat_123
    
  4. Fallback to Database Implement a fallback mechanism for critical data:

    $messageStore = new CacheMessageStore(
        $app->make(CacheInterface::class),
        'chat_messages',
        3600,
        null,
        $app->make(DatabaseMessageStore::class) // Fallback store
    );
    

Gotchas and Tips

Pitfalls

  1. Cache Invalidation Issues

    • Problem: Messages may persist longer than expected due to misconfigured TTLs or missing invalidation logic.
    • Solution: Always define explicit TTLs and implement invalidation triggers (e.g., on message deletion or chat closure).
    • Example:
      $messageStore->delete('chat_123_user_456');
      $cachePool->clear('chat_123_*'); // Clear all related keys
      
  2. Key Collisions

    • Problem: Poor key naming can lead to overwritten or lost messages.
    • Solution: Use a consistent prefix (e.g., chat_{chat_id}_{user_id}) and avoid wildcards in production keys.
    • Tip: Log cache key generation for debugging:
      \Log::debug('Generated cache key:', ['key' => $key]);
      
  3. Serialization Errors

    • Problem: Complex message objects may fail to serialize/deserialize.
    • Solution: Use a custom serializer or simplify message structures. Test serialization early:
      $serializer = $app->make(SerializerInterface::class);
      $serialized = $serializer->serialize($message, 'json');
      $deserialized = $serializer->deserialize($serialized, Message::class, 'json');
      
  4. Performance Bottlenecks

    • Problem: High cache miss rates or slow serialization can degrade performance.
    • Solution:
      • Monitor cache hit/miss ratios using Laravel’s cache logging.
      • Optimize message structures (avoid large payloads).
      • Use Redis pipelines for batch operations.
  5. Dependency Conflicts

    • Problem: Symfony’s Cache component may conflict with Laravel’s dependencies.
    • Solution: Pin versions in composer.json:
      "require": {
          "symfony/cache": "^7.3",
          "symfony/ai-cache-message-store": "^0.8"
      }
      
  6. TTL Misconfiguration

    • Problem: Incorrect TTLs can lead to stale data or unnecessary cache churn.
    • Solution:
      • Start with conservative TTLs (e.g., 1 hour) and adjust based on access patterns.
      • Use shorter TTLs for real-time chats and longer for archives.
  7. Laravel Cache Driver Quirks

    • Problem: Some drivers (e.g., database) may not support all PSR-6 features.
    • Solution: Test with your target driver before production
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.
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
anil/file-picker
broqit/fields-ai