chore: init project
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
using InboxIntel.Application.Abstractions;
|
||||
using InboxIntel.Domain.Enums;
|
||||
using InboxIntel.Infrastructure.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace InboxIntel.Infrastructure.Ai;
|
||||
|
||||
/// <summary>No-op provider used when AI is disabled. Returns empty completions.</summary>
|
||||
public class NullAiProvider : IAiProvider
|
||||
{
|
||||
public AiProviderMode Mode => AiProviderMode.Disabled;
|
||||
public Task<string> CompleteAsync(string systemPrompt, string userPrompt, CancellationToken ct = default)
|
||||
=> Task.FromResult(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>Local LLM via Ollama's /api/chat endpoint.</summary>
|
||||
public class OllamaProvider : IAiProvider
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
private readonly AiOptions _options;
|
||||
|
||||
public OllamaProvider(IHttpClientFactory factory, IOptions<AiOptions> options)
|
||||
{
|
||||
_options = options.Value;
|
||||
_http = factory.CreateClient("ollama");
|
||||
_http.BaseAddress = new Uri(_options.OllamaBaseUrl);
|
||||
}
|
||||
|
||||
public AiProviderMode Mode => AiProviderMode.LocalOllama;
|
||||
|
||||
public async Task<string> CompleteAsync(string systemPrompt, string userPrompt, CancellationToken ct = default)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
model = _options.OllamaModel,
|
||||
stream = false,
|
||||
messages = new[]
|
||||
{
|
||||
new { role = "system", content = systemPrompt },
|
||||
new { role = "user", content = userPrompt }
|
||||
}
|
||||
};
|
||||
var resp = await _http.PostAsJsonAsync("/api/chat", payload, ct);
|
||||
resp.EnsureSuccessStatusCode();
|
||||
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync(ct));
|
||||
return doc.RootElement.GetProperty("message").GetProperty("content").GetString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Cloud LLM via the OpenAI Chat Completions API (optional).</summary>
|
||||
public class OpenAiProvider : IAiProvider
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
private readonly AiOptions _options;
|
||||
|
||||
public OpenAiProvider(IHttpClientFactory factory, IOptions<AiOptions> options)
|
||||
{
|
||||
_options = options.Value;
|
||||
_http = factory.CreateClient("openai");
|
||||
_http.BaseAddress = new Uri("https://api.openai.com");
|
||||
_http.DefaultRequestHeaders.Authorization =
|
||||
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _options.OpenAiApiKey);
|
||||
}
|
||||
|
||||
public AiProviderMode Mode => AiProviderMode.CloudOpenAi;
|
||||
|
||||
public async Task<string> CompleteAsync(string systemPrompt, string userPrompt, CancellationToken ct = default)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
model = _options.OpenAiModel,
|
||||
messages = new[]
|
||||
{
|
||||
new { role = "system", content = systemPrompt },
|
||||
new { role = "user", content = userPrompt }
|
||||
}
|
||||
};
|
||||
var resp = await _http.PostAsJsonAsync("/v1/chat/completions", payload, ct);
|
||||
resp.EnsureSuccessStatusCode();
|
||||
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync(ct));
|
||||
return doc.RootElement.GetProperty("choices")[0].GetProperty("message").GetProperty("content").GetString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user