Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/python-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,12 @@ jobs:
fallback_url: ${{ env.LOCAL_MCP_URL }}
- name: Prefer local MCP URL when available
run: echo "LOCAL_MCP_URL=${{ steps.local-mcp.outputs.effective_url }}" >> "$GITHUB_ENV"
- name: Test with pytest (Anthropic, Hyperlight, Ollama, MCP integration)
- name: Test with pytest (Anthropic, Hyperlight, Mistral, Ollama, MCP integration)
run: >
uv run pytest --import-mode=importlib
packages/anthropic/tests
packages/hyperlight/tests
packages/mistral/tests
packages/ollama/tests
packages/core/tests/core/test_mcp.py
packages/hosting-mcp/tests
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/python-merge-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
misc:
- 'python/packages/anthropic/**'
- 'python/packages/hyperlight/**'
- 'python/packages/mistral/**'
- 'python/packages/ollama/**'
- 'python/packages/core/agent_framework/_mcp.py'
- 'python/packages/core/tests/core/test_mcp.py'
Expand Down Expand Up @@ -339,11 +340,12 @@ jobs:
fallback_url: ${{ env.LOCAL_MCP_URL }}
- name: Prefer local MCP URL when available
run: echo "LOCAL_MCP_URL=${{ steps.local-mcp.outputs.effective_url }}" >> "$GITHUB_ENV"
- name: Test with pytest (Anthropic, Hyperlight, Ollama, MCP integration)
- name: Test with pytest (Anthropic, Hyperlight, Mistral, Ollama, MCP integration)
run: >
uv run pytest --import-mode=importlib
packages/anthropic/tests
packages/hyperlight/tests
packages/mistral/tests
packages/ollama/tests
packages/core/tests/core/test_mcp.py
packages/hosting-mcp/tests
Expand Down
2 changes: 2 additions & 0 deletions python/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ OLLAMA_ENDPOINT=""
OLLAMA_MODEL=""
# Mistral AI
MISTRAL_API_KEY=""
MISTRAL_CHAT_MODEL=""
MISTRAL_EMBEDDING_MODEL=""
MISTRAL_SERVER_URL=""
# Observability (instrumentation is enabled by default; set "ENABLE_INSTRUMENTATION" to "false" to opt out)
ENABLE_SENSITIVE_DATA=true
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317/"
4 changes: 4 additions & 0 deletions python/packages/core/agent_framework/mistral/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
from typing import Any

_IMPORTS: dict[str, tuple[str, str]] = {
"MistralChatClient": ("agent_framework_mistral", "agent-framework-mistral"),
"MistralChatOptions": ("agent_framework_mistral", "agent-framework-mistral"),
"MistralEmbeddingClient": ("agent_framework_mistral", "agent-framework-mistral"),
"MistralEmbeddingOptions": ("agent_framework_mistral", "agent-framework-mistral"),
"MistralEmbeddingSettings": ("agent_framework_mistral", "agent-framework-mistral"),
"MistralSettings": ("agent_framework_mistral", "agent-framework-mistral"),
"RawMistralChatClient": ("agent_framework_mistral", "agent-framework-mistral"),
}


Expand Down
14 changes: 13 additions & 1 deletion python/packages/core/agent_framework/mistral/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
# Copyright (c) Microsoft. All rights reserved.

from agent_framework_mistral import MistralEmbeddingClient, MistralEmbeddingOptions, MistralEmbeddingSettings
from agent_framework_mistral import (
MistralChatClient,
MistralChatOptions,
MistralEmbeddingClient,
MistralEmbeddingOptions,
MistralEmbeddingSettings,
MistralSettings,
RawMistralChatClient,
)

__all__ = [
"MistralChatClient",
"MistralChatOptions",
"MistralEmbeddingClient",
"MistralEmbeddingOptions",
"MistralEmbeddingSettings",
"MistralSettings",
"RawMistralChatClient",
]
4 changes: 4 additions & 0 deletions python/packages/core/tests/core/test_mistral_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
def test_mistral_namespace_dir_lists_lazy_exports() -> None:
names = dir(mistral)
for expected in (
"MistralChatClient",
"MistralChatOptions",
"MistralEmbeddingClient",
"MistralEmbeddingOptions",
"MistralEmbeddingSettings",
"MistralSettings",
"RawMistralChatClient",
):
assert expected in names

Expand Down
33 changes: 29 additions & 4 deletions python/packages/mistral/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
# Mistral Package (agent-framework-mistral)

Integration with Mistral AI for embedding generation.
Integration with Mistral AI for chat completions and embedding generation.

## Implementation Notes

- Talks to the Mistral REST API directly over `httpx`; the official `mistralai` SDK is not used
because its pinned OpenTelemetry requirements conflict with the rest of the framework.

## Main Classes

- **`MistralChatClient`** - Chat client for Mistral AI models with function invocation, middleware, and telemetry
- **`RawMistralChatClient`** - Chat client without the batteries-included layers
- **`MistralChatOptions`** - Options TypedDict for Mistral-specific chat parameters
- **`MistralSettings`** - TypedDict settings for Mistral chat configuration
- **`MistralEmbeddingClient`** - Embedding client for Mistral AI models
- **`MistralEmbeddingOptions`** - Options TypedDict for Mistral-specific embedding parameters
- **`MistralEmbeddingSettings`** - TypedDict settings for Mistral configuration

## Usage

```python
from agent_framework import Agent
from agent_framework.mistral import MistralChatClient

# Requires MISTRAL_API_KEY environment variable (or pass api_key= directly)
client = MistralChatClient(model="mistral-large-latest")
try:
agent = Agent(client=client)
result = await agent.run("Hello!")
finally:
await client.close()
```

```python
from agent_framework.mistral import MistralEmbeddingClient

# Requires MISTRAL_API_KEY environment variable (or pass api_key= directly)
client = MistralEmbeddingClient(model="mistral-embed")
result = await client.get_embeddings(["Hello, world!"])
print(result[0].vector)
try:
result = await client.get_embeddings(["Hello, world!"])
print(result[0].vector)
finally:
await client.close()
```

## Import Path

```python
from agent_framework.mistral import MistralEmbeddingClient
from agent_framework.mistral import MistralChatClient, MistralEmbeddingClient
```
54 changes: 42 additions & 12 deletions python/packages/mistral/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,39 @@ pip install agent-framework-mistral --pre

and see the [README](https://github.com/microsoft/agent-framework/tree/main/python/README.md) for more information.

See the [Mistral embedding sample](../../samples/02-agents/providers/mistral/mistral_embeddings.py) for a runnable example.
See the [Mistral agent sample](../../samples/02-agents/providers/mistral/mistral_agent_basic.py) and the
[Mistral embedding sample](../../samples/02-agents/providers/mistral/mistral_embeddings.py) for runnable examples.

## Chat Client

The `MistralChatClient` provides chat completions using Mistral AI models, with support for
streaming, function tools, and structured output.

### Quick Start

```python
from agent_framework import Agent
from agent_framework.mistral import MistralChatClient

# Using environment variables (MISTRAL_API_KEY, MISTRAL_CHAT_MODEL)
# Parameters can also be passed directly:
# MistralChatClient(model="mistral-large-latest", api_key="your-api-key")
client = MistralChatClient()
try:
agent = Agent(client=client, instructions="You are a helpful assistant.")
response = await agent.run("Hello!")
print(response.text)
finally:
await client.close()
```

### Configuration

| Environment Variable | Description |
|---|---|
| `MISTRAL_API_KEY` | Your Mistral AI API key |
| `MISTRAL_CHAT_MODEL` | Chat model name (e.g., `mistral-large-latest`) |
| `MISTRAL_SERVER_URL` | Optional server URL override |

## Embedding Client

Expand All @@ -22,17 +54,15 @@ from agent_framework.mistral import MistralEmbeddingClient
# Using environment variables (MISTRAL_API_KEY, MISTRAL_EMBEDDING_MODEL)
client = MistralEmbeddingClient()

# Or passing parameters directly
client = MistralEmbeddingClient(
model="mistral-embed",
api_key="your-api-key",
)

# Generate embeddings
result = await client.get_embeddings(["Hello, world!", "How are you?"])
for embedding in result:
print(f"Dimensions: {embedding.dimensions}")
print(f"Vector: {embedding.vector[:5]}...")
try:
# Parameters can also be passed directly:
# MistralEmbeddingClient(model="mistral-embed", api_key="your-api-key")
result = await client.get_embeddings(["Hello, world!", "How are you?"])
for embedding in result:
print(f"Dimensions: {embedding.dimensions}")
print(f"Vector: {embedding.vector[:5]}...")
finally:
await client.close()
```

### Configuration
Expand Down
5 changes: 5 additions & 0 deletions python/packages/mistral/agent_framework_mistral/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import importlib.metadata

from ._chat_client import MistralChatClient, MistralChatOptions, MistralSettings, RawMistralChatClient
from ._embedding_client import MistralEmbeddingClient, MistralEmbeddingOptions, MistralEmbeddingSettings

try:
Expand All @@ -10,8 +11,12 @@
__version__ = "0.0.0" # Fallback for development mode

__all__ = [
"MistralChatClient",
"MistralChatOptions",
"MistralEmbeddingClient",
"MistralEmbeddingOptions",
"MistralEmbeddingSettings",
"MistralSettings",
"RawMistralChatClient",
"__version__",
]
Loading
Loading