146 lines
3.7 KiB
C#
146 lines
3.7 KiB
C#
using BS.Shared.DataContracts;
|
|
using BS.Shared.DataContracts.Feature.AI;
|
|
using BS.Shared.Extensions;
|
|
using BS.Shared.Interface;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Net.Sockets;
|
|
using System.Net;
|
|
using BeWo.ServerUtils.ApiFacade;
|
|
using BS.Shared;
|
|
using BS.Shared.Logger;
|
|
using log4net;
|
|
using System.Runtime.CompilerServices;
|
|
using BS.Shared.Core;
|
|
using BeWo.ServerUtils.Core;
|
|
|
|
namespace AICore.Facade.LLM
|
|
{
|
|
public class OllamaApiClient : BaseLLMApiClient
|
|
{
|
|
private AiModelSource _aiModelSource;
|
|
private ILog _logger;
|
|
|
|
public OllamaApiClient(string base_url, string api_key, AiModelSource modelSource = AiModelSource.ollama) : base(base_url, api_key)
|
|
{
|
|
_aiModelSource = modelSource;
|
|
_logger = LoggerUtils.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
if (modelSource != AiModelSource.ollama && modelSource != AiModelSource.ollama2)
|
|
throw new NotImplementedException("err4548975");
|
|
}
|
|
|
|
public override ApiResponse<IEnumerable<AiModelDC>> GetAiModelle()
|
|
{
|
|
var models = new List<AiModelDC>();
|
|
|
|
_logger.Info($"GetModels: Hole aktuelle Modelle von '{_aiModelSource}'");
|
|
|
|
var response_format = new
|
|
{
|
|
models = new[]
|
|
{
|
|
new
|
|
{
|
|
name = "",
|
|
model = "",
|
|
details = new
|
|
{
|
|
max_context_size = 0
|
|
}
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
var response = _GetClientFacade.GetAnonymousTypeAsync("api/ollama/models", response_format, _ErrorExtractor).GetAwaiter().GetResult();
|
|
|
|
if (!response.Success)
|
|
{
|
|
_logger.Error(response);
|
|
_logger.Error(response.ToErrorString());
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
var data = response.Data.models.Select(x => new AiModelDC(_aiModelSource, x.name, x.details.max_context_size));
|
|
|
|
var log_str = string.Join("", data.Select(x => $"\r\n\t\t\t\t- {x.ToString()}"));
|
|
|
|
_logger.Info($"GetModels: Aktuelle Modelle von '{_aiModelSource}': {log_str}");
|
|
|
|
return ApiResponse<IEnumerable<AiModelDC>>.SuccessResponse(data);
|
|
}
|
|
|
|
public override ApiResponse<string> SendAiMessageRequest(dynamic payload, out string message, out string model, out int? duration, FileLogger logger = null)
|
|
{
|
|
message = null;
|
|
duration = null;
|
|
model = null;
|
|
|
|
_PostClientFacade.JsonObject = payload;
|
|
|
|
if(logger is object)
|
|
{
|
|
logger.Log(LogLevel.Debug, "Chat Request:");
|
|
logger.LogJson(LogLevel.Debug, _PostClientFacade.JsonObject);
|
|
}
|
|
|
|
var response_format = new
|
|
{
|
|
id = string.Empty,
|
|
model = string.Empty,
|
|
message = new
|
|
{
|
|
content = string.Empty,
|
|
role = string.Empty
|
|
},
|
|
done_reason = "stop",
|
|
done = true,
|
|
total_duration = 1316754573L,
|
|
load_duration = 31739136L,
|
|
prompt_eval_count = 22L,
|
|
prompt_eval_duration = 2132887L,
|
|
eval_count = 66L,
|
|
eval_duration = 1282438235L,
|
|
error = ""
|
|
};
|
|
|
|
var response = _PostClientFacade.GetAnonymousTypeAsync("api/ollama/chat/completions", response_format, _ErrorExtractor).GetAwaiter().GetResult();
|
|
|
|
if(response.Data is object && response.Data.error is string err)
|
|
{
|
|
response.ErrorStrings.Add(err);
|
|
}
|
|
|
|
if(logger is object)
|
|
{
|
|
logger.Log(LogLevel.Debug, "Chat Response:");
|
|
logger.LogJson(LogLevel.Debug, response);
|
|
}
|
|
|
|
if (!response.Success)
|
|
return response.Copy<string>();
|
|
|
|
var json = response.GetResponseData();
|
|
|
|
if (json.message is object && !string.IsNullOrEmpty(json.message.content))
|
|
{
|
|
var total_ns = json.total_duration;
|
|
var total_ms = total_ns / 1000000;
|
|
|
|
duration = (int)total_ms;
|
|
model = json.model;
|
|
|
|
var assi_msg = BS.Shared.Core.Utils.ConvertToISO88591(json.message.content);
|
|
|
|
message = assi_msg;
|
|
|
|
return ApiResponse<string>.SuccessResponse(assi_msg);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|