https://github.com/projectsaturnstudios/llm-speak-mistral
https://github.com/projectsaturnstudios/llm-speak-mistral
Last synced: 6 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/projectsaturnstudios/llm-speak-mistral
- Owner: projectsaturnstudios
- Created: 2025-07-30T18:34:58.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-07-31T19:09:59.000Z (11 months ago)
- Last Synced: 2025-12-26T06:20:53.841Z (7 months ago)
- Language: PHP
- Size: 19.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# LLMSpeak Mistral AI
[](https://opensource.org/licenses/MIT)
[](https://php.net/releases/)
[](https://laravel.com)
[](https://packagist.org/packages/llm-speak/mistral-ai)
[](https://packagist.org/packages/llm-speak/mistral-ai)
**LLMSpeak Mistral AI** is a Laravel package that provides a fluent, Laravel-native interface for integrating with Mistral AI's powerful language models. Built as part of the LLMSpeak ecosystem, it offers seamless access to Mistral's cutting-edge models including Mistral Large, Mistral Medium, and specialized models like Codestral for code generation.
> **Note:** This package is part of the larger [LLMSpeak ecosystem](https://github.com/projectsaturnstudios/llm-speak). For universal provider switching and standardized interfaces, check out the [LLMSpeak Core](https://github.com/projectsaturnstudios/llm-speak-core) package.
## Table of Contents
- [Features](#features)
- [Get Started](#get-started)
- [Usage](#usage)
- [Chat Completions](#chat-completions)
- [Embeddings](#embeddings)
- [Fluent Request Building](#fluent-request-building)
- [Tool Calling](#tool-calling)
- [Multiple Choices](#multiple-choices)
- [Response Formatting](#response-formatting)
- [Streaming Responses](#streaming-responses)
- [Advanced Configuration](#advanced-configuration)
- [Response Handling](#response-handling)
- [Testing](#testing)
- [Credits](#credits)
- [License](#license)
## Features
- **🧠 Advanced Models**: Access to Mistral Large, Medium, Small, and specialized models like Codestral
- **🚀 Laravel Native**: Full Laravel integration with automatic service discovery
- **🔧 Fluent Interface**: Expressive request builders with method chaining
- **📊 Laravel Data**: Powered by Spatie Laravel Data for robust data validation
- **🛠️ Tool Support**: Complete function calling capabilities with flexible tool choice
- **📝 Embeddings**: Advanced embedding generation with multiple output formats
- **🎛️ Output Control**: Precise control over embedding dimensions and data types
- **💨 Streaming**: Real-time streaming responses for chat completions
- **🎯 JSON Mode**: Structured output generation for reliable data extraction
- **🎯 Type Safety**: Full PHP 8.2+ type declarations and IDE support
- **🔐 Secure**: Built-in API key management and request validation
## Get Started
> **Requires [PHP 8.2+](https://php.net/releases/) and Laravel 10.x/11.x/12.x**
Install the package via [Composer](https://getcomposer.org/):
```bash
composer require llm-speak/mistral-ai
```
The package will automatically register itself via Laravel's package discovery.
### Environment Configuration
Add your Mistral AI API key to your `.env` file:
```env
MISTRAL_API_KEY=your_mistral_api_key_here
```
Get your API key from [Mistral AI Console](https://console.mistral.ai/).
## Usage
### Chat Completions
The simplest way to chat with Mistral AI models:
```php
use LLMSpeak\Mistral\MistralCompletionsRequest;
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: [
['role' => 'user', 'content' => 'Explain quantum computing in simple terms']
]
);
$response = $request->post();
echo $response->getTextContent(); // "Quantum computing is..."
```
### Model Selection
Choose the right Mistral model for your use case:
```php
// Most capable model for complex reasoning
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: $messages
);
// Balanced performance and speed
$request = new MistralCompletionsRequest(
model: 'mistral-medium-latest',
messages: $messages
);
// Fast and efficient for simple tasks
$request = new MistralCompletionsRequest(
model: 'mistral-small-latest',
messages: $messages
);
// Specialized for code generation
$request = new MistralCompletionsRequest(
model: 'codestral-latest',
messages: $messages
);
```
### Embeddings
Generate embeddings with advanced output control:
```php
use LLMSpeak\Mistral\MistralEmbeddingsRequest;
// Simple text embedding
$request = new MistralEmbeddingsRequest(
model: 'mistral-embed',
input: 'Generate embeddings for this text'
);
$response = $request->post();
$embeddings = $response->getEmbeddings();
$dimensions = $response->getDimensions();
```
### Advanced Embedding Configuration
Control output format and dimensions:
```php
// High-precision embeddings
$request = new MistralEmbeddingsRequest(
model: 'mistral-embed',
input: 'Research paper abstract content'
)
->setOutputDimension(1024) // Custom dimensions
->setOutputDtype('float'); // High precision
// Memory-efficient embeddings
$request = new MistralEmbeddingsRequest(
model: 'mistral-embed',
input: ['Text 1', 'Text 2', 'Text 3'] // Batch processing
)
->setOutputDimension(512) // Reduced dimensions
->setOutputDtype('int8'); // Quantized format
// Ultra-compact embeddings
$request = new MistralEmbeddingsRequest(
model: 'mistral-embed',
input: $documentTexts
)
->setOutputDimension(256)
->setOutputDtype('binary'); // Maximum compression
$response = $request->post();
// Access different embedding formats
$embeddings = $response->getEmbeddings(); // Raw embeddings
$firstEmbedding = $response->getFirstEmbedding(); // Single vector
$count = $response->getEmbeddingCount(); // Number of embeddings
```
### Universal LLMSpeak Interface
For **provider-agnostic embeddings** that work across Mistral, Gemini, Ollama, and other providers, use the universal LLMSpeak interface:
```php
use LLMSpeak\Core\Support\Facades\LLMSpeak;
use LLMSpeak\Core\Support\Requests\LLMSpeakEmbeddingsRequest;
// Universal request works with ANY provider
$request = new LLMSpeakEmbeddingsRequest(
model: 'mistral-embed',
input: 'Generate embeddings for this text',
encoding_format: 'float', // Maps to Mistral's outputDtype
dimensions: 1024, // Maps to Mistral's outputDimension
task_type: null // Not applicable for Mistral
);
// Execute with Mistral - same code works with other providers!
$response = LLMSpeak::embeddingsFrom('mistral', $request);
// Universal response methods
$embeddings = $response->getAllEmbeddings();
$firstVector = $response->getFirstEmbedding();
$dimensions = $response->getDimensions();
$tokenUsage = $response->getTotalTokens();
```
### Universal Format Mapping
The universal interface automatically maps encoding formats to Mistral's native types:
```php
// Float precision (maps to Mistral's outputDtype: 'float')
$floatRequest = new LLMSpeakEmbeddingsRequest(
model: 'mistral-embed',
input: 'High precision embeddings',
encoding_format: 'float', // → outputDtype: 'float'
dimensions: 1024, // → outputDimension: 1024
task_type: null
);
$floatResponse = LLMSpeak::embeddingsFrom('mistral', $floatRequest);
// Quantized format (maps to Mistral's outputDtype: 'int8')
$quantizedRequest = new LLMSpeakEmbeddingsRequest(
model: 'mistral-embed',
input: 'Memory-efficient embeddings',
encoding_format: 'base64', // → outputDtype: 'int8' (quantized)
dimensions: 512, // → outputDimension: 512
task_type: null
);
$quantizedResponse = LLMSpeak::embeddingsFrom('mistral', $quantizedRequest);
// Batch processing with universal interface
$batchRequest = new LLMSpeakEmbeddingsRequest(
model: 'mistral-embed',
input: [
'Document one for embeddings',
'Document two for embeddings',
'Document three for embeddings'
],
encoding_format: 'float',
dimensions: null, // Use model default
task_type: null
);
$batchResponse = LLMSpeak::embeddingsFrom('mistral', $batchRequest);
echo "Generated {$batchResponse->getEmbeddingCount()} embeddings";
echo "Vector dimensions: {$batchResponse->getDimensions()}";
```
### Advanced Universal Configuration
Access Mistral's advanced features through the universal interface:
```php
// Ultra-compact embeddings with automatic format mapping
$compactRequest = new LLMSpeakEmbeddingsRequest(
model: 'mistral-embed',
input: 'Large document corpus for storage',
encoding_format: 'base64', // Automatically maps to binary/int8
dimensions: 256, // Reduced dimensions for storage
task_type: null
);
$compactResponse = LLMSpeak::embeddingsFrom('mistral', $compactRequest);
// Different models with same interface
$models = ['mistral-embed', 'codestral-embed'];
foreach ($models as $model) {
$request = new LLMSpeakEmbeddingsRequest(
model: $model,
input: 'Code snippet for analysis',
encoding_format: 'float',
dimensions: 1024,
task_type: null
);
$response = LLMSpeak::embeddingsFrom('mistral', $request);
echo "Model {$model}: {$response->getDimensions()} dimensions";
}
```
### Why Use Universal Interface?
**✅ Provider Independence:** Switch between Mistral, Gemini, Ollama with zero code changes
**✅ Automatic Mapping:** Encoding formats automatically mapped to provider-specific types
**✅ Future Proof:** New providers automatically supported
**✅ Consistent API:** Same methods across all providers
**✅ Type Safety:** Full PHP type declarations and IDE support
```php
// Same request works with different providers!
$request = new LLMSpeakEmbeddingsRequest(
model: 'embedding-model',
input: 'Universal text input',
encoding_format: 'float',
dimensions: 512,
task_type: null
);
$mistralResponse = LLMSpeak::embeddingsFrom('mistral', $request); // Mistral AI
$geminiResponse = LLMSpeak::embeddingsFrom('gemini', $request); // Google AI
$ollamaResponse = LLMSpeak::embeddingsFrom('ollama', $request); // Local models
```
### Fluent Request Building
Build complex requests using the fluent interface:
```php
use LLMSpeak\Mistral\MistralCompletionsRequest;
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: [
['role' => 'user', 'content' => 'Write a creative story about AI']
]
)
->setMaxTokens(2000)
->setTemperature(0.8)
->setPresencePenalty(0.1)
->setFrequencyPenalty(0.1)
->setStop(['THE END', '---']);
$response = $request->post();
// Access response properties
echo $response->id; // chatcmpl-abc123
echo $response->model; // mistral-large-latest
echo $response->getTotalTokens(); // 1850
echo $response->getTextContent(); // Generated story
```
### Batch Configuration
Set multiple parameters at once:
```php
$request = new MistralCompletionsRequest(
model: 'mistral-medium-latest',
messages: $conversation
)->setMultiple([
'maxTokens' => 1500,
'temperature' => 0.7,
'presencePenalty' => 0.2,
'frequencyPenalty' => 0.1,
'stop' => ['Human:', 'Assistant:'],
'n' => 3 // Generate 3 different responses
]);
```
### Tool Calling
Enable Mistral models to use external functions:
```php
$tools = [
[
'type' => 'function',
'function' => [
'name' => 'get_weather_forecast',
'description' => 'Get weather forecast for a specific location',
'parameters' => [
'type' => 'object',
'properties' => [
'location' => [
'type' => 'string',
'description' => 'City and country (e.g., "Paris, France")'
],
'days' => [
'type' => 'integer',
'description' => 'Number of days to forecast (1-7)',
'minimum' => 1,
'maximum' => 7
]
],
'required' => ['location']
]
]
]
];
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: [
['role' => 'user', 'content' => 'What\'s the weather forecast for London this week?']
]
)
->setTools($tools)
->setToolChoice('auto'); // Let model decide when to use tools
$response = $request->post();
// Check for tool usage
if ($response->usedTools()) {
$toolCalls = $response->getToolCalls();
foreach ($toolCalls as $call) {
echo "Function: {$call['function']['name']}\n";
echo "Arguments: " . json_encode($call['function']['arguments']) . "\n";
}
}
```
### Multiple Choices
Generate multiple response alternatives:
```php
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: [
['role' => 'user', 'content' => 'Give me three different marketing slogans for an eco-friendly product']
]
)
->setN(3) // Generate 3 different responses
->setTemperature(0.9); // Higher creativity for variety
$response = $request->post();
// Access all choices
$allChoices = $response->getAllChoices();
foreach ($allChoices as $index => $choice) {
echo "Option " . ($index + 1) . ": " . $choice['message']['content'] . "\n\n";
}
// Or get a specific choice
$firstChoice = $response->getChoice(0);
$secondChoice = $response->getChoice(1);
```
### Response Formatting
Control output format for structured data:
```php
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: [
[
'role' => 'user',
'content' => 'Extract the following information from this text as JSON: name, age, occupation. Text: "John Smith is a 35-year-old software engineer."'
]
]
)
->setResponseFormat(['type' => 'json_object'])
->setMaxTokens(200);
$response = $request->post();
$jsonContent = $response->getTextContent();
$data = json_decode($jsonContent, true);
echo "Name: " . $data['name']; // John Smith
echo "Age: " . $data['age']; // 35
echo "Occupation: " . $data['occupation']; // software engineer
```
### Streaming Responses
Enable real-time streaming for long responses:
```php
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: [
['role' => 'user', 'content' => 'Write a detailed technical article about machine learning']
]
)
->setStream(true)
->setMaxTokens(4000);
$response = $request->post();
// Stream handling will be processed by the CompletionsEndpoint
// Response contains streaming data format
```
### Advanced Configuration
Configure advanced parameters for optimal performance:
```php
$request = new MistralCompletionsRequest(
model: 'mistral-large-latest',
messages: $conversationHistory
)
->setMaxTokens(4000)
->setTemperature(0.7)
->setPresencePenalty(0.3) // Encourage topic diversity
->setFrequencyPenalty(0.2) // Reduce repetition
->setStop(['[END]', '###']) // Custom stop sequences
->setN(2) // Generate 2 alternatives
->setResponseFormat(['type' => 'json_object']);
$response = $request->post();
```
## Response Handling
Access comprehensive response data:
```php
$response = $request->post();
// Basic response info
$responseId = $response->id;
$modelUsed = $response->model;
$timestamp = $response->created;
$responseObject = $response->object;
// Content access
$textContent = $response->getTextContent();
$allChoices = $response->getAllChoices();
$firstChoice = $response->getChoice(0);
// Token usage analysis
$totalTokens = $response->getTotalTokens();
$promptTokens = $response->getPromptTokens();
$completionTokens = $response->getCompletionTokens();
// Completion analysis
$finishReason = $response->getFinishReason();
$completedNaturally = $response->completedNaturally();
$hitTokenLimit = $response->reachedTokenLimit();
$stoppedBySequence = $response->stoppedBySequence();
// Tool usage analysis
$usedTools = $response->usedTools();
$toolCalls = $response->getToolCalls();
$hasAnyToolCalls = $response->hasAnyToolCalls();
// Quality metrics
$responseQuality = $response->calculateQualityScore();
$isHighQuality = $response->isHighQuality();
// System information
$systemFingerprint = $response->system_fingerprint;
// Convert to array for storage
$responseArray = $response->toArray();
// Embeddings Response Handling
$embeddingResponse = $embeddingRequest->post();
$embeddings = $embeddingResponse->getEmbeddings();
$firstVector = $embeddingResponse->getFirstEmbedding();
$dimensions = $embeddingResponse->getDimensions();
$embeddingCount = $embeddingResponse->getEmbeddingCount();
$tokenUsage = $embeddingResponse->getTotalTokens();
```
## Testing
The package provides testing utilities for mocking Mistral responses:
```php
use LLMSpeak\Mistral\MistralCompletionsRequest;
use LLMSpeak\Mistral\MistralCompletionsResponse;
use LLMSpeak\Mistral\MistralEmbeddingsResponse;
// Create a mock chat completion response
$mockResponse = new MistralCompletionsResponse(
id: 'chatcmpl-test123',
object: 'chat.completion',
created: time(),
model: 'mistral-large-latest',
choices: [
[
'index' => 0,
'message' => [
'role' => 'assistant',
'content' => 'Mock response content'
],
'finish_reason' => 'stop'
]
],
usage: [
'prompt_tokens' => 15,
'completion_tokens' => 20,
'total_tokens' => 35
]
);
// Test your application logic
$this->assertEquals('Mock response content', $mockResponse->getTextContent());
$this->assertEquals(35, $mockResponse->getTotalTokens());
$this->assertTrue($mockResponse->completedNaturally());
// Create a mock embeddings response
$mockEmbeddingResponse = new MistralEmbeddingsResponse(
id: 'emb-test123',
object: 'list',
data: [
[
'object' => 'embedding',
'embedding' => array_fill(0, 1024, 0.1),
'index' => 0
]
],
model: 'mistral-embed',
usage: [
'prompt_tokens' => 5,
'total_tokens' => 5
],
status_code: 200,
headers: []
);
// Test embedding functionality
$this->assertEquals(1024, $mockEmbeddingResponse->getDimensions());
$this->assertEquals(1, $mockEmbeddingResponse->getEmbeddingCount());
```
## Credits
- [Project Saturn Studios](https://github.com/projectsaturnstudios)
- [Mistral AI](https://mistral.ai) for providing advanced language models
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
---
**Part of the LLMSpeak Ecosystem** - Built with ❤️ by [Project Saturn Studios](https://projectsaturnstudios.com)