2024-03-26 21:57:13 +00:00
|
|
|
using BotSharp.Abstraction.Routing;
|
2024-01-31 19:57:54 +00:00
|
|
|
using BotSharp.Abstraction.Users.Models;
|
|
|
|
|
|
2023-08-19 00:15:02 +00:00
|
|
|
namespace BotSharp.OpenAPI.Controllers;
|
|
|
|
|
|
|
|
|
|
[Authorize]
|
|
|
|
|
[ApiController]
|
2023-12-27 15:53:54 +00:00
|
|
|
public class ConversationController : ControllerBase
|
2023-08-19 00:15:02 +00:00
|
|
|
{
|
|
|
|
|
private readonly IServiceProvider _services;
|
|
|
|
|
private readonly IUserIdentity _user;
|
|
|
|
|
|
2023-10-27 22:16:53 +00:00
|
|
|
public ConversationController(IServiceProvider services,
|
2023-08-19 00:15:02 +00:00
|
|
|
IUserIdentity user)
|
|
|
|
|
{
|
|
|
|
|
_services = services;
|
|
|
|
|
_user = user;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost("/conversation/{agentId}")]
|
2023-10-27 15:18:48 +00:00
|
|
|
public async Task<ConversationViewModel> NewConversation([FromRoute] string agentId, [FromBody] MessageConfig config)
|
2023-08-19 00:15:02 +00:00
|
|
|
{
|
|
|
|
|
var service = _services.GetRequiredService<IConversationService>();
|
2023-10-27 15:18:48 +00:00
|
|
|
var conv = new Conversation
|
2023-08-19 00:15:02 +00:00
|
|
|
{
|
2023-11-14 01:25:25 +00:00
|
|
|
AgentId = agentId,
|
2023-11-27 03:04:48 +00:00
|
|
|
Channel = ConversationChannel.OpenAPI,
|
2024-02-12 15:14:33 +00:00
|
|
|
UserId = _user.Id,
|
|
|
|
|
TaskId = config.TaskId
|
2023-08-19 00:15:02 +00:00
|
|
|
};
|
2023-10-27 15:18:48 +00:00
|
|
|
conv = await service.NewConversation(conv);
|
2023-11-20 17:08:05 +00:00
|
|
|
service.SetConversationId(conv.Id, config.States);
|
2023-10-27 15:18:48 +00:00
|
|
|
|
|
|
|
|
return ConversationViewModel.FromSession(conv);
|
2023-08-19 00:15:02 +00:00
|
|
|
}
|
|
|
|
|
|
2024-03-08 22:02:08 +00:00
|
|
|
[HttpPost("/conversations")]
|
|
|
|
|
public async Task<PagedItems<ConversationViewModel>> GetConversations([FromBody] ConversationFilter filter)
|
2023-11-14 01:25:25 +00:00
|
|
|
{
|
|
|
|
|
var service = _services.GetRequiredService<IConversationService>();
|
2023-12-04 23:42:46 +00:00
|
|
|
var conversations = await service.GetConversations(filter);
|
|
|
|
|
|
2023-11-14 01:25:25 +00:00
|
|
|
var userService = _services.GetRequiredService<IUserService>();
|
2024-01-28 01:02:33 +00:00
|
|
|
var agentService = _services.GetRequiredService<IAgentService>();
|
2023-12-04 23:42:46 +00:00
|
|
|
var list = conversations.Items
|
|
|
|
|
.Select(x => ConversationViewModel.FromSession(x))
|
|
|
|
|
.ToList();
|
2023-11-14 01:25:25 +00:00
|
|
|
|
|
|
|
|
foreach (var item in list)
|
|
|
|
|
{
|
|
|
|
|
var user = await userService.GetUser(item.User.Id);
|
|
|
|
|
item.User = UserViewModel.FromUser(user);
|
2024-01-28 01:02:33 +00:00
|
|
|
|
|
|
|
|
var agent = await agentService.GetAgent(item.AgentId);
|
2024-02-12 15:14:33 +00:00
|
|
|
item.AgentName = agent?.Name;
|
2023-11-14 01:25:25 +00:00
|
|
|
}
|
|
|
|
|
|
2023-12-04 23:42:46 +00:00
|
|
|
return new PagedItems<ConversationViewModel>
|
|
|
|
|
{
|
|
|
|
|
Count = conversations.Count,
|
|
|
|
|
Items = list
|
|
|
|
|
};
|
2023-11-14 01:25:25 +00:00
|
|
|
}
|
|
|
|
|
|
2023-11-14 14:13:54 +00:00
|
|
|
[HttpGet("/conversation/{conversationId}/dialogs")]
|
|
|
|
|
public async Task<IEnumerable<ChatResponseModel>> GetDialogs([FromRoute] string conversationId)
|
|
|
|
|
{
|
|
|
|
|
var conv = _services.GetRequiredService<IConversationService>();
|
2024-03-27 18:50:27 +00:00
|
|
|
conv.SetConversationId(conversationId, new List<MessageState>());
|
2024-03-24 01:31:15 +00:00
|
|
|
var history = conv.GetDialogHistory(fromBreakpoint: false);
|
2023-11-14 14:13:54 +00:00
|
|
|
|
|
|
|
|
var userService = _services.GetRequiredService<IUserService>();
|
2024-01-31 20:01:59 +00:00
|
|
|
var agentService = _services.GetRequiredService<IAgentService>();
|
2023-11-14 14:13:54 +00:00
|
|
|
|
|
|
|
|
var dialogs = new List<ChatResponseModel>();
|
|
|
|
|
foreach (var message in history)
|
|
|
|
|
{
|
2024-01-31 19:57:54 +00:00
|
|
|
if (message.Role == AgentRole.User)
|
|
|
|
|
{
|
|
|
|
|
var user = await userService.GetUser(message.SenderId);
|
2023-11-14 14:13:54 +00:00
|
|
|
|
2024-01-31 19:57:54 +00:00
|
|
|
dialogs.Add(new ChatResponseModel
|
|
|
|
|
{
|
|
|
|
|
ConversationId = conversationId,
|
|
|
|
|
MessageId = message.MessageId,
|
|
|
|
|
CreatedAt = message.CreatedAt,
|
|
|
|
|
Text = message.Content,
|
2024-02-06 20:42:35 +00:00
|
|
|
Data = message.Data,
|
2024-01-31 19:57:54 +00:00
|
|
|
Sender = UserViewModel.FromUser(user)
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-02-28 04:36:33 +00:00
|
|
|
else if (message.Role == AgentRole.Assistant)
|
2023-11-14 14:13:54 +00:00
|
|
|
{
|
2024-01-31 20:01:59 +00:00
|
|
|
var agent = await agentService.GetAgent(message.CurrentAgentId);
|
2024-01-31 19:57:54 +00:00
|
|
|
dialogs.Add(new ChatResponseModel
|
|
|
|
|
{
|
|
|
|
|
ConversationId = conversationId,
|
|
|
|
|
MessageId = message.MessageId,
|
|
|
|
|
CreatedAt = message.CreatedAt,
|
2024-01-31 20:01:59 +00:00
|
|
|
Text = message.Content,
|
2024-02-28 16:16:46 +00:00
|
|
|
Function = message.FunctionName,
|
2024-02-06 20:42:35 +00:00
|
|
|
Data = message.Data,
|
2024-01-31 20:01:59 +00:00
|
|
|
Sender = new UserViewModel
|
|
|
|
|
{
|
|
|
|
|
FirstName = agent.Name,
|
|
|
|
|
Role = message.Role,
|
2024-02-22 16:02:11 +00:00
|
|
|
},
|
|
|
|
|
RichContent = message.RichContent
|
2024-01-31 19:57:54 +00:00
|
|
|
});
|
|
|
|
|
}
|
2023-11-14 14:13:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dialogs;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-26 03:16:41 +00:00
|
|
|
[HttpGet("/conversation/{conversationId}")]
|
|
|
|
|
public async Task<ConversationViewModel> GetConversation([FromRoute] string conversationId)
|
|
|
|
|
{
|
|
|
|
|
var service = _services.GetRequiredService<IConversationService>();
|
|
|
|
|
var conversations = await service.GetConversations(new ConversationFilter
|
|
|
|
|
{
|
|
|
|
|
Id = conversationId
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var userService = _services.GetRequiredService<IUserService>();
|
|
|
|
|
var result = ConversationViewModel.FromSession(conversations.Items.First());
|
|
|
|
|
|
2023-12-27 19:27:52 +00:00
|
|
|
var state = _services.GetRequiredService<IConversationStateService>();
|
|
|
|
|
result.States = state.Load(conversationId);
|
|
|
|
|
|
2023-12-26 03:16:41 +00:00
|
|
|
var user = await userService.GetUser(result.User.Id);
|
|
|
|
|
result.User = UserViewModel.FromUser(user);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 14:13:54 +00:00
|
|
|
[HttpDelete("/conversation/{conversationId}")]
|
2023-11-26 06:29:06 +00:00
|
|
|
public async Task<bool> DeleteConversation([FromRoute] string conversationId)
|
2023-08-19 00:15:02 +00:00
|
|
|
{
|
2023-11-26 06:29:06 +00:00
|
|
|
var conversationService = _services.GetRequiredService<IConversationService>();
|
2024-03-07 07:34:52 +00:00
|
|
|
var response = await conversationService.DeleteConversations(new List<string> { conversationId });
|
2023-11-26 06:29:06 +00:00
|
|
|
return response;
|
2023-08-19 00:15:02 +00:00
|
|
|
}
|
|
|
|
|
|
2024-01-29 01:33:40 +00:00
|
|
|
[HttpDelete("/conversation/{conversationId}/message/{messageId}")]
|
|
|
|
|
public async Task<bool> DeleteConversationMessage([FromRoute] string conversationId, [FromRoute] string messageId)
|
|
|
|
|
{
|
|
|
|
|
var conversationService = _services.GetRequiredService<IConversationService>();
|
|
|
|
|
var response = await conversationService.TruncateConversation(conversationId, messageId);
|
|
|
|
|
return response;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-19 00:15:02 +00:00
|
|
|
[HttpPost("/conversation/{agentId}/{conversationId}")]
|
2023-11-14 04:56:06 +00:00
|
|
|
public async Task<ChatResponseModel> SendMessage([FromRoute] string agentId,
|
2023-10-27 22:16:53 +00:00
|
|
|
[FromRoute] string conversationId,
|
2023-09-09 15:37:38 +00:00
|
|
|
[FromBody] NewMessageModel input)
|
2023-08-19 00:15:02 +00:00
|
|
|
{
|
|
|
|
|
var conv = _services.GetRequiredService<IConversationService>();
|
2024-01-29 01:33:40 +00:00
|
|
|
if (!string.IsNullOrEmpty(input.TruncateMessageId))
|
|
|
|
|
{
|
|
|
|
|
await conv.TruncateConversation(conversationId, input.TruncateMessageId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text);
|
2024-03-26 21:57:13 +00:00
|
|
|
var routing = _services.GetRequiredService<IRoutingService>();
|
|
|
|
|
routing.Context.SetMessageId(conversationId, inputMsg.MessageId);
|
|
|
|
|
|
2024-03-26 23:11:05 +00:00
|
|
|
conv.SetConversationId(conversationId, input.States);
|
2023-11-27 03:44:17 +00:00
|
|
|
conv.States.SetState("channel", input.Channel)
|
|
|
|
|
.SetState("provider", input.Provider)
|
2023-11-27 03:04:48 +00:00
|
|
|
.SetState("model", input.Model)
|
|
|
|
|
.SetState("temperature", input.Temperature)
|
|
|
|
|
.SetState("sampling_factor", input.SamplingFactor);
|
2023-09-14 01:41:51 +00:00
|
|
|
|
2023-11-14 04:56:06 +00:00
|
|
|
var response = new ChatResponseModel();
|
2024-01-13 21:17:40 +00:00
|
|
|
|
2023-11-27 03:44:17 +00:00
|
|
|
await conv.SendMessage(agentId, inputMsg,
|
2024-03-16 14:43:00 +00:00
|
|
|
replyMessage: input.Postback,
|
2023-08-19 00:15:02 +00:00
|
|
|
async msg =>
|
2023-08-20 19:02:59 +00:00
|
|
|
{
|
2023-10-30 16:48:18 +00:00
|
|
|
response.Text = msg.Content;
|
|
|
|
|
response.Function = msg.FunctionName;
|
|
|
|
|
response.RichContent = msg.RichContent;
|
|
|
|
|
response.Instruction = msg.Instruction;
|
|
|
|
|
response.Data = msg.Data;
|
2023-08-20 19:02:59 +00:00
|
|
|
},
|
2024-03-16 14:43:00 +00:00
|
|
|
_ => Task.CompletedTask,
|
|
|
|
|
_ => Task.CompletedTask);
|
2023-08-19 00:15:02 +00:00
|
|
|
|
2023-11-03 14:16:16 +00:00
|
|
|
var state = _services.GetRequiredService<IConversationStateService>();
|
|
|
|
|
response.States = state.GetStates();
|
2023-10-27 15:18:48 +00:00
|
|
|
response.MessageId = inputMsg.MessageId;
|
2023-11-14 14:13:54 +00:00
|
|
|
response.ConversationId = conversationId;
|
2023-09-22 20:38:58 +00:00
|
|
|
|
2023-08-19 00:15:02 +00:00
|
|
|
return response;
|
|
|
|
|
}
|
2023-11-09 21:11:36 +00:00
|
|
|
|
2023-11-14 14:13:54 +00:00
|
|
|
[HttpPost("/conversation/{conversationId}/attachments")]
|
|
|
|
|
public IActionResult UploadAttachments([FromRoute] string conversationId,
|
2023-11-09 21:11:36 +00:00
|
|
|
IFormFile[] files)
|
|
|
|
|
{
|
|
|
|
|
if (files != null && files.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
var attachmentService = _services.GetRequiredService<IConversationAttachmentService>();
|
|
|
|
|
var dir = attachmentService.GetDirectory(conversationId);
|
|
|
|
|
foreach (var file in files)
|
|
|
|
|
{
|
|
|
|
|
// Save the file, process it, etc.
|
|
|
|
|
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
|
|
|
|
|
var filePath = Path.Combine(dir, fileName);
|
|
|
|
|
|
|
|
|
|
using (var stream = new FileStream(filePath, FileMode.Create))
|
|
|
|
|
{
|
|
|
|
|
file.CopyTo(stream);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Ok(new { message = "File uploaded successfully." });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return BadRequest(new { message = "Invalid file." });
|
|
|
|
|
}
|
2023-08-19 00:15:02 +00:00
|
|
|
}
|