Add project files.
This commit is contained in:
parent
e9ab75e651
commit
5cec2a7210
17
ChatGemini/ChatGemini.csproj
Normal file
17
ChatGemini/ChatGemini.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<RootNamespace>ChatServerSpace</RootNamespace>
|
||||||
|
<AssemblyName>ChatServerSpace</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.SemanticKernel" Version="1.47.0" />
|
||||||
|
<PackageReference Include="MongoDB.Driver" Version="2.24.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
ChatGemini/ChatGemini.http
Normal file
6
ChatGemini/ChatGemini.http
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@ChatGemini_HostAddress = http://localhost:5004
|
||||||
|
|
||||||
|
GET {{ChatGemini_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
45
ChatGemini/Controllers/ChatController.cs
Normal file
45
ChatGemini/Controllers/ChatController.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using ChatServerSpace.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class ChatController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IChatService _chatService;
|
||||||
|
private readonly ILogger<ChatController> _logger;
|
||||||
|
|
||||||
|
public ChatController(IChatService chatService, ILogger<ChatController> logger)
|
||||||
|
{
|
||||||
|
_chatService = chatService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult<ChatResponse>> Chat([FromBody] ChatRequest request)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(request.SessionId))
|
||||||
|
{
|
||||||
|
return BadRequest("SessionId is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.Message))
|
||||||
|
{
|
||||||
|
return BadRequest("Message is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await _chatService.ProcessMessageAsync(request);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error processing chat message");
|
||||||
|
return StatusCode(500, "An error occurred while processing your message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
ChatGemini/Models/ChatMessage.cs
Normal file
18
ChatGemini/Models/ChatMessage.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using ThirdParty.Json.LitJson;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Models
|
||||||
|
{
|
||||||
|
public class ChatMessage
|
||||||
|
{
|
||||||
|
[BsonElement("_id")]
|
||||||
|
[BsonId]
|
||||||
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string SessionId { get; set; } = string.Empty;
|
||||||
|
public string Role { get; set; } = string.Empty;
|
||||||
|
public string Content { get; set; } = string.Empty;
|
||||||
|
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
ChatGemini/Models/ChatRequest.cs
Normal file
8
ChatGemini/Models/ChatRequest.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace ChatServerSpace.Models
|
||||||
|
{
|
||||||
|
public class ChatRequest
|
||||||
|
{
|
||||||
|
public required string SessionId { get; set; }
|
||||||
|
public required string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
ChatGemini/Models/ChatResponse.cs
Normal file
8
ChatGemini/Models/ChatResponse.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace ChatServerSpace.Models
|
||||||
|
{
|
||||||
|
public class ChatResponse
|
||||||
|
{
|
||||||
|
public required string SessionId { get; set; }
|
||||||
|
public required string Response { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
30
ChatGemini/Program.cs
Normal file
30
ChatGemini/Program.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using ChatServerSpace.Services;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
|
|
||||||
|
// Register services
|
||||||
|
builder.Services.AddSingleton<IChatHistoryService, MongoDbChatHistoryService>();
|
||||||
|
builder.Services.AddScoped<IChatService, ServerSpaceChatService>();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
41
ChatGemini/Properties/launchSettings.json
Normal file
41
ChatGemini/Properties/launchSettings.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:21434",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5004",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7238;http://localhost:5004",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
108
ChatGemini/Services/GeminiChatService.cs
Normal file
108
ChatGemini/Services/GeminiChatService.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using Microsoft.SemanticKernel;
|
||||||
|
using Microsoft.SemanticKernel.ChatCompletion;
|
||||||
|
using Microsoft.SemanticKernel.Connectors.Google;
|
||||||
|
|
||||||
|
#pragma warning disable SKEXP0070 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class GeminiChatService : IChatService
|
||||||
|
{
|
||||||
|
private readonly IChatHistoryService _historyService;
|
||||||
|
private readonly Kernel _kernel;
|
||||||
|
private readonly ILogger<GeminiChatService> _logger;
|
||||||
|
|
||||||
|
public GeminiChatService(IChatHistoryService historyService, IConfiguration config, ILogger<GeminiChatService> logger)
|
||||||
|
{
|
||||||
|
_historyService = historyService;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
var apiKey = config["Google:GeminiApiKey"] ?? throw new ArgumentNullException("Google:GeminiApiKey configuration is missing");
|
||||||
|
var modelId = config["Google:ModelId"] ?? "gemini-1.5-pro";
|
||||||
|
|
||||||
|
_kernel = Kernel.CreateBuilder()
|
||||||
|
.AddGoogleAIGeminiChatCompletion(modelId, apiKey)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ChatResponse> ProcessMessageAsync(ChatRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Save user message to history
|
||||||
|
var userMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "user",
|
||||||
|
Content = request.Message
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(userMessage);
|
||||||
|
|
||||||
|
// Get chat history
|
||||||
|
var history = await _historyService.GetSessionHistoryAsync(request.SessionId);
|
||||||
|
|
||||||
|
// Create chat history for Semantic Kernel
|
||||||
|
var chatHistory = new Microsoft.SemanticKernel.ChatCompletion.ChatHistory();
|
||||||
|
|
||||||
|
foreach (var message in history)
|
||||||
|
{
|
||||||
|
if (message.Role.Equals("user", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
chatHistory.AddUserMessage(message.Content);
|
||||||
|
}
|
||||||
|
else if (message.Role.Equals("assistant", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
chatHistory.AddAssistantMessage(message.Content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get response from Gemini
|
||||||
|
var chatCompletionService = _kernel.GetRequiredService<IChatCompletionService>();
|
||||||
|
|
||||||
|
var exec = new PromptExecutionSettings
|
||||||
|
{
|
||||||
|
ExtensionData = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "maxOutputTokens", 8192 },
|
||||||
|
{ "temperature", 0.7 },
|
||||||
|
{ "topP", 0.95 },
|
||||||
|
{ "stopSequences", new List<string>() }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var result = await chatCompletionService.GetChatMessageContentAsync(chatHistory, exec);
|
||||||
|
var responseText = result.ToString();
|
||||||
|
|
||||||
|
// Save assistant message to history
|
||||||
|
var assistantMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "assistant",
|
||||||
|
Content = responseText
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(assistantMessage);
|
||||||
|
|
||||||
|
await Task.Delay(2000);
|
||||||
|
|
||||||
|
return new ChatResponse
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Response = responseText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error getting response from Gemini");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception("Erro na parada!", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma warning restore SKEXP0070 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||||
10
ChatGemini/Services/IChatHistoryService.cs
Normal file
10
ChatGemini/Services/IChatHistoryService.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public interface IChatHistoryService
|
||||||
|
{
|
||||||
|
Task SaveMessageAsync(ChatMessage message);
|
||||||
|
Task<List<ChatMessage>> GetSessionHistoryAsync(string sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
9
ChatGemini/Services/IChatService.cs
Normal file
9
ChatGemini/Services/IChatService.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public interface IChatService
|
||||||
|
{
|
||||||
|
Task<ChatResponse> ProcessMessageAsync(ChatRequest request);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
ChatGemini/Services/MongoDbChatHistoryService.cs
Normal file
36
ChatGemini/Services/MongoDbChatHistoryService.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class MongoDbChatHistoryService : IChatHistoryService
|
||||||
|
{
|
||||||
|
private readonly IMongoCollection<ChatMessage> _messages;
|
||||||
|
|
||||||
|
public MongoDbChatHistoryService(IConfiguration config)
|
||||||
|
{
|
||||||
|
var connectionString = config["MongoDB:ConnectionString"];
|
||||||
|
var databaseName = config["MongoDB:DatabaseName"];
|
||||||
|
var collectionName = config["MongoDB:CollectionName"];
|
||||||
|
|
||||||
|
var client = new MongoClient(connectionString);
|
||||||
|
var database = client.GetDatabase(databaseName);
|
||||||
|
_messages = database.GetCollection<ChatMessage>(collectionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveMessageAsync(ChatMessage message)
|
||||||
|
{
|
||||||
|
await _messages.InsertOneAsync(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<ChatMessage>> GetSessionHistoryAsync(string sessionId)
|
||||||
|
{
|
||||||
|
var filter = Builders<ChatMessage>.Filter.Eq(m => m.SessionId, sessionId);
|
||||||
|
var sort = Builders<ChatMessage>.Sort.Ascending(m => m.Timestamp);
|
||||||
|
|
||||||
|
return await _messages.Find(filter)
|
||||||
|
.Sort(sort)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
ChatGemini/Services/ServerSpaceChatService.cs
Normal file
120
ChatGemini/Services/ServerSpaceChatService.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class ServerSpaceChatService : IChatService
|
||||||
|
{
|
||||||
|
private readonly IChatHistoryService _historyService;
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private readonly ILogger<ServerSpaceChatService> _logger;
|
||||||
|
private readonly string _apiKey;
|
||||||
|
private readonly JsonSerializerOptions _jsonOptions;
|
||||||
|
|
||||||
|
public ServerSpaceChatService(IChatHistoryService historyService, IConfiguration config, ILogger<ServerSpaceChatService> logger, HttpClient httpClient)
|
||||||
|
{
|
||||||
|
_historyService = historyService;
|
||||||
|
_logger = logger;
|
||||||
|
_httpClient = httpClient;
|
||||||
|
|
||||||
|
_apiKey = config["ServerSpace:ApiKey"] ?? throw new ArgumentNullException("ServerSpace:ApiKey configuration is missing");
|
||||||
|
_httpClient.BaseAddress = new Uri("https://gpt.serverspace.com.br/");
|
||||||
|
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey);
|
||||||
|
|
||||||
|
_jsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ChatResponse> ProcessMessageAsync(ChatRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Save user message to history
|
||||||
|
var userMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "user",
|
||||||
|
Content = request.Message
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(userMessage);
|
||||||
|
|
||||||
|
// Get chat history
|
||||||
|
var history = await _historyService.GetSessionHistoryAsync(request.SessionId);
|
||||||
|
|
||||||
|
// Create messages array for API request
|
||||||
|
var messages = history.Select(m => new
|
||||||
|
{
|
||||||
|
role = m.Role,
|
||||||
|
content = m.Content
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
// Create API request body
|
||||||
|
var requestBody = new
|
||||||
|
{
|
||||||
|
model = "anthropic/claude-3.5-haiku",
|
||||||
|
max_tokens = 1024,
|
||||||
|
top_p = 0.1,
|
||||||
|
temperature = 0.6,
|
||||||
|
messages
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send request to ServerSpace API
|
||||||
|
var jsonContent = JsonSerializer.Serialize(requestBody, _jsonOptions);
|
||||||
|
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
var response = await _httpClient.PostAsync("v1/chat/completions", content);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
var responseJson = await response.Content.ReadAsStringAsync();
|
||||||
|
var responseObj = JsonSerializer.Deserialize<ServerSpaceResponse>(responseJson, _jsonOptions);
|
||||||
|
|
||||||
|
if (responseObj == null || string.IsNullOrEmpty(responseObj.Choices?[0]?.Message?.Content))
|
||||||
|
{
|
||||||
|
throw new Exception("Invalid response from ServerSpace API");
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseText = responseObj.Choices[0].Message.Content;
|
||||||
|
|
||||||
|
// Save assistant message to history
|
||||||
|
var assistantMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "assistant",
|
||||||
|
Content = responseText
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(assistantMessage);
|
||||||
|
|
||||||
|
return new ChatResponse
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Response = responseText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error processing message with ServerSpace API");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServerSpaceResponse
|
||||||
|
{
|
||||||
|
public List<ServerSpaceChoice>? Choices { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServerSpaceChoice
|
||||||
|
{
|
||||||
|
public ServerSpaceMessage? Message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServerSpaceMessage
|
||||||
|
{
|
||||||
|
public string? Content { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
ChatGemini/appsettings.Development.json
Normal file
8
ChatGemini/appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
ChatGemini/appsettings.json
Normal file
21
ChatGemini/appsettings.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"Google": {
|
||||||
|
"GeminiApiKey": "AIzaSyBnea0la9S-rEVBv8qUqbrv37Zl9-0kHpQ",
|
||||||
|
"ModelId": "gemini-1.5-pro"
|
||||||
|
},
|
||||||
|
"ServerSpace": {
|
||||||
|
"ApiKey": "tIAXVf3AkCkkpSX+PjFvktfEeSPyA1ZYam50UO3ye/qmxVZX6PIXstmJsLZXkQ39C33onFD/81mdxvhbGHm7tQ=="
|
||||||
|
},
|
||||||
|
"MongoDB": {
|
||||||
|
"ConnectionString": "mongodb://admin:c4rn31r0@192.168.0.82:27017,192.168.0.81:27017/?authSource=admin",
|
||||||
|
"DatabaseName": "ChatServerSpaceDb",
|
||||||
|
"CollectionName": "ChatMessages"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
ChatServerSpace.sln
Normal file
24
ChatServerSpace.sln
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.8.34511.84
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatDeepInfra", "ChatServerSpace\ChatDeepInfra.csproj", "{9CC710C3-37FE-4B1A-9C6A-D01EA7A74AB7}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{9CC710C3-37FE-4B1A-9C6A-D01EA7A74AB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9CC710C3-37FE-4B1A-9C6A-D01EA7A74AB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9CC710C3-37FE-4B1A-9C6A-D01EA7A74AB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9CC710C3-37FE-4B1A-9C6A-D01EA7A74AB7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {5AF01BE8-CB55-4F4F-90FC-DDF2A1C86A09}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
18
ChatServerSpace/ChatDeepInfra.csproj
Normal file
18
ChatServerSpace/ChatDeepInfra.csproj
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<RootNamespace>ChatServerSpace</RootNamespace>
|
||||||
|
<AssemblyName>ChatServerSpace</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.SemanticKernel" Version="1.47.0" />
|
||||||
|
<PackageReference Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.47.0" />
|
||||||
|
<PackageReference Include="MongoDB.Driver" Version="2.24.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
ChatServerSpace/ChatGemini.http
Normal file
6
ChatServerSpace/ChatGemini.http
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@ChatGemini_HostAddress = http://localhost:5004
|
||||||
|
|
||||||
|
GET {{ChatGemini_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
||||||
47
ChatServerSpace/Controllers/ChatController.cs
Normal file
47
ChatServerSpace/Controllers/ChatController.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using ChatServerSpace.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class ChatController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IChatServiceFactory _chatServiceFactory;
|
||||||
|
private readonly IChatService _chatService;
|
||||||
|
private readonly ILogger<ChatController> _logger;
|
||||||
|
|
||||||
|
public ChatController(IChatServiceFactory chatServiceFactory, ILogger<ChatController> logger)
|
||||||
|
{
|
||||||
|
_chatServiceFactory = chatServiceFactory;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult<ChatResponse>> Chat([FromBody] ChatRequest request)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(request.SessionId))
|
||||||
|
{
|
||||||
|
return BadRequest("SessionId is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.Message))
|
||||||
|
{
|
||||||
|
return BadRequest("Message is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var chatService = _chatServiceFactory.CreateChatService();
|
||||||
|
var response = await chatService.ProcessMessageAsync(request);
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error processing chat message");
|
||||||
|
return StatusCode(500, "An error occurred while processing your message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
ChatServerSpace/Models/ChatMessage.cs
Normal file
18
ChatServerSpace/Models/ChatMessage.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using ThirdParty.Json.LitJson;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Models
|
||||||
|
{
|
||||||
|
public class ChatMessage
|
||||||
|
{
|
||||||
|
[BsonElement("_id")]
|
||||||
|
[BsonId]
|
||||||
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string SessionId { get; set; } = string.Empty;
|
||||||
|
public string Role { get; set; } = string.Empty;
|
||||||
|
public string Content { get; set; } = string.Empty;
|
||||||
|
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
ChatServerSpace/Models/ChatRequest.cs
Normal file
9
ChatServerSpace/Models/ChatRequest.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace ChatServerSpace.Models
|
||||||
|
{
|
||||||
|
public class ChatRequest
|
||||||
|
{
|
||||||
|
public required string SessionId { get; set; }
|
||||||
|
public required string Message { get; set; }
|
||||||
|
public required string Criativity { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
ChatServerSpace/Models/ChatResponse.cs
Normal file
8
ChatServerSpace/Models/ChatResponse.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace ChatServerSpace.Models
|
||||||
|
{
|
||||||
|
public class ChatResponse
|
||||||
|
{
|
||||||
|
public required string SessionId { get; set; }
|
||||||
|
public required string Response { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
40
ChatServerSpace/Program.cs
Normal file
40
ChatServerSpace/Program.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using ChatServerSpace.Services;
|
||||||
|
using Microsoft.SemanticKernel;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
|
|
||||||
|
builder.Services.AddHttpClient<DeepInfraChatService>()
|
||||||
|
.ConfigureHttpClient(client =>
|
||||||
|
{
|
||||||
|
// Aumentar o timeout para 10 minutos (600 segundos)
|
||||||
|
client.Timeout = TimeSpan.FromSeconds(600);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register services
|
||||||
|
builder.Services.AddSingleton<IChatHistoryService, MongoDbChatHistoryService>();
|
||||||
|
builder.Services.AddScoped<IChatService, ServerSpaceChatService>();
|
||||||
|
builder.Services.AddScoped<DeepInfraChatService>();
|
||||||
|
builder.Services.AddScoped<IChatServiceFactory, ChatServiceFactory>();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
41
ChatServerSpace/Properties/launchSettings.json
Normal file
41
ChatServerSpace/Properties/launchSettings.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:21434",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5004",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7238;http://localhost:5004",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
ChatServerSpace/Services/ChatServiceFactory.cs
Normal file
29
ChatServerSpace/Services/ChatServiceFactory.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class ChatServiceFactory : IChatServiceFactory
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
public ChatServiceFactory(IServiceProvider serviceProvider, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IChatService CreateChatService()
|
||||||
|
{
|
||||||
|
// Determine qual implementação usar com base nas configurações
|
||||||
|
var useDirectHttpClient = _configuration.GetValue<string>("ChatServer:UseServer");
|
||||||
|
|
||||||
|
if (useDirectHttpClient== "DeepInfra")
|
||||||
|
{
|
||||||
|
return _serviceProvider.GetRequiredService<DeepInfraChatService>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _serviceProvider.GetRequiredService<ServerSpaceChatService>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
130
ChatServerSpace/Services/DeepInfraChatService.cs
Normal file
130
ChatServerSpace/Services/DeepInfraChatService.cs
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class DeepInfraChatService : IChatService
|
||||||
|
{
|
||||||
|
private readonly IChatHistoryService _historyService;
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private readonly ILogger<DeepInfraChatService> _logger;
|
||||||
|
private readonly string _apiKey;
|
||||||
|
private readonly string _modelId;
|
||||||
|
private readonly string _endpoint;
|
||||||
|
|
||||||
|
public DeepInfraChatService(
|
||||||
|
IChatHistoryService historyService,
|
||||||
|
IConfiguration config,
|
||||||
|
ILogger<DeepInfraChatService> logger,
|
||||||
|
HttpClient httpClient)
|
||||||
|
{
|
||||||
|
_historyService = historyService;
|
||||||
|
_logger = logger;
|
||||||
|
_httpClient = httpClient;
|
||||||
|
|
||||||
|
_apiKey = config["ChatServer:ApiKey"] ?? throw new ArgumentNullException("ServeSpace:ApiKey configuration is missing");
|
||||||
|
_modelId = config["ChatServer:ModelId"] ?? "meta-llama/Meta-Llama-3.1-70B-Instruct";
|
||||||
|
_endpoint = config["ChatServer:Url"] ?? "https://api.deepinfra.com/v1/openai/chat/completions";
|
||||||
|
|
||||||
|
// Configurar o cliente HTTP
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey);
|
||||||
|
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ChatResponse> ProcessMessageAsync(ChatRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Salvar mensagem do usuário no histórico
|
||||||
|
var userMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "user",
|
||||||
|
Content = request.Message
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(userMessage);
|
||||||
|
|
||||||
|
// Obter histórico de chat
|
||||||
|
var history = await _historyService.GetSessionHistoryAsync(request.SessionId);
|
||||||
|
|
||||||
|
// Criar mensagens para a API
|
||||||
|
var messages = history.Select(m => new
|
||||||
|
{
|
||||||
|
role = m.Role.ToLowerInvariant(),
|
||||||
|
content = m.Content
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
// Criando o payload para a requisição
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
model = _modelId,
|
||||||
|
messages,
|
||||||
|
max_tokens = 8192,
|
||||||
|
temperature = 0.8,
|
||||||
|
top_p = 0.95
|
||||||
|
};
|
||||||
|
|
||||||
|
_logger.LogInformation("Enviando solicitação para a API DeepInfra: {0}", JsonSerializer.Serialize(payload));
|
||||||
|
|
||||||
|
// Enviando requisição para a API
|
||||||
|
var content = new StringContent(
|
||||||
|
JsonSerializer.Serialize(payload),
|
||||||
|
Encoding.UTF8,
|
||||||
|
"application/json");
|
||||||
|
|
||||||
|
_httpClient.Timeout = TimeSpan.FromSeconds(600);
|
||||||
|
var response = await _httpClient.PostAsync(_endpoint, content);
|
||||||
|
|
||||||
|
// Garantir que a resposta foi bem-sucedida
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
// Processar resposta
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
_logger.LogInformation("Resposta recebida da API: {0}", responseContent);
|
||||||
|
|
||||||
|
var apiResponse = JsonSerializer.Deserialize<DeepInfraResponse>(responseContent,
|
||||||
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||||
|
|
||||||
|
var responseText = apiResponse?.Choices?.FirstOrDefault()?.Message?.Content ?? "Sem resposta";
|
||||||
|
|
||||||
|
// Salvar resposta do assistente no histórico
|
||||||
|
var assistantMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "assistant",
|
||||||
|
Content = responseText
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(assistantMessage);
|
||||||
|
|
||||||
|
return new ChatResponse
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Response = responseText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Erro ao processar mensagem com DeepInfra API");
|
||||||
|
throw new Exception("Erro ao se comunicar com a API DeepInfra", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Classes para deserialização da resposta da API
|
||||||
|
private class DeepInfraResponse
|
||||||
|
{
|
||||||
|
public List<DeepInfraChoice>? Choices { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DeepInfraChoice
|
||||||
|
{
|
||||||
|
public DeepInfraMessage? Message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DeepInfraMessage
|
||||||
|
{
|
||||||
|
public string? Content { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
ChatServerSpace/Services/IChatHistoryService.cs
Normal file
10
ChatServerSpace/Services/IChatHistoryService.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public interface IChatHistoryService
|
||||||
|
{
|
||||||
|
Task SaveMessageAsync(ChatMessage message);
|
||||||
|
Task<List<ChatMessage>> GetSessionHistoryAsync(string sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
9
ChatServerSpace/Services/IChatService.cs
Normal file
9
ChatServerSpace/Services/IChatService.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public interface IChatService
|
||||||
|
{
|
||||||
|
Task<ChatResponse> ProcessMessageAsync(ChatRequest request);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
ChatServerSpace/Services/IChatServiceFactory.cs
Normal file
7
ChatServerSpace/Services/IChatServiceFactory.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public interface IChatServiceFactory
|
||||||
|
{
|
||||||
|
IChatService CreateChatService();
|
||||||
|
}
|
||||||
|
}
|
||||||
36
ChatServerSpace/Services/MongoDbChatHistoryService.cs
Normal file
36
ChatServerSpace/Services/MongoDbChatHistoryService.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class MongoDbChatHistoryService : IChatHistoryService
|
||||||
|
{
|
||||||
|
private readonly IMongoCollection<ChatMessage> _messages;
|
||||||
|
|
||||||
|
public MongoDbChatHistoryService(IConfiguration config)
|
||||||
|
{
|
||||||
|
var connectionString = config["MongoDB:ConnectionString"];
|
||||||
|
var databaseName = config["MongoDB:DatabaseName"];
|
||||||
|
var collectionName = config["MongoDB:CollectionName"];
|
||||||
|
|
||||||
|
var client = new MongoClient(connectionString);
|
||||||
|
var database = client.GetDatabase(databaseName);
|
||||||
|
_messages = database.GetCollection<ChatMessage>(collectionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveMessageAsync(ChatMessage message)
|
||||||
|
{
|
||||||
|
await _messages.InsertOneAsync(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<ChatMessage>> GetSessionHistoryAsync(string sessionId)
|
||||||
|
{
|
||||||
|
var filter = Builders<ChatMessage>.Filter.Eq(m => m.SessionId, sessionId);
|
||||||
|
var sort = Builders<ChatMessage>.Sort.Ascending(m => m.Timestamp);
|
||||||
|
|
||||||
|
return await _messages.Find(filter)
|
||||||
|
.Sort(sort)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
126
ChatServerSpace/Services/ServerSpaceChatService.cs
Normal file
126
ChatServerSpace/Services/ServerSpaceChatService.cs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
using ChatServerSpace.Models;
|
||||||
|
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
||||||
|
using Microsoft.SemanticKernel;
|
||||||
|
using Microsoft.SemanticKernel.ChatCompletion;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace ChatServerSpace.Services
|
||||||
|
{
|
||||||
|
public class ServerSpaceChatService : IChatService
|
||||||
|
{
|
||||||
|
private readonly IChatHistoryService _historyService;
|
||||||
|
private readonly Kernel _kernel;
|
||||||
|
private readonly ILogger<ServerSpaceChatService> _logger;
|
||||||
|
|
||||||
|
public ServerSpaceChatService(IChatHistoryService historyService, IConfiguration config, ILogger<ServerSpaceChatService> logger, HttpClient httpClient)
|
||||||
|
{
|
||||||
|
_historyService = historyService;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
var apiKey = config["ChatServer:ApiKey"] ?? throw new ArgumentNullException("ServeSpace:ApiKey configuration is missing");
|
||||||
|
var modelId = config["ChatServer:ModelId"] ?? "anthropic/claude-3.7-sonnet";
|
||||||
|
var endpoint = config["ChatServer:Url"] ?? "https://api.deepinfra.com/v1/openai/chat/completions";
|
||||||
|
|
||||||
|
|
||||||
|
_kernel = Kernel.CreateBuilder()
|
||||||
|
.AddOpenAIChatCompletion(modelId, new Uri(endpoint), apiKey)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ChatResponse> ProcessMessageAsync(ChatRequest request)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Save user message to history
|
||||||
|
var userMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "user",
|
||||||
|
Content = request.Message
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(userMessage);
|
||||||
|
|
||||||
|
// Get chat history
|
||||||
|
var history = await _historyService.GetSessionHistoryAsync(request.SessionId);
|
||||||
|
|
||||||
|
// Create chat history for Semantic Kernel
|
||||||
|
var chatHistory = new Microsoft.SemanticKernel.ChatCompletion.ChatHistory();
|
||||||
|
|
||||||
|
foreach (var message in history)
|
||||||
|
{
|
||||||
|
if (message.Role.Equals("user", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
chatHistory.AddUserMessage(message.Content);
|
||||||
|
}
|
||||||
|
else if (message.Role.Equals("assistant", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
chatHistory.AddAssistantMessage(message.Content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get response from Gemini
|
||||||
|
var chatCompletionService = _kernel.GetRequiredService<IChatCompletionService>();
|
||||||
|
|
||||||
|
var exec = new PromptExecutionSettings
|
||||||
|
{
|
||||||
|
ExtensionData = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "maxOutputTokens", 8192 },
|
||||||
|
{ "temperature", 0.8 },
|
||||||
|
{ "topP", 0.95 },
|
||||||
|
//{ "stopSequences", new List<string>() }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var result = await chatCompletionService.GetChatMessageContentAsync(chatHistory, exec);
|
||||||
|
var responseText = result.ToString();
|
||||||
|
|
||||||
|
// Save assistant message to history
|
||||||
|
var assistantMessage = new ChatMessage
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Role = "assistant",
|
||||||
|
Content = responseText
|
||||||
|
};
|
||||||
|
await _historyService.SaveMessageAsync(assistantMessage);
|
||||||
|
|
||||||
|
await Task.Delay(2000);
|
||||||
|
|
||||||
|
return new ChatResponse
|
||||||
|
{
|
||||||
|
SessionId = request.SessionId,
|
||||||
|
Response = responseText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error getting response from Gemini");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception("Erro na parada!", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServerSpaceResponse
|
||||||
|
{
|
||||||
|
public List<ServerSpaceChoice>? Choices { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServerSpaceChoice
|
||||||
|
{
|
||||||
|
public ServerSpaceMessage? Message { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServerSpaceMessage
|
||||||
|
{
|
||||||
|
public string? Content { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
ChatServerSpace/appsettings.Development.json
Normal file
8
ChatServerSpace/appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
ChatServerSpace/appsettings.json
Normal file
23
ChatServerSpace/appsettings.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ChatServer": {
|
||||||
|
//"ApiKey": "tIAXVf3AkCkkpSX+PjFvktfEeSPyA1ZYam50UO3ye/qmxVZX6PIXstmJsLZXkQ39C33onFD/81mdxvhbGHm7tQ==",
|
||||||
|
//"ModelId": "anthropic/claude-3.5-haiku",
|
||||||
|
//"Url": "https://gpt.serverspace.com.br/v1/chat/completions"
|
||||||
|
"ApiKey": "HedaR4yPrp9N2XSHfwdZjpZvPIxejPFK",
|
||||||
|
"ModelId": "meta-llama/Meta-Llama-3.1-70B-Instruct",
|
||||||
|
"Url": "https://api.deepinfra.com/v1/openai/chat/completions",
|
||||||
|
"UseServer": "DeepInfra"
|
||||||
|
},
|
||||||
|
"MongoDB": {
|
||||||
|
"ConnectionString": "mongodb://admin:c4rn31r0@192.168.0.82:27017,192.168.0.81:27017/?authSource=admin",
|
||||||
|
"DatabaseName": "ChatServerSpaceDb",
|
||||||
|
"CollectionName": "ChatMessages"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user