https://github.com/tghamm/mistral.sdk
An unofficial C#/.NET SDK for accessing the Mistral AI API
https://github.com/tghamm/mistral.sdk
c-sharp csharp dotnet dotnet-core dotnet-standard machine-learning mistral mistral-7b mistralai mixtral mixtral-8x7b ml sdk
Last synced: 16 days ago
JSON representation
An unofficial C#/.NET SDK for accessing the Mistral AI API
- Host: GitHub
- URL: https://github.com/tghamm/mistral.sdk
- Owner: tghamm
- License: mit
- Created: 2023-12-15T01:16:27.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-19T00:38:50.000Z (about 1 month ago)
- Last Synced: 2025-03-26T02:51:12.925Z (about 1 month ago)
- Topics: c-sharp, csharp, dotnet, dotnet-core, dotnet-standard, machine-learning, mistral, mistral-7b, mistralai, mixtral, mixtral-8x7b, ml, sdk
- Language: C#
- Homepage: https://www.nuget.org/packages/Mistral.SDK
- Size: 112 KB
- Stars: 39
- Watchers: 2
- Forks: 6
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Mistral.SDK
[](https://github.com/tghamm/Mistral.SDK/actions/workflows/dotnet.yml) [](https://www.nuget.org/packages/Mistral.SDK/)
Mistral.SDK is an unofficial C# client designed for interacting with the Mistral API. This powerful interface simplifies the integration of Mistral AI into your C# applications. It targets netstandard2.0, .net6.0 and .net8.0.
## Table of Contents
- [Installation](#installation)
- [API Keys](#api-keys)
- [HttpClient](#httpclient)
- [Usage](#usage)
- [Examples](#examples)
- [Non-Streaming Call](#non-streaming-call)
- [Streaming Call](#streaming-call)
- [IChatClient](#ichatclient)
- [List Models](#list-models)
- [Embeddings](#embeddings)
- [Function Calling](#function-calling)
- [Contributing](#contributing)
- [License](#license)## Installation
Install Mistral.SDK via the [NuGet](https://www.nuget.org/packages/Mistral.SDK) package manager:
```bash
PM> Install-Package Mistral.SDK
```## API Keys
You can load the API Key from an environment variable named `MISTRAL_API_KEY` by default. Alternatively, you can supply it as a string to the `MistralClient` constructor.
## HttpClient
The `MistralClient` can optionally take a custom `HttpClient` in the `MistralClient` constructor, which allows you to control elements such as retries and timeouts. Note: If you provide your own `HttpClient`, you are responsible for disposal of that client.
## Usage
There are three ways to start using the `MistralClient`. The first is to simply new up an instance of the `MistralClient` and start using it, the second is to use the messaging/Embedding client with the new `Microsoft.Extensions.AI.Abstractions` builder. The third is to use the Completions client with `Microsoft.SemanticKernel`.
Brief examples of each are below.Option 1:
```csharp
var client = new MistralClient();
```Option 2:
```csharp
//chat client
IChatClient client = new MistralClient().Completions;//embeddings generator
IEmbeddingGenerator> client = new MistralClient().Embeddings;
```Option 3:
```csharp
using Microsoft.SemanticKernel;var skChatService =
new ChatClientBuilder(new MistralClient().Completions)
.UseFunctionInvocation()
.Build()
.AsChatCompletionService();var sk = Kernel.CreateBuilder();
sk.Plugins.AddFromType("Weather");
sk.Services.AddSingleton(skChatService);
```
See integration tests for a more complete example.All support all the core features of the `MistralClient's` Messaging and Embedding capabilities, but the latter will be fully featured in .NET 9 and provide built in telemetry and DI and make it easier to choose which SDK you are using.
## Examples
### Non-Streaming Call
Here's an example of a non-streaming call to the mistral-medium completions endpoint (other options are available and documented, but omitted for brevity):
```csharp
var client = new MistralClient();
var request = new ChatCompletionRequest(
//define model - required
ModelDefinitions.MistralMedium,
//define messages - required
new List()
{
new ChatMessage(ChatMessage.RoleEnum.System,
"You are an expert at writing sonnets."),
new ChatMessage(ChatMessage.RoleEnum.User,
"Write me a sonnet about the Statue of Liberty.")
},
//optional - defaults to false
safePrompt: true,
//optional - defaults to 0.7
temperature: 0,
//optional - defaults to null
maxTokens: 500,
//optional - defaults to 1
topP: 1,
//optional - defaults to null
randomSeed: 32);
var response = await client.Completions.GetCompletionAsync(request);
Console.WriteLine(response.Choices.First().Message.Content);
```### Streaming Call
The following is an example of a streaming call to the mistral-medium completions endpoint:
```csharp
var client = new MistralClient();
var request = new ChatCompletionRequest(
ModelDefinitions.MistralMedium,
new List()
{
new ChatMessage(ChatMessage.RoleEnum.System,
"You are an expert at writing sonnets."),
new ChatMessage(ChatMessage.RoleEnum.User,
"Write me a sonnet about the Statue of Liberty.")
});
var results = new List();
await foreach (var res in client.Completions.StreamCompletionAsync(request))
{
results.Add(res);
Console.Write(res.Choices.First().Delta.Content);
}
```
### IChatClientThe `MistralClient` has support for the new `IChatClient` from Microsoft and offers a slightly different mechanism for using the `MistralClient`. Below are a few examples.
```csharp
//non-streaming
IChatClient client = new MistralClient().Completions;var response = await client.GetResponseAsync(new List()
{
new(ChatRole.System, "You are an expert at writing sonnets."),
new(ChatRole.User, "Write me a sonnet about the Statue of Liberty.")
}, new() { ModelId = ModelDefinitions.OpenMistral7b });Assert.IsTrue(!string.IsNullOrEmpty(response.Message.Text));
//streaming call
IChatClient client = new MistralClient().Completions;var sb = new StringBuilder();
await foreach (var update in client.GetStreamingResponseAsync(new List()
{
new(ChatRole.System, "You are an expert at writing Json."),
new(ChatRole.User, "Write me a simple 'hello world' statement in a json object with a single 'result' key.")
}, new() { ModelId = ModelDefinitions.MistralLarge, ResponseFormat = ChatResponseFormat.Json }))
{
sb.Append(update);
}//parse json
Assert.IsNotNull(JsonSerializer.Deserialize(sb.ToString()));//Embeddings call
IEmbeddingGenerator> = new MistralClient().Embeddings;
var response = await client.GenerateEmbeddingVectorAsync("hello world", new() { ModelId = ModelDefinitions.MistralEmbed });
Assert.IsTrue(!response.IsEmpty);//Functions call
IChatClient client = new MistralClient().Completions
.AsBuilder()
.UseFunctionInvocation()
.Build();ChatOptions options = new()
{
ModelId = ModelDefinitions.MistralSmall,
MaxOutputTokens = 512,
ToolMode = ChatToolMode.Auto,
Tools = [AIFunctionFactory.Create((string personName) => personName switch {
"Alice" => "25",
_ => "40"
}, "GetPersonAge", "Gets the age of the person whose name is specified.")]
};var res = await client.GetResponseAsync("How old is Alice?", options);
Assert.IsTrue(
res.Message.Text?.Contains("25") is true,
res.Message.Text);```
Please see the integration tests for even more examples.### List Models
The following is an example of a call to list the available models:
```csharp
var client = new MistralClient();var response = await client.Models.GetModelsAsync();
```### Embeddings
The following is an example of a call to the mistral-embed embeddings model/endpoint:
```csharp
var client = new MistralClient();
var request = new EmbeddingRequest(
ModelDefinitions.MistralEmbed,
new List() { "Hello world" },
EmbeddingRequest.EncodingFormatEnum.Float);
var response = await client.Embeddings.GetEmbeddingsAsync(request);
```### Function Calling
The `MistralClient` supports Function Calling through a variety of mechanisms. It's worth noting that currently some models seem to hallucinate function calling behavior more than others, and this is a known issue with Mistral.
```csharp
public enum TempType
{
Fahrenheit,
Celsius
}[Function("This function returns the weather for a given location")]
public static async Task GetWeather([FunctionParameter("Location of the weather", true)] string location,
[FunctionParameter("Unit of temperature, celsius or fahrenheit", true)] TempType tempType)
{
await Task.Yield();
return "72 degrees and sunny";
}//declared globally
var client = new MistralClient();
var messages = new List()
{
new ChatMessage(ChatMessage.RoleEnum.User, "What is the weather in San Francisco, CA in Fahrenheit?")
};
var request = new ChatCompletionRequest(ModelDefinitions.MistralSmall, messages);
request.MaxTokens = 1024;
request.Temperature = 0.0m;
request.ToolChoice = ToolChoiceType.Auto;request.Tools = Common.Tool.GetAllAvailableTools(includeDefaults: false, forceUpdate: true, clearCache: true).ToList();
var response = await client.Completions.GetCompletionAsync(request).ConfigureAwait(false);
messages.Add(response.Choices.First().Message);
foreach (var toolCall in response.ToolCalls)
{
var resp = await toolCall.InvokeAsync();
messages.Add(new ChatMessage(toolCall, resp));
}var finalResult = await client.Completions.GetCompletionAsync(request).ConfigureAwait(false);
Assert.IsTrue(finalResult.Choices.First().Message.Content.Contains("72"));
//from a func
var client = new MistralClient();
var messages = new List()
{
new ChatMessage(ChatMessage.RoleEnum.User,"How many characters are in the word Christmas, multiply by 5, add 6, subtract 2, then divide by 2.1?")
};
var request = new ChatCompletionRequest(ModelDefinitions.MistralSmall, messages);request.ToolChoice = ToolChoiceType.Auto;
request.Tools = new List
{
Common.Tool.FromFunc("ChristmasMathFunction",
([FunctionParameter("word to start with", true)]string word,
[FunctionParameter("number to multiply word count by", true)]int multiplier,
[FunctionParameter("amount to add to word count", true)]int addition,
[FunctionParameter("amount to subtract from word count", true)]int subtraction,
[FunctionParameter("amount to divide word count by", true)]double divisor) =>
{
return ((word.Length * multiplier + addition - subtraction) / divisor).ToString(CultureInfo.InvariantCulture);
}, "Function that can be used to determine the number of characters in a word combined with a mathematical formula")
};var response = await client.Completions.GetCompletionAsync(request);
messages.Add(response.Choices.First().Message);
foreach (var toolCall in response.ToolCalls)
{
var resp = toolCall.Invoke();
messages.Add(new ChatMessage(toolCall, resp));
}var finalResult = await client.Completions.GetCompletionAsync(request);
Assert.IsTrue(finalResult.Choices.First().Message.Content.Contains("23"));
//see integration tests for examples like streaming function calls, calling a static or instance based function, and more.
```
## Contributing
Pull requests are welcome with associated integration tests. If you're planning to make a major change, please open an issue first to discuss your proposed changes.
## License
This project is licensed under the [MIT](https://choosealicense.com/licenses/mit/) License.