diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
index c764f391..b722d3fa 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
@@ -69,21 +69,6 @@ public interface IConversationHook
Task OnResponseGenerated(RoleDialogModel message);
- ///
- /// LLM detected user requested a new task different from previous topic.
- ///
- ///
- ///
- Task OnNewTaskDetected(RoleDialogModel message, string reason);
-
- ///
- /// LLM detected the current task is completed.
- /// It's useful for the situation of multiple tasks in the same conversation.
- ///
- ///
- ///
- Task OnTaskCompleted(RoleDialogModel message);
-
///
/// LLM detected the whole conversation is going to be end.
///
diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionCallFromLlm.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionCallFromLlm.cs
index 661a1437..0bb248f4 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionCallFromLlm.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionCallFromLlm.cs
@@ -36,13 +36,6 @@ public class FunctionCallFromLlm : RoutingArgs
{
var route = string.IsNullOrEmpty(AgentName) ? "" : $"";
- if (string.IsNullOrEmpty(Response))
- {
- return $"[{Function} {route} {JsonSerializer.Serialize(Arguments)}]: {Question}";
- }
- else
- {
- return $"[{Function} {route} {JsonSerializer.Serialize(Arguments)}]: {Question} => {Response}";
- }
+ return $"[{Function} {route} {JsonSerializer.Serialize(Arguments)}]: {Question}";
}
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs
deleted file mode 100644
index 95cddf2e..00000000
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using BotSharp.Abstraction.Functions.Models;
-
-namespace BotSharp.Abstraction.Routing;
-
-///
-/// The routing handler will be injected to Router's FUNCTIONS section of the system prompt
-/// So the handler will be invoked by LLM autonomously.
-///
-public interface IRoutingHandler
-{
- string Name { get; }
- string Description { get; }
- List Planers => null;
- bool Enabled => true;
- List Parameters => new List();
-
- void SetDialogs(List dialogs);
-
- 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 c0f7c81c..d98dd495 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
@@ -26,8 +26,6 @@ public interface IRoutingService
///
RoutingRule[] GetRulesByAgentId(string id);
- List GetHandlers(Agent router);
-
//void ResetRecursiveCounter();
//int GetRecursiveCounter();
//void SetRecursiveCounter(int counter);
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/ResponseUserArgs.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/ResponseUserArgs.cs
new file mode 100644
index 00000000..4a3a027b
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/ResponseUserArgs.cs
@@ -0,0 +1,7 @@
+namespace BotSharp.Abstraction.Routing.Models;
+
+public class ResponseUserArgs
+{
+ [JsonPropertyName("content")]
+ public string Content { get; set; } = string.Empty;
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingArgs.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingArgs.cs
index bc9a6fa8..44d41f31 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingArgs.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingArgs.cs
@@ -15,19 +15,6 @@ public class RoutingArgs
[JsonPropertyName("conversation_end")]
public bool ConversationEnd { get; set; }
- [JsonPropertyName("task_completed")]
- public bool TaskCompleted { get; set; }
-
- [JsonPropertyName("is_new_task")]
- public bool IsNewTask { get; set; }
-
- ///
- /// The content of replying to user
- ///
- [JsonPropertyName("response")]
- [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- public string Response { get; set; } = string.Empty;
-
///
/// Agent for next action based on user latest response
///
@@ -38,10 +25,12 @@ public class RoutingArgs
///
/// Agent who can achieve user original goal
///
+ [Obsolete("Will be replaced by dedicate Reasoner")]
[JsonPropertyName("user_goal_agent")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string OriginalAgent { get; set; } = string.Empty;
+ [Obsolete("Will be replaced by dedicate Reasoner")]
[JsonPropertyName("user_goal_description")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string UserGoal { get; set; } = string.Empty;
@@ -50,13 +39,6 @@ public class RoutingArgs
{
var route = string.IsNullOrEmpty(AgentName) ? "" : $"";
- if (string.IsNullOrEmpty(Response))
- {
- return $"[{Function} {route}]";
- }
- else
- {
- return $"[{Function} {route}] => {Response}";
- }
+ return $"[{Function} {route}]";
}
}
diff --git a/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs
index cd85e358..19b6df53 100644
--- a/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs
+++ b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs
@@ -150,17 +150,6 @@ public static class BotSharpCoreExtensions
var loader = new PluginLoader(services, config, pluginSettings);
loader.Load(assembly =>
{
- // Register routing handlers
- var handlers = assembly.GetTypes()
- .Where(x => x.IsClass)
- .Where(x => x.GetInterface(nameof(IRoutingHandler)) != null)
- .ToArray();
-
- foreach (var handler in handlers)
- {
- services.AddScoped(typeof(IRoutingHandler), handler);
- }
-
// Register function callback
var functions = assembly.GetTypes()
.Where(x => x.IsClass
diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
index 3967aaaa..6a844c41 100644
--- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
+++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs
@@ -155,14 +155,6 @@ public partial class ConversationService
var conversation = _services.GetRequiredService();
var updatedConversation = await conversation.UpdateConversationTitle(_conversationId, response.Instruction.NextActionReason);
- // Emit conversation task completed hook
- if (response.Instruction.TaskCompleted)
- {
- await HookEmitter.Emit(_services, async hook =>
- await hook.OnTaskCompleted(response)
- );
- }
-
// Emit conversation ending hook
if (response.Instruction.ConversationEnd)
{
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs
index 0ee3e585..fe322f31 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs
@@ -20,8 +20,8 @@ public class ResponseToUserFn : IFunctionCallback
public Task Execute(RoleDialogModel message)
{
- var args = JsonSerializer.Deserialize(message.FunctionArgs);
- message.Content = args.Response;
+ var args = JsonSerializer.Deserialize(message.FunctionArgs);
+ message.Content = args.Content;
message.Handled = true;
message.StopCompletion = true;
return Task.FromResult(true);
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs
deleted file mode 100644
index ea50ef72..00000000
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/ContinueExecuteTaskRoutingHandler.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using BotSharp.Abstraction.Functions.Models;
-using BotSharp.Abstraction.Models;
-using BotSharp.Abstraction.Repositories;
-using BotSharp.Abstraction.Repositories.Filters;
-using BotSharp.Abstraction.Routing;
-using BotSharp.Abstraction.Routing.Settings;
-using BotSharp.Core.Routing.Reasoning;
-
-namespace BotSharp.Core.Routing.Handlers;
-
-public class ContinueExecuteTaskRoutingHandler : RoutingHandlerBase//, IRoutingHandler
-{
- public string Name => "continue_execute_task";
-
- public string Description => "Continue to execute user's request without further information retrival.";
-
- public List Parameters => new List
- {
- new ParameterPropertyDef("next_action_agent", "agent for next action based on user latest response"),
- new ParameterPropertyDef("user_goal_agent", "agent who can achieve user original goal"),
- new ParameterPropertyDef("reason", "why continue to execute current task"),
- new ParameterPropertyDef("args", "required parameters extracted from question")
- {
- Type = "object"
- }
- };
-
- public List Planers => new List
- {
- nameof(HFReasoner)
- };
-
- public ContinueExecuteTaskRoutingHandler(IServiceProvider services, ILogger logger, RoutingSettings settings)
- : base(services, logger, settings)
- {
- }
-
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
- {
- var db = _services.GetRequiredService();
- var filter = new AgentFilter { AgentNames = [inst.AgentName] };
- var record = db.GetAgents(filter).FirstOrDefault();
-
- message.FunctionName = inst.Function;
- message.CurrentAgentId = record.Id;
- message.FunctionArgs = JsonSerializer.Serialize(inst.Arguments);
-
- return true;
- }
-}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs
deleted file mode 100644
index 0d11f296..00000000
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/InterruptTaskExecutionRoutingHandler.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using BotSharp.Abstraction.Functions.Models;
-using BotSharp.Abstraction.Routing;
-using BotSharp.Abstraction.Routing.Settings;
-using BotSharp.Core.Routing.Reasoning;
-
-namespace BotSharp.Core.Routing.Handlers;
-
-public class InterruptTaskExecutionRoutingHandler : RoutingHandlerBase//, IRoutingHandler
-{
- public string Name => "interrupt_task_execution";
-
- public string Description => "Can't continue user's request becauase the requirements are not met.";
-
- public List Parameters => new List
- {
- new ParameterPropertyDef("reason", "the reason why the request is interrupted"),
- new ParameterPropertyDef("answer", "the content response to user")
- };
-
- public List Planers => new List
- {
- nameof(HFReasoner)
- };
-
- public InterruptTaskExecutionRoutingHandler(IServiceProvider services, ILogger logger, RoutingSettings settings)
- : base(services, logger, settings)
- {
- }
-
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
- {
- message.FunctionName = inst.Function;
- message.StopCompletion = true;
-
- return true;
- }
-}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
deleted file mode 100644
index 038488eb..00000000
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using BotSharp.Abstraction.Routing.Settings;
-using BotSharp.Core.Routing.Reasoning;
-
-namespace BotSharp.Core.Routing.Handlers;
-
-///
-/// Retrieve information from specific agent
-///
-public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase//, IRoutingHandler
-{
- public string Name => "retrieve_data_from_agent";
-
- public string Description => "Retrieve data from appropriate agent.";
-
- public List Parameters => new List
- {
- new ParameterPropertyDef("reason", "why choose this function"),
- new ParameterPropertyDef("question", "the question you will ask the next action agent to get the necessary information"),
- new ParameterPropertyDef("next_action_agent", "agent that can handle the question"),
- new ParameterPropertyDef("user_goal_agent", "agent that can achieve user original goal"),
- new ParameterPropertyDef("args", "required parameters extracted from question and hand over to the next agent")
- {
- Type = "object"
- }
- };
-
- public List Planers => new List
- {
- nameof(HFReasoner)
- };
-
- public RetrieveDataFromAgentRoutingHandler(IServiceProvider services, ILogger logger, RoutingSettings settings)
- : base(services, logger, settings)
- {
- }
-
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
- {
- var context = _services.GetRequiredService();
- var agentId = context.GetCurrentAgentId();
- var dialogs = new List
- {
- new RoleDialogModel(AgentRole.User, inst.Question)
- {
- CurrentAgentId = agentId,
- MessageId = message.MessageId
- }
- };
-
- var ret = await routing.InvokeAgent(agentId, dialogs);
- var response = dialogs.Last();
- inst.Response = response.Content;
-
- // Add final response to parent dialog
- _dialogs.Add(response);
-
- return ret;
- }
-}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
deleted file mode 100644
index 1dc808a0..00000000
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using BotSharp.Abstraction.Infrastructures.Enums;
-using BotSharp.Abstraction.Routing.Settings;
-
-namespace BotSharp.Core.Routing.Handlers;
-
-public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
-{
- public string Name => "route_to_agent";
-
- public string Description => "Route request to appropriate virtual agent.";
-
- public List Parameters => new List
- {
- new ParameterPropertyDef("next_action_reason",
- "the reason why route to this virtual agent.",
- required: true),
- new ParameterPropertyDef("next_action_agent",
- "agent for next action based on user latest response, if user is replying last agent's question, you must route to this agent.",
- required: true),
- new ParameterPropertyDef("args",
- "useful parameters of next action agent, format: { }",
- type: "object"),
- new ParameterPropertyDef("user_goal_description",
- "user goal based on user initial task.",
- required: true),
- new ParameterPropertyDef("user_goal_agent",
- "agent who can acheive user initial task.",
- required: true),
- new ParameterPropertyDef("conversation_end",
- "user is ending the conversation.",
- type: "boolean",
- required: true),
- new ParameterPropertyDef("is_new_task",
- "whether the user is requesting a new task that is different from the previous topic. Set the first round of conversation to false.",
- type: "boolean")
- };
-
- public RouteToAgentRoutingHandler(IServiceProvider services, ILogger logger, RoutingSettings settings)
- : base(services, logger, settings)
- {
- }
-
- public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
- {
- var states = _services.GetRequiredService();
- var goalAgent = states.GetState(StateConst.EXPECTED_GOAL_AGENT);
- if (!string.IsNullOrEmpty(goalAgent) && inst.OriginalAgent != goalAgent)
- {
- inst.OriginalAgent = goalAgent;
- // Emit hook
- await HookEmitter.Emit(_services, async hook =>
- await hook.OnRoutingInstructionRevised(inst, message)
- );
- }
-
- if (inst.IsNewTask)
- {
- await HookEmitter.Emit(_services, async hook =>
- await hook.OnNewTaskDetected(message, inst.NextActionReason)
- );
- }
-
- message.FunctionArgs = JsonSerializer.Serialize(inst);
- if (message.FunctionName != null)
- {
- var msg = RoleDialogModel.From(message, role: AgentRole.Function);
- await routing.InvokeFunction(message.FunctionName, msg);
- }
-
- var agentId = routing.Context.GetCurrentAgentId();
-
- // Update next action agent's name
- var agentService = _services.GetRequiredService();
- var agent = await agentService.GetAgent(agentId);
- inst.AgentName = agent.Name;
-
- if (inst.ExecutingDirectly)
- {
- message.Content = inst.Question;
- }
-
- if (agent.Disabled)
- {
- var content = $"This agent ({agent.Name}) is disabled, please install the corresponding plugin ({agent.Plugin.Name}) to activate this agent.";
-
- message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: content);
- _dialogs.Add(message);
- }
- else
- {
- var ret = await routing.InvokeAgent(agentId, _dialogs);
- }
-
- var response = _dialogs.Last();
- inst.Response = response.Content;
-
- return true;
- }
-}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs
index f83afedf..53a54669 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs
@@ -59,7 +59,6 @@ public class RoutingAgentHook : AgentHookBase
}
dict["routing_agents"] = agents;
- dict["routing_handlers"] = routing.GetHandlers(_agent);
return base.OnInstructionLoaded(template, dict);
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/HFReasoner.cs b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/HFReasoner.cs
index fc7c1009..55867e00 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/HFReasoner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/HFReasoner.cs
@@ -38,43 +38,21 @@ public class HFReasoner : IRoutingReasoner
{
var next = GetNextStepPrompt(router);
- RoleDialogModel response = default;
- var inst = new FunctionCallFromLlm();
-
var completion = CompletionProvider.GetChatCompletion(_services,
provider: router?.LlmConfig?.Provider,
model: router?.LlmConfig?.Model);
- int retryCount = 0;
- while (retryCount < 3)
+ dialogs = new List
{
- try
+ new RoleDialogModel(AgentRole.User, next)
{
- dialogs = new List
- {
- new RoleDialogModel(AgentRole.User, next)
- {
- FunctionName = nameof(HFReasoner),
- MessageId = messageId
- }
- };
- response = await completion.GetChatCompletions(router, dialogs);
+ FunctionName = nameof(HFReasoner),
+ MessageId = messageId
+ }
+ };
+ var response = await completion.GetChatCompletions(router, dialogs);
- inst = response.Content.JsonContent();
- break;
- }
- catch (Exception ex)
- {
- _logger.LogError($"{ex.Message}: {response.Content}");
- inst.Function = "response_to_user";
- inst.Response = ex.Message;
- inst.AgentName = "Router";
- }
- finally
- {
- retryCount++;
- }
- }
+ var inst = response.Content.JsonContent();
// Fix LLM malformed response
ReasonerHelper.FixMalformedResponse(_services, inst);
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs
index 6bb23e97..e911437d 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs
@@ -1,3 +1,4 @@
+using BotSharp.Abstraction.Infrastructures.Enums;
using BotSharp.Abstraction.Planning;
namespace BotSharp.Core.Routing.Reasoning;
@@ -18,17 +19,50 @@ public class InstructExecutor : IExecutor
RoleDialogModel message,
List dialogs)
{
- message.Instruction = inst;
+ var states = _services.GetRequiredService();
+ var goalAgent = states.GetState(StateConst.EXPECTED_GOAL_AGENT);
+ if (!string.IsNullOrEmpty(goalAgent) && inst.OriginalAgent != goalAgent)
+ {
+ inst.OriginalAgent = goalAgent;
+ // Emit hook
+ await HookEmitter.Emit(_services, async hook =>
+ await hook.OnRoutingInstructionRevised(inst, message)
+ );
+ }
- var handlers = _services.GetServices();
- var handler = handlers.FirstOrDefault(x => x.Name == inst.Function);
- handler.SetDialogs(dialogs);
+ message.FunctionArgs = JsonSerializer.Serialize(inst);
+ if (message.FunctionName != null)
+ {
+ var msg = RoleDialogModel.From(message, role: AgentRole.Function);
+ await routing.InvokeFunction(message.FunctionName, msg);
+ }
- var handled = await handler.Handle(routing, inst, message);
+ var agentId = routing.Context.GetCurrentAgentId();
+
+ // Update next action agent's name
+ var agentService = _services.GetRequiredService();
+ var agent = await agentService.GetAgent(agentId);
+ inst.AgentName = agent.Name;
+
+ if (inst.ExecutingDirectly)
+ {
+ message.Content = inst.Question;
+ }
+
+ if (agent.Disabled)
+ {
+ var content = $"This agent ({agent.Name}) is disabled, please install the corresponding plugin ({agent.Plugin.Name}) to activate this agent.";
+
+ message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: content);
+ dialogs.Add(message);
+ }
+ else
+ {
+ var ret = await routing.InvokeAgent(agentId, dialogs);
+ }
- // For client display purpose
var response = dialogs.Last();
- response.MessageId = message.MessageId;
+
response.Instruction = inst;
return response;
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/NaiveReasoner.cs b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/NaiveReasoner.cs
index 8980246e..6adc9bc5 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/NaiveReasoner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/NaiveReasoner.cs
@@ -41,53 +41,22 @@ public class NaiveReasoner : IRoutingReasoner
{
var next = GetNextStepPrompt(router);
- var inst = new FunctionCallFromLlm();
-
- // text completion
- /*var agentService = _services.GetRequiredService();
- var instruction = agentService.RenderedInstruction(router);
- var content = $"{instruction}\r\n###\r\n{next}";
- content = content + "\r\nResponse: ";
- var completion = CompletionProvider.GetTextCompletion(_services);*/
-
// chat completion
var completion = CompletionProvider.GetChatCompletion(_services,
provider: router?.LlmConfig?.Provider,
model: router?.LlmConfig?.Model);
- int retryCount = 0;
- while (retryCount < 3)
+ dialogs = new List
{
- string text = string.Empty;
- try
+ new RoleDialogModel(AgentRole.User, next)
{
- // text completion
- // text = await completion.GetCompletion(content, router.Id, messageId);
- dialogs = new List
- {
- new RoleDialogModel(AgentRole.User, next)
- {
- FunctionName = nameof(NaiveReasoner),
- MessageId = messageId
- }
- };
- var response = await completion.GetChatCompletions(router, dialogs);
+ FunctionName = nameof(NaiveReasoner),
+ MessageId = messageId
+ }
+ };
+ var response = await completion.GetChatCompletions(router, dialogs);
- inst = (response.FunctionArgs ?? response.Content).JsonContent();
- break;
- }
- catch (Exception ex)
- {
- _logger.LogError($"{ex.Message}: {text}");
- inst.Function = "response_to_user";
- inst.Response = ex.Message;
- inst.AgentName = "Router";
- }
- finally
- {
- retryCount++;
- }
- }
+ var inst = (response.FunctionArgs ?? response.Content).JsonContent();
// Fix LLM malformed response
ReasonerHelper.FixMalformedResponse(_services, inst);
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/OneStepForwardReasoner.cs b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/OneStepForwardReasoner.cs
index 7e6d2624..800b2457 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/OneStepForwardReasoner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/OneStepForwardReasoner.cs
@@ -44,46 +44,26 @@ public class OneStepForwardReasoner : IRoutingReasoner
{
var next = GetNextStepPrompt(router);
- var inst = new FunctionCallFromLlm();
-
// chat completion
var completion = CompletionProvider.GetChatCompletion(_services,
provider: router?.LlmConfig?.Provider,
model: router?.LlmConfig?.Model);
- int retryCount = 0;
- while (retryCount < 3)
- {
- string text = string.Empty;
- try
- {
- // text completion
- // text = await completion.GetCompletion(content, router.Id, messageId);
- dialogs = new List
- {
- new RoleDialogModel(AgentRole.User, next)
- {
- FunctionName = Name,
- MessageId = messageId
- }
- };
- var response = await completion.GetChatCompletions(router, dialogs);
+ string text = string.Empty;
- inst = response.Content.JsonContent();
- break;
- }
- catch (Exception ex)
+ // text completion
+ // text = await completion.GetCompletion(content, router.Id, messageId);
+ dialogs = new List
+ {
+ new RoleDialogModel(AgentRole.User, next)
{
- _logger.LogError($"{ex.Message}: {text}");
- inst.Function = "response_to_user";
- inst.Response = ex.Message;
- inst.AgentName = "Router";
+ FunctionName = Name,
+ MessageId = messageId
}
- finally
- {
- retryCount++;
- }
- }
+ };
+ var response = await completion.GetChatCompletions(router, dialogs);
+
+ var inst = response.Content.JsonContent();
// Fix LLM malformed response
ReasonerHelper.FixMalformedResponse(_services, inst);
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InstructLoop.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InstructLoop.cs
index 07b2f6fa..20aa16b6 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InstructLoop.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InstructLoop.cs
@@ -58,11 +58,8 @@ public partial class RoutingService
// Save states
states.SaveStateByArgs(inst.Arguments);
-#if DEBUG
- Console.WriteLine($"*** Next Instruction *** {inst}");
-#else
- _logger.LogInformation($"*** Next Instruction *** {inst}");
-#endif
+ _logger.LogDebug($"*** Next Instruction *** {inst}");
+
await reasoner.AgentExecuting(_router, inst, message, dialogs);
// Handover to Task Agent
@@ -79,7 +76,7 @@ public partial class RoutingService
await reasoner.AgentExecuted(_router, inst, response, dialogs);
- if (loopCount >= reasoner.MaxLoopCount || _context.IsEmpty)
+ if (loopCount >= reasoner.MaxLoopCount || _context.IsEmpty || response.StopCompletion)
{
break;
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
index 19654deb..253e7b54 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
@@ -28,17 +28,12 @@ public partial class RoutingService : IRoutingService
public async Task InstructDirect(Agent agent, RoleDialogModel message)
{
- var handlers = _services.GetServices();
-
- var handler = handlers.FirstOrDefault(x => x.Name == "route_to_agent");
-
var conv = _services.GetRequiredService();
var storage = _services.GetRequiredService();
storage.Append(conv.ConversationId, message);
var dialogs = conv.GetDialogHistory();
Context.SetDialogs(dialogs);
- handler.SetDialogs(dialogs);
var inst = new FunctionCallFromLlm
{
@@ -50,7 +45,8 @@ public partial class RoutingService : IRoutingService
ExecutingDirectly = true
};
- var result = await handler.Handle(this, inst, message);
+ message.Instruction = inst;
+ var result = await InvokeFunction("route_to_agent", message);
var response = dialogs.Last();
response.MessageId = message.MessageId;
@@ -59,21 +55,6 @@ public partial class RoutingService : IRoutingService
return response;
}
- public List GetHandlers(Agent router)
- {
- var reasoner = GetReasoner(router);
-
- return _services.GetServices()
- .Where(x => x.Planers == null || x.Planers.Contains(reasoner.GetType().Name))
- .Where(x => !string.IsNullOrEmpty(x.Description))
- .Select((x, i) => new RoutingHandlerDef
- {
- Name = x.Name,
- Description = x.Description,
- Parameters = x.Parameters
- }).ToList();
- }
-
#if !DEBUG
[SharpCache(10)]
#endif
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json
index a2685810..9e7f8929 100644
--- a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json
+++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json
@@ -1,15 +1,14 @@
{
"name": "response_to_user",
- "description": "Response to user without routing to any other agent",
- "visibility_expression": "{% if states.routing_mode == 'lazy' %}visible{% endif %}",
+ "description": "Response to user without routing to any other agent, user has no specific request.",
"parameters": {
"type": "object",
"properties": {
- "response": {
+ "content": {
"type": "string",
"description": "Response content"
}
},
- "required": [ "response" ]
+ "required": [ "content" ]
}
}
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/route_to_agent.json b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/route_to_agent.json
index 08f938ec..01301bbf 100644
--- a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/route_to_agent.json
+++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/route_to_agent.json
@@ -1,7 +1,6 @@
{
"name": "route_to_agent",
"description": "Route request to appropriate AI agent.",
- "visibility_expression": "{% if states.routing_mode == 'lazy' %}visible{% endif %}",
"parameters": {
"type": "object",
"properties": {
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid
index 99f7a219..d49215d1 100644
--- a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid
+++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid
@@ -18,21 +18,6 @@ Follow these steps to handle user request:
{%- endfor %}
{% endif %}
-{% if routing_mode != 'lazy' %}
-[FUNCTIONS]
-{% for handler in routing_handlers -%}
-# {{ handler.description}}
-{% if handler.parameters and handler.parameters != empty -%}
-Parameters:
- - function: {{ handler.name }}
- {% for p in handler.parameters -%}
- - {{ p.name }} {% if p.required -%}(required){%- endif %}: {{ p.description }}{{ "\r\n " }}
- {%- endfor %}
-{%- endif %}
-{{ "\r\n" }}
-{%- endfor %}
-{% endif %}
-
[AGENTS]
{% for agent in routing_agents -%}
* Agent: {{ agent.name }}
diff --git a/src/Plugins/BotSharp.Plugin.Planner/Sequential/SequentialPlanner.cs b/src/Plugins/BotSharp.Plugin.Planner/Sequential/SequentialPlanner.cs
index 043c7380..94b4a687 100644
--- a/src/Plugins/BotSharp.Plugin.Planner/Sequential/SequentialPlanner.cs
+++ b/src/Plugins/BotSharp.Plugin.Planner/Sequential/SequentialPlanner.cs
@@ -41,7 +41,7 @@ public class SequentialPlanner : ITaskPlanner
var decomposation = await GetDecomposedStepAsync(router, messageId, dialogs);
if (decomposation.TotalRemainingSteps > 0 && _lastInst != null)
{
- _lastInst.Response = decomposation.Description;
+ // _lastInst.Response = decomposation.Description;
_lastInst.NextActionReason = $"Having {decomposation.TotalRemainingSteps} steps left.";
return _lastInst;
}
@@ -62,8 +62,6 @@ public class SequentialPlanner : ITaskPlanner
var next = GetNextStepPrompt(router);
- var inst = new FunctionCallFromLlm();
-
// text completion
/*var agentService = _services.GetRequiredService();
var instruction = agentService.RenderedInstruction(router);
@@ -76,43 +74,26 @@ public class SequentialPlanner : ITaskPlanner
provider: router?.LlmConfig?.Provider,
model: router?.LlmConfig?.Model);
- int retryCount = 0;
- while (retryCount < 3)
- {
- string text = string.Empty;
- try
- {
- // text completion
- // text = await completion.GetCompletion(content, router.Id, messageId);
- dialogs = new List
- {
- new RoleDialogModel(AgentRole.User, next)
- {
- FunctionName = nameof(SequentialPlanner),
- MessageId = messageId
- }
- };
- var response = await completion.GetChatCompletions(router, dialogs);
- inst = response.Content.JsonContent();
- break;
- }
- catch (Exception ex)
+ string text = string.Empty;
+
+ // text completion
+ // text = await completion.GetCompletion(content, router.Id, messageId);
+ dialogs = new List
+ {
+ new RoleDialogModel(AgentRole.User, next)
{
- _logger.LogError($"{ex.Message}: {text}");
- inst.Function = "response_to_user";
- inst.Response = ex.Message;
- inst.AgentName = "Router";
+ FunctionName = nameof(SequentialPlanner),
+ MessageId = messageId
}
- finally
- {
- retryCount++;
- }
- }
+ };
+ var response = await completion.GetChatCompletions(router, dialogs);
+
+ var inst = response.Content.JsonContent();
if (decomposation.TotalRemainingSteps > 0)
{
- inst.Response = decomposation.Description;
+ // inst.Response = decomposation.Description;
inst.NextActionReason = $"{decomposation.TotalRemainingSteps} steps left.";
inst.HandleDialogsByPlanner = true;
}
@@ -125,10 +106,10 @@ public class SequentialPlanner : ITaskPlanner
{
var taskAgentDialogs = new List
{
- new RoleDialogModel(AgentRole.User, inst.Response)
+ /*new RoleDialogModel(AgentRole.User, inst.Response)
{
MessageId = message.MessageId,
- }
+ }*/
};
return taskAgentDialogs;
diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs
index 62340e9c..a804b073 100644
--- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs
+++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs
@@ -42,14 +42,14 @@ public class SqlGenerationPlanner : ITaskPlanner
public List BeforeHandleContext(FunctionCallFromLlm inst, RoleDialogModel message, List dialogs)
{
- var question = inst.Response;
+ // var question = inst.Response;
var taskAgentDialogs = new List
{
- new RoleDialogModel(AgentRole.User, question)
+ /*new RoleDialogModel(AgentRole.User, question)
{
MessageId = message.MessageId,
- }
+ }*/
};
return taskAgentDialogs;
diff --git a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs
index 6935bfbf..ea89cd71 100644
--- a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs
+++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs
@@ -70,14 +70,14 @@ public partial class TwoStageTaskPlanner : ITaskPlanner
public List BeforeHandleContext(FunctionCallFromLlm inst, RoleDialogModel message, List dialogs)
{
- var question = inst.Response;
+ // var question = inst.Response;
var taskAgentDialogs = new List
{
- new RoleDialogModel(AgentRole.User, question)
+ /*new RoleDialogModel(AgentRole.User, question)
{
MessageId = message.MessageId,
- }
+ }*/
};
return taskAgentDialogs;
diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json
index ce052798..b48d2963 100644
--- a/src/WebStarter/appsettings.json
+++ b/src/WebStarter/appsettings.json
@@ -254,8 +254,8 @@
"HostAgentId": "01e2fc5c-2c89-4ec7-8470-7688608b496c",
"EnableTranslator": false,
"LlmConfig": {
- "Provider": "azure-openai",
- "Model": "gpt-4o-mini"
+ "Provider": "openai",
+ "Model": "gpt-4.1-nano"
}
},
diff --git a/tests/BotSharp.Plugin.PizzaBot/BotSharp.Plugin.PizzaBot.csproj b/tests/BotSharp.Plugin.PizzaBot/BotSharp.Plugin.PizzaBot.csproj
index d132125f..c056982d 100644
--- a/tests/BotSharp.Plugin.PizzaBot/BotSharp.Plugin.PizzaBot.csproj
+++ b/tests/BotSharp.Plugin.PizzaBot/BotSharp.Plugin.PizzaBot.csproj
@@ -32,9 +32,7 @@
-
-
@@ -63,9 +61,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -93,7 +88,7 @@
PreserveNewest
-
+
PreserveNewest
diff --git a/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs b/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs
index 87466956..e4198f34 100644
--- a/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs
+++ b/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs
@@ -1,11 +1,12 @@
using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Conversations.Models;
+using BotSharp.Abstraction.Infrastructures.Enums;
namespace BotSharp.Plugin.PizzaBot.Functions;
public class PlaceOrderFn : IFunctionCallback
{
- public string Name => "place_an_order";
+ public string Name => "place_order";
private readonly IServiceProvider _service;
public PlaceOrderFn(IServiceProvider service)
@@ -19,6 +20,9 @@ public class PlaceOrderFn : IFunctionCallback
var state = _service.GetRequiredService();
state.SetState("order_number", "P123-01");
+ // Set the next action agent to Payment
+ state.SetState(StateConst.EXPECTED_ACTION_AGENT, "Payment", activeRounds: 2);
+
return true;
}
}
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/8970b1e5-d260-4e2c-90b1-f1415a257c18/agent.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/8970b1e5-d260-4e2c-90b1-f1415a257c18/agent.json
index 3a28b3e0..99f1f2fd 100644
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/8970b1e5-d260-4e2c-90b1-f1415a257c18/agent.json
+++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/8970b1e5-d260-4e2c-90b1-f1415a257c18/agent.json
@@ -1,7 +1,7 @@
{
"id": "8970b1e5-d260-4e2c-90b1-f1415a257c18",
"name": "Pizza Bot",
- "description": "AI assistant that can help customer place pizza order, make payment or inquiry order status.",
+ "description": "AI assistant that can help customer place pizza order, make payment or inquiry existing order.",
"type": "routing",
"inheritAgentId": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a",
"createdDateTime": "2023-08-18T10:39:32.2349685Z",
@@ -11,6 +11,10 @@
"isPublic": true,
"profiles": [ "pizza" ],
"labels": [ "experiment" ],
+ "llmConfig": {
+ "provider": "openai",
+ "model": "gpt-4.1-nano"
+ },
"routingRules": [
{
"type": "reasoner",
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/agent.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/agent.json
index 09f7489b..e9bb78d0 100644
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/agent.json
+++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/agent.json
@@ -1,6 +1,6 @@
{
"name": "Order Inquiry",
- "description": "Check the order status like payment, delivery or baking.",
+ "description": "Check the existing order status like payment, delivery or baking.",
"createdDateTime": "2023-08-18T14:39:32.2349685Z",
"updatedDateTime": "2023-08-18T14:39:32.2349686Z",
"id": "b284db86-e9c2-4c25-a59e-4649797dd130",
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/functions/get_order_status.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/functions/get_order_status.json
index 49de63fe..fc7abb8b 100644
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/functions/get_order_status.json
+++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/b284db86-e9c2-4c25-a59e-4649797dd130/functions/get_order_status.json
@@ -6,7 +6,7 @@
"properties": {
"order_number": {
"type": "string",
- "description": "order number."
+ "description": "order number, value must be provided by user."
}
},
"required": [ "order_number" ]
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/agent.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/agent.json
index a6948ac4..8cade6f1 100644
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/agent.json
+++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/agent.json
@@ -1,5 +1,5 @@
{
- "name": "Ordering",
+ "name": "Order Placement",
"description": "Provide types of pizza available, pizza unit price, total cost and place the order.",
"createdDateTime": "2023-07-26T02:29:25.123224Z",
"updatedDateTime": "2023-07-26T02:29:25.123274Z",
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_order.json
similarity index 94%
rename from tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json
rename to tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_order.json
index d5514fba..9fe8278a 100644
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json
+++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_order.json
@@ -1,5 +1,5 @@
{
- "name": "place_an_order",
+ "name": "place_order",
"description": "Place an order when user has confirmed the pizza type and quantity.",
"parameters": {
"type": "object",
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/instructions/instruction.liquid b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/instructions/instruction.liquid
index 73b33cc3..5194fc79 100644
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/instructions/instruction.liquid
+++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/instructions/instruction.liquid
@@ -1,10 +1,9 @@
You are now a Pizza Ordering agent, and you can help customers order a pizza according to the user's preferences.
-Follow below step to place order:
-1: Ask user preferences, call function get_pizza_types to provide the variety of pizza options.
-2: Confirm with user the pizza type and quantity.
-3: Call function place_an_order to purchase.
-4: Ask user how to pay for this order.
-
-Use below information to help ordering process:
* Today is {{current_date}}, the time now is {{current_time}}, day of week is {{current_weekday}}.
+
+Follow below step to response:
+1: Ask user preferences, call function get_pizza_types to provide the variety of pizza options.
+2: Call get_pizza_price to tell customer the price per unit, then ask user for the quantity.
+3: Confirm the order with total price, call function place_order to place the order.
+4: Ask user how to pay for this order.
diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/responses/func.get_pizza_price.0.liquid b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/responses/func.get_pizza_price.0.liquid
deleted file mode 100644
index 62041ece..00000000
--- a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/responses/func.get_pizza_price.0.liquid
+++ /dev/null
@@ -1,13 +0,0 @@
-{% 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?
-{%- 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?
-{%- 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?
-{%- else -%}
- We don't have {{pizza_type}} pizza, would you like something else?
-{%- endif %}
-{% if quantity == nil -%}
- How many slices would you like to order?
-{%- endif %}
\ No newline at end of file