* Extended functionalities

* Added different UIs
This commit is contained in:
2026-06-24 21:43:40 +02:00
parent 282f4864c4
commit f15bb7a916
348 changed files with 59057 additions and 498 deletions

View File

@@ -0,0 +1,80 @@
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Options;
namespace MealPlan.Api.Services.AI;
public class OpenAiChatService : IOpenAiChatService
{
private readonly HttpClient _http;
private readonly OpenAiOptions _options;
private readonly ILogger<OpenAiChatService> _logger;
public OpenAiChatService(HttpClient http, IOptions<OpenAiOptions> options, ILogger<OpenAiChatService> logger)
{
_http = http;
_options = options.Value;
_logger = logger;
}
public bool IsConfigured => _options.IsConfigured;
public async Task<string> CompleteJsonAsync(
string systemPrompt,
string userPrompt,
OpenAiUseCase useCase = OpenAiUseCase.Default,
CancellationToken ct = default)
{
if (!IsConfigured)
{
throw new InvalidOperationException(
"OpenAI is not configured. Set OpenAI__ApiKey in appsettings.Local.json.");
}
var model = _options.ResolveModel(useCase);
var payload = new
{
model,
max_tokens = _options.MaxTokens,
response_format = new { type = "json_object" },
messages = new[]
{
new { role = "system", content = systemPrompt },
new { role = "user", content = userPrompt },
},
};
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.openai.com/v1/chat/completions");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _options.ApiKey);
request.Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var response = await _http.SendAsync(request, ct);
var body = await response.Content.ReadAsStringAsync(ct);
if (!response.IsSuccessStatusCode)
{
_logger.LogWarning("OpenAI API error {Status}: {Body}", response.StatusCode, body);
throw new InvalidOperationException("OpenAI request failed. Check API key and quota.");
}
using var doc = JsonDocument.Parse(body);
var content = doc.RootElement
.GetProperty("choices")[0]
.GetProperty("message")
.GetProperty("content")
.GetString() ?? "{}";
return StripMarkdownFence(content);
}
private static string StripMarkdownFence(string content)
{
var trimmed = content.Trim();
if (!trimmed.StartsWith("```", StringComparison.Ordinal)) return trimmed;
var firstNewline = trimmed.IndexOf('\n');
if (firstNewline < 0) return trimmed;
var endFence = trimmed.LastIndexOf("```", StringComparison.Ordinal);
if (endFence <= firstNewline) return trimmed;
return trimmed[(firstNewline + 1)..endFence].Trim();
}
}