Laravel AI: Configurable Conversation and Message Table Names
@timmcleod merged PR #484 into laravel/ai, making the two database table names used by DatabaseConversationStore configurable via config/ai.php. The change resolves issue #483.
The Problem
DatabaseConversationStore hardcoded agent_conversations and agent_conversation_messages as string literals in five separate places. Any project that needed different names, to avoid collisions with another package, or to follow a naming convention like module_* or tenant_*, had to reimplement the entire ConversationStore interface from scratch. That meant inheriting none of the future improvements made to the built-in implementation.
The New Config Keys
A storage.tables array now lives in config/ai.php. Both keys fall back to the original literals, so no existing install needs any changes.
'storage' => [
'tables' => [
'conversations' => env('AI_TABLE_CONVERSATIONS', 'agent_conversations'),
'messages' => env('AI_TABLE_MESSAGES', 'agent_conversation_messages'),
],
],
Override via .env if the defaults conflict with anything on the same database:
AI_TABLE_CONVERSATIONS=acme_ai_conversations
AI_TABLE_MESSAGES=acme_ai_conversation_messages
How DatabaseConversationStore Reads Them
Two protected accessors replace the five scattered string literals inside DatabaseConversationStore:
protected function conversationsTable(): string
{
return config('ai.storage.tables.conversations', 'agent_conversations');
}
protected function messagesTable(): string
{
return config('ai.storage.tables.messages', 'agent_conversation_messages');
}
Every query method now calls one of those accessors rather than referencing a string directly:
public function storeConversation(string|int|null $userId, string $title): string
{
// ...
DB::table($this->conversationsTable())->insert([ /* ... */ ]);
// ...
}
Migration Consistency
The published migration reads from the same config keys, so publishing both the config and the migration gives consistent table names with no manual edits required:
Schema::create(config('ai.storage.tables.conversations'), function (Blueprint $table) {
// ...
});
Schema::create(config('ai.storage.tables.messages'), function (Blueprint $table) {
// ...
});
Projects that have already run the original migration and want to rename their tables need to write a short rename migration alongside the config change. The package does not ship one automatically.
Test Coverage
@timmcleod added tests/Feature/Storage/DatabaseConversationStoreTest.php with four cases: default-config sanity, the default-tables write path, an overridden-tables write path that asserts the default table names are not created, and migration correctness under configured names. The full Pest suite passes 985 of 985 tests.
Who Should Care
Any project sharing a database with another package that also uses agent_conversations, or following strict internal table-naming conventions, can now set two environment variables and move on. No custom store implementation needed.