mirror of
https://github.com/Shchoholiev/shopping-assistant-api.git
synced 2025-04-12 01:48:49 +00:00
SA-29 created openai service
This commit is contained in:
parent
236153d486
commit
3a6c72a8be
@ -0,0 +1,10 @@
|
|||||||
|
using ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Application.IServices;
|
||||||
|
|
||||||
|
public interface IOpenAiService
|
||||||
|
{
|
||||||
|
Task<OpenAiResponse?> GetChatCompletion(ChatCompletionRequest chat, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
IAsyncEnumerable<OpenAiResponse> GetChatCompletionStream(ChatCompletionRequest chat, CancellationToken cancellationToken);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
public class OpenAiChoice
|
||||||
|
{
|
||||||
|
public OpenAiMessage Message { get; set; }
|
||||||
|
|
||||||
|
public OpenAiDelta Delta { get; set; }
|
||||||
|
|
||||||
|
public string FinishReason { get; set; }
|
||||||
|
|
||||||
|
public int Index { get; set; }
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
public class OpenAiDelta
|
||||||
|
{
|
||||||
|
public string Role { get; set; }
|
||||||
|
|
||||||
|
public string Content { get; set; }
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
public class OpenAiResponse
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
public string Object { get; set; }
|
||||||
|
|
||||||
|
public int Created { get; set; }
|
||||||
|
|
||||||
|
public string Model { get; set; }
|
||||||
|
|
||||||
|
public OpenAiUsage Usage { get; set; }
|
||||||
|
|
||||||
|
public List<OpenAiChoice> Choices { get; set; }
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
public class OpenAiUsage
|
||||||
|
{
|
||||||
|
public int PromptTokens { get; set; }
|
||||||
|
|
||||||
|
public int CompletionTokens { get; set; }
|
||||||
|
|
||||||
|
public int TotalTokens { get; set; }
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using ShoppingAssistantApi.Application.IServices;
|
||||||
|
using ShoppingAssistantApi.Application.Models.OpenAi;
|
||||||
|
|
||||||
|
namespace ShoppingAssistantApi.Infrastructure.Services;
|
||||||
|
|
||||||
|
public class OpenaiService : IOpenAiService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
|
private readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
ContractResolver = new DefaultContractResolver
|
||||||
|
{
|
||||||
|
NamingStrategy = new SnakeCaseNamingStrategy()
|
||||||
|
},
|
||||||
|
NullValueHandling = NullValueHandling.Ignore,
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
//private readonly OpenAIClient _openAiClient;
|
||||||
|
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public OpenaiService(
|
||||||
|
IConfiguration configuration,
|
||||||
|
IHttpClientFactory httpClientFactory,
|
||||||
|
ILogger<OpenaiService> logger
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_httpClient = httpClientFactory.CreateClient("OpenAiHttpClient");
|
||||||
|
_configuration = configuration;
|
||||||
|
|
||||||
|
//var openAIApiKey = _configuration.GetSection("OpenAi")?.GetValue<string>("ApiKey");
|
||||||
|
//_openAiClient = new OpenAIClient(openAIApiKey, new OpenAIClientOptions());
|
||||||
|
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async IAsyncEnumerable<OpenAiResponse> GetChatCompletionStream(ChatCompletionRequest chat, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
chat.Stream = true;
|
||||||
|
var jsonBody = JsonConvert.SerializeObject(chat, _jsonSettings);
|
||||||
|
_logger.LogInformation(jsonBody);
|
||||||
|
var body = new StringContent(jsonBody, Encoding.UTF8, "application/json");
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Post, "chat/completions")
|
||||||
|
{
|
||||||
|
Content = body
|
||||||
|
};
|
||||||
|
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));
|
||||||
|
|
||||||
|
using var httpResponse = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||||
|
|
||||||
|
var allData = string.Empty;
|
||||||
|
|
||||||
|
using var streamReader = new StreamReader(await httpResponse.Content.ReadAsStringAsync(cancellationToken));
|
||||||
|
while(!streamReader.EndOfStream)
|
||||||
|
{
|
||||||
|
var line = await streamReader.ReadLineAsync();
|
||||||
|
allData += line + "\n\n";
|
||||||
|
if (string.IsNullOrEmpty(line)) continue;
|
||||||
|
|
||||||
|
var json = line?.Substring(6, line.Length - 6);
|
||||||
|
if (json == "[DONE]") yield break;
|
||||||
|
|
||||||
|
var OpenAiResponse = JsonConvert.DeserializeObject<OpenAiResponse>(json, _jsonSettings);
|
||||||
|
yield return OpenAiResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OpenAiResponse?> GetChatCompletion(ChatCompletionRequest chat, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
chat.Stream = false;
|
||||||
|
var jsonBody = JsonConvert.SerializeObject(chat, _jsonSettings);
|
||||||
|
var body = new StringContent(jsonBody, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
_logger.LogInformation(jsonBody);
|
||||||
|
using var httpResponse = await _httpClient.PostAsync("chat/completions", body, cancellationToken);
|
||||||
|
|
||||||
|
var responseBody = await httpResponse.Content.ReadAsStringAsync(cancellationToken);
|
||||||
|
|
||||||
|
var responses = new List<OpenAiResponse>();
|
||||||
|
foreach (var line in responseBody.Split(new[] {"\n\n"}, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
if (line.Trim() == "[DONE]") break;
|
||||||
|
|
||||||
|
var json = line.Substring(6);
|
||||||
|
var OpenAiResponse = JsonConvert.DeserializeObject<OpenAiResponse>(json, _jsonSettings);
|
||||||
|
responses.Add(OpenAiResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return responses.Count > 0 ? responses.Last() : null;
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
|
||||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.32.0" />
|
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.32.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.32.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.32.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user