Add provider abstraction layer with Mistral and Ollama implementations

Define IProvider interface and implement concrete providers for Mistral
(with custom DTOs for chat completion API) and Ollama (via OllamaSharp).
Includes DI registration extensions using Microsoft.Extensions.AI.
This commit is contained in:
2026-04-04 04:10:39 +02:00
parent 63818df4b5
commit 45d3ee1ed6
18 changed files with 515 additions and 0 deletions
@@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralChatCompletionChunk
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("object")]
public string? Object { get; set; }
[JsonPropertyName("model")]
public string? Model { get; set; }
[JsonPropertyName("choices")]
public List<MistralChoiceChunk>? Choices { get; set; }
}
@@ -0,0 +1,31 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralChatCompletionRequest
{
[JsonPropertyName("model")]
public required string Model { get; set; }
[JsonPropertyName("messages")]
public required List<MistralMessage> Messages { get; set; }
[JsonPropertyName("temperature")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public float? Temperature { get; set; }
[JsonPropertyName("max_tokens")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? MaxTokens { get; set; }
[JsonPropertyName("top_p")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public float? TopP { get; set; }
[JsonPropertyName("stream")]
public bool Stream { get; set; }
[JsonPropertyName("response_format")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public ResponseFormat? ResponseFormat { get; set; }
}
@@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralChatCompletionResponse
{
[JsonPropertyName("id")]
public string? Id { get; set; }
[JsonPropertyName("object")]
public string? Object { get; set; }
[JsonPropertyName("model")]
public string? Model { get; set; }
[JsonPropertyName("choices")]
public List<MistralChoice>? Choices { get; set; }
[JsonPropertyName("usage")]
public Usage? Usage { get; set; }
}
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralChoice
{
[JsonPropertyName("index")]
public int Index { get; set; }
[JsonPropertyName("message")]
public MistralMessage? Message { get; set; }
[JsonPropertyName("finish_reason")]
public string? FinishReason { get; set; }
}
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralChoiceChunk
{
[JsonPropertyName("index")]
public int Index { get; set; }
[JsonPropertyName("delta")]
public MistralDelta? Delta { get; set; }
[JsonPropertyName("finish_reason")]
public string? FinishReason { get; set; }
}
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralDelta
{
[JsonPropertyName("role")]
public string? Role { get; set; }
[JsonPropertyName("content")]
public string? Content { get; set; }
}
@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
[JsonSerializable(typeof(MistralChatCompletionRequest))]
[JsonSerializable(typeof(MistralChatCompletionResponse))]
[JsonSerializable(typeof(MistralChatCompletionChunk))]
public partial class MistralJsonContext : JsonSerializerContext
{
}
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class MistralMessage
{
[JsonPropertyName("role")]
public required string Role { get; set; }
[JsonPropertyName("content")]
public required string Content { get; set; }
}
@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class ResponseFormat
{
[JsonPropertyName("type")]
public required string Type { get; set; }
}
+15
View File
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace Luna.Providers.Mistral.DTOs;
public class Usage
{
[JsonPropertyName("prompt_tokens")]
public int PromptTokens { get; set; }
[JsonPropertyName("completion_tokens")]
public int CompletionTokens { get; set; }
[JsonPropertyName("total_tokens")]
public int TotalTokens { get; set; }
}