#pragma warning disable OPENAI001 using OpenAI.Responses; using System.ClientModel; namespace Intendant.Shared.Services; public sealed class OpenAiResponsesService : IOpenAiResponsesService { private readonly IOpenAiSettingsService _settingsService; public OpenAiResponsesService(IOpenAiSettingsService settingsService) { _settingsService = settingsService; } public async Task GenerateTextAsync(string prompt, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(prompt)) { throw new ArgumentException("Le prompt ne peut pas être vide.", nameof(prompt)); } OpenAiResponsesOptions settings = await _settingsService.GetAsync(cancellationToken); string apiKey = settings.ApiKey?.Trim() ?? string.Empty; if (string.IsNullOrWhiteSpace(apiKey)) { throw new InvalidOperationException("La clé API OpenAI est requise pour appeler la Responses API."); } string model = string.IsNullOrWhiteSpace(settings.Model) ? "gpt-5-mini" : settings.Model; ResponsesClient client = CreateClient(apiKey, settings.Endpoint); CreateResponseOptions options = new() { Model = model, }; options.InputItems.Add(ResponseItem.CreateUserMessageItem(prompt)); ResponseResult response = await client.CreateResponseAsync(options, cancellationToken); string text = string.Join( Environment.NewLine, response.OutputItems .OfType() .SelectMany(message => message.Content) .Select(content => content.Text) .Where(value => !string.IsNullOrWhiteSpace(value))); return text; } private static ResponsesClient CreateClient(string apiKey, string endpoint) { if (string.IsNullOrWhiteSpace(endpoint)) { return new ResponsesClient(apiKey); } if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? endpointUri)) { throw new InvalidOperationException("L'endpoint OpenAI configuré est invalide."); } ResponsesClientOptions clientOptions = new() { Endpoint = endpointUri, }; return new ResponsesClient(new ApiKeyCredential(apiKey), clientOptions); } } #pragma warning restore OPENAI001