Merge branch 'SciSharp:master' into master
This commit is contained in:
commit
6ae74a4dc8
|
|
@ -12,6 +12,7 @@ public interface IConversationService
|
|||
Task<Conversation> GetConversation(string id);
|
||||
Task<PagedItems<Conversation>> GetConversations(ConversationFilter filter);
|
||||
Task<Conversation> UpdateConversationTitle(string id, string title);
|
||||
Task<bool> UpdateConversationMessage(string conversationId, UpdateMessageRequest request);
|
||||
Task<List<Conversation>> GetLastConversations();
|
||||
Task<List<string>> GetIdleConversations(int batchSize, int messageLimit, int bufferHours, IEnumerable<string> excludeAgentIds);
|
||||
Task<bool> DeleteConversations(IEnumerable<string> ids);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class UpdateMessageRequest
|
||||
{
|
||||
public DialogElement Message { get; set; } = null!;
|
||||
public int InnderIndex { get; set; }
|
||||
}
|
||||
|
|
@ -5,6 +5,6 @@ public class InstructResult : ITrackableMessage
|
|||
[JsonPropertyName("message_id")]
|
||||
public string MessageId { get; set; }
|
||||
public string Text { get; set; }
|
||||
public object Data { get; set; }
|
||||
public Dictionary<string, string> States { get; set; }
|
||||
public object? Data { get; set; }
|
||||
public Dictionary<string, string>? States { get; set; } = new();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ public interface IBotSharpRepository
|
|||
Conversation GetConversation(string conversationId);
|
||||
PagedItems<Conversation> GetConversations(ConversationFilter filter);
|
||||
void UpdateConversationTitle(string conversationId, string title);
|
||||
bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request);
|
||||
void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint);
|
||||
ConversationBreakpoint? GetConversationBreakpoint(string conversationId);
|
||||
List<Conversation> GetLastConversations();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,13 @@ public partial class ConversationService : IConversationService
|
|||
var conversation = db.GetConversation(id);
|
||||
return conversation;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateConversationMessage(string conversationId, UpdateMessageRequest request)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
return db.UpdateConversationMessage(conversationId, request);
|
||||
}
|
||||
|
||||
public async Task<Conversation> GetConversation(string id)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
|
|
|
|||
|
|
@ -156,22 +156,25 @@ public class BotSharpDbContext : Database, IBotSharpRepository
|
|||
=> throw new NotImplementedException();
|
||||
|
||||
public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
|
||||
=> new NotImplementedException();
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public void UpdateConversationTitle(string conversationId, string title)
|
||||
=> new NotImplementedException();
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint)
|
||||
=> new NotImplementedException();
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public ConversationBreakpoint? GetConversationBreakpoint(string conversationId)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
|
||||
=> new NotImplementedException();
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public void UpdateConversationStatus(string conversationId, string status)
|
||||
=> new NotImplementedException();
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
|
||||
=> throw new NotImplementedException();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using BotSharp.Abstraction.Loggers.Models;
|
|||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace BotSharp.Core.Repository
|
||||
{
|
||||
|
|
@ -133,6 +134,38 @@ namespace BotSharp.Core.Repository
|
|||
}
|
||||
}
|
||||
|
||||
public bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return false;
|
||||
|
||||
var dialogs = GetConversationDialogs(conversationId);
|
||||
var candidates = dialogs.Where(x => x.MetaData.MessageId == request.Message.MetaData.MessageId
|
||||
&& x.MetaData.Role == request.Message.MetaData.Role).ToList();
|
||||
|
||||
var found = candidates.Where((_, idx) => idx == request.InnderIndex).FirstOrDefault();
|
||||
if (found == null) return false;
|
||||
|
||||
found.Content = request.Message.Content;
|
||||
found.RichContent = request.Message.RichContent;
|
||||
|
||||
if (!string.IsNullOrEmpty(found.SecondaryContent))
|
||||
{
|
||||
found.SecondaryContent = request.Message.Content;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(found.SecondaryRichContent))
|
||||
{
|
||||
found.SecondaryRichContent = request.Message.RichContent;
|
||||
}
|
||||
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
if (string.IsNullOrEmpty(convDir)) return false;
|
||||
|
||||
var dialogFile = Path.Combine(convDir, DIALOG_FILE);
|
||||
File.WriteAllText(dialogFile, JsonSerializer.Serialize(dialogs, _options));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint)
|
||||
{
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
|
|
|
|||
|
|
@ -221,6 +221,29 @@ public class ConversationController : ControllerBase
|
|||
return response != null;
|
||||
}
|
||||
|
||||
[HttpPut("/conversation/{conversationId}/update-message")]
|
||||
public async Task<bool> UpdateConversationMessage([FromRoute] string conversationId, [FromBody] UpdateMessageModel model)
|
||||
{
|
||||
var conversationService = _services.GetRequiredService<IConversationService>();
|
||||
var request = new UpdateMessageRequest
|
||||
{
|
||||
Message = new DialogElement
|
||||
{
|
||||
MetaData = new DialogMetaData
|
||||
{
|
||||
MessageId = model.Message.MessageId,
|
||||
Role = model.Message.Sender?.Role
|
||||
},
|
||||
Content = model.Message.Text,
|
||||
RichContent = JsonSerializer.Serialize(model.Message.RichContent, _jsonOptions),
|
||||
},
|
||||
InnderIndex = model.InnerIndex
|
||||
};
|
||||
|
||||
return await conversationService.UpdateConversationMessage(conversationId, request);
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("/conversation/{conversationId}")]
|
||||
public async Task<bool> DeleteConversation([FromRoute] string conversationId)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Conversations;
|
||||
|
||||
public class UpdateMessageModel
|
||||
{
|
||||
[JsonPropertyName("message")]
|
||||
public ChatResponseModel Message { get; set; } = null!;
|
||||
|
||||
[JsonPropertyName("inner_index")]
|
||||
public int InnerIndex { get; set; }
|
||||
}
|
||||
|
|
@ -5,11 +5,11 @@ namespace BotSharp.OpenAPI.ViewModels.Users;
|
|||
|
||||
public class UserViewModel
|
||||
{
|
||||
public string Id { get; set; } = null!;
|
||||
public string Id { get; set; } = string.Empty;
|
||||
[JsonPropertyName("user_name")]
|
||||
public string UserName { get; set; } = null!;
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
[JsonPropertyName("first_name")]
|
||||
public string FirstName { get; set; } = null!;
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
[JsonPropertyName("last_name")]
|
||||
public string? LastName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
|
|
@ -18,7 +18,7 @@ public class UserViewModel
|
|||
public string Role { get; set; } = UserRole.User;
|
||||
[JsonPropertyName("full_name")]
|
||||
public string FullName => $"{FirstName} {LastName}".Trim();
|
||||
public string Source { get; set; }
|
||||
public string? Source { get; set; }
|
||||
[JsonPropertyName("external_id")]
|
||||
public string? ExternalId { get; set; }
|
||||
public string Avatar { get; set; } = "/user/avatar";
|
||||
|
|
|
|||
|
|
@ -41,13 +41,22 @@ public class WelcomeHook : ConversationHookBase
|
|||
});
|
||||
var richContentService = _services.GetRequiredService<IRichContentService>();
|
||||
var messages = richContentService.ConvertToMessages(content);
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
var richContent = new RichContent<IRichMessage>(message);
|
||||
var dialog = new RoleDialogModel(AgentRole.Assistant, message.Text)
|
||||
{
|
||||
MessageId = guid,
|
||||
CurrentAgentId = agent.Id,
|
||||
RichContent = richContent
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(new ChatResponseModel()
|
||||
{
|
||||
ConversationId = conversation.Id,
|
||||
MessageId = dialog.MessageId,
|
||||
Text = message.Text,
|
||||
RichContent = richContent,
|
||||
Sender = new UserViewModel()
|
||||
|
|
@ -60,12 +69,7 @@ public class WelcomeHook : ConversationHookBase
|
|||
|
||||
await Task.Delay(300);
|
||||
|
||||
_storage.Append(conversation.Id, new RoleDialogModel(AgentRole.Assistant, message.Text)
|
||||
{
|
||||
MessageId = conversation.Id,
|
||||
CurrentAgentId = agent.Id,
|
||||
RichContent = richContent
|
||||
});
|
||||
_storage.Append(conversation.Id, dialog);
|
||||
|
||||
await _chatHub.Clients.User(_user.Id).SendAsync("OnMessageReceivedFromAssistant", json);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,42 @@ public partial class MongoRepository
|
|||
_dc.Conversations.UpdateOne(filterConv, updateConv);
|
||||
}
|
||||
|
||||
public bool UpdateConversationMessage(string conversationId, UpdateMessageRequest request)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return false;
|
||||
|
||||
var filter = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
|
||||
var foundDialog = _dc.ConversationDialogs.Find(filter).FirstOrDefault();
|
||||
if (foundDialog == null || foundDialog.Dialogs.IsNullOrEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var dialogs = foundDialog.Dialogs;
|
||||
var candidates = dialogs.Where(x => x.MetaData.MessageId == request.Message.MetaData.MessageId
|
||||
&& x.MetaData.Role == request.Message.MetaData.Role).ToList();
|
||||
|
||||
var found = candidates.Where((_, idx) => idx == request.InnderIndex).FirstOrDefault();
|
||||
if (found == null) return false;
|
||||
|
||||
found.Content = request.Message.Content;
|
||||
found.RichContent = request.Message.RichContent;
|
||||
|
||||
if (!string.IsNullOrEmpty(found.SecondaryContent))
|
||||
{
|
||||
found.SecondaryContent = request.Message.Content;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(found.SecondaryRichContent))
|
||||
{
|
||||
found.SecondaryRichContent = request.Message.RichContent;
|
||||
}
|
||||
|
||||
var update = Builders<ConversationDialogDocument>.Update.Set(x => x.Dialogs, dialogs);
|
||||
_dc.ConversationDialogs.UpdateOne(filter, update);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return;
|
||||
|
|
|
|||
Loading…
Reference in a new issue