Skip to content

Commit b64b0db

Browse files
committed
refactor: spilt ConversationController
1 parent ee816cc commit b64b0db

File tree

1 file changed

+23
-217
lines changed

1 file changed

+23
-217
lines changed

src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs

Lines changed: 23 additions & 217 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
1-
using BotSharp.Abstraction.Chart;
21
using BotSharp.Abstraction.Files.Constants;
32
using BotSharp.Abstraction.Files.Enums;
4-
using BotSharp.Abstraction.Files.Utilities;
53
using BotSharp.Abstraction.MessageHub.Models;
64
using BotSharp.Abstraction.MessageHub.Services;
75
using BotSharp.Abstraction.Options;
86
using BotSharp.Abstraction.Routing;
97
using BotSharp.Abstraction.Users.Dtos;
108
using BotSharp.Core.Infrastructures;
11-
using BotSharp.Core.Users.Services;
12-
using System.Diagnostics;
13-
using static BotSharp.Abstraction.Diagnostics.ModelDiagnostics;
149

1510
namespace BotSharp.OpenAPI.Controllers;
1611

1712
[Authorize]
1813
[ApiController]
19-
public class ConversationController : ControllerBase
14+
public partial class ConversationController : ControllerBase
2015
{
2116
private readonly IServiceProvider _services;
2217
private readonly IUserIdentity _user;
2318
private readonly JsonSerializerOptions _jsonOptions;
2419

25-
public ConversationController(IServiceProvider services,
20+
public ConversationController(
21+
IServiceProvider services,
2622
IUserIdentity user,
2723
BotSharpOptions options)
2824
{
@@ -46,12 +42,8 @@ public async Task<ConversationViewModel> NewConversation([FromRoute] string agen
4642
};
4743
conv = await service.NewConversation(conv);
4844
service.SetConversationId(conv.Id, config.States);
49-
using (var trace = new ActivitySource("BotSharp").StartActivity("NewUserSession", ActivityKind.Internal))
50-
{
51-
trace?.SetTag("user_id", _user.FullName);
52-
trace?.SetTag("conversation_id", conv.Id);
53-
return ConversationViewModel.FromSession(conv);
54-
}
45+
46+
return ConversationViewModel.FromSession(conv);
5547
}
5648

5749
[HttpGet("/conversations")]
@@ -371,34 +363,25 @@ public async Task<ChatResponseModel> SendMessage(
371363
conv.SetConversationId(conversationId, input.States);
372364
SetStates(conv, input);
373365

374-
using (var trace = new ActivitySource("BotSharp").StartActivity("UserSession", ActivityKind.Internal))
375-
{
376-
trace?.SetTag("user.id", _user.FullName);
377-
trace?.SetTag("session.id", conversationId);
378-
trace?.SetTag("input", inputMsg.Content);
379-
trace?.SetTag(ModelDiagnosticsTags.AgentId, agentId);
380-
381-
var response = new ChatResponseModel();
382-
await conv.SendMessage(agentId, inputMsg,
383-
replyMessage: input.Postback,
384-
async msg =>
385-
{
386-
response.Text = !string.IsNullOrEmpty(msg.SecondaryContent) ? msg.SecondaryContent : msg.Content;
387-
response.Function = msg.FunctionName;
388-
response.MessageLabel = msg.MessageLabel;
389-
response.RichContent = msg.SecondaryRichContent ?? msg.RichContent;
390-
response.Instruction = msg.Instruction;
391-
response.Data = msg.Data;
392-
});
366+
var response = new ChatResponseModel();
367+
await conv.SendMessage(agentId, inputMsg,
368+
replyMessage: input.Postback,
369+
async msg =>
370+
{
371+
response.Text = !string.IsNullOrEmpty(msg.SecondaryContent) ? msg.SecondaryContent : msg.Content;
372+
response.Function = msg.FunctionName;
373+
response.MessageLabel = msg.MessageLabel;
374+
response.RichContent = msg.SecondaryRichContent ?? msg.RichContent;
375+
response.Instruction = msg.Instruction;
376+
response.Data = msg.Data;
377+
});
393378

394-
var state = _services.GetRequiredService<IConversationStateService>();
395-
response.States = state.GetStates();
396-
response.MessageId = inputMsg.MessageId;
397-
response.ConversationId = conversationId;
379+
var state = _services.GetRequiredService<IConversationStateService>();
380+
response.States = state.GetStates();
381+
response.MessageId = inputMsg.MessageId;
382+
response.ConversationId = conversationId;
398383

399-
trace?.SetTag("output", response.Data);
400-
return response;
401-
}
384+
return response;
402385
}
403386

404387

@@ -449,7 +432,7 @@ await conv.SendMessage(agentId, inputMsg,
449432
response.Instruction = msg.Instruction;
450433
response.Data = msg.Data;
451434
response.States = state.GetStates();
452-
435+
453436
await OnChunkReceived(Response, response);
454437
});
455438

@@ -475,183 +458,6 @@ private async Task OnReceiveToolCallIndication(string conversationId, RoleDialog
475458
}
476459
#endregion
477460

478-
#region Files and attachments
479-
[HttpGet("/conversation/{conversationId}/attachments")]
480-
public List<MessageFileViewModel> ListAttachments([FromRoute] string conversationId)
481-
{
482-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
483-
var dir = fileStorage.GetDirectory(conversationId);
484-
485-
// List files in the directory
486-
var files = Directory.Exists(dir)
487-
? Directory.GetFiles(dir).Select(f => new MessageFileViewModel
488-
{
489-
FileName = Path.GetFileName(f),
490-
FileExtension = Path.GetExtension(f).TrimStart('.').ToLower(),
491-
ContentType = FileUtility.GetFileContentType(f),
492-
FileDownloadUrl = $"/conversation/{conversationId}/attachments/file/{Path.GetFileName(f)}",
493-
}).ToList()
494-
: new List<MessageFileViewModel>();
495-
496-
return files;
497-
}
498-
499-
[AllowAnonymous]
500-
[HttpGet("/conversation/{conversationId}/attachments/file/{fileName}")]
501-
public IActionResult GetAttachment([FromRoute] string conversationId, [FromRoute] string fileName)
502-
{
503-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
504-
var dir = fileStorage.GetDirectory(conversationId);
505-
var filePath = Path.Combine(dir, fileName);
506-
if (!System.IO.File.Exists(filePath))
507-
{
508-
return NotFound();
509-
}
510-
return BuildFileResult(filePath);
511-
}
512-
513-
[HttpPost("/conversation/{conversationId}/attachments")]
514-
public IActionResult UploadAttachments([FromRoute] string conversationId, IFormFile[] files)
515-
{
516-
if (files != null && files.Length > 0)
517-
{
518-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
519-
var dir = fileStorage.GetDirectory(conversationId);
520-
foreach (var file in files)
521-
{
522-
// Save the file, process it, etc.
523-
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
524-
var filePath = Path.Combine(dir, fileName);
525-
526-
fileStorage.SaveFileStreamToPath(filePath, file.OpenReadStream());
527-
}
528-
529-
return Ok(new { message = "File uploaded successfully." });
530-
}
531-
532-
return BadRequest(new { message = "Invalid file." });
533-
}
534-
535-
[HttpPost("/agent/{agentId}/conversation/{conversationId}/upload")]
536-
public async Task<IActionResult> UploadConversationMessageFiles([FromRoute] string agentId, [FromRoute] string conversationId, [FromBody] InputMessageFiles input)
537-
{
538-
var convService = _services.GetRequiredService<IConversationService>();
539-
convService.SetConversationId(conversationId, input.States);
540-
var conv = await convService.GetConversationRecordOrCreateNew(agentId);
541-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
542-
var messageId = Guid.NewGuid().ToString();
543-
var isSaved = fileStorage.SaveMessageFiles(conv.Id, messageId, FileSource.User, input.Files);
544-
return Ok(new { messageId = isSaved ? messageId : string.Empty });
545-
}
546-
547-
[HttpGet("/conversation/{conversationId}/files/{messageId}/{source}")]
548-
public IEnumerable<MessageFileViewModel> GetConversationMessageFiles([FromRoute] string conversationId, [FromRoute] string messageId, [FromRoute] string source)
549-
{
550-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
551-
var files = fileStorage.GetMessageFiles(conversationId, [messageId], options: new() { Sources = [source] });
552-
return files?.Select(x => MessageFileViewModel.Transform(x))?.ToList() ?? [];
553-
}
554-
555-
[HttpGet("/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}")]
556-
public IActionResult GetMessageFile([FromRoute] string conversationId, [FromRoute] string messageId, [FromRoute] string source, [FromRoute] string index, [FromRoute] string fileName)
557-
{
558-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
559-
var file = fileStorage.GetMessageFile(conversationId, messageId, source, index, fileName);
560-
if (string.IsNullOrEmpty(file))
561-
{
562-
return NotFound();
563-
}
564-
return BuildFileResult(file);
565-
}
566-
567-
[HttpGet("/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}/download")]
568-
public IActionResult DownloadMessageFile([FromRoute] string conversationId, [FromRoute] string messageId, [FromRoute] string source, [FromRoute] string index, [FromRoute] string fileName)
569-
{
570-
var fileStorage = _services.GetRequiredService<IFileStorageService>();
571-
var file = fileStorage.GetMessageFile(conversationId, messageId, source, index, fileName);
572-
if (string.IsNullOrEmpty(file))
573-
{
574-
return NotFound();
575-
}
576-
577-
var fName = file.Split(Path.DirectorySeparatorChar).Last();
578-
var contentType = FileUtility.GetFileContentType(fName);
579-
var stream = System.IO.File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read);
580-
var bytes = new byte[stream.Length];
581-
stream.Read(bytes, 0, (int)stream.Length);
582-
stream.Position = 0;
583-
584-
return new FileStreamResult(stream, contentType) { FileDownloadName = fName };
585-
}
586-
#endregion
587-
588-
#region Chart
589-
[AllowAnonymous]
590-
[HttpGet("/conversation/{conversationId}/message/{messageId}/user/chart/data")]
591-
public async Task<ConversationChartDataResponse?> GetConversationChartData(
592-
[FromRoute] string conversationId,
593-
[FromRoute] string messageId,
594-
[FromQuery] ConversationChartDataRequest request)
595-
{
596-
var chart = _services.GetServices<IBotSharpChartService>().FirstOrDefault(x => x.Provider == request?.ChartProvider);
597-
if (chart == null) return null;
598-
599-
var result = await chart.GetConversationChartData(conversationId, messageId, request);
600-
return ConversationChartDataResponse.From(result);
601-
}
602-
603-
[HttpPost("/conversation/{conversationId}/message/{messageId}/user/chart/code")]
604-
public async Task<ConversationChartCodeResponse?> GetConversationChartCode(
605-
[FromRoute] string conversationId,
606-
[FromRoute] string messageId,
607-
[FromBody] ConversationChartCodeRequest request)
608-
{
609-
var chart = _services.GetServices<IBotSharpChartService>().FirstOrDefault(x => x.Provider == request?.ChartProvider);
610-
if (chart == null) return null;
611-
612-
var result = await chart.GetConversationChartCode(conversationId, messageId, request);
613-
return ConversationChartCodeResponse.From(result);
614-
}
615-
#endregion
616-
617-
#region Dashboard
618-
[HttpPut("/agent/{agentId}/conversation/{conversationId}/dashboard")]
619-
public async Task<bool> PinConversationToDashboard([FromRoute] string agentId, [FromRoute] string conversationId)
620-
{
621-
var userService = _services.GetRequiredService<IUserService>();
622-
var pinned = await userService.AddDashboardConversation(conversationId);
623-
return pinned;
624-
}
625-
626-
[HttpDelete("/agent/{agentId}/conversation/{conversationId}/dashboard")]
627-
public async Task<bool> UnpinConversationFromDashboard([FromRoute] string agentId, [FromRoute] string conversationId)
628-
{
629-
var userService = _services.GetRequiredService<IUserService>();
630-
var unpinned = await userService.RemoveDashboardConversation(conversationId);
631-
return unpinned;
632-
}
633-
#endregion
634-
635-
#region Search state keys
636-
[HttpGet("/conversation/state/keys")]
637-
public async Task<List<string>> GetConversationStateKeys([FromQuery] ConversationStateKeysFilter request)
638-
{
639-
var convService = _services.GetRequiredService<IConversationService>();
640-
var keys = await convService.GetConversationStateSearhKeys(request);
641-
return keys;
642-
}
643-
#endregion
644-
645-
#region Migrate Latest States
646-
[HttpPost("/conversation/latest-state/migrate")]
647-
public async Task<bool> MigrateConversationLatestStates([FromBody] MigrateLatestStateRequest request)
648-
{
649-
var convService = _services.GetRequiredService<IConversationService>();
650-
var res = await convService.MigrateLatestStates(request.BatchSize, request.ErrorLimit);
651-
return res;
652-
}
653-
#endregion
654-
655461
#region Private methods
656462
private void SetStates(IConversationService conv, NewMessageModel input)
657463
{

0 commit comments

Comments
 (0)