# Mistral AI Provider

Mistral AI provides powerful open-source and proprietary language models with strong reasoning capabilities, function calling, and competitive pricing. Known for efficient architectures and European data sovereignty.

## Setup

### Installation

```go
import (
    "github.com/digitallysavvy/go-ai/pkg/ai"
    "github.com/digitallysavvy/go-ai/pkg/providers/mistral"
)
```

### Configuration

```go
provider := mistral.New(mistral.Config{
    APIKey: os.Getenv("MISTRAL_API_KEY"),
})

model, err := provider.LanguageModel("mistral-large-latest")
if err != nil {
    log.Fatal(err)
}
```

### Get API Key

1. Sign up at [console.mistral.ai](https://console.mistral.ai)
2. Create API key
3. Set environment variable:

```bash
export MISTRAL_API_KEY=...
```

## Available Models

### Language Models

| Model ID | Context | Input Price | Output Price | Best For |
|----------|---------|-------------|--------------|----------|
| mistral-large-latest | 128K | $3.00/1M | $9.00/1M | Complex reasoning, code |
| mistral-small-latest | 32K | $1.00/1M | $3.00/1M | Fast, cost-effective |
| mistral-medium-3 | 128K | Varies | Varies | Balanced quality/latency |
| mistral-medium-3.5 | 128K | Varies | Varies | Balanced quality/latency |
| pixtral-large-latest | 128K | $3.00/1M | $9.00/1M | Multimodal (vision) |
| codestral-latest | 32K | $1.00/1M | $3.00/1M | Code generation |
| mistral-nemo | 128K | $0.30/1M | $0.30/1M | Open-source |

### Embedding Models

| Model ID | Dimensions | Price | Best For |
|----------|-----------|-------|----------|
| mistral-embed | 1024 | $0.10/1M | Semantic search |

`mistral.EmbeddingModel` batches at most 32 inputs per call
(`MaxEmbeddingsPerCall() == 32`) and does not support parallel calls
(`SupportsParallelCalls() == false`), matching the Mistral API's own
limits — `ai.EmbedMany` automatically splits larger input sets into
sequential batched requests.

### Speech and Transcription (Voxtral)

```go
speechModel, err := provider.SpeechModel("voxtral-mini-tts-latest") // default when empty
if err != nil {
    log.Fatal(err)
}

result, err := ai.GenerateSpeech(ctx, ai.GenerateSpeechOptions{
    Model: speechModel,
    Text:  "Hello from Mistral.",
})
```

```go
transcriptionModel, err := provider.TranscriptionModel("voxtral-mini-latest") // default when empty
if err != nil {
    log.Fatal(err)
}

transcript, err := ai.Transcribe(ctx, ai.TranscribeOptions{
    Model: transcriptionModel,
    Audio: audioBytes,
})
```

Other Voxtral model IDs include `mistral.ModelVoxtralSmall2507` /
`voxtral-small-2507` and `mistral.ModelVoxtralSmallLatest`.

## Provider-Specific Features

### Cached Token Usage

Mistral usage responses can include cache fields such as:
- `num_cached_tokens`
- `cache_read_input_tokens`
- `cache_creation_input_tokens`

These are mapped into `Usage.InputDetails.CacheReadTokens`, `Usage.InputDetails.CacheWriteTokens`, and `Usage.Raw`.

### Function Calling

Mistral supports parallel function calling:

```go
tools := []types.Tool{
    {
        Name:        "get_weather",
        Description: "Get weather for location",
        Parameters: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "location": map[string]string{"type": "string"},
            },
            "required": []string{"location"},
        },
    },
}

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
    Model:  model,
    Prompt: "What's the weather in Paris and London?",
    Tools:  tools,
    StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
})

// Processes both calls in parallel
```

### JSON Mode

Structured output generation:

```go
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
    Model:  model,
    Prompt: "Extract: John, 30, engineer",
    ResponseFormat: &provider.ResponseFormat{Type: "json_object"},
})
```

If you supply a JSON schema but disable structured outputs
(`providerOptions.mistral.structuredOutputs: false`), Mistral still receives
a plain `{"type": "json_object"}` response format, but the schema is
preserved by injecting it into the system message so the model still sees
the intended shape:

```go
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
    Model:  model,
    Prompt: "Extract: John, 30, engineer",
    ResponseFormat: &provider.ResponseFormat{
        Type:   "json",
        Schema: mySchema,
    },
    ProviderOptions: map[string]interface{}{
        "mistral": map[string]interface{}{"structuredOutputs": false},
    },
})
```

### Code Generation

Codestral is optimized for code:

```go
codeModel, err := provider.LanguageModel("codestral-latest")

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
    Model:  codeModel,
    Prompt: "Write a binary search function in Go",
})
```

## Examples

### Basic Text Generation

```go
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/digitallysavvy/go-ai/pkg/ai"
    "github.com/digitallysavvy/go-ai/pkg/providers/mistral"
)

func main() {
    ctx := context.Background()
    provider := mistral.New(mistral.Config{
        APIKey: os.Getenv("MISTRAL_API_KEY"),
    })

    model, err := provider.LanguageModel("mistral-large-latest")
    if err != nil {
        log.Fatal(err)
    }

    result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
        Model:  model,
        Prompt: "Explain Mistral AI advantages",
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(result.Text)
}
```

## Best Practices

1. **Model Selection**
   - Use mistral-large for complex reasoning
   - Use mistral-small for fast, cost-effective tasks
   - Use pixtral for vision tasks
   - Use codestral for code generation

2. **Cost Optimization**
   - Use smaller models for simple tasks
   - Implement caching
   - Monitor token usage

3. **Function Calling**
   - Define clear tool descriptions
   - Handle parallel calls efficiently

## Rate Limits & Pricing

### Rate Limits

| Tier | RPM | Tokens/Min |
|------|-----|------------|
| Free | 10 | 10K |
| Premium | 1000 | 1M |

## Workflow Serialization

Mistral embedding, speech, and transcription models can cross a workflow
boundary with `providerutils.SerializeModel` / `DeserializeModel` (language
models could already be serialized). See
[Provider Serialization](https://goaisdk.com/docs/agents/workflow-agent.md#provider-serialization)
for the mechanism.

## See Also

- [API Reference: GenerateText](https://goaisdk.com/docs/reference/ai/generate-text.md)
- [Mistral AI Documentation](https://docs.mistral.ai)

## May 2026 parity updates

### Mistral Medium 3 and 3.5

Use `mistral.ModelMistralMedium3` for `mistral-medium-3` and
`mistral.ModelMistralMedium35` for `mistral-medium-3.5`.

```go
p := mistral.New(mistral.Config{APIKey: os.Getenv("MISTRAL_API_KEY")})
model, err := p.LanguageModel(mistral.ModelMistralMedium35)
```

### Cached token usage

Mistral cached token counts map into `types.Usage.InputDetails.CacheReadTokens` when returned by the provider.
