symfony/ai-redis-message-store
Redis-backed message store for Symfony AI Chat. Persists and retrieves chat messages using Redis (phpredis) for fast, durable conversation history and session state. Part of the Symfony AI ecosystem; issues and PRs handled in the main symfony/ai repo.
Install Dependencies Add the package and required Symfony components to your Laravel project:
composer require symfony/ai-redis-message-store symfony/serializer symfony/messenger
Configure Redis
Ensure your config/redis.php is properly set up for your Redis server. Example:
'default' => [
'url' => env('REDIS_URL'),
'client' => 'phpredis',
],
Basic Integration Create a service provider to bind the Redis message store to Laravel’s container:
// app/Providers/SymfonyAIServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\AI\Chat\RedisMessageStore;
use Symfony\Component\AI\Chat\MessageStoreInterface;
class SymfonyAIServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(MessageStoreInterface::class, function ($app) {
$redis = $app['redis']->connection();
return new RedisMessageStore($redis);
});
}
}
Register the provider in config/app.php under providers.
First Use Case Use the message store in a Laravel service or controller:
use Symfony\Component\AI\Chat\MessageStoreInterface;
class ChatService
{
protected $messageStore;
public function __construct(MessageStoreInterface $messageStore)
{
$this->messageStore = $messageStore;
}
public function saveMessage(string $conversationId, array $message)
{
$this->messageStore->save($conversationId, $message);
}
public function loadMessages(string $conversationId): array
{
return $this->messageStore->findAll($conversationId);
}
}
Dependency Injection
Leverage Laravel’s service container to inject MessageStoreInterface into your services. Example:
class ChatController extends Controller
{
public function __construct(private MessageStoreInterface $messageStore) {}
public function store(Request $request)
{
$this->messageStore->save($request->conversation_id, $request->message);
return response()->json(['status' => 'saved']);
}
}
Key Naming Convention Define a consistent key naming strategy to avoid collisions. Example:
$key = "chat:{$userId}:{$conversationId}";
$this->messageStore->save($key, $message);
Error Handling and Retries
Implement retry logic for Redis operations using Laravel’s retry helper:
use Illuminate\Support\Facades\Redis;
$this->messageStore->save($conversationId, $message);
retry(5, function () use ($conversationId, $message) {
$redis = Redis::connection();
$redis->set($this->getKey($conversationId), json_encode($message));
}, function () {
return Redis::connection()->ping() !== 'PONG';
});
Integration with Laravel Events Dispatch Laravel events when messages are saved or loaded:
use Illuminate\Support\Facades\Event;
$this->messageStore->save($conversationId, $message);
Event::dispatch(new MessageSaved($conversationId, $message));
Real-Time Chat Application
AI Agent Collaboration
Multi-Tenant Chat System
$key = "tenant:{$tenantId}:chat:{$conversationId}";
Symfony Messenger Integration If using Symfony Messenger, configure it to use the Redis message store for transport:
# config/packages/messenger.yaml
framework:
messenger:
transports:
redis_chat:
dsn: '%env(REDIS_DSN)%'
options:
queue_name: 'chat_messages'
retry_strategy:
max_retries: 3
delay: 1000
multiplier: 2
Caching Layer Cache frequently accessed conversations in Laravel’s cache:
$cacheKey = "chat:conversation:{$conversationId}";
if (!cache()->has($cacheKey)) {
$messages = $this->messageStore->findAll($conversationId);
cache()->put($cacheKey, $messages, now()->addMinutes(5));
}
Monitoring and Metrics Track Redis operations using Laravel Telescope or Prometheus:
use Illuminate\Support\Facades\Redis;
$start = microtime(true);
$this->messageStore->save($conversationId, $message);
$latency = microtime(true) - $start;
\Log::info("Redis save latency: {$latency}s");
Key Collisions
appname:chat:{$conversationId}.Memory Management
$redis = Redis::connection();
$redis->setex($key, 86400, json_encode($message)); // Expire in 24 hours
Serialization Issues
Lack of Advanced Redis Features
SET, GET). Advanced features like streams or hashes are not supported.RedisMessageStore class to add custom Redis commands as needed.Dependency Conflicts
Redis Connection Issues
config/redis.php.Redis::connection()->ping() to check connectivity.Serialization Errors
$serialized = json_encode($message);
\Log::debug("Serialized message: {$serialized}");
Key Not Found Errors
$key = "chat:{$conversationId}";
\Log::debug("Using key: {$key}");
Redis Client Configuration
phpredis. If using predis, ensure it’s properly configured.config/redis.php:
'client' => env('REDIS_CLIENT', 'phpredis'),
Symfony Container Initialization
SymfonyAIServiceProvider is registered and loaded before use.Custom Message Store
RedisMessageStore to add custom functionality:
use Symfony\Component\AI\Chat\RedisMessageStore as BaseRedisMessageStore;
class CustomRedisMessageStore extends BaseRedisMessageStore
{
public function saveWithTTL(string $conversationId, array $message, int $ttl)
{
$key = $this->getKey($conversationId);
$this->redis->setex($key, $ttl, json_encode($message));
}
}
Event Listeners
$messageStore->addListener(function ($event) {
\Log::info("Message event: " . $event->getType());
});
Fallback Mechanism
use Symfony\Component\AI\Chat\MessageStoreInterface;
class FallbackMessageStore implements MessageStoreInterface
{
public function save(string $conversationId, array $message): void
{
// Fallback logic
How can I help you explore Laravel packages today?