Fix CurrentRecursionDepth bug in Testing mode.
This commit is contained in:
parent
8fcada182f
commit
13e17acc76
12
README.md
12
README.md
|
|
@ -19,9 +19,11 @@ It's written in C# running on .Net Core that is full cross-platform framework, t
|
|||
|
||||
### Some Features
|
||||
|
||||
* Built-in multi-agents and conversation management.
|
||||
* Support multiple LLM platforms.
|
||||
* Support export/ import agent from other bot platforms directly.
|
||||
* Built-in multi-agents and conversation with state management.
|
||||
* Built-in RAG related interfaces, Memeory based vector searching.
|
||||
* Support multiple LLM platforms (ChatGPT, PaLM 2, LLaMA 2).
|
||||
* Allow multiple agents with different responsibilities cooperate to complete complex tasks.
|
||||
* Build, test, evaluate and audit your LLM agent in one place.
|
||||
* Support different open source UI [Chatbot UI](src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md), [HuggingChat UI](src/Plugins/BotSharp.Plugin.HuggingFace/HuggingChat-UI.md).
|
||||
* Integrate with popular message channels like Facebook Messenger, Slack and Telegram.
|
||||
|
||||
|
|
@ -50,7 +52,3 @@ Read the docs: https://botsharp.readthedocs.io
|
|||
If you feel that this project is helpful to you, please Star the project, we would be very grateful.
|
||||
|
||||
Member project of [SciSharp STACK](https://github.com/SciSharp) which is the .NET based ecosystem of open-source software for mathematics, science, and engineering.
|
||||
|
||||
Scan QR code to join TIM group:
|
||||
|
||||

|
||||
|
|
|
|||
|
|
@ -1,37 +1,37 @@
|
|||
<mxfile host="Electron" modified="2023-09-05T01:59:06.699Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.8 Chrome/114.0.5735.289 Electron/25.5.0 Safari/537.36" etag="cm-9kpR-IQWk9TqhWNbL" version="21.6.8" type="device">
|
||||
<mxfile host="Electron" modified="2023-10-20T14:03:23.944Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.8 Chrome/114.0.5735.289 Electron/25.5.0 Safari/537.36" etag="Q2NG1mP47cvCG7Qq9r-D" version="21.6.8" type="device">
|
||||
<diagram name="Page-1" id="FNTbtRNAYl-cjTgH9x2x">
|
||||
<mxGraphModel dx="1434" dy="836" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<mxGraphModel dx="1418" dy="820" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="DrYO5MgT0EdguJCGkx49-1" target="DrYO5MgT0EdguJCGkx49-8">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DrYO5MgT0EdguJCGkx49-1" target="DrYO5MgT0EdguJCGkx49-8" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-1" value="<b><font style="font-size: 15px;">BotSharp</font></b>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-1" value="<b><font style="font-size: 15px;">BotSharp</font></b>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="345" y="460" width="180" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;fillColor=#e51400;strokeColor=#B20000;" edge="1" parent="1" source="DrYO5MgT0EdguJCGkx49-3" target="DrYO5MgT0EdguJCGkx49-1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;fillColor=#e51400;strokeColor=#B20000;" parent="1" source="DrYO5MgT0EdguJCGkx49-3" target="DrYO5MgT0EdguJCGkx49-1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-3" value="<b>User</b>" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-3" value="<b>User</b>" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="420" y="340" width="30" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-4" value="<div style="line-height: 18px;"><font color="#1e1e1e"><b>Can I have a slice of cheese pizza?</b></font><br></div>" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-4" value="<div style="line-height: 18px;"><font color="#1e1e1e"><b>Can I have a slice of cheese pizza?</b></font><br></div>" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="345" y="270" width="230" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="DrYO5MgT0EdguJCGkx49-8" target="DrYO5MgT0EdguJCGkx49-12">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DrYO5MgT0EdguJCGkx49-8" target="DrYO5MgT0EdguJCGkx49-12" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="DrYO5MgT0EdguJCGkx49-8" target="DrYO5MgT0EdguJCGkx49-14">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DrYO5MgT0EdguJCGkx49-8" target="DrYO5MgT0EdguJCGkx49-14" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="DrYO5MgT0EdguJCGkx49-8" target="DrYO5MgT0EdguJCGkx49-15">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DrYO5MgT0EdguJCGkx49-8" target="DrYO5MgT0EdguJCGkx49-15" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-8" value="<b><font style="font-size: 15px;">Router</font></b>" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_2;whiteSpace=wrap;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-8" value="<b><font style="font-size: 15px;">Router</font></b>" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_2;whiteSpace=wrap;fillColor=#ffcc99;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="385" y="570" width="100" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.3333333333333333;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#e51400;strokeColor=#B20000;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="DrYO5MgT0EdguJCGkx49-12" target="DrYO5MgT0EdguJCGkx49-3">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.3333333333333333;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#e51400;strokeColor=#B20000;sketch=1;curveFitting=1;jiggle=2;" parent="1" source="DrYO5MgT0EdguJCGkx49-12" target="DrYO5MgT0EdguJCGkx49-3" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="190" y="793" />
|
||||
|
|
@ -39,18 +39,18 @@
|
|||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-29" value="<b style="font-size: 11px;">How many slices would you like to order?</b>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=11;" vertex="1" connectable="0" parent="DrYO5MgT0EdguJCGkx49-28">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-29" value="<b style="font-size: 11px;">How many slices would you like to order?</b>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=11;" parent="DrYO5MgT0EdguJCGkx49-28" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.1958" relative="1" as="geometry">
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-12" value="<b><br><br>Ordering</b>" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-12" value="<b><br><br>Ordering</b>" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="740" width="60" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-14" value="<b><br><br>Baking<br></b>" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-14" value="<b><br><br>Order Inquiry<br></b>" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="405" y="740" width="60" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-15" value="<b><br><br>Payment<br></b>" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
|
||||
<mxCell id="DrYO5MgT0EdguJCGkx49-15" value="<b><br><br>Payment<br></b>" style="shape=actor;whiteSpace=wrap;html=1;fillColor=#ffff88;strokeColor=#36393d;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
|
||||
<mxGeometry x="570" y="740" width="60" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,18 @@
|
|||
using BotSharp.Abstraction.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Functions.Models;
|
||||
|
||||
public class ParameterPropertyDef
|
||||
public class ParameterPropertyDef : NameDesc
|
||||
{
|
||||
public ParameterPropertyDef(string name, string description, string type = "string")
|
||||
: base(name, description)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// string, number, object
|
||||
/// </summary>
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; } = "string";
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ public interface IRoutingHandler
|
|||
{
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
bool IsReasoning { get => false; }
|
||||
bool Enabled { get => true; }
|
||||
List<NameDesc> Parameters { get => new List<NameDesc>(); }
|
||||
bool IsReasoning => false;
|
||||
bool Enabled => true;
|
||||
List<NameDesc> Parameters => new List<NameDesc>();
|
||||
|
||||
void SetRouter(Agent router) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace BotSharp.Abstraction.Routing;
|
|||
public interface IRoutingService
|
||||
{
|
||||
List<RoleDialogModel> Dialogs { get; }
|
||||
void ResetRecursiveCounter();
|
||||
void RefreshDialogs();
|
||||
Task<FunctionCallFromLlm> GetNextInstruction();
|
||||
Task<RoleDialogModel> InvokeAgent(string agentId);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
using BotSharp.Abstraction.Routing.Settings;
|
||||
|
||||
namespace BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
public class RoutingContext
|
||||
{
|
||||
private readonly RoutingSettings _setting;
|
||||
public RoutingContext(RoutingSettings setting)
|
||||
{
|
||||
_setting = setting;
|
||||
}
|
||||
|
||||
private Stack<string> _stack { get; set; }
|
||||
= new Stack<string>();
|
||||
|
||||
|
|
@ -13,8 +21,14 @@ public class RoutingContext
|
|||
public string OriginAgentId
|
||||
=> _stack.Last();
|
||||
|
||||
public string CurrentAgentId
|
||||
=> _stack.Peek();
|
||||
public string GetCurrentAgentId()
|
||||
{
|
||||
if (_stack.Count == 0)
|
||||
{
|
||||
_stack.Push(_setting.RouterId);
|
||||
}
|
||||
return _stack.Peek();
|
||||
}
|
||||
|
||||
public void Push(string agentId)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
|
|
@ -14,5 +14,5 @@ public class RoutingItem
|
|||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("required_fields")]
|
||||
public List<NameDesc> RequiredFields { get; set; } = new List<NameDesc>();
|
||||
public List<ParameterPropertyDef> RequiredFields { get; set; } = new List<ParameterPropertyDef>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ public class RoutingRule
|
|||
|
||||
public string Field { get; set; }
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// Field type: string, number, object
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
public bool Required { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,12 @@ public partial class ConversationService
|
|||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
Agent agent = await agentService.LoadAgent(agentId);
|
||||
|
||||
_logger.LogInformation($"[{agent.Name}] {incoming.Role}: {incoming.Content}");
|
||||
var message = $"Received [{agent.Name}] {incoming.Role}: {incoming.Content}";
|
||||
#if DEBUG
|
||||
Console.WriteLine(message, Color.OrangeRed);
|
||||
#else
|
||||
_logger.LogInformation(message);
|
||||
#endif
|
||||
|
||||
incoming.CurrentAgentId = agent.Id;
|
||||
|
||||
|
|
@ -56,6 +61,7 @@ public partial class ConversationService
|
|||
var statistics = _services.GetRequiredService<ITokenStatistics>();
|
||||
statistics.PrintStatistics();
|
||||
|
||||
routing.ResetRecursiveCounter();
|
||||
routing.RefreshDialogs();
|
||||
|
||||
return true;
|
||||
|
|
@ -81,16 +87,15 @@ public partial class ConversationService
|
|||
|
||||
private async Task HandleAssistantMessage(RoleDialogModel message, Func<RoleDialogModel, Task> onMessageReceived)
|
||||
{
|
||||
var routingSetting = _services.GetRequiredService<RoutingSettings>();
|
||||
var agentName = routingSetting.RouterId == message.CurrentAgentId ?
|
||||
"Router" :
|
||||
(await _services.GetRequiredService<IAgentService>().GetAgent(message.CurrentAgentId)).Name;
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agent = await agentService.GetAgent(message.CurrentAgentId);
|
||||
var agentName = agent.Name;
|
||||
|
||||
var text = message.Role == AgentRole.Function ?
|
||||
$"[{agentName}] {message.FunctionName}: {message.Content}" :
|
||||
$"[{agentName}] {message.Role}: {message.Content}";
|
||||
$"Sending [{agentName}] {message.FunctionName}: {message.Content}" :
|
||||
$"Sending [{agentName}] {message.Role}: {message.Content}";
|
||||
#if DEBUG
|
||||
Console.WriteLine(text, Color.Pink);
|
||||
Console.WriteLine(text, Color.Yellow);
|
||||
#else
|
||||
_logger.LogInformation(text);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ public class ConversationStorage : IConversationStorage
|
|||
}
|
||||
else
|
||||
{
|
||||
var routingSetting = _services.GetRequiredService<RoutingSettings>();
|
||||
var agentName = routingSetting.RouterId == agentId ? "Router" : db.GetAgent(agentId)?.Name;
|
||||
var agentName = db.GetAgent(agentId)?.Name;
|
||||
|
||||
sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{agentName}|");
|
||||
var content = dialog.Content.Replace("\r", " ").Replace("\n", " ").Trim();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public class RouteToAgentFn : IFunctionCallback
|
|||
if (!string.IsNullOrEmpty(args.OriginalAgent) && args.OriginalAgent.Length < 32)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var originalAgent = db.GetAgents(args.OriginalAgent).FirstOrDefault();
|
||||
var originalAgent = db.GetAgents(name: args.OriginalAgent).FirstOrDefault();
|
||||
if (originalAgent != null)
|
||||
{
|
||||
_context.Push(originalAgent.Id);
|
||||
|
|
|
|||
|
|
@ -30,18 +30,19 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
{
|
||||
var context = _services.GetRequiredService<RoutingContext>();
|
||||
|
||||
var function = _services.GetServices<IFunctionCallback>().FirstOrDefault(x => x.Name == inst.Function);
|
||||
var message = new RoleDialogModel(AgentRole.Function, inst.Question)
|
||||
{
|
||||
FunctionName = inst.Function,
|
||||
FunctionArgs = JsonSerializer.Serialize(inst),
|
||||
CurrentAgentId = routing.Dialogs.Last().CurrentAgentId
|
||||
CurrentAgentId = context.GetCurrentAgentId(),
|
||||
};
|
||||
|
||||
var ret = await function.Execute(message);
|
||||
|
||||
var context = _services.GetRequiredService<RoutingContext>();
|
||||
var result = await routing.InvokeAgent(context.CurrentAgentId);
|
||||
var result = await routing.InvokeAgent(context.GetCurrentAgentId());
|
||||
// Keep last message data for debug
|
||||
result.ExecutionData = result.ExecutionData ?? message.ExecutionData;
|
||||
result.FunctionName = result.FunctionName ?? message.FunctionName;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
|
|
@ -89,8 +90,9 @@ public class RouterInstance : IRouterInstance
|
|||
AgentId = x.Id,
|
||||
Description = x.Description,
|
||||
Name = x.Name,
|
||||
RequiredFields = x.RoutingRules.Where(x => x.Required)
|
||||
.Select(x => new NameDesc(x.Field, x.Description))
|
||||
RequiredFields = x.RoutingRules
|
||||
.Where(x => x.Required)
|
||||
.Select(p => new ParameterPropertyDef(p.Field, p.Description, type: p.Type))
|
||||
.ToList()
|
||||
}).ToArray();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public partial class RoutingService
|
|||
}
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine(response.Content, Color.Gray);
|
||||
Console.WriteLine(response.Content, Color.Green);
|
||||
#else
|
||||
_logger.LogInformation(response.Content);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ namespace BotSharp.Core.Routing;
|
|||
public partial class RoutingService
|
||||
{
|
||||
const int MAXIMUM_RECURSION_DEPTH = 3;
|
||||
int CurrentRecursionDepth = 0;
|
||||
private int _currentRecursionDepth = 0;
|
||||
public async Task<RoleDialogModel> InvokeAgent(string agentId)
|
||||
{
|
||||
CurrentRecursionDepth++;
|
||||
if (CurrentRecursionDepth > MAXIMUM_RECURSION_DEPTH)
|
||||
_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();
|
||||
}
|
||||
|
||||
|
|
@ -23,13 +24,15 @@ public partial class RoutingService
|
|||
|
||||
if (response.Role == AgentRole.Function)
|
||||
{
|
||||
await InvokeFunction(agent, response);
|
||||
return await InvokeFunction(agent, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private async Task InvokeFunction(Agent agent, RoleDialogModel response)
|
||||
private async Task<RoleDialogModel> InvokeFunction(Agent agent, RoleDialogModel response)
|
||||
{
|
||||
// execute function
|
||||
// Save states
|
||||
|
|
@ -41,11 +44,12 @@ public partial class RoutingService
|
|||
|
||||
if (string.IsNullOrEmpty(response.Content))
|
||||
{
|
||||
response.Content = response.ExecutionResult;
|
||||
response.Content = response.ExecutionResult ?? JsonSerializer.Serialize(response.ExecutionData);
|
||||
}
|
||||
|
||||
Dialogs.Add(response);
|
||||
|
||||
// Pass execution result to LLM to get response
|
||||
if (!response.StopCompletion)
|
||||
{
|
||||
// Find response template
|
||||
|
|
@ -54,17 +58,14 @@ public partial class RoutingService
|
|||
if (!string.IsNullOrEmpty(responseTemplate))
|
||||
{
|
||||
response.Role = AgentRole.Assistant;
|
||||
response.Content = responseTemplate;
|
||||
response.Content = responseTemplate.Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
var recursiveResponse = await InvokeAgent(response.CurrentAgentId);
|
||||
response.Role = recursiveResponse.Role;
|
||||
response.Content = recursiveResponse.Content;
|
||||
response.ExecutionResult = recursiveResponse.ExecutionResult;
|
||||
response.ExecutionData = recursiveResponse.ExecutionData ?? response.ExecutionData;
|
||||
response.StopCompletion = recursiveResponse.StopCompletion;
|
||||
response = await InvokeAgent(response.CurrentAgentId);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ public partial class RoutingService : IRoutingService
|
|||
}
|
||||
}
|
||||
|
||||
public void ResetRecursiveCounter()
|
||||
{
|
||||
_currentRecursionDepth = 0;
|
||||
}
|
||||
|
||||
public void RefreshDialogs()
|
||||
{
|
||||
_dialogs = null;
|
||||
|
|
@ -88,7 +93,6 @@ public partial class RoutingService : IRoutingService
|
|||
if (handler == null)
|
||||
{
|
||||
handler = handlers.FirstOrDefault(x => x.Name == "get_next_instruction");
|
||||
router.Instruction += $"\r\n{AgentRole.System}: the function must be one of {string.Join(",", _routerInstance.GetHandlers().Select(x => x.Name))}.";
|
||||
continue;
|
||||
}
|
||||
handler.SetRouter(router);
|
||||
|
|
@ -96,8 +100,6 @@ public partial class RoutingService : IRoutingService
|
|||
|
||||
result = await handler.Handle(this, inst);
|
||||
|
||||
message = result.Content.Replace("\r\n", " ");
|
||||
|
||||
stop = !_settings.EnableReasoning;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
|
|
@ -21,6 +22,7 @@ public class TemplateRender : ITemplateRender
|
|||
_options.MemberAccessStrategy.MemberNameStrategy = MemberNameStrategies.SnakeCase;
|
||||
|
||||
_options.MemberAccessStrategy.Register<NameDesc>();
|
||||
_options.MemberAccessStrategy.Register<ParameterPropertyDef>();
|
||||
_options.MemberAccessStrategy.Register<RoleDialogModel>();
|
||||
_options.MemberAccessStrategy.Register<Agent>();
|
||||
_options.MemberAccessStrategy.Register<RoutingItem>();
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ Response: { "function": "{{ handler.name }}",
|
|||
* Agent: {{ agent.name }}
|
||||
{{ agent.description}}
|
||||
{% if agent.required_fields and agent.required_fields != empty -%}
|
||||
Required args: {
|
||||
Required args:
|
||||
{% for f in agent.required_fields -%}
|
||||
"{{ f.name }}": "{{ f.description }}"{{ ",\r\n " }}
|
||||
{%- endfor %}}
|
||||
- {{ f.name }} ({{ f.type }}): {{ f.description }}{{ "\r\n " }}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{% assign pizza_type = pizza_type | downcase %}
|
||||
{% if pizza_type contains "cheese" -%}
|
||||
The price for a slice of {{pizza_type}} pizza is {{ cheese_unit_price }}. Would you like to proceed the order?
|
||||
The price for a slice of {{pizza_type}} pizza is ${{ cheese_unit_price }}. Would you like to proceed the order?
|
||||
{%- elsif pizza_type contains "pepperoni" -%}
|
||||
The price for a slice of {{pizza_type}} pizza is {{ pepperoni_unit_price }}. Would you like to proceed the order?
|
||||
The price for a slice of {{pizza_type}} pizza is ${{ pepperoni_unit_price }}. Would you like to proceed the order?
|
||||
{%- elsif pizza_type contains "margherita" -%}
|
||||
The price for a slice of {{pizza_type}} pizza is {{ margherita_unit_price }}. Would you like to proceed the order?
|
||||
The price for a slice of {{pizza_type}} pizza is ${{ margherita_unit_price }}. Would you like to proceed the order?
|
||||
{%- else -%}
|
||||
We don't have {{pizza_type}} pizza, would you like something else?
|
||||
{%- endif %}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
{
|
||||
"field": "order_number",
|
||||
"description": "order number",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"redirectTo": "c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ public class GetPizzaPricesFn : IFunctionCallback
|
|||
{
|
||||
message.ExecutionData = new
|
||||
{
|
||||
pepperoni_unit_price = "$3.2",
|
||||
cheese_unit_price = "$3.5",
|
||||
margherita_unit_price = "$3.8",
|
||||
pepperoni_unit_price = 3.2,
|
||||
cheese_unit_price = 3.5,
|
||||
margherita_unit_price = 3.8,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,6 @@ public class PizzaBotPlugin : IBotSharpPlugin
|
|||
{
|
||||
public void RegisterDI(IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
// Register callback function
|
||||
services.AddScoped<IFunctionCallback, GetPizzaTypesFn>();
|
||||
services.AddScoped<IFunctionCallback, GetPizzaPricesFn>();
|
||||
services.AddScoped<IFunctionCallback, PlaceOrderFn>();
|
||||
services.AddScoped<IFunctionCallback, GetOrderStatusFn>();
|
||||
services.AddScoped<IFunctionCallback, MakePaymentFn>();
|
||||
|
||||
// Register hooks
|
||||
services.AddScoped<IAgentHook, PizzaBotAgentHook>();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue