feat: primeira versão
This commit is contained in:
parent
917c03206f
commit
bb3315625d
30
.dockerignore
Normal file
30
.dockerignore
Normal file
@ -0,0 +1,30 @@
|
||||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
!**/.gitignore
|
||||
!.git/HEAD
|
||||
!.git/config
|
||||
!.git/packed-refs
|
||||
!.git/refs/heads/**
|
||||
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@ -0,0 +1,4 @@
|
||||
[*.cs]
|
||||
|
||||
# SKEXP0070: Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
dotnet_diagnostic.SKEXP0070.severity = silent
|
||||
11
AuthMiddleware.cs
Normal file
11
AuthMiddleware.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
|
||||
namespace ChatApi
|
||||
{
|
||||
public class AuthMiddleware
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
31
ChatApi.csproj
Normal file
31
ChatApi.csproj
Normal file
@ -0,0 +1,31 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>10e5023f-8f45-46d6-8637-bc2127842068</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<DockerfileContext>.</DockerfileContext>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lost.SemanticKernel.Connectors.Anthropic" Version="1.25.0-alpha3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.Extensions.AI.Ollama" Version="9.0.0-preview.9.24525.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.VectorData.Abstractions" Version="9.0.0-preview.1.24523.1" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.2.1" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.26.0" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Connectors.Google" Version="1.26.0-alpha" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Connectors.InMemory" Version="1.26.0-preview" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Connectors.Ollama" Version="1.26.0-alpha" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.26.0" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.26.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="3.0.0" />
|
||||
<PackageReference Include="MongoDB.Driver.Core" Version="2.30.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
9
ChatApi.csproj.user
Normal file
9
ChatApi.csproj.user
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ActiveDebugProfile>http</ActiveDebugProfile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
6
ChatApi.http
Normal file
6
ChatApi.http
Normal file
@ -0,0 +1,6 @@
|
||||
@ChatApi_HostAddress = http://localhost:5020
|
||||
|
||||
GET {{ChatApi_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
||||
25
ChatApi.sln
Normal file
25
ChatApi.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35122.118
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatApi", "ChatApi.csproj", "{B5287933-4BFA-4EC1-8522-393864C46B1F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B5287933-4BFA-4EC1-8522-393864C46B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B5287933-4BFA-4EC1-8522-393864C46B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B5287933-4BFA-4EC1-8522-393864C46B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B5287933-4BFA-4EC1-8522-393864C46B1F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {332EC001-9CEA-4261-9DE0-110EEB502728}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
92
ChatHistoryService.cs
Normal file
92
ChatHistoryService.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ChatApi
|
||||
{
|
||||
public class ChatHistoryService
|
||||
{
|
||||
private readonly Dictionary<string, ChatHistory> _keyValues = new Dictionary<string, ChatHistory>();
|
||||
public ChatHistoryService()
|
||||
{
|
||||
}
|
||||
|
||||
public ChatHistory Get(string sessionId)
|
||||
{
|
||||
//var msg = new List<ChatMessageContent>();
|
||||
////msg.Add(new ChatMessageContent(AuthorRole.System, "Your name is SuperChat. \nYou only generate answers using portuguese.\nYou are friendly and polite.\nYou speak only Brazilian Portuguese.\nYou never create a response in English. Always brazilian portuguese."));
|
||||
//msg.Add(new ChatMessageContent(AuthorRole.System, "Seu nome é SuperChat."));
|
||||
//msg.Add(new ChatMessageContent(AuthorRole.System, "Você só gera respostas usando português do Brasil."));
|
||||
//msg.Add(new ChatMessageContent(AuthorRole.System, "Você fala apenas português brasileiro."));
|
||||
//msg.Add(new ChatMessageContent(AuthorRole.System, "Você nunca cria respostas em inglês, mas sempre em português brasileiro."));
|
||||
//string json = JsonSerializer.Serialize(msg);
|
||||
//var history = new ChatHistory(JsonSerializer.Deserialize<List<ChatMessageContent>>(json));
|
||||
|
||||
//return history;
|
||||
|
||||
if (_keyValues.ContainsKey(sessionId))
|
||||
{
|
||||
var history = _keyValues[sessionId];
|
||||
return history;
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = new List<ChatMessageContent>();
|
||||
TestePrompt(msg);
|
||||
string json = JsonSerializer.Serialize(msg);
|
||||
var history = new ChatHistory(JsonSerializer.Deserialize<List<ChatMessageContent>>(json));
|
||||
_keyValues[sessionId] = history;
|
||||
return _keyValues[sessionId];
|
||||
}
|
||||
}
|
||||
|
||||
public ChatHistory GetSumarizer(string sessionId)
|
||||
{
|
||||
if (_keyValues.ContainsKey(sessionId))
|
||||
{
|
||||
var history = _keyValues[sessionId];
|
||||
return history;
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = new List<ChatMessageContent>();
|
||||
PromptIan(msg);
|
||||
string json = JsonSerializer.Serialize(msg);
|
||||
var history = new ChatHistory(JsonSerializer.Deserialize<List<ChatMessageContent>>(json));
|
||||
_keyValues[sessionId] = history;
|
||||
return _keyValues[sessionId];
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateHistory(string sessionId, ChatHistory history)
|
||||
{
|
||||
_keyValues[sessionId] = history;
|
||||
}
|
||||
|
||||
public void TestePromptBot(List<ChatMessageContent> msg)
|
||||
{
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Seu nome é Rosa, uma vendedora de bolos que está atendendo seus clientes. "));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Você tem apenas os seguintes sabores de bolo: chocolate, baunilha e morango. "));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Excepcionalmente hoje, o sabor morango está fora de estoque. Você não tem mais morangos. "));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Cada fatia de bolo custa 5 reais. \n"));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.User, "Responda sempre em portugues do Brasil as minhas perguntas."));
|
||||
}
|
||||
|
||||
public void PromptIan(List<ChatMessageContent> msg)
|
||||
{
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Seu nome é Ian, um assistente ajuda empresas de Consultoria e RH. "));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Você responde sempre em português do Brasil."));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Em breve, você será capaz de consultar o linkedin."));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.User, "Use sempre portugues do Brasil."));
|
||||
}
|
||||
|
||||
public void TestePrompt(List<ChatMessageContent> msg)
|
||||
{
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Seu nome é Ian."));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Você só gera respostas usando português do Brasil."));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Você fala apenas português brasileiro."));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.System, "Você nunca cria respostas em inglês, mas sempre em português brasileiro."));
|
||||
msg.Add(new ChatMessageContent(AuthorRole.User, "Responda sempre em portugues do Brasil as minhas perguntas."));
|
||||
}
|
||||
}
|
||||
}
|
||||
7
ChatHistoryStore.cs
Normal file
7
ChatHistoryStore.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace ChatApi
|
||||
{
|
||||
public class ChatHistoryStore
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
7
ChatRequest.cs
Normal file
7
ChatRequest.cs
Normal file
@ -0,0 +1,7 @@
|
||||
using System;
|
||||
|
||||
public class ChatRequest
|
||||
{
|
||||
public string SessionId { get; set; } = string.Empty;
|
||||
public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
95
Controllers/ChatController.cs
Normal file
95
Controllers/ChatController.cs
Normal file
@ -0,0 +1,95 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using Microsoft.SemanticKernel.Embeddings;
|
||||
using Microsoft.SemanticKernel.Memory;
|
||||
using Microsoft.SemanticKernel.Connectors.InMemory;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using MongoDB.Driver;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using ChatApi.Services;
|
||||
using ChatApi.Services.ResponseService;
|
||||
using ChatApi.Services.Classifier;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using System.Security.Claims;
|
||||
using ChatApi.Models;
|
||||
|
||||
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
|
||||
namespace ChatApi.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class ChatController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<ChatController> _logger;
|
||||
private readonly TextFilter _textFilter;
|
||||
private readonly ResponseFactory _responseFactory;
|
||||
private readonly ClassifierPersistence _classifierPersistence;
|
||||
|
||||
public ChatController(
|
||||
ILogger<ChatController> logger,
|
||||
TextFilter textFilter,
|
||||
ResponseFactory responseFactory,
|
||||
ClassifierPersistence classifierPersistence)
|
||||
{
|
||||
_logger = logger;
|
||||
_textFilter = textFilter;
|
||||
_responseFactory = responseFactory;
|
||||
_classifierPersistence = classifierPersistence;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "Response")]
|
||||
public async Task<string?> Get([FromQuery] ChatRequest chatRequest)
|
||||
{
|
||||
var userData = UserData.Create(User);
|
||||
var textClassifier = new TextClassifier(_textFilter, _classifierPersistence);
|
||||
var textType = await textClassifier.ClassifyQuestion(chatRequest.SessionId, chatRequest.Message);
|
||||
var responseText = _responseFactory.GetService(textType);
|
||||
var response = await responseText.GetResponse(HttpContext, userData, chatRequest.SessionId, chatRequest.Message);
|
||||
return response;
|
||||
}
|
||||
|
||||
[HttpPost(Name = "LoadDBData")]
|
||||
public async Task SaveData([FromQuery] DBLoadRequest loadRequest)
|
||||
{
|
||||
//string readText = System.IO.File.ReadAllText("C:\\vscode\\ChatApi\\bin\\Debug\\net8.0\\Servicos.txt");
|
||||
string readText = loadRequest.Content;
|
||||
await SalvarTextoComEmbeddingNoMongoDB(readText);
|
||||
}
|
||||
|
||||
|
||||
async Task SalvarTextoComEmbeddingNoMongoDB(string textoCompleto)
|
||||
{
|
||||
var textoArray = new List<string>();
|
||||
string[] textolinhas = textoCompleto.Split(
|
||||
new string[] { "\n" },
|
||||
StringSplitOptions.None
|
||||
);
|
||||
|
||||
var title = textolinhas[0];
|
||||
|
||||
var builder = new StringBuilder();
|
||||
foreach (string line in textolinhas)
|
||||
{
|
||||
if (line.StartsWith("**") || line.StartsWith("\r**"))
|
||||
{
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
textoArray.Add(title.Replace("**", "").Replace("\r", "") + ": " + Environment.NewLine + builder.ToString());
|
||||
builder = new StringBuilder();
|
||||
title = line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
68
Controllers/ChatController.cs~RF39ccb1.TMP
Normal file
68
Controllers/ChatController.cs~RF39ccb1.TMP
Normal file
@ -0,0 +1,68 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using Microsoft.SemanticKernel.Embeddings;
|
||||
using Microsoft.SemanticKernel.Memory;
|
||||
using Microsoft.SemanticKernel.Connectors.InMemory;
|
||||
|
||||
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
|
||||
namespace ChatApi.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class ChatController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<ChatController> _logger;
|
||||
private readonly ChatHistoryService _chatHistoryService;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
private readonly Kernel _kernel;
|
||||
|
||||
public ChatController(ILogger<ChatController> logger, ChatHistoryService chatHistoryService, IChatCompletionService chatCompletionService, Kernel kernel)
|
||||
{
|
||||
_logger = logger;
|
||||
_chatHistoryService = chatHistoryService;
|
||||
_chatCompletionService = chatCompletionService;
|
||||
_kernel = kernel;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "Response")]
|
||||
public async Task<string> Get([FromQuery] ChatRequest chatRequest)
|
||||
{
|
||||
var stopWatch = new System.Diagnostics.Stopwatch();
|
||||
|
||||
stopWatch.Start();
|
||||
SessionIdStore sessionIdStore = new SessionIdStore(HttpContext);
|
||||
var sessionId = sessionIdStore.GetSessionId();
|
||||
var history = _chatHistoryService.Get(sessionId);
|
||||
|
||||
history.AddUserMessage(chatRequest.Message);
|
||||
|
||||
var embeddingGenerator = _kernel.GetRequiredService<ITextEmbeddingGenerationService>();
|
||||
// Setup a memory store and create a memory out of it
|
||||
#pragma warning disable SKEXP0020 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
var memoryStore = new InMemoryVectorStore();
|
||||
#pragma warning restore SKEXP0020 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
var memory = new SemanticTextMemory(memoryStore, embeddingGenerator);
|
||||
// Loading it for Save, Recall and other methods
|
||||
_kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
|
||||
string MemoryCollectionName = "MyCustomDataCollection";
|
||||
|
||||
var option = new PromptExecutionSettings
|
||||
{
|
||||
|
||||
Memory = memory,
|
||||
MemoryCollectionName = MemoryCollectionName
|
||||
};
|
||||
|
||||
var response = await _chatCompletionService.GetChatMessageContentAsync(history);
|
||||
history.AddMessage(response.Role, response.Content ?? "");
|
||||
|
||||
_chatHistoryService.UpdateHistory(sessionId, history);
|
||||
|
||||
stopWatch.Stop();
|
||||
return $"{response.Content ?? ""}\n\nTempo: {stopWatch.ElapsedMilliseconds/1000}s";
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
7
DBLoadRequest.cs
Normal file
7
DBLoadRequest.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace ChatApi
|
||||
{
|
||||
public class DBLoadRequest
|
||||
{
|
||||
public string Content { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@ -0,0 +1,25 @@
|
||||
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
USER app
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
COPY ["ChatApi.csproj", "."]
|
||||
RUN dotnet restore "./ChatApi.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/."
|
||||
RUN dotnet build "./ChatApi.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "./ChatApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "ChatApi.dll"]
|
||||
15
DomvsDatabaseSettings.cs
Normal file
15
DomvsDatabaseSettings.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace ChatApi
|
||||
{
|
||||
public class DomvsDatabaseSettings
|
||||
{
|
||||
public string ConnectionString { get; set; } = null!;
|
||||
|
||||
public string DatabaseName { get; set; } = null!;
|
||||
|
||||
public string SharepointCollectionName { get; set; } = null!;
|
||||
|
||||
public string ChatBotRHCollectionName { get; set; } = null!;
|
||||
|
||||
public string ClassifierCollectionName { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
56
Infra/Result.cs
Normal file
56
Infra/Result.cs
Normal file
@ -0,0 +1,56 @@
|
||||
namespace ChatApi.Infra
|
||||
{
|
||||
public class Result
|
||||
{
|
||||
protected Result(bool success, string error)
|
||||
{
|
||||
if (success && error != string.Empty)
|
||||
throw new InvalidOperationException();
|
||||
if (!success && error == string.Empty)
|
||||
throw new InvalidOperationException();
|
||||
Success = success;
|
||||
Error = error;
|
||||
}
|
||||
|
||||
public bool Success { get; }
|
||||
public string Error { get; }
|
||||
public bool IsFailure => !Success;
|
||||
|
||||
public static Result Fail(string message)
|
||||
{
|
||||
return new Result(false, message);
|
||||
}
|
||||
|
||||
public static Result<T> Fail<T>(string message)
|
||||
{
|
||||
return new Result<T>(default, false, message);
|
||||
}
|
||||
|
||||
public static Result Ok()
|
||||
{
|
||||
return new Result(true, string.Empty);
|
||||
}
|
||||
|
||||
public static Result<T> Ok<T>(T value)
|
||||
{
|
||||
return new Result<T>(value, true, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public class Result<T> : Result
|
||||
{
|
||||
protected internal Result(T value, bool success, string error)
|
||||
: base(success, error)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
protected internal Result(T value)
|
||||
: base(true, "")
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public T Value { get; set; }
|
||||
}
|
||||
}
|
||||
30
Models/UserData.cs
Normal file
30
Models/UserData.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace ChatApi.Models
|
||||
{
|
||||
public class UserData
|
||||
{
|
||||
private UserData()
|
||||
{
|
||||
}
|
||||
|
||||
public string Email { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public static UserData Create(ClaimsPrincipal user)
|
||||
{
|
||||
var email = user.FindFirst(ClaimTypes.Email)?.Value
|
||||
?? user.FindFirst("email")?.Value;
|
||||
|
||||
var name = user.FindFirst(ClaimTypes.Name)?.Value
|
||||
?? user.FindFirst("name")?.Value;
|
||||
|
||||
|
||||
return new UserData
|
||||
{
|
||||
Email = email,
|
||||
Name = name
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Models/UserData.cs~RF3dab6a.TMP
Normal file
30
Models/UserData.cs~RF3dab6a.TMP
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace ChatApi.Models
|
||||
{
|
||||
public class UserData
|
||||
{
|
||||
private UserData()
|
||||
{
|
||||
}
|
||||
|
||||
public int Email { get; set; }
|
||||
public int Name { get; set; }
|
||||
|
||||
public static UserData Create(ClaimsPrincipal user)
|
||||
{
|
||||
var email = user.FindFirst(ClaimTypes.Email)?.Value
|
||||
?? user.FindFirst("email")?.Value;
|
||||
|
||||
var name = user.FindFirst(ClaimTypes.Name)?.Value
|
||||
?? user.FindFirst("name")?.Value;
|
||||
|
||||
|
||||
return new UserData
|
||||
{
|
||||
Email = email,
|
||||
Name = name
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
157
Program.cs
Normal file
157
Program.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using ChatApi;
|
||||
using ChatApi.Services;
|
||||
using ChatApi.Services.Bot;
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
using ChatApi.Services.Classifier;
|
||||
using ChatApi.Services.ResponseService;
|
||||
using ChatApi.Settings;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using OllamaSharp;
|
||||
|
||||
#pragma warning disable SKEXP0010 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.Configure<DomvsDatabaseSettings>(
|
||||
builder.Configuration.GetSection("DomvsDatabase"));
|
||||
|
||||
builder.Services.Configure<ChatRHSettings>(
|
||||
builder.Configuration.GetSection("ChatRHSettings"));
|
||||
|
||||
builder.Services.AddScoped<ClassifierPersistence>();
|
||||
builder.Services.AddSingleton<ChatHistoryService>();
|
||||
builder.Services.AddScoped<SharepointDomvsService>();
|
||||
builder.Services.AddSingleton<TextFilter>();
|
||||
builder.Services.AddScoped<ResponseFactory>();
|
||||
|
||||
builder.Services.AddScoped<ChatBotRHCall>();
|
||||
builder.Services.AddScoped<IResponseService, ResponseChatService>();
|
||||
builder.Services.AddScoped<IResponseService, ResponseCompanyService>();
|
||||
builder.Services.AddScoped<IResponseService, ResponseBotRHService>();
|
||||
|
||||
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinydolphin", new Uri("http://localhost:11435"));
|
||||
//var apiClient = new OllamaApiClient(new Uri("http://localhost:11435"), "tinydolphin");
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinydolphin", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinyllama", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("starling-lm", new Uri("http://localhost:11435"));
|
||||
|
||||
//ServerSpace - GPT Service
|
||||
builder.Services.AddOpenAIChatCompletion("openchat-3.5-0106", new Uri("https://gpt.serverspace.com.br/v1/chat/completions"), "tIAXVf3AkCkkpSX+PjFvktfEeSPyA1ZYam50UO3ye/qmxVZX6PIXstmJsLZXkQ39C33onFD/81mdxvhbGHm7tQ==");
|
||||
|
||||
builder.Services.AddOllamaTextEmbeddingGeneration("all-minilm", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOpenAIChatCompletion("gpt-4o-mini", "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");
|
||||
//builder.Services.AddGoogleAIGeminiChatCompletion("gemini-1.5-flash-latest", "AIzaSyDKBMX5yW77vxJFVJVE-5VLxlQRxCepck8");
|
||||
|
||||
//Anthropic / Claude
|
||||
//builder.Services.AddAnthropicChatCompletion(
|
||||
// modelId: "claude-3-5-sonnet-latest", // ou outro modelo Claude desejado
|
||||
// apiKey: "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"
|
||||
//);
|
||||
|
||||
builder.Services.AddKernel();
|
||||
//builder.Services.AddKernel()
|
||||
// .AddOllamaChatCompletion("phi3", new Uri("http://localhost:11435"))
|
||||
// .AddOllamaTextEmbeddingGeneration()
|
||||
// .Build();
|
||||
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://192.168.0.150:11436"));
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
var tenantId = builder.Configuration.GetSection("AppTenantId");
|
||||
var clientId = builder.Configuration.GetSection("AppClientID");
|
||||
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.Authority = $"https://login.microsoftonline.com/{tenantId}/v2.0";
|
||||
options.Audience = "api://" + clientId; // Client ID da sua API
|
||||
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidIssuer = $"https://login.microsoftonline.com/{tenantId}/v2.0",
|
||||
ValidAudience = "api://" + clientId
|
||||
};
|
||||
});
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
//builder.Services.AddAuthentication(options =>
|
||||
// {
|
||||
// options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
// options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
// })
|
||||
// .AddJwtBearer(options =>
|
||||
// {
|
||||
// // Configurações anteriores...
|
||||
|
||||
// // Eventos para log e tratamento de erros
|
||||
// options.Events = new JwtBearerEvents
|
||||
// {
|
||||
// OnAuthenticationFailed = context =>
|
||||
// {
|
||||
// // Log de erros de autenticação
|
||||
// Console.WriteLine($"Erro de autenticação: {context.Exception.Message}");
|
||||
// return Task.CompletedTask;
|
||||
// },
|
||||
// OnTokenValidated = context =>
|
||||
// {
|
||||
// // Validações adicionais se necessário
|
||||
// return Task.CompletedTask;
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var cookieOpt = new CookieOptions()
|
||||
{
|
||||
Path = "/",
|
||||
Expires = DateTimeOffset.UtcNow.AddDays(1),
|
||||
IsEssential = true,
|
||||
HttpOnly = false,
|
||||
Secure = false,
|
||||
};
|
||||
|
||||
await next();
|
||||
});
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.Run();
|
||||
|
||||
#pragma warning restore SKEXP0010 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
61
Program.cs~RF419917.TMP
Normal file
61
Program.cs~RF419917.TMP
Normal file
@ -0,0 +1,61 @@
|
||||
using ChatApi;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using OllamaSharp;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.AddSingleton<ChatHistoryService>();
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinydolphin", new Uri("http://localhost:11435"));
|
||||
//var apiClient = new OllamaApiClient(new Uri("http://localhost:11435"), "tinydolphin");
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinydolphin", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinyllama", new Uri("http://localhost:11435"));
|
||||
builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
builder.Services.AddOllamaTextEmbeddingGeneration("all-minilm", new Uri("http://localhost:11435"));
|
||||
builder.Services.AddKernel();
|
||||
//builder.Services.AddKernel()
|
||||
// .AddOllamaChatCompletion("phi3", new Uri("http://localhost:11435"))
|
||||
// .AddOllamaTextEmbeddingGeneration()
|
||||
// .Build();
|
||||
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://192.168.0.150:11436"));
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var cookieOpt = new CookieOptions()
|
||||
{
|
||||
Path = "/",
|
||||
Expires = DateTimeOffset.UtcNow.AddDays(1),
|
||||
IsEssential = true,
|
||||
HttpOnly = false,
|
||||
Secure = false,
|
||||
};
|
||||
|
||||
await next();
|
||||
});
|
||||
|
||||
app.Run();
|
||||
98
Program.cs~RF68750a0.TMP
Normal file
98
Program.cs~RF68750a0.TMP
Normal file
@ -0,0 +1,98 @@
|
||||
using ChatApi;
|
||||
using ChatApi.Services;
|
||||
using ChatApi.Services.Bot;
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
using ChatApi.Services.Classifier;
|
||||
using ChatApi.Services.ResponseService;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using OllamaSharp;
|
||||
|
||||
#pragma warning disable SKEXP0010 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
builder.Services.Configure<DomvsDatabaseSettings>(
|
||||
builder.Configuration.GetSection("DomvsDatabase"));
|
||||
|
||||
builder.Services.AddScoped<ClassifierPersistence>();
|
||||
builder.Services.AddSingleton<ChatHistoryService>();
|
||||
builder.Services.AddScoped<SharepointDomvsService>();
|
||||
builder.Services.AddSingleton<TextFilter>();
|
||||
builder.Services.AddScoped<ResponseFactory>();
|
||||
|
||||
builder.Services.AddScoped<ChatBotRHCall>();
|
||||
builder.Services.AddScoped<IResponseService, ResponseChatService>();
|
||||
builder.Services.AddScoped<IResponseService, ResponseCompanyService>();
|
||||
builder.Services.AddScoped<IResponseService, ResponseBotRHService>();
|
||||
|
||||
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinydolphin", new Uri("http://localhost:11435"));
|
||||
//var apiClient = new OllamaApiClient(new Uri("http://localhost:11435"), "tinydolphin");
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinydolphin", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("tinyllama", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("starling-lm", new Uri("http://localhost:11435"));
|
||||
|
||||
//ServerSpace - GPT Service
|
||||
builder.Services.AddOpenAIChatCompletion("openchat-3.5-0106", new Uri("https://gpt.serverspace.com.br/v1/chat/completions"), "tIAXVf3AkCkkpSX+PjFvktfEeSPyA1ZYam50UO3ye/qmxVZX6PIXstmJsLZXkQ39C33onFD/81mdxvhbGHm7tQ==");
|
||||
|
||||
builder.Services.AddOllamaTextEmbeddingGeneration("all-minilm", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://localhost:11435"));
|
||||
//builder.Services.AddOpenAIChatCompletion("gpt-4o-mini", "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");
|
||||
//builder.Services.AddGoogleAIGeminiChatCompletion("gemini-1.5-flash-latest", "AIzaSyDKBMX5yW77vxJFVJVE-5VLxlQRxCepck8");
|
||||
|
||||
//Anthropic / Claude
|
||||
//builder.Services.AddAnthropicChatCompletion(
|
||||
// modelId: "claude-3-5-sonnet-latest", // ou outro modelo Claude desejado
|
||||
// apiKey: "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"
|
||||
//);
|
||||
|
||||
builder.Services.AddKernel();
|
||||
//builder.Services.AddKernel()
|
||||
// .AddOllamaChatCompletion("phi3", new Uri("http://localhost:11435"))
|
||||
// .AddOllamaTextEmbeddingGeneration()
|
||||
// .Build();
|
||||
|
||||
//builder.Services.AddOllamaChatCompletion("phi3.5", new Uri("http://192.168.0.150:11436"));
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var cookieOpt = new CookieOptions()
|
||||
{
|
||||
Path = "/",
|
||||
Expires = DateTimeOffset.UtcNow.AddDays(1),
|
||||
IsEssential = true,
|
||||
HttpOnly = false,
|
||||
Secure = false,
|
||||
};
|
||||
|
||||
await next();
|
||||
});
|
||||
|
||||
app.Run();
|
||||
|
||||
#pragma warning restore SKEXP0010 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
52
Properties/launchSettings.json
Normal file
52
Properties/launchSettings.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5020"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7163;http://localhost:5020"
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_HTTPS_PORTS": "8081",
|
||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||
},
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:61198",
|
||||
"sslPort": 44305
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Services/Bot/5vb0vxog.ejb~
Normal file
64
Services/Bot/5vb0vxog.ejb~
Normal file
@ -0,0 +1,64 @@
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
|
||||
namespace ChatApi.Services.Bot
|
||||
{
|
||||
public class ChatBotRHCall
|
||||
{
|
||||
private readonly ChatBot _chatbot;
|
||||
|
||||
Dictionary<string, string> _opcoesSolicitação =
|
||||
new Dictionary<string, string> {
|
||||
{ "Inclusão/Exclusão Alura", "Inclusão/Exclusão Alura"},
|
||||
{ "Inclusão/Exclusão Auxílio Idioma", "Inclusão/Exclusão Auxílio Idioma"},
|
||||
{ "Inclusão/Exclusão Plano Odonto", "Inclusão/Exclusão Plano Odonto"},
|
||||
//{ "Envio de Atestado", "Envio de Atestado"},
|
||||
//{ "Envio de Reembolso Idioma", "Envio de Reembolso Idioma"},
|
||||
//{ "Afastamento e Licenças", "Afastamento e Licenças"},
|
||||
{ "Dúvidas Plano de Saúde", "Dúvidas Plano de Saúde"},
|
||||
{ "Dúvidas Folha de Pagamento", "Dúvidas Folha de Pagamento"},
|
||||
{ "Ajuste Cargo/Salário", "Ajuste Cargo/Salário"},
|
||||
{ "Feedbacks, reclamações", "1 - Feedbacks, reclamações"},
|
||||
{ "Feedz - Dúvida 1:1", "Feedz - Dúvida 1:1"},
|
||||
{ "Feedz - Dúvida Feedback", "Feedz - Dúvida Feedback"},
|
||||
{ "Feedz - Cadastro de Objetivo", "Feedz - Cadastro de Objetivo"},
|
||||
{ "Feedz - Erro Cadastro", "Feedz - Erro Cadastro"},
|
||||
{ "Feedz - Outros", "Feedz - Outros"},
|
||||
{ "Ciclo de Performance", "Ciclo de Performance"},
|
||||
{ "Declaração Bolsa Faculdade", "Declaração Bolsa Faculdade"},
|
||||
{ "Inclusão/Exclusão Programa de Especialização", "Inclusão/Exclusão Programa de Especialização"},
|
||||
//{ "Envio de Reembolso Especialização", "Envio de Reembolso Especialização"},
|
||||
{ "DayOff", "DayOff"}
|
||||
};
|
||||
|
||||
public ChatBotRHCall(ChatBot chatbot)
|
||||
{
|
||||
_chatbot = chatbot;
|
||||
AddNumbersBeforShow(_opcoesSolicitação);
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Qual seu número de celular (com WhatsApp)?",
|
||||
resposta => !string.IsNullOrEmpty(resposta) && resposta.Length >= 10));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Qual o tipo de solicitação (1 para Reembolso de Idioma, 2 para Reembolso Alura, 3 para Dúvidas)?",
|
||||
resposta => resposta == "1" || resposta == "2" || resposta == "3"));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Texto/Descrição da solicitação (em caso de dúvidas)",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Tudo bem? Posso enviar sua solicitação? Ou prefere que eu tente fazer algum ajuste no texto da descrição?",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
}
|
||||
|
||||
private void AddNumbersBeforShow(Dictionary<string, string> dict)
|
||||
{
|
||||
int optionNumber = 1;
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
dict[key] = $"{optionNumber} - {dict[key]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Services/Bot/ActionCreateCall.cs
Normal file
63
Services/Bot/ActionCreateCall.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using ChatApi.Infra;
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
using ChatApi.Settings;
|
||||
using System.Text;
|
||||
|
||||
namespace ChatApi.Services.Bot
|
||||
{
|
||||
public class ActionCreateCall : IActionCall
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ChatRHSettings _configuration;
|
||||
private dynamic _callRH;
|
||||
|
||||
public ActionCreateCall(IHttpClientFactory httpClientFactory, ChatRHSettings configuration)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public Task<Result<string>> Call()
|
||||
{
|
||||
var httpClient =_httpClientFactory.CreateClient();
|
||||
var url = new Uri(new Uri(_configuration.Url), _configuration.Create);
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||
request.Content = new StringContent(System.Text.Json.JsonSerializer.Serialize(_callRH), Encoding.UTF8, "application/json");
|
||||
var response = httpClient.SendAsync(request).Result;
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var content = response.Content.ReadAsStringAsync().Result;
|
||||
return Task.FromResult(Result.Ok<string>(content));
|
||||
}
|
||||
|
||||
var errorContent = "";
|
||||
try
|
||||
{
|
||||
errorContent = response.Content.ReadAsStringAsync().Result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorContent = "Náo foi possivel criar sua solicitação. Reinicie.";
|
||||
}
|
||||
|
||||
return Task.FromResult(Result.Fail<string>(errorContent));
|
||||
}
|
||||
|
||||
public Task<Result> Populate(Dictionary<string, string>? knowParameters, Dictionary<int, string> answers)
|
||||
{
|
||||
if (knowParameters == null) return Task.FromResult(Result.Fail("Nome e/ou email não foram informados."));
|
||||
|
||||
_callRH = new
|
||||
{
|
||||
Nome = knowParameters["Nome"],
|
||||
Email = knowParameters["Email"],
|
||||
WhatsApp = answers[0],
|
||||
TipoSolicitacao = answers[1],
|
||||
Descricao = answers[2],
|
||||
};
|
||||
|
||||
return Task.FromResult(Result.Ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Services/Bot/ChatBotRHCall.cs
Normal file
120
Services/Bot/ChatBotRHCall.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using ChatApi.Models;
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
using ChatApi.Settings;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using System.Text;
|
||||
|
||||
namespace ChatApi.Services.Bot
|
||||
{
|
||||
public class ChatBotRHCall
|
||||
{
|
||||
private ChatBot _chatbot;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IOptions<ChatRHSettings> _chatRHApiConfig;
|
||||
public UserData UserData { get; set; }
|
||||
|
||||
Dictionary<string, string> _opcoesSolicitação =
|
||||
new Dictionary<string, string> {
|
||||
{ "Inclusão/Exclusão Alura", "Inclusão/Exclusão Alura"},
|
||||
{ "Inclusão/Exclusão Auxílio Idioma", "Inclusão/Exclusão Auxílio Idioma"},
|
||||
{ "Inclusão/Exclusão Plano Odonto", "Inclusão/Exclusão Plano Odonto"},
|
||||
//{ "Envio de Atestado", "Envio de Atestado"},
|
||||
//{ "Envio de Reembolso Idioma", "Envio de Reembolso Idioma"},
|
||||
//{ "Afastamento e Licenças", "Afastamento e Licenças"},
|
||||
{ "Dúvidas Plano de Saúde", "Dúvidas Plano de Saúde"},
|
||||
{ "Dúvidas Folha de Pagamento", "Dúvidas Folha de Pagamento"},
|
||||
{ "Ajuste Cargo/Salário", "Ajuste Cargo/Salário"},
|
||||
{ "Feedbacks, reclamações", "Feedbacks, reclamações"},
|
||||
{ "Feedz - Dúvida 1:1", "Feedz - Dúvida 1:1"},
|
||||
{ "Feedz - Dúvida Feedback", "Feedz - Dúvida Feedback"},
|
||||
{ "Feedz - Cadastro de Objetivo", "Feedz - Cadastro de Objetivo"},
|
||||
{ "Feedz - Erro Cadastro", "Feedz - Erro Cadastro"},
|
||||
{ "Feedz - Outros", "Feedz - Outros"},
|
||||
{ "Ciclo de Performance", "Ciclo de Performance"},
|
||||
{ "Declaração Bolsa Faculdade", "Declaração Bolsa Faculdade"},
|
||||
{ "Inclusão/Exclusão Programa de Especialização", "Inclusão/Exclusão Programa de Especialização"},
|
||||
//{ "Envio de Reembolso Especialização", "Envio de Reembolso Especialização"},
|
||||
{ "DayOff", "DayOff"}
|
||||
};
|
||||
private readonly IOptions<DomvsDatabaseSettings> _config;
|
||||
|
||||
public ChatBotRHCall(
|
||||
IOptions<DomvsDatabaseSettings> config,
|
||||
IChatCompletionService chatCompletionService,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
IOptions<ChatRHSettings> chatRHApiConfig)
|
||||
{
|
||||
_chatCompletionService = chatCompletionService;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_chatRHApiConfig = chatRHApiConfig;
|
||||
_config = config;
|
||||
}
|
||||
public string SetAnswer(string sessionId, string resposta)
|
||||
{
|
||||
if (_chatbot==null)
|
||||
{
|
||||
this.Init(sessionId);
|
||||
}
|
||||
|
||||
return _chatbot.SetAnswer(resposta);
|
||||
}
|
||||
|
||||
public async Task<string> GetNextQuestion()
|
||||
{
|
||||
return await _chatbot.GetNextQuestion();
|
||||
}
|
||||
|
||||
public string GetCurrentQuestion()
|
||||
{
|
||||
return _chatbot.GetCurrentQuestion();
|
||||
}
|
||||
|
||||
public bool HasNextQuestion()
|
||||
{
|
||||
return _chatbot.HasNextQuestion();
|
||||
}
|
||||
|
||||
public void Init(string sessionId)
|
||||
{
|
||||
var persist = ChatPersistence.Create(_config.Value).SetBotName("RHCall");
|
||||
var actionOnEnd = new ActionCreateCall(_httpClientFactory, _chatRHApiConfig.Value);
|
||||
_chatbot = new ChatBot(persist, sessionId, this.UserData, _chatCompletionService, actionOnEnd);
|
||||
|
||||
AddNumbersBeforShow(_opcoesSolicitação);
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Você quer fazer uma solicitação ao RH, certo??",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Qual seu número de celular (com WhatsApp)?",
|
||||
resposta => !string.IsNullOrEmpty(resposta) && resposta.Length >= 10));
|
||||
|
||||
var builder = new StringBuilder();
|
||||
_opcoesSolicitação.Select(s => s.Value).ToList().ForEach(s => builder.AppendLine(s));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
$"Indique o tipo de solicitação: \n {builder}",
|
||||
resposta => resposta == "1" || resposta == "2" || resposta == "3"));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Texto/Descrição da solicitação (em caso de dúvidas)",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Tudo bem? Posso enviar sua solicitação? Ou prefere que eu tente fazer algum ajuste no texto da descrição?",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
}
|
||||
private void AddNumbersBeforShow(Dictionary<string, string> dict)
|
||||
{
|
||||
int optionNumber = 1;
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
dict[key] = $"{optionNumber} - {dict[key]}";
|
||||
optionNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Services/Bot/Structs/ChatBot.cs
Normal file
148
Services/Bot/Structs/ChatBot.cs
Normal file
@ -0,0 +1,148 @@
|
||||
using Amazon.Auth.AccessControlPolicy;
|
||||
using ChatApi.Models;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatBot
|
||||
{
|
||||
private readonly List<Question> _questions;
|
||||
private readonly ChatPersistence _persistence;
|
||||
private readonly Dictionary<int, string> _answers;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
private readonly IActionCall _actionCall;
|
||||
private readonly string _usuarioId;
|
||||
private readonly UserData _userData;
|
||||
private Dictionary<string, string> _knowParameters;
|
||||
private int _indiceAtual;
|
||||
|
||||
public ChatBot(ChatPersistence persistence, string usuarioId, UserData userData, IChatCompletionService chatCompletionService, IActionCall actionCall)
|
||||
{
|
||||
_chatCompletionService = chatCompletionService;
|
||||
_actionCall = actionCall;
|
||||
_questions = new List<Question>();
|
||||
_answers = new Dictionary<int, string>();
|
||||
_knowParameters = new Dictionary<string, string>();
|
||||
_indiceAtual = 0;
|
||||
_persistence = persistence;
|
||||
_usuarioId = usuarioId;
|
||||
_userData = userData;
|
||||
var estado = _persistence.GetState(_usuarioId);
|
||||
if (estado != null)
|
||||
{
|
||||
_indiceAtual = estado.IndicePerguntaAtual;
|
||||
_answers = estado.Respostas;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetParameter(string key, string value)
|
||||
{
|
||||
_knowParameters[key] = value;
|
||||
}
|
||||
|
||||
public void AddQuestion(Question Question)
|
||||
{
|
||||
_questions.Add(Question);
|
||||
}
|
||||
|
||||
public string SetAnswer(string resposta)
|
||||
{
|
||||
if (!this.HasNextQuestion()) return "";
|
||||
|
||||
var state = _persistence.GetState(_usuarioId);
|
||||
if (state != null)
|
||||
{
|
||||
_questions[_indiceAtual].CountTry = state.TentativasPerguntaAtual;
|
||||
}
|
||||
else
|
||||
{
|
||||
_knowParameters = new Dictionary<string, string>()
|
||||
{
|
||||
{ "Nome", _userData.Name },
|
||||
{ "Email", _userData.Email }
|
||||
};
|
||||
}
|
||||
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
var testByChat = TestAnswerByChat(resposta);
|
||||
var abort = TestIfWantToAbort(resposta);
|
||||
var validResp = perguntaAtual.TryToAnswer(resposta);
|
||||
|
||||
if (string.IsNullOrEmpty(validResp) && !abort.Contains("ABORTAR") && perguntaAtual.Validator(resposta) && testByChat.Contains("SIM"))
|
||||
{
|
||||
_answers[_indiceAtual] = resposta;
|
||||
_indiceAtual++;
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
Id = _usuarioId,
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
TentativasPerguntaAtual = _questions[_indiceAtual].CountTry,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return "";
|
||||
}
|
||||
else if (validResp.Contains("reiniciar") || abort.Contains("ABORTAR"))
|
||||
{
|
||||
_persistence.DeleteState(_usuarioId);
|
||||
return "REINICIAR";
|
||||
}
|
||||
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
Id = _usuarioId,
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
TentativasPerguntaAtual = _questions[_indiceAtual].CountTry,
|
||||
DadosConhecidos = _knowParameters,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return $"Resposta inválida. Tente novamente. {(testByChat.Contains("NÃO") ? "Motivo: " + testByChat.Replace("NÂO", "") : "")} \n\n {perguntaAtual.Text}";
|
||||
}
|
||||
|
||||
public string GetCurrentQuestion() => _questions[_indiceAtual].Text;
|
||||
public async Task<string> GetNextQuestion()
|
||||
{
|
||||
while (_indiceAtual < _questions.Count)
|
||||
{
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
if (perguntaAtual.MustShow(_answers))
|
||||
{
|
||||
return perguntaAtual.Text;
|
||||
}
|
||||
_indiceAtual++;
|
||||
}
|
||||
|
||||
var resp = await _actionCall.Populate(_knowParameters, _answers);
|
||||
if (!resp.Success) return "Obrigado por responder a nossas perguntas!";
|
||||
|
||||
var result = await _actionCall.Call();
|
||||
|
||||
return result.Success ? result.Value : "Obrigado por responder a nossas perguntas!";
|
||||
}
|
||||
|
||||
public string TestAnswerByChat(string resposta)
|
||||
{
|
||||
var resp = _chatCompletionService.GetChatMessageContentAsync($"Por favor, responda com SIM/NÂO e o motivo para eu saber se a pergunta: ({this.GetCurrentQuestion()}) foi respondida pelo usuário quando ele digitou: ({resposta})? É um chatbot, por isso preciso saber apenas se a resposta faz sentido e/ou tem o formato certo.").Result;
|
||||
return resp.Content;
|
||||
}
|
||||
|
||||
public string TestIfWantToAbort(string resposta)
|
||||
{
|
||||
if (_indiceAtual==0) return "";
|
||||
var resp = _chatCompletionService.GetChatMessageContentAsync($"Este é um chatbot. Foi feita a pergunta para o usuario: ({this.GetCurrentQuestion()}) e ele digitou: ({resposta})? Ele respondeu a pergunta com a informação solicitada, ou ele está pedindo para sair do chat? Responda com (SIM = Ele quer sair ou não quer responder) ou (NÃO = Ele responde a pergunta de maneira coerente) e indique o motivo.").Result;
|
||||
return resp.Content.Contains("SIM") ? "ABORTAR" : "";
|
||||
}
|
||||
|
||||
public bool HasNextQuestion()
|
||||
{
|
||||
return _indiceAtual < _questions.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
54
Services/Bot/Structs/ChatBot.cs~RFf86c93a.TMP
Normal file
54
Services/Bot/Structs/ChatBot.cs~RFf86c93a.TMP
Normal file
@ -0,0 +1,54 @@
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatBot
|
||||
{
|
||||
private readonly List<Question> _Questions;
|
||||
private readonly ChatPersistence _persistence;
|
||||
private readonly Dictionary<int, string> _answers;
|
||||
private readonly Guid _usuarioId;
|
||||
private int _indiceAtual;
|
||||
|
||||
public ChatBot(ChatPersistence persistence, Guid usuarioId)
|
||||
{
|
||||
_Questions = new List<Question>();
|
||||
_answers = new Dictionary<int, string>();
|
||||
_indiceAtual = 0;
|
||||
_persistence = persistence;
|
||||
_usuarioId = usuarioId;
|
||||
|
||||
var estado = _persistence.GetState(_usuarioId);
|
||||
if (estado != null)
|
||||
{
|
||||
_indiceAtual = estado.IndicePerguntaAtual;
|
||||
_answers = estado.Respostas;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddQuestion(Question Question)
|
||||
{
|
||||
_Questions.Add(Question);
|
||||
}
|
||||
|
||||
public void Iniciar()
|
||||
{
|
||||
while (_indiceAtual < _Questions.Count)
|
||||
{
|
||||
var QuestionAtual = _Questions[_indiceAtual];
|
||||
if (QuestionAtual.TryToAnswer(out _))
|
||||
{
|
||||
_indiceAtual++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0; // Reinicia o fluxo
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Obrigado por responder a todas as perguntas!");
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Services/Bot/Structs/ChatBot.cs~RFf89467e.TMP
Normal file
75
Services/Bot/Structs/ChatBot.cs~RFf89467e.TMP
Normal file
@ -0,0 +1,75 @@
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatBot
|
||||
{
|
||||
private readonly List<Question> _questions;
|
||||
private readonly ChatPersistence _persistence;
|
||||
private readonly Dictionary<int, string> _answers;
|
||||
private readonly Guid _usuarioId;
|
||||
private int _indiceAtual;
|
||||
|
||||
public ChatBot(ChatPersistence persistence, Guid usuarioId)
|
||||
{
|
||||
_questions = new List<Question>();
|
||||
_answers = new Dictionary<int, string>();
|
||||
_indiceAtual = 0;
|
||||
_persistence = persistence;
|
||||
_usuarioId = usuarioId;
|
||||
|
||||
var estado = _persistence.GetState(_usuarioId);
|
||||
if (estado != null)
|
||||
{
|
||||
_indiceAtual = estado.IndicePerguntaAtual;
|
||||
_answers = estado.Respostas;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddQuestion(Question Question)
|
||||
{
|
||||
_questions.Add(Question);
|
||||
}
|
||||
|
||||
public bool InformarResposta(string resposta)
|
||||
{
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
if (perguntaAtual.Validator(resposta))
|
||||
{
|
||||
_answers[_indiceAtual] = resposta;
|
||||
_indiceAtual++;
|
||||
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Console.WriteLine("Resposta inválida. Tente novamente.");
|
||||
return false;
|
||||
}
|
||||
public void Iniciar()
|
||||
{
|
||||
while (_indiceAtual < _questions.Count)
|
||||
{
|
||||
var QuestionAtual = _questions[_indiceAtual];
|
||||
if (QuestionAtual.TryToAnswer(out _))
|
||||
{
|
||||
_indiceAtual++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0; // Reinicia o fluxo
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Obrigado por responder a todas as perguntas!");
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Services/Bot/Structs/ChatPersistence.cs
Normal file
45
Services/Bot/Structs/ChatPersistence.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using ChatApi.Services.Classifier;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatPersistence
|
||||
{
|
||||
private readonly IMongoCollection<ChatState> _collection;
|
||||
private string _botName;
|
||||
|
||||
private ChatPersistence(DomvsDatabaseSettings config)
|
||||
{
|
||||
var client = new MongoClient(config.ConnectionString);
|
||||
var database = client.GetDatabase(config.DatabaseName);
|
||||
_collection = database.GetCollection<ChatState>(config.ChatBotRHCollectionName);
|
||||
}
|
||||
|
||||
public static ChatPersistence Create(DomvsDatabaseSettings config)
|
||||
{
|
||||
return new ChatPersistence(config);
|
||||
}
|
||||
|
||||
public ChatPersistence SetBotName(string botName)
|
||||
{
|
||||
_botName = botName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatState GetState(string usuarioId)
|
||||
{
|
||||
return _collection.Find(x => x.UsuarioId == usuarioId).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void DeleteState(string usuarioId)
|
||||
{
|
||||
_collection.DeleteOne(x => x.UsuarioId == usuarioId);
|
||||
}
|
||||
|
||||
public void SaveState(ChatState estado)
|
||||
{
|
||||
var filtro = Builders<ChatState>.Filter.Eq(x => x.UsuarioId, estado.UsuarioId);
|
||||
_collection.ReplaceOne(filtro, estado, new ReplaceOptions { IsUpsert = true });
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Services/Bot/Structs/ChatState.cs
Normal file
20
Services/Bot/Structs/ChatState.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using MongoDB.Bson.Serialization.Options;
|
||||
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatState
|
||||
{
|
||||
[BsonId]
|
||||
[BsonElement("_id")]
|
||||
public string Id { get; set; }
|
||||
public string UsuarioId { get; set; }
|
||||
public int IndicePerguntaAtual { get; set; }
|
||||
public int TentativasPerguntaAtual { get; set; }
|
||||
|
||||
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
|
||||
public Dictionary<int, string> Respostas { get; set; }
|
||||
public Dictionary<string, string> DadosConhecidos { get; set; }
|
||||
}
|
||||
}
|
||||
10
Services/Bot/Structs/IActionCall.cs
Normal file
10
Services/Bot/Structs/IActionCall.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using ChatApi.Infra;
|
||||
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public interface IActionCall
|
||||
{
|
||||
Task<Result> Populate(Dictionary<string, string>? knowParameters, Dictionary<int, string> answers);
|
||||
Task<Result<string>> Call();
|
||||
}
|
||||
}
|
||||
42
Services/Bot/Structs/Question.cs
Normal file
42
Services/Bot/Structs/Question.cs
Normal file
@ -0,0 +1,42 @@
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class Question
|
||||
{
|
||||
public string Text { get; }
|
||||
public Func<string, bool> Validator { get; }
|
||||
public int CountTry { get; set; }
|
||||
public Func<Dictionary<int, string>, bool> Condition { get; }
|
||||
|
||||
private const int MaxTentativas = 2;
|
||||
|
||||
public Question(string texto, Func<string, bool> validador, Func<Dictionary<int, string>, bool> condition=null)
|
||||
{
|
||||
Text = texto;
|
||||
Validator = validador;
|
||||
CountTry = 0;
|
||||
Condition = condition;
|
||||
}
|
||||
|
||||
public bool MustShow(Dictionary<int, string> respostasAnteriores)
|
||||
{
|
||||
return Condition == null || Condition(respostasAnteriores);
|
||||
}
|
||||
|
||||
public string TryToAnswer(string resposta)
|
||||
{
|
||||
if (Validator(resposta))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
CountTry++;
|
||||
if (CountTry >= MaxTentativas)
|
||||
{
|
||||
CountTry = 0;
|
||||
return "Não entendi sua resposta. Vamos reiniciar.";
|
||||
}
|
||||
|
||||
return "Resposta inválida. Tente novamente.";
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Services/Bot/Structs/e4zbjmgl.vwg~
Normal file
137
Services/Bot/Structs/e4zbjmgl.vwg~
Normal file
@ -0,0 +1,137 @@
|
||||
using Amazon.Auth.AccessControlPolicy;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatBot
|
||||
{
|
||||
private readonly List<Question> _questions;
|
||||
private readonly ChatPersistence _persistence;
|
||||
private readonly Dictionary<string, string> _knowParameters;
|
||||
private readonly Dictionary<int, string> _answers;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
private readonly IActionCall _actionCall;
|
||||
private readonly string _usuarioId;
|
||||
private int _indiceAtual;
|
||||
|
||||
public ChatBot(ChatPersistence persistence, string usuarioId, IChatCompletionService chatCompletionService, IActionCall actionCall)
|
||||
{
|
||||
_chatCompletionService = chatCompletionService;
|
||||
_actionCall = actionCall;
|
||||
_questions = new List<Question>();
|
||||
_answers = new Dictionary<int, string>();
|
||||
_knowParameters = new Dictionary<string, string>();
|
||||
_indiceAtual = 0;
|
||||
_persistence = persistence;
|
||||
_usuarioId = usuarioId;
|
||||
|
||||
var estado = _persistence.GetState(_usuarioId);
|
||||
if (estado != null)
|
||||
{
|
||||
_indiceAtual = estado.IndicePerguntaAtual;
|
||||
_answers = estado.Respostas;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetParameter(string key, string value)
|
||||
{
|
||||
_knowParameters[key] = value;
|
||||
}
|
||||
|
||||
public void AddQuestion(Question Question)
|
||||
{
|
||||
_questions.Add(Question);
|
||||
}
|
||||
|
||||
public string SetAnswer(string resposta)
|
||||
{
|
||||
if (!this.HasNextQuestion()) return "";
|
||||
|
||||
var state = _persistence.GetState(_usuarioId);
|
||||
if (state != null)
|
||||
{
|
||||
_questions[_indiceAtual].CountTry = state.TentativasPerguntaAtual;
|
||||
}
|
||||
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
var testByChat = TestAnswerByChat(resposta);
|
||||
var abort = TestIfWantToAbort(resposta);
|
||||
var validResp = perguntaAtual.TryToAnswer(resposta);
|
||||
|
||||
if (string.IsNullOrEmpty(validResp) && !abort.Contains("ABORTAR") && perguntaAtual.Validator(resposta) && testByChat.Contains("SIM"))
|
||||
{
|
||||
_answers[_indiceAtual] = resposta;
|
||||
_indiceAtual++;
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
Id = _usuarioId,
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
TentativasPerguntaAtual = _questions[_indiceAtual].CountTry,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return "";
|
||||
}
|
||||
else if (validResp.Contains("reiniciar") || abort.Contains("ABORTAR"))
|
||||
{
|
||||
_persistence.DeleteState(_usuarioId);
|
||||
return "REINICIAR";
|
||||
}
|
||||
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
Id = _usuarioId,
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
TentativasPerguntaAtual = _questions[_indiceAtual].CountTry,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return $"Resposta inválida. Tente novamente. {(testByChat.Contains("NÃO") ? "Motivo: " + testByChat.Replace("NÂO", "") : "")} \n\n {perguntaAtual.Text}";
|
||||
}
|
||||
|
||||
public string GetCurrentQuestion() => _questions[_indiceAtual].Text;
|
||||
public async Task<string> GetNextQuestion()
|
||||
{
|
||||
while (_indiceAtual < _questions.Count)
|
||||
{
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
if (perguntaAtual.MustShow(_answers))
|
||||
{
|
||||
return perguntaAtual.Text;
|
||||
}
|
||||
_indiceAtual++;
|
||||
}
|
||||
|
||||
var resp = await _actionCall.Populate(_knowParameters, _answers);
|
||||
if (!resp.Success) return "Obrigado por responder a nossas perguntas!";
|
||||
|
||||
var result = await _actionCall.Call();
|
||||
|
||||
return result.Success ? result.Value : "Obrigado por responder a nossas perguntas!";
|
||||
}
|
||||
|
||||
public string TestAnswerByChat(string resposta)
|
||||
{
|
||||
var resp = _chatCompletionService.GetChatMessageContentAsync($"Por favor, responda com SIM/NÂO e o motivo para eu saber se a pergunta: ({this.GetCurrentQuestion()}) foi respondida pelo usuário quando ele digitou: ({resposta})? É um chatbot, por isso preciso saber apenas se a resposta faz sentido e/ou tem o formato certo.").Result;
|
||||
return resp.Content;
|
||||
}
|
||||
|
||||
public string TestIfWantToAbort(string resposta)
|
||||
{
|
||||
if (_indiceAtual==0) return "";
|
||||
var resp = _chatCompletionService.GetChatMessageContentAsync($"Este é um chatbot. Foi feita a pergunta para o usuario: ({this.GetCurrentQuestion()}) e ele digitou: ({resposta})? Ele respondeu a pergunta com a informação solicitada, ou ele está pedindo para sair do chat? Responda com (SIM = Ele quer sair ou não quer responder) ou (NÃO = Ele responde a pergunta de maneira coerente) e indique o motivo.").Result;
|
||||
return resp.Content.Contains("SIM") ? "ABORTAR" : "";
|
||||
}
|
||||
|
||||
public bool HasNextQuestion()
|
||||
{
|
||||
return _indiceAtual < _questions.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Services/Bot/Structs/v0pubwmg.zkp~
Normal file
148
Services/Bot/Structs/v0pubwmg.zkp~
Normal file
@ -0,0 +1,148 @@
|
||||
using Amazon.Auth.AccessControlPolicy;
|
||||
using ChatApi.Models;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
|
||||
namespace ChatApi.Services.Bot.Structs
|
||||
{
|
||||
public class ChatBot
|
||||
{
|
||||
private readonly List<Question> _questions;
|
||||
private readonly ChatPersistence _persistence;
|
||||
private readonly Dictionary<int, string> _answers;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
private readonly IActionCall _actionCall;
|
||||
private readonly string _usuarioId;
|
||||
private readonly UserData _userData;
|
||||
private Dictionary<string, string> _knowParameters;
|
||||
private int _indiceAtual;
|
||||
|
||||
public ChatBot(ChatPersistence persistence, string usuarioId, UserData userData, IChatCompletionService chatCompletionService, IActionCall actionCall)
|
||||
{
|
||||
_chatCompletionService = chatCompletionService;
|
||||
_actionCall = actionCall;
|
||||
_questions = new List<Question>();
|
||||
_answers = new Dictionary<int, string>();
|
||||
_knowParameters = new Dictionary<string, string>();
|
||||
_indiceAtual = 0;
|
||||
_persistence = persistence;
|
||||
_usuarioId = usuarioId;
|
||||
_userData = userData;
|
||||
var estado = _persistence.GetState(_usuarioId);
|
||||
if (estado != null)
|
||||
{
|
||||
_indiceAtual = estado.IndicePerguntaAtual;
|
||||
_answers = estado.Respostas;
|
||||
}
|
||||
else
|
||||
{
|
||||
_indiceAtual = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetParameter(string key, string value)
|
||||
{
|
||||
_knowParameters[key] = value;
|
||||
}
|
||||
|
||||
public void AddQuestion(Question Question)
|
||||
{
|
||||
_questions.Add(Question);
|
||||
}
|
||||
|
||||
public string SetAnswer(string resposta)
|
||||
{
|
||||
if (!this.HasNextQuestion()) return "";
|
||||
|
||||
var state = _persistence.GetState(_usuarioId);
|
||||
if (state != null)
|
||||
{
|
||||
_questions[_indiceAtual].CountTry = state.TentativasPerguntaAtual;
|
||||
}
|
||||
else
|
||||
{
|
||||
_knowParameters = new Dictionary<string, string>()
|
||||
{
|
||||
{ "Nome", _userData.Name },
|
||||
{ "Email", _userData.Email }
|
||||
};
|
||||
}
|
||||
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
var testByChat = TestAnswerByChat(resposta);
|
||||
var abort = TestIfWantToAbort(resposta);
|
||||
var validResp = perguntaAtual.TryToAnswer(resposta);
|
||||
|
||||
if (string.IsNullOrEmpty(validResp) && !abort.Contains("ABORTAR") && perguntaAtual.Validator(resposta) && testByChat.Contains("SIM"))
|
||||
{
|
||||
_answers[_indiceAtual] = resposta;
|
||||
_indiceAtual++;
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
Id = _usuarioId,
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
TentativasPerguntaAtual = _questions[_indiceAtual].CountTry,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return "";
|
||||
}
|
||||
else if (validResp.Contains("reiniciar") || abort.Contains("ABORTAR"))
|
||||
{
|
||||
_persistence.DeleteState(_usuarioId);
|
||||
return "REINICIAR";
|
||||
}
|
||||
|
||||
_persistence.SaveState(new ChatState
|
||||
{
|
||||
Id = _usuarioId,
|
||||
UsuarioId = _usuarioId,
|
||||
IndicePerguntaAtual = _indiceAtual,
|
||||
TentativasPerguntaAtual = _questions[_indiceAtual].CountTry,
|
||||
DadosConhecidos = _knowParameters,
|
||||
Respostas = new Dictionary<int, string>(_answers)
|
||||
});
|
||||
|
||||
return $"Resposta inválida. Tente novamente. {(testByChat.Contains("NÃO") ? "Motivo: " + testByChat.Replace("NÂO", "") : "")} \n\n {perguntaAtual.Text}";
|
||||
}
|
||||
|
||||
public string GetCurrentQuestion() => _questions[_indiceAtual].Text;
|
||||
public async Task<string> GetNextQuestion()
|
||||
{
|
||||
while (_indiceAtual < _questions.Count)
|
||||
{
|
||||
var perguntaAtual = _questions[_indiceAtual];
|
||||
if (perguntaAtual.MustShow(_answers))
|
||||
{
|
||||
return perguntaAtual.Text;
|
||||
}
|
||||
_indiceAtual++;
|
||||
}
|
||||
|
||||
var resp = await _actionCall.Populate(_knowParameters, _answers);
|
||||
if (!resp.Success) return "Obrigado por responder a nossas perguntas!";
|
||||
|
||||
var result = await _actionCall.Call();
|
||||
|
||||
return result.Success ? result. : "Obrigado por responder a nossas perguntas!";
|
||||
}
|
||||
|
||||
public string TestAnswerByChat(string resposta)
|
||||
{
|
||||
var resp = _chatCompletionService.GetChatMessageContentAsync($"Por favor, responda com SIM/NÂO e o motivo para eu saber se a pergunta: ({this.GetCurrentQuestion()}) foi respondida pelo usuário quando ele digitou: ({resposta})? É um chatbot, por isso preciso saber apenas se a resposta faz sentido e/ou tem o formato certo.").Result;
|
||||
return resp.Content;
|
||||
}
|
||||
|
||||
public string TestIfWantToAbort(string resposta)
|
||||
{
|
||||
if (_indiceAtual==0) return "";
|
||||
var resp = _chatCompletionService.GetChatMessageContentAsync($"Este é um chatbot. Foi feita a pergunta para o usuario: ({this.GetCurrentQuestion()}) e ele digitou: ({resposta})? Ele respondeu a pergunta com a informação solicitada, ou ele está pedindo para sair do chat? Responda com (SIM = Ele quer sair ou não quer responder) ou (NÃO = Ele responde a pergunta de maneira coerente) e indique o motivo.").Result;
|
||||
return resp.Content.Contains("SIM") ? "ABORTAR" : "";
|
||||
}
|
||||
|
||||
public bool HasNextQuestion()
|
||||
{
|
||||
return _indiceAtual < _questions.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Services/Bot/tdpgs1ms.1ky~
Normal file
64
Services/Bot/tdpgs1ms.1ky~
Normal file
@ -0,0 +1,64 @@
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
|
||||
namespace ChatApi.Services.Bot
|
||||
{
|
||||
public class ChatBotRHCall
|
||||
{
|
||||
private readonly ChatBot _chatbot;
|
||||
|
||||
Dictionary<string, string> _opcoesSolicitação =
|
||||
new Dictionary<string, string> {
|
||||
{ "Inclusão/Exclusão Alura", "Inclusão/Exclusão Alura"},
|
||||
{ "Inclusão/Exclusão Auxílio Idioma", "Inclusão/Exclusão Auxílio Idioma"},
|
||||
{ "Inclusão/Exclusão Plano Odonto", "Inclusão/Exclusão Plano Odonto"},
|
||||
//{ "Envio de Atestado", "Envio de Atestado"},
|
||||
//{ "Envio de Reembolso Idioma", "Envio de Reembolso Idioma"},
|
||||
//{ "Afastamento e Licenças", "Afastamento e Licenças"},
|
||||
{ "Dúvidas Plano de Saúde", "Dúvidas Plano de Saúde"},
|
||||
{ "Dúvidas Folha de Pagamento", "Dúvidas Folha de Pagamento"},
|
||||
{ "Ajuste Cargo/Salário", "Ajuste Cargo/Salário"},
|
||||
{ "Feedbacks, reclamações", "1 - Feedbacks, reclamações"},
|
||||
{ "Feedz - Dúvida 1:1", "Feedz - Dúvida 1:1"},
|
||||
{ "Feedz - Dúvida Feedback", "Feedz - Dúvida Feedback"},
|
||||
{ "Feedz - Cadastro de Objetivo", "Feedz - Cadastro de Objetivo"},
|
||||
{ "Feedz - Erro Cadastro", "Feedz - Erro Cadastro"},
|
||||
{ "Feedz - Outros", "Feedz - Outros"},
|
||||
{ "Ciclo de Performance", "Ciclo de Performance"},
|
||||
{ "Declaração Bolsa Faculdade", "Declaração Bolsa Faculdade"},
|
||||
{ "Inclusão/Exclusão Programa de Especialização", "Inclusão/Exclusão Programa de Especialização"},
|
||||
//{ "Envio de Reembolso Especialização", "Envio de Reembolso Especialização"},
|
||||
{ "DayOff", "DayOff"}
|
||||
};
|
||||
|
||||
public ChatBotRHCall(ChatBot chatbot)
|
||||
{
|
||||
_chatbot = chatbot;
|
||||
AddNumbersBeforShow(_opcoesSolicitação);
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Qual seu número de celular (com WhatsApp)?",
|
||||
resposta => !string.IsNullOrEmpty(resposta) && resposta.Length >= 10));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Qual o tipo de solicitação (1 para Reembolso de Idioma, 2 para Reembolso Alura, 3 para Dúvidas)?",
|
||||
resposta => resposta == "1" || resposta == "2" || resposta == "3"));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Texto/Descrição da solicitação (em caso de dúvidas)",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
|
||||
_chatbot.AddQuestion(new Question(
|
||||
"Tudo bem? Posso enviar sua solicitação?",
|
||||
resposta => !string.IsNullOrEmpty(resposta)));
|
||||
}
|
||||
|
||||
private void AddNumbersBeforShow(Dictionary<string, string> dict)
|
||||
{
|
||||
int optionNumber = 1;
|
||||
foreach (var key in dict.Keys)
|
||||
{
|
||||
dict[key] = $"{optionNumber} - {dict[key]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Services/Classifier/ClassifierPersistence.cs
Normal file
35
Services/Classifier/ClassifierPersistence.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace ChatApi.Services.Classifier
|
||||
{
|
||||
public class ClassifierPersistence
|
||||
{
|
||||
private readonly IMongoCollection<ClassifierSate> _collection;
|
||||
|
||||
public ClassifierPersistence(IOptions<DomvsDatabaseSettings> config)
|
||||
{
|
||||
var client = new MongoClient(config.Value.ConnectionString);
|
||||
var database = client.GetDatabase(config.Value.DatabaseName);
|
||||
_collection = database.GetCollection<ClassifierSate>(config.Value.ClassifierCollectionName);
|
||||
}
|
||||
|
||||
public ClassifierSate GetState(string usuarioId)
|
||||
{
|
||||
return _collection.Find(x => x.Id == usuarioId).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void DeleteState(string usuarioId)
|
||||
{
|
||||
_collection.DeleteOne(x => x.UsuarioId == usuarioId);
|
||||
}
|
||||
|
||||
public void SaveState(ClassifierSate estado)
|
||||
{
|
||||
estado.Id = estado.UsuarioId;
|
||||
var filtro = Builders<ClassifierSate>.Filter.Eq(x => x.Id, estado.UsuarioId);
|
||||
_collection.ReplaceOne(filtro, estado, new ReplaceOptions { IsUpsert = true });
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Services/Classifier/ClassifierSate.cs
Normal file
17
Services/Classifier/ClassifierSate.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using ChatApi.Services.ClassifyHandlers;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace ChatApi.Services.Classifier
|
||||
{
|
||||
public class ClassifierSate
|
||||
{
|
||||
[BsonId]
|
||||
[BsonElement("_id")]
|
||||
public string Id { get; set; }
|
||||
public string UsuarioId { get; set; }
|
||||
public EnumClassification Classification { get; set; }
|
||||
public DateTime DhInicio { get; set; }
|
||||
public EnumClassificationType ClassificationType { get; set; }
|
||||
}
|
||||
}
|
||||
6
Services/Classifier/ClassifierSate.cs~RF14991194.TMP
Normal file
6
Services/Classifier/ClassifierSate.cs~RF14991194.TMP
Normal file
@ -0,0 +1,6 @@
|
||||
namespace ChatApi.Services.Classifier
|
||||
{
|
||||
public class ClassifierSate
|
||||
{
|
||||
}
|
||||
}
|
||||
50
Services/ClassifyHandlers/AClassifyHandler.cs
Normal file
50
Services/ClassifyHandlers/AClassifyHandler.cs
Normal file
@ -0,0 +1,50 @@
|
||||
namespace ChatApi.Services.ClassifyHandlers
|
||||
{
|
||||
public enum EnumClassificationType
|
||||
{
|
||||
Stay,
|
||||
Free
|
||||
}
|
||||
|
||||
public class AHandlerClassify : IHandlerClassify
|
||||
{
|
||||
private IHandlerClassify _nextHandlerClassify;
|
||||
protected TextFilter _textFilter;
|
||||
private EnumClassificationType _type = EnumClassificationType.Free;
|
||||
|
||||
public EnumClassificationType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
_type = EnumClassificationType.Stay;
|
||||
}
|
||||
}
|
||||
|
||||
public int StayInMinutes { get; set; }
|
||||
public EnumClassification MyClassification { get; set; }
|
||||
|
||||
public AHandlerClassify()
|
||||
{
|
||||
_textFilter = new TextFilter();
|
||||
}
|
||||
|
||||
public IHandlerClassify SetNext(IHandlerClassify handler)
|
||||
{
|
||||
_nextHandlerClassify = handler;
|
||||
return handler;
|
||||
}
|
||||
|
||||
public virtual EnumClassification Handle(string request)
|
||||
{
|
||||
if (_nextHandlerClassify != null)
|
||||
{
|
||||
return _nextHandlerClassify.Handle(request);
|
||||
}
|
||||
return EnumClassification.CantDetect;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Services/ClassifyHandlers/ClassifyBotRHCall.cs
Normal file
30
Services/ClassifyHandlers/ClassifyBotRHCall.cs
Normal file
@ -0,0 +1,30 @@
|
||||
namespace ChatApi.Services.ClassifyHandlers
|
||||
{
|
||||
public class ClassifyBotRHCall : AHandlerClassify
|
||||
{
|
||||
public ClassifyBotRHCall()
|
||||
{
|
||||
this.MyClassification = EnumClassification.BotRHCall;
|
||||
this.Type = EnumClassificationType.Stay;
|
||||
this.StayInMinutes = 240;
|
||||
}
|
||||
|
||||
public override EnumClassification Handle(string request)
|
||||
{
|
||||
var companyKeywords = new List<string> { "solicitação", "solicitações", "pedido", "dúvida", "dúvidas", "alura", "auxilio idioma", "plano odonto", "envio atestado", "reembolso idioma", "afastamento", "Agility as a Service", "agilidade",
|
||||
"plano de saúde", "folha de pagamento", "feedbacks", "reclamações", "1:1", "feedback", "Erro de cadsatro", "performance",
|
||||
"bolsa faculdade", "especialização", "reembolso de especialização", "dayoff", "aws", "cadastro", "dúvidas"
|
||||
};
|
||||
|
||||
var questionLower = base._textFilter.ToLowerAndWithoutAccents(request);
|
||||
|
||||
if (questionLower.Contains(_textFilter.ToLowerAndWithoutAccents(" rh")) &&
|
||||
companyKeywords.Any(keyword => questionLower.Contains(_textFilter.ToLowerAndWithoutAccents(keyword))))
|
||||
{
|
||||
return this.MyClassification;
|
||||
}
|
||||
|
||||
return base.Handle(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Services/ClassifyHandlers/ClassifyChat.cs
Normal file
10
Services/ClassifyHandlers/ClassifyChat.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace ChatApi.Services.ClassifyHandlers
|
||||
{
|
||||
public class ClassifyChat : AHandlerClassify
|
||||
{
|
||||
public override EnumClassification Handle(string request)
|
||||
{
|
||||
return EnumClassification.Chat;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Services/ClassifyHandlers/ClassifyCompany.cs
Normal file
25
Services/ClassifyHandlers/ClassifyCompany.cs
Normal file
@ -0,0 +1,25 @@
|
||||
namespace ChatApi.Services.ClassifyHandlers
|
||||
{
|
||||
public class ClassifyCompany : AHandlerClassify
|
||||
{
|
||||
public ClassifyCompany()
|
||||
{
|
||||
this.MyClassification = EnumClassification.Company;
|
||||
}
|
||||
|
||||
public override EnumClassification Handle(string request)
|
||||
{
|
||||
var companyKeywords = new List<string> { "Domvs", "DomvsiT", "squad gerenciada", "squad híbrida", "alocação", "Professional Service", "solução", "Soluções", "Agility as a Service", "agilidade",
|
||||
"DDC", "Design Diamond Conception", "Bussiness Process Optmization", "Otimização de processos", "Soluções em Cloud", "Delphix", "UX", "Squad" };
|
||||
|
||||
var questionLower = base._textFilter.ToLowerAndWithoutAccents(request);
|
||||
|
||||
if (companyKeywords.Any(keyword => questionLower.Contains(_textFilter.ToLowerAndWithoutAccents(keyword))))
|
||||
{
|
||||
return this.MyClassification;
|
||||
}
|
||||
|
||||
return base.Handle(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Services/ClassifyHandlers/ClassifyEstimate.cs
Normal file
20
Services/ClassifyHandlers/ClassifyEstimate.cs
Normal file
@ -0,0 +1,20 @@
|
||||
namespace ChatApi.Services.ClassifyHandlers
|
||||
{
|
||||
public class ClassifyEstimate : AHandlerClassify
|
||||
{
|
||||
public override EnumClassification Handle(string request)
|
||||
{
|
||||
var companyKeywords = new List<string> { "Domvs", "DomvsiT", "squad gerenciada", "squad híbrida", "alocação", "Professional Service", "solução", "Soluções", "Agility as a Service", "agilidade",
|
||||
"DDC", "Design Diamond Conception", "Bussiness Process Optmization", "Otimização de processos", "Soluções em Cloud", "Delphix", "UX", "Squad" };
|
||||
|
||||
var questionLower = base._textFilter.ToLowerAndWithoutAccents(request);
|
||||
|
||||
if (companyKeywords.Any(keyword => questionLower.Contains(_textFilter.ToLowerAndWithoutAccents(keyword))))
|
||||
{
|
||||
return EnumClassification.Company;
|
||||
}
|
||||
|
||||
return base.Handle(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Services/ClassifyHandlers/IHandlerClassify.cs
Normal file
11
Services/ClassifyHandlers/IHandlerClassify.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace ChatApi.Services.ClassifyHandlers
|
||||
{
|
||||
public interface IHandlerClassify
|
||||
{
|
||||
IHandlerClassify SetNext(IHandlerClassify handler);
|
||||
|
||||
EnumClassification Handle(string request);
|
||||
}
|
||||
}
|
||||
10
Services/ResponseService/IResponseService.cs
Normal file
10
Services/ResponseService/IResponseService.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using ChatApi.Models;
|
||||
|
||||
namespace ChatApi.Services.ResponseService
|
||||
{
|
||||
public interface IResponseService
|
||||
{
|
||||
EnumClassification Classification { get; }
|
||||
Task<string> GetResponse(HttpContext context, UserData userData, string sessionId, string question);
|
||||
}
|
||||
}
|
||||
76
Services/ResponseService/ResponseBotRHService.cs
Normal file
76
Services/ResponseService/ResponseBotRHService.cs
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
using ChatApi.Models;
|
||||
using ChatApi.Services.Bot;
|
||||
using ChatApi.Services.Bot.Structs;
|
||||
using ChatApi.Services.Classifier;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using Microsoft.SemanticKernel.Embeddings;
|
||||
using OllamaSharp.Models.Chat;
|
||||
|
||||
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
|
||||
namespace ChatApi.Services.ResponseService
|
||||
{
|
||||
public class ResponseBotRHService : IResponseService
|
||||
{
|
||||
private readonly ChatHistoryService _chatHistoryService;
|
||||
private readonly TextFilter _textFilter;
|
||||
private readonly ChatBotRHCall _chatBotCall;
|
||||
private readonly ClassifierPersistence _classifierPersistence;
|
||||
|
||||
public ResponseBotRHService(
|
||||
ChatHistoryService chatHistoryService,
|
||||
TextFilter textFilter,
|
||||
ChatBotRHCall chatBotCall,
|
||||
ClassifierPersistence classifierPersistence)
|
||||
{
|
||||
_chatHistoryService = chatHistoryService;
|
||||
_textFilter = textFilter;
|
||||
_chatBotCall = chatBotCall;
|
||||
_classifierPersistence = classifierPersistence;
|
||||
}
|
||||
public EnumClassification Classification => EnumClassification.BotRHCall;
|
||||
|
||||
public async Task<string> GetResponse(HttpContext context, UserData userData, string sessionId, string question)
|
||||
{
|
||||
var stopWatch = new System.Diagnostics.Stopwatch();
|
||||
stopWatch.Start();
|
||||
|
||||
SessionIdStore sessionIdStore = new SessionIdStore(context);
|
||||
ChatHistory history = _chatHistoryService.GetSumarizer(sessionId);
|
||||
_chatBotCall.UserData = userData;
|
||||
var resp = _chatBotCall.SetAnswer(sessionId, question);
|
||||
var resposta = "";
|
||||
if (string.IsNullOrEmpty(resp) && resp!="REINICIAR")
|
||||
{
|
||||
resposta = await _chatBotCall.GetNextQuestion();
|
||||
history.AddUserMessage(question);
|
||||
|
||||
history.AddMessage(AuthorRole.Assistant, resposta ?? "");
|
||||
|
||||
_chatHistoryService.UpdateHistory(sessionId, history);
|
||||
|
||||
if (!_chatBotCall.HasNextQuestion())
|
||||
{
|
||||
_classifierPersistence.DeleteState(sessionId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (resp == "REINICIAR")
|
||||
{
|
||||
_classifierPersistence.DeleteState(sessionId);
|
||||
resp = "Ok! Parece que você não quer continuar e/ou eu não entendi sua resposta. Tudo bem! Se quiser, tente novamente depois...";
|
||||
}
|
||||
|
||||
resposta = resp;
|
||||
}
|
||||
|
||||
stopWatch.Stop();
|
||||
return $"{resposta ?? ""}\n\nTempo: {stopWatch.ElapsedMilliseconds / 1000}s";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
42
Services/ResponseService/ResponseChatService.cs
Normal file
42
Services/ResponseService/ResponseChatService.cs
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
using ChatApi.Models;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using OllamaSharp.Models.Chat;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ChatApi.Services.ResponseService
|
||||
{
|
||||
public class ResponseChatService : IResponseService
|
||||
{
|
||||
private readonly ChatHistoryService _chatHistoryService;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
|
||||
public ResponseChatService(
|
||||
ChatHistoryService chatHistoryService,
|
||||
IChatCompletionService chatCompletionService)
|
||||
{
|
||||
this._chatHistoryService = chatHistoryService;
|
||||
this._chatCompletionService = chatCompletionService;
|
||||
}
|
||||
public EnumClassification Classification => EnumClassification.Chat;
|
||||
|
||||
public async Task<string> GetResponse(HttpContext context, UserData userData, string sessionId, string question)
|
||||
{
|
||||
var stopWatch = new System.Diagnostics.Stopwatch();
|
||||
|
||||
stopWatch.Start();
|
||||
|
||||
SessionIdStore sessionIdStore = new SessionIdStore(context);
|
||||
ChatHistory history = _chatHistoryService.Get(sessionId);
|
||||
|
||||
history.AddUserMessage(question);
|
||||
var response = await _chatCompletionService.GetChatMessageContentAsync(history);
|
||||
history.AddMessage(response.Role, response.Content ?? "");
|
||||
|
||||
_chatHistoryService.UpdateHistory(sessionId, history);
|
||||
|
||||
stopWatch.Stop();
|
||||
return $"{response.Content ?? ""}\n\nTempo: {stopWatch.ElapsedMilliseconds / 1000}s";
|
||||
}
|
||||
}
|
||||
}
|
||||
99
Services/ResponseService/ResponseCompanyService.cs
Normal file
99
Services/ResponseService/ResponseCompanyService.cs
Normal file
@ -0,0 +1,99 @@
|
||||
|
||||
using ChatApi.Models;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using Microsoft.SemanticKernel.Embeddings;
|
||||
using OllamaSharp.Models.Chat;
|
||||
|
||||
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
|
||||
namespace ChatApi.Services.ResponseService
|
||||
{
|
||||
public class ResponseCompanyService : IResponseService
|
||||
{
|
||||
private readonly ChatHistoryService _chatHistoryService;
|
||||
private readonly Kernel _kernel;
|
||||
private readonly TextFilter _textFilter;
|
||||
private readonly SharepointDomvsService _sharepointDomvsService;
|
||||
private readonly IChatCompletionService _chatCompletionService;
|
||||
|
||||
public ResponseCompanyService(
|
||||
ChatHistoryService chatHistoryService,
|
||||
Kernel kernel,
|
||||
TextFilter textFilter,
|
||||
SharepointDomvsService sharepointDomvsService,
|
||||
IChatCompletionService chatCompletionService)
|
||||
{
|
||||
this._chatHistoryService = chatHistoryService;
|
||||
this._kernel = kernel;
|
||||
this._textFilter = textFilter;
|
||||
this._sharepointDomvsService = sharepointDomvsService;
|
||||
this._chatCompletionService = chatCompletionService;
|
||||
}
|
||||
public EnumClassification Classification => EnumClassification.Company;
|
||||
|
||||
public async Task<string> GetResponse(HttpContext context, UserData userData, string sessionId, string question)
|
||||
{
|
||||
var stopWatch = new System.Diagnostics.Stopwatch();
|
||||
stopWatch.Start();
|
||||
|
||||
SessionIdStore sessionIdStore = new SessionIdStore(context);
|
||||
|
||||
var resposta = await BuscarTextoRelacionado(question);
|
||||
question = "Para responder à pergunta: \"" + question + "\" por favor, gere um resumo com 3 linhas baseado exclusivamente no texto: \"" + resposta + "\"";
|
||||
ChatHistory history = _chatHistoryService.GetSumarizer(sessionId);
|
||||
|
||||
history.AddUserMessage(question);
|
||||
|
||||
var response = await _chatCompletionService.GetChatMessageContentAsync(history);
|
||||
history.AddMessage(response.Role, response.Content ?? "");
|
||||
|
||||
_chatHistoryService.UpdateHistory(sessionId, history);
|
||||
|
||||
stopWatch.Stop();
|
||||
return $"{response.Content ?? ""}\n\nTempo: {stopWatch.ElapsedMilliseconds / 1000}s";
|
||||
|
||||
}
|
||||
|
||||
async Task<string> BuscarTextoRelacionado(string pergunta)
|
||||
{
|
||||
var embeddingService = _kernel.GetRequiredService<ITextEmbeddingGenerationService>();
|
||||
var embeddingPergunta = await embeddingService.GenerateEmbeddingAsync(_textFilter.ToLowerAndWithoutAccents(pergunta));
|
||||
var embeddingArrayPergunta = embeddingPergunta.ToArray().Select(e => (double)e).ToArray();
|
||||
|
||||
var textos = await _sharepointDomvsService.GetAsync();
|
||||
|
||||
TextoComEmbedding melhorTexto = null;
|
||||
double melhorSimilaridade = -1.0;
|
||||
|
||||
foreach (var texto in textos)
|
||||
{
|
||||
double similaridade = CalcularSimilaridadeCoseno(embeddingArrayPergunta, texto.Embedding);
|
||||
if (similaridade > melhorSimilaridade)
|
||||
{
|
||||
melhorSimilaridade = similaridade;
|
||||
melhorTexto = texto;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Retornar o conteúdo mais similar, ou uma mensagem padrão
|
||||
return melhorTexto != null ? melhorTexto.Conteudo : "Não encontrei uma resposta adequada.";
|
||||
}
|
||||
|
||||
double CalcularSimilaridadeCoseno(double[] embedding1, double[] embedding2)
|
||||
{
|
||||
double dotProduct = 0.0;
|
||||
double normA = 0.0;
|
||||
double normB = 0.0;
|
||||
for (int i = 0; i < embedding1.Length; i++)
|
||||
{
|
||||
dotProduct += embedding1[i] * embedding2[i];
|
||||
normA += Math.Pow(embedding1[i], 2);
|
||||
normB += Math.Pow(embedding2[i], 2);
|
||||
}
|
||||
return dotProduct / (Math.Sqrt(normA) * Math.Sqrt(normB));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
18
Services/ResponseService/ResponseFactory.cs
Normal file
18
Services/ResponseService/ResponseFactory.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace ChatApi.Services.ResponseService
|
||||
{
|
||||
public class ResponseFactory
|
||||
{
|
||||
private readonly IEnumerable<IResponseService> _responseServices;
|
||||
public ResponseFactory(IEnumerable<IResponseService> responseService)
|
||||
{
|
||||
_responseServices = responseService;
|
||||
}
|
||||
|
||||
public IResponseService? GetService(EnumClassification classification)
|
||||
{
|
||||
return _responseServices.FirstOrDefault(w => w.Classification == classification);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Services/TextClassifier.cs
Normal file
60
Services/TextClassifier.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using ChatApi.Services.Classifier;
|
||||
using ChatApi.Services.ClassifyHandlers;
|
||||
|
||||
namespace ChatApi.Services
|
||||
{
|
||||
public enum EnumClassification
|
||||
{
|
||||
Company=0,
|
||||
Estimate=1,
|
||||
BotRHCall = 2,
|
||||
Chat = 3,
|
||||
CantDetect=4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// enum
|
||||
/// </summary>
|
||||
public class TextClassifier
|
||||
{
|
||||
private readonly TextFilter _textFilter;
|
||||
private readonly ClassifierPersistence _classifierPersistence;
|
||||
|
||||
public TextClassifier(TextFilter textFilter, ClassifierPersistence classifierPersistence)
|
||||
{
|
||||
_textFilter = textFilter;
|
||||
_classifierPersistence = classifierPersistence;
|
||||
}
|
||||
public async Task<EnumClassification> ClassifyQuestion(string sessionId, string question)
|
||||
{
|
||||
var state = _classifierPersistence.GetState(sessionId);
|
||||
|
||||
if (state!=null && (state.ClassificationType == EnumClassificationType.Stay))
|
||||
{
|
||||
return state.Classification;
|
||||
}
|
||||
else
|
||||
{
|
||||
var classifyCompany = new ClassifyCompany();
|
||||
var classifyChat = new ClassifyChat();
|
||||
var botChat = new ClassifyBotRHCall();
|
||||
|
||||
classifyCompany
|
||||
.SetNext(botChat)
|
||||
.SetNext(classifyChat);
|
||||
|
||||
var classify = classifyCompany.Handle(question);
|
||||
|
||||
_classifierPersistence.SaveState(new ClassifierSate
|
||||
{
|
||||
Id = sessionId,
|
||||
UsuarioId = sessionId,
|
||||
Classification = classify,
|
||||
DhInicio = DateTime.Now,
|
||||
ClassificationType = botChat.MyClassification == classify ? EnumClassificationType.Stay : EnumClassificationType.Free
|
||||
});
|
||||
return classify;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Services/TextFilter.cs
Normal file
33
Services/TextFilter.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace ChatApi.Services
|
||||
{
|
||||
public class TextFilter
|
||||
{
|
||||
public string ToLowerAndWithoutAccents(string text)
|
||||
{
|
||||
return RemoveDiacritics(text.ToLower());
|
||||
}
|
||||
|
||||
public string RemoveDiacritics(string text)
|
||||
{
|
||||
var normalizedString = text.Normalize(NormalizationForm.FormD);
|
||||
var stringBuilder = new StringBuilder(capacity: normalizedString.Length);
|
||||
|
||||
for (int i = 0; i < normalizedString.Length; i++)
|
||||
{
|
||||
char c = normalizedString[i];
|
||||
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
|
||||
{
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder
|
||||
.ToString()
|
||||
.Normalize(NormalizationForm.FormC);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
SessionIdStore.cs
Normal file
32
SessionIdStore.cs
Normal file
@ -0,0 +1,32 @@
|
||||
namespace ChatApi
|
||||
{
|
||||
public class SessionIdStore
|
||||
{
|
||||
HttpContext _context;
|
||||
|
||||
public SessionIdStore(HttpContext httpContext)
|
||||
{
|
||||
_context = httpContext;
|
||||
}
|
||||
|
||||
public string GetSessionId()
|
||||
{
|
||||
var sessionId = _context.Request.Cookies["ChatSessionId"];
|
||||
|
||||
if (sessionId == null)
|
||||
{
|
||||
sessionId = Guid.NewGuid().ToString("N");
|
||||
_context.Response.Cookies.Append("ChatSessionId", sessionId, new CookieOptions
|
||||
{
|
||||
Expires = DateTimeOffset.Now.AddMonths(12),
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.None,
|
||||
Secure = true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Settings/ChatRHSettings.cs
Normal file
8
Settings/ChatRHSettings.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace ChatApi.Settings
|
||||
{
|
||||
public class ChatRHSettings
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string Create { get; set; }
|
||||
}
|
||||
}
|
||||
38
SharepointDomvsService.cs
Normal file
38
SharepointDomvsService.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace ChatApi
|
||||
{
|
||||
public class SharepointDomvsService
|
||||
{
|
||||
private readonly IMongoCollection<TextoComEmbedding> _booksCollection;
|
||||
|
||||
public SharepointDomvsService(
|
||||
IOptions<DomvsDatabaseSettings> bookStoreDatabaseSettings)
|
||||
{
|
||||
var mongoClient = new MongoClient(
|
||||
bookStoreDatabaseSettings.Value.ConnectionString);
|
||||
|
||||
var mongoDatabase = mongoClient.GetDatabase(
|
||||
bookStoreDatabaseSettings.Value.DatabaseName);
|
||||
|
||||
_booksCollection = mongoDatabase.GetCollection<TextoComEmbedding>(
|
||||
bookStoreDatabaseSettings.Value.SharepointCollectionName);
|
||||
}
|
||||
|
||||
public async Task<List<TextoComEmbedding>> GetAsync() =>
|
||||
await _booksCollection.Find(_ => true).ToListAsync();
|
||||
|
||||
public async Task<TextoComEmbedding?> GetAsync(string id) =>
|
||||
await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync();
|
||||
|
||||
public async Task CreateAsync(TextoComEmbedding newBook) =>
|
||||
await _booksCollection.InsertOneAsync(newBook);
|
||||
|
||||
public async Task UpdateAsync(string id, TextoComEmbedding updatedBook) =>
|
||||
await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook);
|
||||
|
||||
public async Task RemoveAsync(string id) =>
|
||||
await _booksCollection.DeleteOneAsync(x => x.Id == id);
|
||||
}
|
||||
}
|
||||
16
TextoComEmbedding.cs
Normal file
16
TextoComEmbedding.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using MongoDB.Bson;
|
||||
|
||||
namespace ChatApi
|
||||
{
|
||||
public class TextoComEmbedding
|
||||
{
|
||||
[BsonId]
|
||||
[BsonElement("_id")]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Conteudo { get; set; }
|
||||
public double[] Embedding { get; set; }
|
||||
}
|
||||
}
|
||||
19
appsettings.Development.json
Normal file
19
appsettings.Development.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"DomvsDatabase": {
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "DomvsSites",
|
||||
"SharepointCollectionName": "SharepointSite",
|
||||
"ChatBotRHCollectionName": "ChatBotRHData",
|
||||
"ClassifierCollectionName": "ClassifierData"
|
||||
},
|
||||
"ChatRHSettings": {
|
||||
"Url": "https://localhost:7070/",
|
||||
"Create": "/CallRH"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
22
appsettings.json
Normal file
22
appsettings.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"DomvsDatabase": {
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "DomvsSites",
|
||||
"SharepointCollectionName": "SharepointSite",
|
||||
"ChatBotRHCollectionName": "ChatBotRHData",
|
||||
"ClassifierCollectionName": "ClassifierData"
|
||||
},
|
||||
"ChatRHSettings": {
|
||||
"Url": "mongodb://localhost:27017",
|
||||
"Create": "DomvsSites"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"AppTenantId": "20190830-5fd4-4a72-b8fd-1c1cb35b25bc",
|
||||
"AppClientID": "8f4248fc-ee30-4f54-8793-66edcca3fd20"
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user