Files
BeWoPlaner/Service/ServiceProxy/OpenWebApiClient.cs
2025-07-04 14:27:08 +02:00

133 lines
3.5 KiB
C#

using BeWo.Data.Entities;
using BeWo.Service.Api.ErrorExtractor;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BS.Shared.Core;
using BS.Shared.Core.Facade;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Feature.AI;
using BS.Shared.Exceptions;
using BS.Shared.Extensions;
using BS.Shared.Interface;
using DevExpress.DataProcessing.InMemoryDataProcessor;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using static DevExpress.Xpo.Helpers.AssociatedCollectionCriteriaHelper;
namespace BeWo.Service.ServiceProxy
{
public class OpenWebApiClient
{
private readonly HttpClientFacade _GetClientFacade;
private readonly JsonHttpClientFacade _PostClientFacade;
private readonly IApiErrorExtractor _ErrorExtractor;
public OpenWebApiClient() : this(MergedConfig.GetSetting("OpenWebUIUrl"), MergedConfig.GetSetting("OpenWebUIKey")) { }
public OpenWebApiClient(string base_url, string api_key)
{
var authorization = $"Bearer {api_key}";
_GetClientFacade = new HttpClientFacade(base_url);
_GetClientFacade.SetToken(authorization);
_PostClientFacade = new JsonHttpClientFacade(base_url);
_PostClientFacade.SetToken(authorization);
_PostClientFacade.Timeout = TimeSpan.FromSeconds(300);
_ErrorExtractor = new DefaultErrorExtractor();
}
public ApiResponse<IEnumerable<AiModel>> GetAiModelle()
{
var models = new List<AiModelDC>();
var response_format = new
{
data = models
};
var response = _GetClientFacade.GetAnonymousTypeAsync("api/models", response_format, _ErrorExtractor).GetAwaiter().GetResult();
if (!response.Success)
{
throw new NotImplementedException();
}
var data = MapperFactory.AiModel.MapToNewEntities(response.Data.data);
return ApiResponse<IEnumerable<AiModel>>.SuccessResponse(data);
}
public ApiResponse<string> SendAiMessageRequest(AiConversationDC conversation, AiConfigDC config, out string message, out string model, out int? duration)
{
message = null;
duration = null;
model = null;
var sub_url = "api/chat/completions";
var payload = new
{
model = config.SelectedModel.ModelName,
messages = conversation.Messages.Select(m => new { role = m.Role.ToString().ToLower(), content = m.Message })
};
var response_format = new
{
id = string.Empty,
model = string.Empty,
choices = new[]
{
new
{
index = 0,
message = new
{
content = string.Empty,
role = string.Empty
}
}
},
usage = new
{
total_duration = 0L,
total_tokens = 68L
}
};
_PostClientFacade.JsonObject = payload;
var response = _PostClientFacade.GetAnonymousTypeAsync(sub_url, response_format, _ErrorExtractor).GetAwaiter().GetResult();
if (!response.Success)
return response.Copy<string>();
var json = response.GetResponseData();
foreach (var choice in json.choices)
{
if (choice?.message is object && !string.IsNullOrEmpty(choice.message.content))
{
var total_ns = json.usage.total_duration;
var total_ms = total_ns / 1000000;
duration = (int)total_ms;
model = json.model;
var assi_msg = BS.Shared.Core.Utils.ConvertToISO88591(choice.message.content);
message = assi_msg;
return ApiResponse<string>.SuccessResponse(assi_msg);
}
}
return ApiResponse<string>.FailureResponse("Keine Antwort");
}
}
}