Merge pull request #509 from iceljc/features/add-file-upload-endpoint
refine message files
This commit is contained in:
commit
bca845e572
|
|
@ -56,4 +56,6 @@ public interface IConversationService
|
||||||
Task UpdateBreakpoint(bool resetStates = false, string? reason = null, params string[] excludedStates);
|
Task UpdateBreakpoint(bool resetStates = false, string? reason = null, params string[] excludedStates);
|
||||||
|
|
||||||
Task<string> GetConversationSummary(IEnumerable<string> conversationId);
|
Task<string> GetConversationSummary(IEnumerable<string> conversationId);
|
||||||
|
|
||||||
|
Task<Conversation> GetConversationRecordOrCreateNew(string agentId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ public class IncomingMessageModel : MessageConfig
|
||||||
public string Text { get; set; } = string.Empty;
|
public string Text { get; set; } = string.Empty;
|
||||||
public virtual string Channel { get; set; } = string.Empty;
|
public virtual string Channel { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonPropertyName("input_message_id")]
|
||||||
|
public string? InputMessageId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Postback message
|
/// Postback message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,6 @@ namespace BotSharp.Abstraction.Conversations.Models;
|
||||||
|
|
||||||
public class TruncateMessageRequest
|
public class TruncateMessageRequest
|
||||||
{
|
{
|
||||||
public string? TruncateMessageId { get; set; }
|
[JsonPropertyName("is_new_message")]
|
||||||
|
public bool isNewMessage { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
namespace BotSharp.Abstraction.Models;
|
namespace BotSharp.Abstraction.Models;
|
||||||
|
|
||||||
public class MessageConfig : TruncateMessageRequest
|
public class MessageConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Completion Provider
|
/// Completion Provider
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,7 @@ public partial class ConversationService
|
||||||
Func<RoleDialogModel, Task> onFunctionExecuting,
|
Func<RoleDialogModel, Task> onFunctionExecuting,
|
||||||
Func<RoleDialogModel, Task> onFunctionExecuted)
|
Func<RoleDialogModel, Task> onFunctionExecuted)
|
||||||
{
|
{
|
||||||
var conversation = await GetConversationRecord(agentId);
|
var conversation = await GetConversationRecordOrCreateNew(agentId);
|
||||||
|
|
||||||
// Save message files
|
|
||||||
var fileService = _services.GetRequiredService<IBotSharpFileService>();
|
|
||||||
fileService.SaveMessageFiles(_conversationId, message.MessageId, FileSourceType.User, message.Files);
|
|
||||||
message.Files?.Clear();
|
|
||||||
|
|
||||||
var agentService = _services.GetRequiredService<IAgentService>();
|
var agentService = _services.GetRequiredService<IAgentService>();
|
||||||
Agent agent = await agentService.LoadAgent(agentId);
|
Agent agent = await agentService.LoadAgent(agentId);
|
||||||
|
|
||||||
|
|
@ -99,27 +93,6 @@ public partial class ConversationService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Conversation> GetConversationRecord(string agentId)
|
|
||||||
{
|
|
||||||
var converation = await GetConversation(_conversationId);
|
|
||||||
|
|
||||||
// Create conversation if this conversation does not exist
|
|
||||||
if (converation == null)
|
|
||||||
{
|
|
||||||
var state = _services.GetRequiredService<IConversationStateService>();
|
|
||||||
var channel = state.GetState("channel");
|
|
||||||
var sess = new Conversation
|
|
||||||
{
|
|
||||||
Id = _conversationId,
|
|
||||||
Channel = channel,
|
|
||||||
AgentId = agentId
|
|
||||||
};
|
|
||||||
converation = await NewConversation(sess);
|
|
||||||
}
|
|
||||||
|
|
||||||
return converation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleAssistantMessage(RoleDialogModel response, Func<RoleDialogModel, Task> onResponseReceived)
|
private async Task HandleAssistantMessage(RoleDialogModel response, Func<RoleDialogModel, Task> onResponseReceived)
|
||||||
{
|
{
|
||||||
var agentService = _services.GetRequiredService<IAgentService>();
|
var agentService = _services.GetRequiredService<IAgentService>();
|
||||||
|
|
|
||||||
|
|
@ -140,4 +140,25 @@ public partial class ConversationService : IConversationService
|
||||||
_state.Load(_conversationId);
|
_state.Load(_conversationId);
|
||||||
states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External));
|
states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Conversation> GetConversationRecordOrCreateNew(string agentId)
|
||||||
|
{
|
||||||
|
var converation = await GetConversation(_conversationId);
|
||||||
|
|
||||||
|
// Create conversation if this conversation does not exist
|
||||||
|
if (converation == null)
|
||||||
|
{
|
||||||
|
var state = _services.GetRequiredService<IConversationStateService>();
|
||||||
|
var channel = state.GetState("channel");
|
||||||
|
var sess = new Conversation
|
||||||
|
{
|
||||||
|
Id = _conversationId,
|
||||||
|
Channel = channel,
|
||||||
|
AgentId = agentId
|
||||||
|
};
|
||||||
|
converation = await NewConversation(sess);
|
||||||
|
}
|
||||||
|
|
||||||
|
return converation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,6 @@ public partial class BotSharpFileService
|
||||||
using var fs = new FileStream(Path.Combine(subDir, file.FileName), FileMode.Create);
|
using var fs = new FileStream(Path.Combine(subDir, file.FileName), FileMode.Create);
|
||||||
fs.Write(bytes, 0, bytes.Length);
|
fs.Write(bytes, 0, bytes.Length);
|
||||||
fs.Flush(true);
|
fs.Flush(true);
|
||||||
Thread.Sleep(2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using BotSharp.Abstraction.Files.Enums;
|
||||||
using BotSharp.Abstraction.Options;
|
using BotSharp.Abstraction.Options;
|
||||||
using BotSharp.Abstraction.Routing;
|
using BotSharp.Abstraction.Routing;
|
||||||
using BotSharp.Abstraction.Users.Enums;
|
using BotSharp.Abstraction.Users.Enums;
|
||||||
|
|
@ -142,7 +143,7 @@ public class ConversationController : ControllerBase
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = ConversationViewModel.FromSession(conversations.Items.First());
|
var result = ConversationViewModel.FromSession(conversations.Items.First());
|
||||||
var state = _services.GetRequiredService<IConversationStateService>();
|
var state = _services.GetRequiredService<IConversationStateService>();
|
||||||
result.States = state.Load(conversationId, isReadOnly: true);
|
result.States = state.Load(conversationId, isReadOnly: true);
|
||||||
|
|
@ -211,11 +212,12 @@ public class ConversationController : ControllerBase
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("/conversation/{conversationId}/message/{messageId}")]
|
[HttpDelete("/conversation/{conversationId}/message/{messageId}")]
|
||||||
public async Task<bool> DeleteConversationMessage([FromRoute] string conversationId, [FromRoute] string messageId)
|
public async Task<string?> DeleteConversationMessage([FromRoute] string conversationId, [FromRoute] string messageId, [FromBody] TruncateMessageRequest request)
|
||||||
{
|
{
|
||||||
var conversationService = _services.GetRequiredService<IConversationService>();
|
var conversationService = _services.GetRequiredService<IConversationService>();
|
||||||
var response = await conversationService.TruncateConversation(conversationId, messageId);
|
var newMessageId = request.isNewMessage ? Guid.NewGuid().ToString() : null;
|
||||||
return response;
|
var isSuccess = await conversationService.TruncateConversation(conversationId, messageId, newMessageId);
|
||||||
|
return isSuccess ? newMessageId : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Send message
|
#region Send message
|
||||||
|
|
@ -227,15 +229,10 @@ public class ConversationController : ControllerBase
|
||||||
var conv = _services.GetRequiredService<IConversationService>();
|
var conv = _services.GetRequiredService<IConversationService>();
|
||||||
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text)
|
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text)
|
||||||
{
|
{
|
||||||
Files = input.Files,
|
MessageId = !string.IsNullOrWhiteSpace(input.InputMessageId) ? input.InputMessageId : Guid.NewGuid().ToString(),
|
||||||
CreatedAt = DateTime.UtcNow
|
CreatedAt = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(input.TruncateMessageId))
|
|
||||||
{
|
|
||||||
await conv.TruncateConversation(conversationId, input.TruncateMessageId, inputMsg.MessageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
var routing = _services.GetRequiredService<IRoutingService>();
|
var routing = _services.GetRequiredService<IRoutingService>();
|
||||||
routing.Context.SetMessageId(conversationId, inputMsg.MessageId);
|
routing.Context.SetMessageId(conversationId, inputMsg.MessageId);
|
||||||
|
|
||||||
|
|
@ -243,7 +240,7 @@ public class ConversationController : ControllerBase
|
||||||
SetStates(conv, input);
|
SetStates(conv, input);
|
||||||
|
|
||||||
var response = new ChatResponseModel();
|
var response = new ChatResponseModel();
|
||||||
|
|
||||||
await conv.SendMessage(agentId, inputMsg,
|
await conv.SendMessage(agentId, inputMsg,
|
||||||
replyMessage: input.Postback,
|
replyMessage: input.Postback,
|
||||||
async msg =>
|
async msg =>
|
||||||
|
|
@ -273,15 +270,10 @@ public class ConversationController : ControllerBase
|
||||||
var conv = _services.GetRequiredService<IConversationService>();
|
var conv = _services.GetRequiredService<IConversationService>();
|
||||||
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text)
|
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text)
|
||||||
{
|
{
|
||||||
Files = input.Files,
|
MessageId = !string.IsNullOrWhiteSpace(input.InputMessageId) ? input.InputMessageId : Guid.NewGuid().ToString(),
|
||||||
CreatedAt = DateTime.UtcNow
|
CreatedAt = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(input.TruncateMessageId))
|
|
||||||
{
|
|
||||||
await conv.TruncateConversation(conversationId, input.TruncateMessageId, inputMsg.MessageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
var state = _services.GetRequiredService<IConversationStateService>();
|
var state = _services.GetRequiredService<IConversationStateService>();
|
||||||
|
|
||||||
var routing = _services.GetRequiredService<IRoutingService>();
|
var routing = _services.GetRequiredService<IRoutingService>();
|
||||||
|
|
@ -322,7 +314,7 @@ public class ConversationController : ControllerBase
|
||||||
{
|
{
|
||||||
ConversationId = conversationId,
|
ConversationId = conversationId,
|
||||||
MessageId = msg.MessageId,
|
MessageId = msg.MessageId,
|
||||||
Text = msg.Indication,
|
Text = msg.Indication,
|
||||||
Function = "indicating",
|
Function = "indicating",
|
||||||
Instruction = msg.Instruction,
|
Instruction = msg.Instruction,
|
||||||
States = new Dictionary<string, string>()
|
States = new Dictionary<string, string>()
|
||||||
|
|
@ -370,8 +362,20 @@ public class ConversationController : ControllerBase
|
||||||
return BadRequest(new { message = "Invalid file." });
|
return BadRequest(new { message = "Invalid file." });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("/agent/{agentId}/conversation/{conversationId}/upload")]
|
||||||
|
public async Task<string> UploadConversationMessageFiles([FromRoute] string agentId, [FromRoute] string conversationId, [FromBody] NewMessageModel input)
|
||||||
|
{
|
||||||
|
var convService = _services.GetRequiredService<IConversationService>();
|
||||||
|
convService.SetConversationId(conversationId, input.States);
|
||||||
|
var conv = await convService.GetConversationRecordOrCreateNew(agentId);
|
||||||
|
var fileService = _services.GetRequiredService<IBotSharpFileService>();
|
||||||
|
var messageId = Guid.NewGuid().ToString();
|
||||||
|
var isSaved = fileService.SaveMessageFiles(conv.Id, messageId, FileSourceType.User, input.Files);
|
||||||
|
return isSaved ? messageId : string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("/conversation/{conversationId}/files/{messageId}/{source}")]
|
[HttpGet("/conversation/{conversationId}/files/{messageId}/{source}")]
|
||||||
public IEnumerable<MessageFileViewModel> GetMessageFiles([FromRoute] string conversationId, [FromRoute] string messageId, [FromRoute] string source)
|
public IEnumerable<MessageFileViewModel> GetConversationMessageFiles([FromRoute] string conversationId, [FromRoute] string messageId, [FromRoute] string source)
|
||||||
{
|
{
|
||||||
var fileService = _services.GetRequiredService<IBotSharpFileService>();
|
var fileService = _services.GetRequiredService<IBotSharpFileService>();
|
||||||
var files = fileService.GetMessageFiles(conversationId, new List<string> { messageId }, source, imageOnly: false);
|
var files = fileService.GetMessageFiles(conversationId, new List<string> { messageId }, source, imageOnly: false);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue