Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ public interface IConversationService
/// Send message to LLM
/// </summary>
/// <param name="agentId"></param>
/// <param name="conversationId"></param>
/// <param name="lastDalog"></param>
/// <param name="onMessageReceived"></param>
/// <param name="onFunctionExecuting">This delegate is useful when you want to report progress on UI</param>
/// <param name="onFunctionExecuted">This delegate is useful when you want to report progress on UI</param>
/// <returns></returns>
Task<bool> SendMessage(string agentId,
Task<bool> SendMessage(string agentId,
RoleDialogModel lastDalog,
Func<RoleDialogModel, Task> onMessageReceived,
Func<RoleDialogModel, Task> onFunctionExecuting,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ List<Agent> GetAgents(string? name = null, bool? disabled = null, bool? allowRou
void UpdateConversationStates(string conversationId, List<StateKeyValue> states);
void UpdateConversationStatus(string conversationId, string status);
Conversation GetConversation(string conversationId);
List<Conversation> GetConversations(string userId);
List<Conversation> GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we define these fields in ConversationFilters class?

void UpdateConversationTitle(string conversationId, string title);
List<Conversation> GetLastConversations();
void AddExectionLogs(string conversationId, List<string> logs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace BotSharp.Core.Conversations.Services;

public partial class ConversationService
{
public async Task<bool> SendMessage(string agentId,
public async Task<bool> SendMessage(string agentId,
RoleDialogModel message,
Func<RoleDialogModel, Task> onMessageReceived,
Func<RoleDialogModel, Task> onFunctionExecuting,
Expand Down Expand Up @@ -73,12 +73,15 @@ private async Task<Conversation> GetConversationRecord(string agentId)
{
var converation = await GetConversation(_conversationId);

// Create conversation if this conversation not exists
// 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public async Task<List<Conversation>> GetConversations()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserById(_user.Id);
var conversations = db.GetConversations(user.Role == UserRole.CSR ? null : user?.Id);
var targetUserId = user.Role == UserRole.CSR ? null : user?.Id;
var conversations = db.GetConversations(userId: targetUserId);
return conversations.OrderByDescending(x => x.CreatedTime).ToList();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Evaluations;
using BotSharp.Abstraction.Evaluations.Models;
using BotSharp.Abstraction.Evaluations.Settings;
Expand Down Expand Up @@ -87,12 +88,15 @@ public async Task<EvaluationResult> Evaluate(string conversationId, EvaluationRe
private async Task<RoleDialogModel> SendMessage(string agentId, string conversationId, string text)
{
var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(conversationId, new List<string>());
conv.SetConversationId(conversationId, new List<string>
{
$"channel={ConversationChannel.OpenAPI}"
});

RoleDialogModel response = default;

await conv.SendMessage(agentId,
new RoleDialogModel("user", text),
new RoleDialogModel(AgentRole.User, text),
async msg => response = msg,
fnExecuting => Task.CompletedTask,
fnExecuted => Task.CompletedTask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public Conversation GetConversation(string conversationId)
throw new NotImplementedException();
}

public List<Conversation> GetConversations(string userId)
public List<Conversation> GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null)
{
throw new NotImplementedException();
}
Expand Down
71 changes: 28 additions & 43 deletions src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,7 @@ private IQueryable<UserAgent> UserAgents

public void Add<TTableInterface>(object entity)
{
if (entity is Conversation conversation)
{
_conversations.Add(conversation);
_changedTableNames.Add(nameof(Conversation));
}
else if (entity is Agent agent)
if (entity is Agent agent)
{
_agents.Add(agent);
_changedTableNames.Add(nameof(Agent));
Expand All @@ -159,20 +154,7 @@ public int Transaction<TTableInterface>(Action action)
// Persist to disk
foreach (var table in _changedTableNames)
{
if (table == nameof(Conversation))
{
foreach (var conversation in _conversations)
{
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, conversation.Id);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
var path = Path.Combine(dir, "conversation.json");
File.WriteAllText(path, JsonSerializer.Serialize(conversation, _options));
}
}
else if (table == nameof(Agent))
if (table == nameof(Agent))
{
foreach (var agent in _agents)
{
Expand Down Expand Up @@ -730,32 +712,29 @@ public void UpdateConversationStatus(string conversationId, string status)
public Conversation GetConversation(string conversationId)
{
var convDir = FindConversationDirectory(conversationId);
if (!string.IsNullOrEmpty(convDir))
{
var convFile = Path.Combine(convDir, "conversation.json");
var content = File.ReadAllText(convFile);
var record = JsonSerializer.Deserialize<Conversation>(content, _options);
if (string.IsNullOrEmpty(convDir)) return null;

var dialogFile = Path.Combine(convDir, "dialogs.txt");
if (record != null)
{
record.Dialogs = CollectDialogElements(dialogFile);
}
var convFile = Path.Combine(convDir, "conversation.json");
var content = File.ReadAllText(convFile);
var record = JsonSerializer.Deserialize<Conversation>(content, _options);

var stateFile = Path.Combine(convDir, "state.dict");
if (record != null)
{
var states = CollectConversationStates(stateFile);
record.States = new ConversationState(states);
}
var dialogFile = Path.Combine(convDir, "dialogs.txt");
if (record != null)
{
record.Dialogs = CollectDialogElements(dialogFile);
}

return record;
var stateFile = Path.Combine(convDir, "state.dict");
if (record != null)
{
var states = CollectConversationStates(stateFile);
record.States = new ConversationState(states);
}

return null;
return record;
}

public List<Conversation> GetConversations(string userId)
public List<Conversation> GetConversations(string? agentId = null, string? status = null, string? channel = null, string? userId = null)
{
var records = new List<Conversation>();
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir);
Expand All @@ -767,10 +746,16 @@ public List<Conversation> GetConversations(string userId)

var json = File.ReadAllText(path);
var record = JsonSerializer.Deserialize<Conversation>(json, _options);
if (record != null && (record.UserId == userId || userId == null))
{
records.Add(record);
}
if (record == null) continue;

var matched = true;
if (!string.IsNullOrEmpty(agentId)) matched = matched && record.AgentId == agentId;
if (!string.IsNullOrEmpty(status)) matched = matched && record.Status == status;
if (!string.IsNullOrEmpty(channel)) matched = matched && record.Channel == channel;
if (!string.IsNullOrEmpty(userId)) matched = matched && record.UserId == userId;

if (!matched) continue;
records.Add(record);
}

return records;
Expand Down
6 changes: 3 additions & 3 deletions src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ protected RoutingRule[] GetRoutingRecords()

// Filter agents by profile
var state = _services.GetRequiredService<IConversationStateService>();
var name = state.GetState("channel");
var specifiedProfile = agents.FirstOrDefault(x => x.Profiles.Contains(name));
var channel = state.GetState("channel");
var specifiedProfile = agents.FirstOrDefault(x => x.Profiles.Contains(channel));
if (specifiedProfile != null)
{
records = records.Where(x => specifiedProfile.Profiles.Contains(name)).ToArray();
records = records.Where(x => specifiedProfile.Profiles.Contains(channel)).ToArray();
}

return records;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.ApiAdapters;
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Models;
using BotSharp.OpenAPI.ViewModels.Conversations;
Expand Down Expand Up @@ -30,6 +32,7 @@ public async Task<ConversationViewModel> NewConversation([FromRoute] string agen
var conv = new Conversation
{
AgentId = agentId,
Channel = ConversationChannel.OpenAPI,
UserId = _user.Id
};
conv = await service.NewConversation(conv);
Expand Down Expand Up @@ -98,13 +101,13 @@ public async Task<ChatResponseModel> SendMessage([FromRoute] string agentId,
var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(conversationId, input.States);
conv.States.SetState("channel", input.Channel)
.SetState("provider", input.Provider)
.SetState("model", input.Model)
.SetState("temperature", input.Temperature)
.SetState("sampling_factor", input.SamplingFactor);
.SetState("provider", input.Provider)
.SetState("model", input.Model)
.SetState("temperature", input.Temperature)
.SetState("sampling_factor", input.SamplingFactor);

var response = new ChatResponseModel();
var inputMsg = new RoleDialogModel("user", input.Text);
var inputMsg = new RoleDialogModel(AgentRole.User, input.Text);
await conv.SendMessage(agentId, inputMsg,
async msg =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Conversations.Models;

namespace BotSharp.OpenAPI.ViewModels.Conversations;

public class NewMessageModel : IncomingMessageModel
{
public override string Channel { get; set; } = "openapi";
public override string Channel { get; set; } = ConversationChannel.OpenAPI;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.OpenAPI.ViewModels.Instructs;

public class InstructMessageModel : IncomingMessageModel
{
public override string Channel { get; set; } = "openapi";
public override string Channel { get; set; } = ConversationChannel.OpenAPI;
public string? Template { get; set; }
}
12 changes: 6 additions & 6 deletions src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ public async Task SendMessage([FromBody] OpenAiMessageInput input)

var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(input.ConversationId, input.States);
conv.States.SetState("provider", input.Provider)
.SetState("model", input.Model)
.SetState("channel", input.Channel)
.SetState("temperature", input.Temperature)
.SetState("sampling_factor", input.SamplingFactor);
conv.States.SetState("channel", input.Channel)
.SetState("provider", input.Provider)
.SetState("model", input.Model)
.SetState("temperature", input.Temperature)
.SetState("sampling_factor", input.SamplingFactor);

var result = await conv.SendMessage(input.AgentId,
var result = await conv.SendMessage(input.AgentId,
message,
async msg =>
await OnChunkReceived(outputStream, msg),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Conversations.Models;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -9,7 +10,7 @@ public class OpenAiMessageInput : IncomingMessageModel
{
public string AgentId { get; set; } = string.Empty;
public string ConversationId { get; set; } = string.Empty;
public override string Channel { get; set; } = "webchat";
public override string Channel { get; set; } = ConversationChannel.WebChat;

public List<OpenAiMessageBody> Messages { get; set; } = new List<OpenAiMessageBody>();

Expand Down
Loading