diff --git a/docs/channels/components.md b/docs/channels/components.md
index 3754a1c3..89ab8cb4 100644
--- a/docs/channels/components.md
+++ b/docs/channels/components.md
@@ -1,6 +1,6 @@
# Messaging Components
-Conversations are a lot more than simple text messages when you are building a AI chatbot. In addition to text, the `BotSharp`` allows you to send rich-media, like audio, video, and images, and provides a set of structured messaging options in the form of message templates, quick replies, buttons and more. The UI rendering program can render components according to the returned data format.
+Conversations are a lot more than simple text messages when you are building a AI chatbot. In addition to text, the `BotSharp` allows you to send rich-media, like audio, video, and images, and provides a set of structured messaging options in the form of message templates, quick replies, buttons and more. The UI rendering program can render components according to the returned data format.
## Text Messages
@@ -75,7 +75,7 @@ Message templates are structured message formats used for various purposes to pr
...
}
]
- }
+ }
}
}
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs
index 98381559..903e5d0b 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs
@@ -1,36 +1,9 @@
+using BotSharp.Abstraction.Models;
+
namespace BotSharp.Abstraction.Conversations.Models;
-public class IncomingMessageModel
+public class IncomingMessageModel : MessageConfig
{
public string Text { get; set; } = string.Empty;
-
- public virtual string Channel { get; set; } = string.Empty;
-
- ///
- /// Completion Provider
- ///
- [JsonPropertyName("provider")]
- public virtual string? Provider { get; set; } = null;
-
- ///
- /// Model name
- ///
- [JsonPropertyName("model")]
- public virtual string? Model { get; set; } = null;
-
- ///
- /// The sampling temperature to use that controls the apparent creativity of generated completions.
- ///
- public float Temperature { get; set; } = 0.5f;
-
- ///
- /// An alternative value to Temperature, called nucleus sampling, that causes
- /// the model to consider the results of the tokens with probability mass.
- ///
- public float SamplingFactor { get; set; } = 0.5f;
-
- ///
- /// Conversation states from input
- ///
- public List States { get; set; } = new List();
+ public virtual string Channel { get; set; }
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
index fcfada99..0aa0cd04 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs
@@ -1,7 +1,12 @@
+using BotSharp.Abstraction.Functions.Models;
+using BotSharp.Abstraction.Models;
+
namespace BotSharp.Abstraction.Conversations.Models;
-public class RoleDialogModel
+public class RoleDialogModel : ITrackableMessage
{
+ public string MessageId { get; set; }
+
///
/// user, system, assistant, function
///
@@ -36,10 +41,17 @@ public class RoleDialogModel
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public bool StopCompletion { get; set; }
+ public FunctionCallFromLlm Instruction { get; set; }
+
+ private RoleDialogModel()
+ {
+ }
+
public RoleDialogModel(string role, string text)
{
Role = role;
Content = text;
+ MessageId = Guid.NewGuid().ToString();
}
public override string ToString()
diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs
index 153fb473..d89620a9 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs
@@ -4,6 +4,7 @@ public class FunctionDef
{
public string Name { get; set; }
public string Description { get; set; }
+ public string? Impact { get; set; }
public FunctionParametersDef Parameters { get; set; } = new FunctionParametersDef();
public override string ToString()
diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs
index 10635152..67bd2039 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs
@@ -1,7 +1,10 @@
+using BotSharp.Abstraction.Models;
+
namespace BotSharp.Abstraction.Instructs.Models;
-public class InstructResult
+public class InstructResult : ITrackableMessage
{
+ public string MessageId { get; set; }
public string Text { get; set; }
public object Data { get; set; }
public ConversationState States { get; set; }
diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/ITrackableMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Models/ITrackableMessage.cs
new file mode 100644
index 00000000..5756cfd6
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Models/ITrackableMessage.cs
@@ -0,0 +1,9 @@
+namespace BotSharp.Abstraction.Models;
+
+///
+/// Define a message ID to extend message-level applications, such as model fees, token usage, and data collection
+///
+public interface ITrackableMessage
+{
+ string MessageId { get; set; }
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/MessageConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Models/MessageConfig.cs
new file mode 100644
index 00000000..95d72492
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Models/MessageConfig.cs
@@ -0,0 +1,32 @@
+namespace BotSharp.Abstraction.Models;
+
+public class MessageConfig
+{
+ ///
+ /// Completion Provider
+ ///
+ [JsonPropertyName("provider")]
+ public virtual string? Provider { get; set; } = null;
+
+ ///
+ /// Model name
+ ///
+ [JsonPropertyName("model")]
+ public virtual string? Model { get; set; } = null;
+
+ ///
+ /// The sampling temperature to use that controls the apparent creativity of generated completions.
+ ///
+ public float Temperature { get; set; } = 0.5f;
+
+ ///
+ /// An alternative value to Temperature, called nucleus sampling, that causes
+ /// the model to consider the results of the tokens with probability mass.
+ ///
+ public float SamplingFactor { get; set; } = 0.5f;
+
+ ///
+ /// Conversation states from input
+ ///
+ public List States { get; set; } = new List();
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs
index d86c6298..6c8ae94e 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs
@@ -1,5 +1,4 @@
using BotSharp.Abstraction.Functions.Models;
-using BotSharp.Abstraction.Models;
namespace BotSharp.Abstraction.Routing;
@@ -19,5 +18,5 @@ public interface IRoutingHandler
void SetDialogs(List dialogs) { }
- Task Handle(IRoutingService routing, FunctionCallFromLlm inst);
+ Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
index 802f8f73..47744957 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
@@ -8,7 +8,7 @@ public interface IRoutingService
void ResetRecursiveCounter();
void RefreshDialogs();
Task GetNextInstruction();
- Task InvokeAgent(string agentId);
- Task InstructLoop();
- Task ExecuteOnce(Agent agent);
+ Task InvokeAgent(string agentId, RoleDialogModel message);
+ Task InstructLoop(RoleDialogModel message);
+ Task ExecuteOnce(Agent agent, RoleDialogModel message);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs
index 49b38274..b24c7941 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs
@@ -18,8 +18,11 @@ public class RoutingContext
///
public string IntentName { get; set; }
+ ///
+ /// Agent that can handl user original goal.
+ ///
public string OriginAgentId
- => _stack.Last();
+ => _stack.Where(x => x != _setting.RouterId).Last();
public string GetCurrentAgentId()
{
diff --git a/src/Infrastructure/BotSharp.Abstraction/Using.cs b/src/Infrastructure/BotSharp.Abstraction/Using.cs
index 87d42791..39ececfe 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Using.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Using.cs
@@ -7,4 +7,5 @@ global using System.ComponentModel.DataAnnotations;
global using System.Text.Json.Serialization;
global using BotSharp.Abstraction.Agents.Models;
global using BotSharp.Abstraction.Conversations.Models;
-global using BotSharp.Abstraction.Agents.Enums;
\ No newline at end of file
+global using BotSharp.Abstraction.Agents.Enums;
+global using BotSharp.Abstraction.Models;
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Abstraction/Utilities/StringExtensions.cs b/src/Infrastructure/BotSharp.Abstraction/Utilities/StringExtensions.cs
index d62b9ec0..17232920 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Utilities/StringExtensions.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Utilities/StringExtensions.cs
@@ -1,3 +1,4 @@
+using System.Text.Json;
using System.Text.RegularExpressions;
namespace BotSharp.Abstraction.Utilities;
@@ -27,4 +28,16 @@ public static class StringExtensions
{
return str1.Equals(str2, option);
}
+
+ public static string JsonContent(this string text)
+ {
+ var m = Regex.Match(text, @"\{(?:[^{}]|(?\{)|(?<-open>\}))+(?(open)(?!))\}");
+ return m.Success ? m.Value : "{}";
+ }
+
+ public static T? JsonContent(this string text)
+ {
+ text = JsonContent(text);
+ return JsonSerializer.Deserialize(text);
+ }
}
diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs
index 6b749b3b..5912b1e0 100644
--- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs
+++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs
@@ -4,18 +4,14 @@ namespace BotSharp.Core.Agents.Services;
public partial class AgentService
{
-#if !DEBUG
- [MemoryCache(10 * 60)]
-#endif
+ [MemoryCache(10 * 60, PerInstanceCache = true)]
public async Task> GetAgents(bool? allowRouting = null)
{
var agents = _db.GetAgents(allowRouting: allowRouting);
return await Task.FromResult(agents);
}
-#if !DEBUG
- [MemoryCache(10 * 60)]
-#endif
+ [MemoryCache(10 * 60, PerInstanceCache = true)]
public async Task GetAgent(string id)
{
var profile = _db.GetAgent(id);
diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
index e80b5b1e..387a18e7 100644
--- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
+++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
@@ -8,7 +8,7 @@ namespace BotSharp.Core.Conversations.Services;
public partial class ConversationService
{
public async Task SendMessage(string agentId,
- RoleDialogModel incoming,
+ RoleDialogModel message,
Func onMessageReceived,
Func onFunctionExecuting,
Func onFunctionExecuted)
@@ -18,16 +18,16 @@ public partial class ConversationService
var agentService = _services.GetRequiredService();
Agent agent = await agentService.LoadAgent(agentId);
- var message = $"Received [{agent.Name}] {incoming.Role}: {incoming.Content}";
+ var content = $"Received [{agent.Name}] {message.Role}: {message.Content}";
#if DEBUG
- Console.WriteLine(message, Color.OrangeRed);
+ Console.WriteLine(content, Color.OrangeRed);
#else
- _logger.LogInformation(message);
+ _logger.LogInformation(content);
#endif
- incoming.CurrentAgentId = agent.Id;
+ message.CurrentAgentId = agent.Id;
- _storage.Append(_conversationId, incoming);
+ _storage.Append(_conversationId, message);
var hooks = _services.GetServices().ToList();
@@ -37,13 +37,13 @@ public partial class ConversationService
hook.SetAgent(agent)
.SetConversation(conversation);
- await hook.OnMessageReceived(incoming);
+ await hook.OnMessageReceived(message);
// Interrupted by hook
- if (incoming.StopCompletion)
+ if (message.StopCompletion)
{
- await onMessageReceived(incoming);
- _storage.Append(_conversationId, incoming);
+ await onMessageReceived(message);
+ _storage.Append(_conversationId, message);
return true;
}
}
@@ -52,11 +52,11 @@ public partial class ConversationService
var routing = _services.GetRequiredService();
var settings = _services.GetRequiredService();
- var response = agentId == settings.RouterId ?
- await routing.InstructLoop() :
- await routing.ExecuteOnce(agent);
+ var ret = agentId == settings.RouterId ?
+ await routing.InstructLoop(message) :
+ await routing.ExecuteOnce(agent, message);
- await HandleAssistantMessage(response, onMessageReceived);
+ await HandleAssistantMessage(message, onMessageReceived);
var statistics = _services.GetRequiredService();
statistics.PrintStatistics();
@@ -64,7 +64,7 @@ public partial class ConversationService
routing.ResetRecursiveCounter();
routing.RefreshDialogs();
- return true;
+ return ret;
}
private async Task GetConversationRecord(string agentId)
diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs
index 8f3a865e..db6fc90a 100644
--- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs
+++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs
@@ -54,8 +54,6 @@ public partial class ConversationService : IConversationService
public async Task NewConversation(Conversation sess)
{
var db = _services.GetRequiredService();
- var dbSettings = _services.GetRequiredService();
- var conversationSettings = _services.GetRequiredService();
var user = db.GetUserByExternalId(_user.Id);
var foundUserId = user?.Id ?? string.Empty;
@@ -80,11 +78,11 @@ public partial class ConversationService : IConversationService
throw new NotImplementedException();
}
- public List GetDialogHistory(int lastCount = 20)
+ public List GetDialogHistory(int lastCount = 50)
{
var dialogs = _storage.GetDialogs(_conversationId);
return dialogs
- .Where(x => x.CreatedAt > DateTime.UtcNow.AddHours(-8))
+ .Where(x => x.CreatedAt > DateTime.UtcNow.AddHours(-24))
.TakeLast(lastCount)
.ToList();
}
diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs
index 2d8af0ad..3d8b3085 100644
--- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs
+++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs
@@ -6,19 +6,13 @@ namespace BotSharp.Core.Conversations.Services;
public class ConversationStorage : IConversationStorage
{
private readonly BotSharpDatabaseSettings _dbSettings;
- private readonly AgentSettings _agentSettings;
private readonly IServiceProvider _services;
- private readonly IUserIdentity _user;
public ConversationStorage(
BotSharpDatabaseSettings dbSettings,
- AgentSettings agentSettings,
- IServiceProvider services,
- IUserIdentity user)
+ IServiceProvider services)
{
_dbSettings = dbSettings;
- _agentSettings = agentSettings;
_services = services;
- _user = user;
}
public void Append(string conversationId, RoleDialogModel dialog)
@@ -32,7 +26,7 @@ public class ConversationStorage : IConversationStorage
{
var args = dialog.FunctionArgs.Replace("\r", " ").Replace("\n", " ").Trim();
- sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{dialog.FunctionName}|{args}");
+ sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{dialog.MessageId}");
var content = dialog.Content;
content = content.Replace("\r", " ").Replace("\n", " ").Trim();
@@ -44,9 +38,7 @@ public class ConversationStorage : IConversationStorage
}
else
{
- var agentName = db.GetAgent(agentId)?.Name;
-
- sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{agentName}|");
+ sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{dialog.MessageId}");
var content = dialog.Content.Replace("\r", " ").Replace("\n", " ").Trim();
if (string.IsNullOrEmpty(content))
{
@@ -73,15 +65,13 @@ public class ConversationStorage : IConversationStorage
var createdAt = DateTime.Parse(meta.Split('|')[0]);
var role = meta.Split('|')[1];
var currentAgentId = meta.Split('|')[2];
- var funcName = meta.Split('|')[3];
- var funcArgs= meta.Split('|')[4];
+ var messageId = meta.Split('|')[3];
var text = dialog.Substring(4);
results.Add(new RoleDialogModel(role, text)
{
CurrentAgentId = currentAgentId,
- FunctionName = funcName,
- FunctionArgs = funcArgs,
+ MessageId = messageId,
Content = text,
CreatedAt = createdAt
});
diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs b/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs
index bb328753..8ee49eac 100644
--- a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs
+++ b/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs
@@ -33,6 +33,7 @@ public partial class InstructService : IInstructService
{
return new InstructResult
{
+ MessageId = message.MessageId,
Text = message.Content
};
}
@@ -42,6 +43,7 @@ public partial class InstructService : IInstructService
var result = await completer.GetCompletion(agent.Instruction);
var response = new InstructResult
{
+ MessageId = message.MessageId,
Text = result
};
diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs
index 4d862e7a..8aed5989 100644
--- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs
+++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs
@@ -5,7 +5,6 @@ using BotSharp.Abstraction.Users.Models;
using BotSharp.Abstraction.Agents.Models;
using MongoDB.Driver;
using BotSharp.Abstraction.Routing.Models;
-using Amazon.Util;
namespace BotSharp.Core.Repository;
@@ -373,13 +372,7 @@ public class FileRepository : IBotSharpRepository
var functionFile = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir,
agentId, "functions.json");
- var functions = new List();
- foreach (var function in inputFunctions)
- {
- functions.Add(JsonSerializer.Serialize(function, _options));
- }
-
- var functionText = JsonSerializer.Serialize(functions, _options);
+ var functionText = JsonSerializer.Serialize(inputFunctions, _options);
File.WriteAllText(functionFile, functionText);
}
@@ -493,9 +486,6 @@ public class FileRepository : IBotSharpRepository
return responses;
}
-#if !DEBUG
- [MemoryCache(10 * 60)]
-#endif
public Agent? GetAgent(string agentId)
{
var agentDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir);
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs
index dcfe47e4..fd916b12 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs
@@ -66,14 +66,11 @@ public class RouteToAgentFn : IFunctionCallback
else
{
message.CurrentAgentId = targetAgent.Id;
- message.Content = $"Routing to {args.AgentName}";
}
}
_context.Push(message.CurrentAgentId);
- // Set default execution data
- message.Data = JsonSerializer.Deserialize(message.FunctionArgs);
return true;
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs
index 984651f0..1c809ef4 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs
@@ -26,18 +26,15 @@ public class ContinueExecuteTaskRoutingHandler : RoutingHandlerBase, IRoutingHan
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
var db = _services.GetRequiredService();
var record = db.GetAgents(inst.AgentName).FirstOrDefault();
- var result = new RoleDialogModel(AgentRole.Function, inst.Question)
- {
- FunctionName = inst.Function,
- FunctionArgs = JsonSerializer.Serialize(inst.Arguments),
- CurrentAgentId = record.Id
- };
+ message.FunctionName = inst.Function;
+ message.CurrentAgentId = record.Id;
+ message.FunctionArgs = JsonSerializer.Serialize(inst.Arguments);
- return result;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ConversationEndRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ConversationEndRoutingHandler.cs
index 44563f42..97eafa46 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ConversationEndRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ConversationEndRoutingHandler.cs
@@ -24,14 +24,11 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
- {
- CurrentAgentId = _settings.RouterId,
- FunctionName = inst.Function,
- Data = inst
- };
+ message.Content = inst.Response;
+ message.FunctionName = inst.Function;
var hooks = _services.GetServices()
.OrderBy(x => x.Priority)
@@ -39,9 +36,9 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
foreach (var hook in hooks)
{
- await hook.OnConversationEnding(result);
+ await hook.OnConversationEnding(message);
}
- return result;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/HumanInterventionNeededHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/HumanInterventionNeededHandler.cs
index 3df04f69..671dc644 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/HumanInterventionNeededHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/HumanInterventionNeededHandler.cs
@@ -9,30 +9,24 @@ public class HumanInterventionNeededHandler : RoutingHandlerBase, IRoutingHandle
{
public string Name => "human_intervention_needed";
- public string Description => "Reach out to a real human or customer representative.";
-
- private readonly RoutingSettings _settings;
+ public string Description => "Reach out to human being, customer service or customer representative.";
public List Parameters => new List
{
- new NameDesc("reason", "why need customer service representative (human being)"),
+ new NameDesc("reason", "why need customer service"),
new NameDesc("response", "response content to user")
};
public HumanInterventionNeededHandler(IServiceProvider services, ILogger logger, RoutingSettings settings)
: base(services, logger, settings)
{
- _settings = settings;
+
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
- {
- CurrentAgentId = _settings.RouterId,
- FunctionName = inst.Function,
- Data = inst
- };
+ message.Role = AgentRole.Assistant;
+ message.Content = inst.Response;
var hooks = _services.GetServices()
.OrderBy(x => x.Priority)
@@ -40,9 +34,9 @@ public class HumanInterventionNeededHandler : RoutingHandlerBase, IRoutingHandle
foreach (var hook in hooks)
{
- await hook.OnHumanInterventionNeeded(result);
+ await hook.OnHumanInterventionNeeded(message);
}
- return result;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs
index 096f9d61..76d18be3 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs
@@ -24,14 +24,11 @@ public class InterruptTaskExecutionRoutingHandler : RoutingHandlerBase, IRouting
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var result = new RoleDialogModel(AgentRole.User, inst.Reason)
- {
- FunctionName = inst.Function,
- StopCompletion = true
- };
+ message.FunctionName = inst.Function;
+ message.StopCompletion = true;
- return result;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ResponseToUserRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ResponseToUserRoutingHandler.cs
index ec1c5bcf..cb480e56 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ResponseToUserRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ResponseToUserRoutingHandler.cs
@@ -24,15 +24,11 @@ public class ResponseToUserRoutingHandler : RoutingHandlerBase, IRoutingHandler
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
- {
- CurrentAgentId = _settings.RouterId,
- FunctionName = inst.Function,
- Data = inst,
- StopCompletion = true
- };
- return result;
+ message.Content = inst.Response;
+ message.StopCompletion = true;
+ message.Role = AgentRole.Assistant;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
index d4492d2b..3b30c19d 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
@@ -27,14 +27,12 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
// Retrieve information from specific agent
var db = _services.GetRequiredService();
var record = db.GetAgents(inst.AgentName).FirstOrDefault();
- var response = await routing.InvokeAgent(record.Id);
-
- inst.Response = response.Content;
+ var ret = await routing.InvokeAgent(record.Id, message);
/*_dialogs.Add(new RoleDialogModel(AgentRole.Assistant, inst.Parameters.Question)
{
@@ -45,6 +43,7 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
/*_dialogs.Add(new RoleDialogModel(AgentRole.Function, inst.Parameters.Answer)
{
+ MessageId = inst.MessageId,
FunctionName = inst.Function,
FunctionArgs = JsonSerializer.Serialize(inst.Parameters.Arguments),
ExecutionResult = inst.Parameters.Answer,
@@ -52,11 +51,11 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
CurrentAgentId = record.Id
});*/
- _router.Instruction += $"\r\n{AgentRole.Function}: {response.Content}";
+ _router.Instruction += $"\r\n{AgentRole.Function}: {message.Content}";
// Got the response from agent, then send to reasoner again to make the decision
// inst = await GetNextInstructionFromReasoner($"What's the next step based on user's original goal and function result?");
- return null;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
index d4fba5ff..daa4e734 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
@@ -28,24 +28,15 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
var context = _services.GetRequiredService();
-
var function = _services.GetServices().FirstOrDefault(x => x.Name == inst.Function);
- var message = new RoleDialogModel(AgentRole.Function, inst.Question)
- {
- FunctionName = inst.Function,
- FunctionArgs = JsonSerializer.Serialize(inst),
- CurrentAgentId = context.GetCurrentAgentId(),
- };
-
+ message.FunctionArgs = JsonSerializer.Serialize(inst);
var ret = await function.Execute(message);
- var result = await routing.InvokeAgent(context.GetCurrentAgentId());
- // Keep last message data for debug
- result.Data = result.Data ?? message.Data;
- result.FunctionName = result.FunctionName ?? message.FunctionName;
- return result;
+ ret = await routing.InvokeAgent(context.GetCurrentAgentId(), message);
+
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/TaskEndRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/TaskEndRoutingHandler.cs
index 9190bba5..edb2cfc9 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/TaskEndRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/TaskEndRoutingHandler.cs
@@ -23,24 +23,17 @@ public class TaskEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
{
}
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst)
+ public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
- {
- CurrentAgentId = _settings.RouterId,
- FunctionName = inst.Function,
- Data = inst
- };
-
var hooks = _services.GetServices()
.OrderBy(x => x.Priority)
.ToList();
foreach (var hook in hooks)
{
- await hook.OnCurrentTaskEnding(result);
+ await hook.OnCurrentTaskEnding(message);
}
- return result;
+ return true;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs
index c08230ad..e217dd89 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs
@@ -56,15 +56,25 @@ public partial class RoutingService
model: _settings.Model);
int retryCount = 0;
+ var agentService = _services.GetRequiredService();
+ var dialogs = Dialogs;
while (retryCount < 3)
{
try
{
var conversation = "";
- foreach (var dialog in _dialogs.TakeLast(20))
+
+ foreach (var dialog in dialogs.TakeLast(50))
{
- conversation += $"{dialog.Role}: {dialog.Content}\r\n";
+ var role = dialog.Role;
+ if (role != AgentRole.User)
+ {
+ var agent = await agentService.GetAgent(dialog.CurrentAgentId);
+ role = agent.Name;
+ }
+
+ conversation += $"{role}: {dialog.Content}\r\n";
}
content = $"{conversation}\r\n###\r\n{content}";
@@ -73,9 +83,7 @@ public partial class RoutingService
new RoleDialogModel(AgentRole.User, content)
});
- var pattern = @"\{(?:[^{}]|(?\{)|(?<-open>\}))+(?(open)(?!))\}";
- response.Content = Regex.Match(response.Content, pattern).Value;
- args = JsonSerializer.Deserialize(response.Content);
+ args = response.Content.JsonContent();
break;
}
catch (Exception ex)
@@ -113,9 +121,6 @@ public partial class RoutingService
return args;
}
-#if !DEBUG
- [MemoryCache(10 * 60)]
-#endif
private string GetNextStepPrompt()
{
var template = _routerInstance.Router.Templates.First(x => x.Name == "next_step_prompt").Content;
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
index 8147f437..f19bee3f 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
@@ -8,13 +8,13 @@ public partial class RoutingService
{
const int MAXIMUM_RECURSION_DEPTH = 3;
private int _currentRecursionDepth = 0;
- public async Task InvokeAgent(string agentId)
+ public async Task InvokeAgent(string agentId, RoleDialogModel message)
{
_currentRecursionDepth++;
if (_currentRecursionDepth > MAXIMUM_RECURSION_DEPTH)
{
_logger.LogWarning($"Current recursive call depth greater than {MAXIMUM_RECURSION_DEPTH}, which will cause unexpected result.");
- return Dialogs.Last();
+ return false;
}
var agentService = _services.GetRequiredService();
@@ -23,50 +23,56 @@ public partial class RoutingService
var settings = _services.GetRequiredService();
var chatCompletion = CompletionProvider.GetChatCompletion(_services, provider: settings.Provider, model: settings.Model);
RoleDialogModel response = chatCompletion.GetChatCompletions(agent, Dialogs);
+ message.Role = response.Role;
if (response.Role == AgentRole.Function)
{
- return await InvokeFunction(agent, response);
+ message.FunctionName = response.FunctionName;
+ message.FunctionArgs = response.FunctionArgs;
+
+ await InvokeFunction(agent, message);
}
else
{
- return response;
+ message.Content = response.Content;
}
+
+ return true;
}
- private async Task InvokeFunction(Agent agent, RoleDialogModel response)
+ private async Task InvokeFunction(Agent agent, RoleDialogModel message)
{
// execute function
// Save states
- SaveStateByArgs(JsonSerializer.Deserialize(response.FunctionArgs));
+ SaveStateByArgs(JsonSerializer.Deserialize(message.FunctionArgs));
var conversationService = _services.GetRequiredService();
// Call functions
- await conversationService.CallFunctions(response);
+ await conversationService.CallFunctions(message);
- Dialogs.Add(response);
+ Dialogs.Add(message);
// Pass execution result to LLM to get response
- if (!response.StopCompletion)
+ if (!message.StopCompletion)
{
// Find response template
var templateService = _services.GetRequiredService();
- var responseTemplate = await templateService.RenderFunctionResponse(agent.Id, response);
+ var responseTemplate = await templateService.RenderFunctionResponse(agent.Id, message);
if (!string.IsNullOrEmpty(responseTemplate))
{
- response.Role = AgentRole.Assistant;
- response.Content = responseTemplate.Trim();
+ message.Role = AgentRole.Assistant;
+ message.Content = responseTemplate.Trim();
}
else
{
- response = await InvokeAgent(response.CurrentAgentId);
+ await InvokeAgent(message.CurrentAgentId, message);
}
}
else
{
- response.Role = AgentRole.Assistant;
+ message.Role = AgentRole.Assistant;
}
- return response;
+ return message;
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
index 9159434d..b7073f04 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
@@ -46,38 +46,29 @@ public partial class RoutingService : IRoutingService
_routerInstance = routerInstance;
}
-
- public async Task ExecuteOnce(Agent agent)
+ public async Task ExecuteOnce(Agent agent, RoleDialogModel message)
{
- var message = Dialogs.Last().Content;
-
var handlers = _services.GetServices();
var handler = handlers.FirstOrDefault(x => x.Name == "route_to_agent");
handler.SetDialogs(Dialogs);
+
var result = await handler.Handle(this, new FunctionCallFromLlm
{
Function = "route_to_agent",
- Question = message,
- Reason = message,
+ Question = message.Content,
+ Reason = message.Content,
AgentName = agent.Name
- });
+ }, message);
return result;
}
- public async Task InstructLoop()
+ public async Task InstructLoop(RoleDialogModel message)
{
_routerInstance.Load();
var router = _routerInstance.Router;
- var result = new RoleDialogModel(AgentRole.Assistant, "Can you repeat your request again?")
- {
- CurrentAgentId = router.Id
- };
-
- var message = Dialogs.Last().Content;
-
var handlers = _services.GetServices();
int loopCount = 0;
@@ -87,7 +78,8 @@ public partial class RoutingService : IRoutingService
loopCount++;
var inst = await GetNextInstruction();
- inst.Question = inst.Question ?? message;
+ message.Instruction = inst;
+ inst.Question = message.Content;
var handler = handlers.FirstOrDefault(x => x.Name == inst.Function);
if (handler == null)
@@ -98,12 +90,18 @@ public partial class RoutingService : IRoutingService
handler.SetRouter(router);
handler.SetDialogs(Dialogs);
- result = await handler.Handle(this, inst);
+ message.FunctionName = inst.Function;
+ message.Role = AgentRole.Function;
+ message.FunctionArgs = inst.Arguments == null ? "{}" : JsonSerializer.Serialize(inst.Arguments);
+
+ await handler.Handle(this, inst, message);
+
+ inst.Response = message.Content;
stop = !_settings.EnableReasoning;
}
- return result;
+ return true;
}
protected void SaveStateByArgs(JsonDocument args)
diff --git a/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs b/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs
index cb536e0e..6bde9ce6 100644
--- a/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs
+++ b/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs
@@ -35,6 +35,10 @@ public class ResponseTemplateService : IResponseTemplateService
// Convert args and execute data to dictionary
var dict = new Dictionary();
+ // Populate states
+ var state = _services.GetRequiredService();
+ state.GetStates().Select(x => dict[x.Key] = x.Value).ToList();
+
if (message.FunctionArgs != null)
{
ExtractArgs(JsonSerializer.Deserialize(message.FunctionArgs), dict);
diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
index fb73fdf6..5fb5cd7c 100644
--- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
+++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs
@@ -1,5 +1,6 @@
using BotSharp.Abstraction.ApiAdapters;
using BotSharp.Abstraction.Conversations.Models;
+using BotSharp.Abstraction.Models;
using BotSharp.OpenAPI.ViewModels.Conversations;
namespace BotSharp.OpenAPI.Controllers;
@@ -19,15 +20,17 @@ public class ConversationController : ControllerBase, IApiAdapter
}
[HttpPost("/conversation/{agentId}")]
- public async Task NewConversation([FromRoute] string agentId)
+ public async Task NewConversation([FromRoute] string agentId, [FromBody] MessageConfig config)
{
var service = _services.GetRequiredService();
- var sess = new Conversation
+ var conv = new Conversation
{
AgentId = agentId
};
- sess = await service.NewConversation(sess);
- return ConversationViewModel.FromSession(sess);
+ conv = await service.NewConversation(conv);
+ config.States.ForEach(x => conv.States[x.Split('=')[0]] = x.Split('=')[1]);
+
+ return ConversationViewModel.FromSession(conv);
}
[HttpDelete("/conversation/{agentId}/{conversationId}")]
@@ -50,13 +53,11 @@ public class ConversationController : ControllerBase, IApiAdapter
.SetState("sampling_factor", input.SamplingFactor);
var response = new MessageResponseModel();
- var stackMsg = new List();
-
- await conv.SendMessage(agentId,
- new RoleDialogModel("user", input.Text),
+ var inputMsg = new RoleDialogModel("user", input.Text);
+ await conv.SendMessage(agentId, inputMsg,
async msg =>
{
- stackMsg.Add(msg);
+
},
async fnExecuting =>
{
@@ -64,15 +65,14 @@ public class ConversationController : ControllerBase, IApiAdapter
},
async fnExecuted =>
{
- response.Function = fnExecuted.FunctionName;
- response.Data = fnExecuted.Data;
- response.RichContent = fnExecuted.RichContent;
+
});
- response.Text = string.Join("\r\n", stackMsg.Select(x => x.Content));
- response.Data = response.Data ?? stackMsg.Last().Data;
- response.Function = stackMsg.Last().FunctionName;
- response.RichContent = response.RichContent ?? stackMsg.Last().RichContent;
+ response.MessageId = inputMsg.MessageId;
+ response.Text = inputMsg.Content;
+ response.Data = inputMsg.Data;
+ response.Function = inputMsg.FunctionName;
+ response.Instruction = inputMsg.Instruction;
return response;
}
diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs
index f5045ed1..4dcf0c58 100644
--- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs
+++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/MessageResponseModel.cs
@@ -1,9 +1,14 @@
+using BotSharp.Abstraction.Functions.Models;
+using BotSharp.Abstraction.Models;
+using BotSharp.Abstraction.Routing.Models;
+
namespace BotSharp.OpenAPI.ViewModels.Conversations;
-public class MessageResponseModel
+public class MessageResponseModel : ITrackableMessage
{
+ public string MessageId { get; set; }
public string Text { get; set; }
public string Function { get; set; }
public object Data { get; set; }
- public object? RichContent { get; set; }
+ public FunctionCallFromLlm Instruction { get; set; }
}
diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs
index ee556549..26ddebbc 100644
--- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs
+++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentResponseMongoElement.cs
@@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Models;
namespace BotSharp.Plugin.MongoStorage.Models;
+[BsonIgnoreExtraElements]
public class AgentResponseMongoElement
{
public string Prefix { get; set; }
diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs
index 719a11d9..847ec5c9 100644
--- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs
+++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs
@@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Models;
namespace BotSharp.Plugin.MongoStorage.Models;
+[BsonIgnoreExtraElements]
public class AgentTemplateMongoElement
{
public string Name { get; set; }
diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs
index ec9699c0..5910661f 100644
--- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs
+++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/FunctionDefMongoElement.cs
@@ -3,10 +3,12 @@ using System.Text.Json;
namespace BotSharp.Plugin.MongoStorage.Models;
+[BsonIgnoreExtraElements]
public class FunctionDefMongoElement
{
public string Name { get; set; }
public string Description { get; set; }
+ public string? Impact { get; set; }
public FunctionParametersDefMongoElement Parameters { get; set; } = new FunctionParametersDefMongoElement();
public FunctionDefMongoElement()
@@ -20,6 +22,7 @@ public class FunctionDefMongoElement
{
Name = function.Name,
Description = function.Description,
+ Impact = function.Impact,
Parameters = new FunctionParametersDefMongoElement
{
Type = function.Parameters.Type,
@@ -35,6 +38,7 @@ public class FunctionDefMongoElement
{
Name = mongoFunction.Name,
Description = mongoFunction.Description,
+ Impact = mongoFunction.Impact,
Parameters = new FunctionParametersDef
{
Type = mongoFunction.Parameters.Type,
diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/RoutingRuleMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/RoutingRuleMongoElement.cs
index 9f644c68..1a40b0f7 100644
--- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/RoutingRuleMongoElement.cs
+++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/RoutingRuleMongoElement.cs
@@ -2,6 +2,7 @@ using BotSharp.Abstraction.Routing.Models;
namespace BotSharp.Plugin.MongoStorage.Models;
+[BsonIgnoreExtraElements]
public class RoutingRuleMongoElement
{
public string Field { get; set; }
diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs
index 5debd75f..ca13f204 100644
--- a/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs
+++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Using.cs
@@ -10,4 +10,5 @@ global using BotSharp.Abstraction.Plugins;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using MongoDB.Bson;
-global using MongoDB.Driver;
\ No newline at end of file
+global using MongoDB.Driver;
+global using MongoDB.Bson.Serialization.Attributes;
\ No newline at end of file
diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj
index b05729a7..6723a4da 100644
--- a/src/WebStarter/WebStarter.csproj
+++ b/src/WebStarter/WebStarter.csproj
@@ -5,6 +5,7 @@
enable
enable
4fb8c9df-7975-4926-ba73-46c8ca440691
+ False
diff --git a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instruction.liquid b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instruction.liquid
index 1543518d..67cd6d1a 100644
--- a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instruction.liquid
+++ b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instruction.liquid
@@ -2,8 +2,8 @@ You're {{router.name}} ({{router.description}}). Follow these steps to handle us
1. Read the [CONVERSATION] content.
2. Select a appropriate function from [FUNCTIONS].
3. Determine which agent is suitable to handle this conversation.
-4. Re-think about the selected function or agent is the best choice.
-5. For agent required arguments, leave it blank if user doesn't provide it.
+4. Re-think on whether the function you chose matches the reason.
+5. For agent required arguments, leave it as blank object if user doesn't provide it.
[FUNCTIONS]
{% for handler in routing_handlers %}
diff --git a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.liquid b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.liquid
index 24132c96..12de3ffd 100644
--- a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.liquid
+++ b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.liquid
@@ -1 +1,4 @@
-What is the next step based on the CONVERSATION? Response must be in appropriate JSON format.
\ No newline at end of file
+What is the next step based on the CONVERSATION?
+Response must be in appropriate JSON format.
+Route to the Agent that last handled the conversation if necessary.
+If user wants to speak to customer service, use function human_intervention_needed.
\ No newline at end of file
diff --git a/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs b/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs
index 9e39a155..4fa39c7c 100644
--- a/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs
+++ b/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs
@@ -1,4 +1,5 @@
using BotSharp.Abstraction.Conversations.Models;
+using System.Text.Json;
namespace BotSharp.Plugin.PizzaBot.Functions;
@@ -14,6 +15,7 @@ public class GetPizzaPricesFn : IFunctionCallback
cheese_unit_price = 3.5,
margherita_unit_price = 3.8,
};
+ message.Content = JsonSerializer.Serialize(message.Data);
return true;
}
}