symfony/ai-mistral-platform
Symfony AI bridge for the Mistral platform. Integrates Mistral’s API (including chat completions) into Symfony AI, enabling easy use of Mistral models in Symfony applications with standard client abstractions and tooling.
Install Dependencies:
composer require symfony/ai-mistral-platform symfony/http-client
(Laravel users: Ensure symfony/http-client is compatible with Laravel’s HTTP stack.)
Configure API Key:
Add Mistral’s API key to Laravel’s .env:
MISTRAL_API_KEY=your_mistral_api_key_here
Basic Chat Completion: Create a service to wrap the client:
// app/Services/MistralService.php
use Symfony\Component\Ai\Client\MistralClient;
use Symfony\Component\Ai\Client\ChatClientInterface;
class MistralService
{
public function __construct(private ChatClientInterface $chatClient) {}
public function generateResponse(string $prompt): string
{
$response = $this->chatClient->complete($prompt);
return $response->getContent();
}
}
Register the Client:
Bind the MistralClient in AppServiceProvider:
use Symfony\Component\Ai\Client\MistralClient;
use Symfony\Component\HttpClient\HttpClient;
public function register()
{
$this->app->singleton(MistralClient::class, function ($app) {
return new MistralClient(
HttpClient::create(['auth_bearer' => env('MISTRAL_API_KEY')])
);
});
}
First Use Case: Call the service from a controller:
use App\Services\MistralService;
public function askMistral(Request $request, MistralService $mistral)
{
$prompt = $request->input('prompt');
$response = $mistral->generateResponse($prompt);
return response()->json(['response' => $response]);
}
src/Client/MistralClient.php (core client logic).src/Client/ChatClient.php (chat completions).src/Client/EmbeddingClient.php (embeddings).ChatClient for structured prompts:
$response = $chatClient->complete([
'model' => 'mistral-tiny', // or 'mistral-latest'
'messages' => [
['role' => 'user', 'content' => 'Explain Laravel Eloquent.'],
],
]);
DeltaInterface for real-time updates:
$chatClient->streamComplete($prompt, function ($delta) {
// Process each chunk (e.g., append to a view or queue)
Log::info('Stream chunk:', ['content' => $delta->getContent()]);
});
Laravel Tip: Use Laravel Queues to store chunks in a database table (e.g., ai_responses) and stream via a job.$embeddings = $embeddingClient->create([
'model' => 'mistral-embed',
'inputs' => ['document text 1', 'document text 2'],
]);
pgvector):
// Pseudocode for Laravel + Meilisearch
$client->index('documents')->addDocuments([
'id' => 1,
'embedding' => $embeddings[0]['embedding'],
'content' => 'document text 1',
]);
Provider abstraction to route requests:
// config/ai.php
'providers' => [
'mistral' => [
'class' => \Symfony\Component\Ai\Provider\MistralProvider::class,
'model' => 'mistral-tiny',
],
'fallback' => [
'class' => \Symfony\Component\Ai\Provider\OpenAiProvider::class,
],
],
Laravel Tip: Create a facade to switch providers dynamically:
// app/Facades/AiProvider.php
public static function get(string $providerName): ProviderInterface
{
return app(\Symfony\Component\Ai\Provider\ProviderRegistry::class)
->getProvider($providerName);
}
Symfony\Component\Ai\Exception\AiException for Mistral-specific errors:
try {
$response = $chatClient->complete($prompt);
} catch (AiException $e) {
Log::error('Mistral API error:', ['error' => $e->getMessage()]);
// Fallback to another provider
}
retry helper or a package like spatie/laravel-retryable:
retry(3, function () use ($chatClient, $prompt) {
$chatClient->complete($prompt);
}, function (AiException $e) {
return $e instanceof \Symfony\Component\Ai\Exception\RateLimitException;
});
MistralService → ChatClient.DeltaInterface → Store in DB or broadcast via Laravel Echo.EmbeddingClient.mistral provider (default).openai provider.Laravel HTTP Client:
Replace Symfony’s HttpClient with Laravel’s Http facade for consistency:
$this->app->singleton(MistralClient::class, function ($app) {
return new MistralClient(
$app->make(\Illuminate\Http\Client\PendingRequest::class)
->withToken(env('MISTRAL_API_KEY'))
);
});
Event-Driven Extensions:
Extend Symfony’s AiEventDispatcher to dispatch Laravel events:
// app/Providers/EventServiceProvider.php
public function boot()
{
event(new \Symfony\Component\Ai\Event\AiEvent(
$this->app->make(\Symfony\Component\Ai\Event\AiEventDispatcher::class)
));
}
Testing: Use Laravel’s HTTP tests to mock Mistral responses:
public function test_mistral_chat()
{
$response = json_encode(['choices' => [['message' => ['content' => 'Test']]]]);
Http::fake([
'api.mistral.ai/*' => Http::response($response, 200),
]);
$this->get('/chat')->assertSee('Test');
}
Streaming Chunks in Laravel:
DeltaInterface streams may timeout if not handled asynchronously.$chatClient->streamComplete($prompt, function ($delta) {
ProcessStreamChunkJob::dispatch($delta->getContent());
});
Token Usage Tracking:
tokenUsage may not be exposed uniformly in early versions.$usage = json_decode($response->getContent(), true)['usage'] ?? null;
Model Name Typos:
mistral-tiny vs. mistral-tiny-s) may change.Rate Limiting:
use Symfony\Component\Ai\
How can I help you explore Laravel packages today?