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.
Install the Package Add the package to your Laravel project via Composer:
composer require symfony/ai-cache-message-store
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
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)
);
});
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');
Cache Driver Selection
Configure in config/cache.php or .env:
CACHE_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
TTL Management Set appropriate Time-To-Live (TTL) values for chat messages based on use case:
3600 seconds).86400 seconds).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
);
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);
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
);
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');
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());
}
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
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
);
}
);
}
}
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
);
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
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
);
Cache Invalidation Issues
$messageStore->delete('chat_123_user_456');
$cachePool->clear('chat_123_*'); // Clear all related keys
Key Collisions
chat_{chat_id}_{user_id}) and avoid wildcards in production keys.\Log::debug('Generated cache key:', ['key' => $key]);
Serialization Errors
$serializer = $app->make(SerializerInterface::class);
$serialized = $serializer->serialize($message, 'json');
$deserialized = $serializer->deserialize($serialized, Message::class, 'json');
Performance Bottlenecks
Dependency Conflicts
Cache component may conflict with Laravel’s dependencies.composer.json:
"require": {
"symfony/cache": "^7.3",
"symfony/ai-cache-message-store": "^0.8"
}
TTL Misconfiguration
Laravel Cache Driver Quirks
How can I help you explore Laravel packages today?