Move next step prompt to liquid template.
This commit is contained in:
parent
bf151a0d09
commit
1c0fe993ba
|
|
@ -15,13 +15,13 @@ public class FunctionCallFromLlm : RoutingArgs
|
|||
{
|
||||
var route = string.IsNullOrEmpty(AgentName) ? "" : $"<Route to {AgentName.ToUpper()} because {Reason}>";
|
||||
|
||||
if (string.IsNullOrEmpty(Answer))
|
||||
if (string.IsNullOrEmpty(Response))
|
||||
{
|
||||
return $"[{Function} {route} {JsonSerializer.Serialize(Arguments)}]: {Question}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"[{Function} {route} {JsonSerializer.Serialize(Arguments)}]: {Question} => {Answer}";
|
||||
return $"[{Function} {route} {JsonSerializer.Serialize(Arguments)}]: {Question} => {Response}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,29 +5,41 @@ public class RoutingArgs
|
|||
[JsonPropertyName("function")]
|
||||
public string Function { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The reason why you select this function or agent
|
||||
/// </summary>
|
||||
[JsonPropertyName("reason")]
|
||||
public string Reason { get; set; } = "the reason why you select this function or agent";
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("answer")]
|
||||
public string Answer { get; set; } = "the content of response to user";
|
||||
/// <summary>
|
||||
/// The content of replying to user
|
||||
/// </summary>
|
||||
[JsonPropertyName("response")]
|
||||
public string Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Agent for next action based on user latest response
|
||||
/// </summary>
|
||||
[JsonPropertyName("next_action_agent")]
|
||||
public string AgentName { get; set; } = "agent for next action based on user latest response";
|
||||
public string AgentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Agent who can achieve user original goal
|
||||
/// </summary>
|
||||
[JsonPropertyName("user_goal_agent")]
|
||||
public string OriginalAgent { get; set; } = "agent who can achieve user original goal";
|
||||
public string OriginalAgent { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var route = string.IsNullOrEmpty(AgentName) ? "" : $"<Route to {AgentName.ToUpper()} because {Reason}>";
|
||||
|
||||
if (string.IsNullOrEmpty(Answer))
|
||||
if (string.IsNullOrEmpty(Response))
|
||||
{
|
||||
return $"[{Function} {route}]";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"[{Function} {route}] => {Answer}";
|
||||
return $"[{Function} {route}] => {Response}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
{
|
||||
public string Name => "conversation_end";
|
||||
|
||||
public string Description => "User wants to end the conversation.";
|
||||
public string Description => "User completed his task and wants to end the conversation.";
|
||||
|
||||
public bool IsReasoning => false;
|
||||
|
||||
|
|
@ -19,11 +19,11 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Answer)
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
|
||||
{
|
||||
CurrentAgentId = _settings.RouterId,
|
||||
FunctionName = inst.Function,
|
||||
StopCompletion = true
|
||||
ExecutionData = inst
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@ public class ResponseToUserRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Answer)
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
|
||||
{
|
||||
CurrentAgentId = _settings.RouterId,
|
||||
FunctionName = inst.Function,
|
||||
ExecutionData = inst,
|
||||
StopCompletion = true
|
||||
};
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
|
|||
var record = db.Agents.First(x => x.Name.ToLower() == inst.AgentName.ToLower());
|
||||
var response = await routing.InvokeAgent(record.Id);
|
||||
|
||||
inst.Answer = response.Content;
|
||||
inst.Response = response.Content;
|
||||
|
||||
/*_dialogs.Add(new RoleDialogModel(AgentRole.Assistant, inst.Parameters.Question)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
|
@ -9,17 +11,7 @@ public partial class RoutingService
|
|||
{
|
||||
public async Task<FunctionCallFromLlm> GetNextInstruction()
|
||||
{
|
||||
var prompt = "Which is the next step based on the CONVERSATION? Or you can handle without asking specific agent.";
|
||||
var responseFormat = _settings.EnableReasoning ?
|
||||
JsonSerializer.Serialize(new FunctionCallFromLlm()) :
|
||||
JsonSerializer.Serialize(new RoutingArgs
|
||||
{
|
||||
Function = "route_to_agent"
|
||||
});
|
||||
var content = $"{prompt} Response must be in JSON format {responseFormat}.";
|
||||
content += " Set function as conversation_end with courtesy greeting if user is willing to end conversation";
|
||||
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var content = GetNextStepPrompt();
|
||||
|
||||
RoleDialogModel response = default;
|
||||
var args = new FunctionCallFromLlm();
|
||||
|
|
@ -50,7 +42,7 @@ public partial class RoutingService
|
|||
{
|
||||
_logger.LogError($"{ex.Message}: {response.Content}");
|
||||
args.Function = "response_to_user";
|
||||
args.Answer = ex.Message;
|
||||
args.Response = ex.Message;
|
||||
args.AgentName = "Router";
|
||||
content += "\r\nPlease response in JSON format.";
|
||||
}
|
||||
|
|
@ -86,7 +78,7 @@ public partial class RoutingService
|
|||
{
|
||||
_logger.LogError($"{ex.Message}: {response.Content}");
|
||||
args.Function = "response_to_user";
|
||||
args.Answer = ex.Message;
|
||||
args.Response = ex.Message;
|
||||
args.AgentName = "Router";
|
||||
content += "\r\nPlease response in JSON format.";
|
||||
}
|
||||
|
|
@ -135,4 +127,24 @@ public partial class RoutingService
|
|||
|
||||
return args;
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
[MemoryCache(60 * 60)]
|
||||
#endif
|
||||
private string GetNextStepPrompt()
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agentSettings = _services.GetRequiredService<AgentSettings>();
|
||||
var filePath = Path.Combine(agentService.GetAgentDataDir(_routerInstance.AgentId), $"next_step_prompt.{agentSettings.TemplateFormat}");
|
||||
var template = File.ReadAllText(filePath);
|
||||
|
||||
// If enabled reasoning
|
||||
// JsonSerializer.Serialize(new FunctionCallFromLlm());
|
||||
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
{
|
||||
{ "enabled_reasoning", false }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
What is the next step based on the CONVERSATION? Or you can handle without asking specific agent.
|
||||
|
||||
Response must be in JSON format
|
||||
{% if enabled_reasoning -%}
|
||||
{"function":"route_to_agent"}
|
||||
{%- else -%}
|
||||
{"function":"route_to_agent","reason":"the reason why you select this function or agent","response":"content of replying to user","next_action_agent":"agent for next action based on user latest response","user_goal_agent":"agent who can achieve user original goal"}
|
||||
{%- endif %}
|
||||
|
||||
If the user has no other tasks need help with, set function as conversation_end with reason and reply user courteously.
|
||||
Loading…
Reference in a new issue