Skip to content

Bulk Operations ​

Converse provides several methods for efficiently working with multiple messages at once, whether you're importing conversation history, migrating from other systems, or building conversation context.

Bulk Importing Messages ​

The addMessages() method allows you to add multiple messages at once, perfect for importing conversation history or migrating from other systems.

Using Message DTOs ​

The most type-safe approach uses message Data Transfer Objects:

php
use ElliottLawson\Converse\Messages\UserMessage;
use ElliottLawson\Converse\Messages\AssistantMessage;
use ElliottLawson\Converse\Messages\SystemMessage;

// Add multiple messages using DTOs
$messages = $conversation->addMessages([
    new SystemMessage('You are a Laravel expert'),
    new UserMessage('How do I deploy to production?'),
    new AssistantMessage('Let me help you with deployment...'),
]);

// With metadata in DTOs
$messages = $conversation->addMessages([
    new UserMessage('Analyze this code', [
        'timestamp' => now(), 
        'ip' => request()->ip()
    ]),
    new AssistantMessage('I found several issues...', [
        'model' => 'gpt-4', 
        'tokens' => 245
    ]),
]);

Simple String Messages ​

For quick user messages, you can pass strings directly:

php
// Pass multiple arguments directly (all treated as user messages)
$messages = $conversation->addMessages(
    'Hello',
    'I need help with Laravel',
    'How do I set up queues?'
);

// Or pass an array of strings
$messages = $conversation->addMessages([
    'Hello',
    'I need help with Laravel',
    'How do I set up queues?',
]);

Practical Examples ​

Importing from Another System ​

php
// Migrate conversations from legacy system
$legacyMessages = DB::table('old_chat_messages')
    ->where('chat_id', $oldChatId)
    ->orderBy('created_at')
    ->get();

$messageDTOs = $legacyMessages->map(function ($msg) {
    return match($msg->sender_type) {
        'user' => new UserMessage($msg->text, [
            'legacy_id' => $msg->id,
            'created_at' => $msg->created_at,
        ]),
        'bot' => new AssistantMessage($msg->text, [
            'legacy_id' => $msg->id,
            'model' => $msg->bot_model,
        ]),
        'system' => new SystemMessage($msg->text),
    };
})->toArray();

$conversation->addMessages($messageDTOs);

Building Context from Templates ​

php
// Load context messages from configuration
$contextMessages = collect(config('ai.context_messages'))->map(function ($msg) {
    return new SystemMessage(
        view($msg['template'], $msg['data'] ?? [])->render()
    );
})->toArray();

$conversation->addMessages($contextMessages);

Importing from JSON ​

php
// Import from JSON export
$jsonData = json_decode(file_get_contents('conversation-export.json'), true);

$messages = collect($jsonData['messages'])->map(function ($msg) {
    $class = match($msg['role']) {
        'user' => UserMessage::class,
        'assistant' => AssistantMessage::class,
        'system' => SystemMessage::class,
        'tool_call' => ToolCallMessage::class,
        'tool_result' => ToolResultMessage::class,
    };
    
    return new $class($msg['content'], $msg['metadata'] ?? []);
})->toArray();

$conversation->addMessages($messages);

Performance Considerations ​

Database Efficiency ​

The addMessages() method uses Laravel's insert() for efficiency when adding multiple messages:

php
// Efficient - single database query
$conversation->addMessages($largeArrayOfMessages);

// Less efficient - multiple database queries
foreach ($largeArrayOfMessages as $message) {
    $conversation->addUserMessage($message);
}

Memory Usage ​

When importing very large conversations, consider chunking:

php
collect($messages)->chunk(100)->each(function ($chunk) use ($conversation) {
    $conversation->addMessages($chunk->toArray());
});

Working with Metadata ​

Metadata allows you to store provider-specific information, request details, or any custom data alongside messages:

php
// Track user context
$conversation->addUserMessage('What about costs?', [
    'ip_address' => request()->ip(),
    'user_agent' => request()->userAgent(),
    'session_id' => session()->getId(),
]);

// Store AI provider details
$conversation->addAssistantMessage('Here are the pricing details...', [
    'model' => 'gpt-4-turbo',
    'temperature' => 0.7,
    'max_tokens' => 500,
    'prompt_tokens' => 85,
    'completion_tokens' => 150,
    'total_cost' => 0.0234,
]);

// Function call metadata
$conversation->addToolCallMessage('search_products(query="laptops")', [
    'function_name' => 'search_products',
    'arguments' => ['query' => 'laptops'],
    'call_id' => 'call_abc123',
]);

Querying by Metadata ​

php
// Find messages with specific metadata
$highCostMessages = $conversation->messages()
    ->where('metadata->total_cost', '>', 0.10)
    ->get();

// Messages from a specific model
$gpt4Messages = $conversation->messages()
    ->where('metadata->model', 'gpt-4')
    ->get();

// Group messages by session
$sessions = $conversation->messages()
    ->whereNotNull('metadata->session_id')
    ->get()
    ->groupBy('metadata.session_id');

Next Steps ​

Released under the MIT License.