Merge pull request #428 from hchen2020/master
Return reason from HasMissingRequiredField.
This commit is contained in:
commit
875821ec6f
|
|
@ -44,5 +44,5 @@ public interface IRoutingService
|
|||
|
||||
Task<string> GetConversationContent(List<RoleDialogModel> dialogs, int maxDialogCount = 50);
|
||||
|
||||
bool HasMissingRequiredField(RoleDialogModel message, out string agentId);
|
||||
(bool, string) HasMissingRequiredField(RoleDialogModel message, out string agentId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ public class RoutingArgs
|
|||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string UserGoal { get; set; }
|
||||
|
||||
[JsonPropertyName("user_message_in_english")]
|
||||
public string UserMessageInEnglish { get; set; }
|
||||
|
||||
[JsonPropertyName("language")]
|
||||
public string Language { get; set; } = LanguageType.ENGLISH;
|
||||
|
||||
[JsonPropertyName("lastest_message_translated_to_english")]
|
||||
public string UserMessageInEnglish { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var route = string.IsNullOrEmpty(AgentName) ? "" : $"<Route to {AgentName.ToUpper()} because {NextActionReason}>";
|
||||
|
|
|
|||
|
|
@ -83,11 +83,11 @@ public partial class RouteToAgentFn : IFunctionCallback
|
|||
}
|
||||
|
||||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
var missingfield = routing.HasMissingRequiredField(message, out var agentId);
|
||||
var (missingfield, reason) = routing.HasMissingRequiredField(message, out var agentId);
|
||||
if (missingfield && message.CurrentAgentId != agentId)
|
||||
{
|
||||
// Stack redirection agent
|
||||
_context.Push(agentId, reason: $"REDIRECTION {message.Content}");
|
||||
_context.Push(agentId, reason: $"REDIRECTION {reason}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,20 +11,20 @@ public class ResponseToUserRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
public List<ParameterPropertyDef> Parameters => new List<ParameterPropertyDef>
|
||||
{
|
||||
new ParameterPropertyDef("reason",
|
||||
"why response to user directly without go to other agents"),
|
||||
"why response to user directly without go to other agents."),
|
||||
new ParameterPropertyDef("response",
|
||||
"response content to user in courteous words with language English. If the user wants to end the conversation, you must set conversation_end to true and response politely."),
|
||||
new ParameterPropertyDef("conversation_end",
|
||||
"whether to end this conversation",
|
||||
"whether to end this conversation.",
|
||||
type: "boolean"),
|
||||
new ParameterPropertyDef("task_completed ",
|
||||
"whether the user's task request has been completed.",
|
||||
type: "boolean"),
|
||||
new ParameterPropertyDef("user_message_in_english",
|
||||
"Translate user message from non-English to English"),
|
||||
new ParameterPropertyDef("language",
|
||||
"User prefered language, considering the whole conversation. Language could be English, Spanish or Chinese.",
|
||||
"User preferred language, considering the whole conversation. Language could be English, Spanish or Chinese.",
|
||||
required: true),
|
||||
new ParameterPropertyDef("lastest_message_translated_to_english",
|
||||
"Translate user lastest message in [CONVERSATION] to English"),
|
||||
};
|
||||
|
||||
public ResponseToUserRoutingHandler(IServiceProvider services, ILogger<ResponseToUserRoutingHandler> logger, RoutingSettings settings)
|
||||
|
|
|
|||
|
|
@ -12,28 +12,28 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
public List<ParameterPropertyDef> Parameters => new List<ParameterPropertyDef>
|
||||
{
|
||||
new ParameterPropertyDef("next_action_reason",
|
||||
"the reason why route to this virtual agent",
|
||||
"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",
|
||||
"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, must align with user_goal_description.",
|
||||
required: true),
|
||||
new ParameterPropertyDef("args",
|
||||
"useful parameters of next action agent, format: { }",
|
||||
type: "object"),
|
||||
new ParameterPropertyDef("is_new_task",
|
||||
"whether the user is requesting a new task that is different from the previous topic.",
|
||||
type: "boolean"),
|
||||
new ParameterPropertyDef("user_message_in_english",
|
||||
"Translate user message from non-English to English"),
|
||||
new ParameterPropertyDef("language",
|
||||
"User prefered language, considering the whole conversation. Language could be English, Spanish or Chinese.",
|
||||
"User preferred language, considering the whole conversation. Language could be English, Spanish or Chinese.",
|
||||
required: true),
|
||||
new ParameterPropertyDef("lastest_message_translated_to_english",
|
||||
"Translate lastest user message in [CONVERSATION] to English"),
|
||||
};
|
||||
|
||||
public RouteToAgentRoutingHandler(IServiceProvider services, ILogger<RouteToAgentRoutingHandler> logger, RoutingSettings settings)
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ public class RoutingContext : IRoutingContext
|
|||
};
|
||||
|
||||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
var missingfield = routing.HasMissingRequiredField(message, out agentId);
|
||||
var (missingfield, _) = routing.HasMissingRequiredField(message, out agentId);
|
||||
if (missingfield)
|
||||
{
|
||||
if (currentAgentId != agentId)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ public partial class RoutingService
|
|||
/// If the target agent needs some required fields but the
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool HasMissingRequiredField(RoleDialogModel message, out string agentId)
|
||||
public (bool, string) HasMissingRequiredField(RoleDialogModel message, out string agentId)
|
||||
{
|
||||
var reason = string.Empty;
|
||||
var args = JsonSerializer.Deserialize<RoutingArgs>(message.FunctionArgs);
|
||||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ public partial class RoutingService
|
|||
if (routingRules == null || !routingRules.Any())
|
||||
{
|
||||
agentId = message.CurrentAgentId;
|
||||
return false;
|
||||
return (false, reason);
|
||||
}
|
||||
|
||||
agentId = routingRules.First().AgentId;
|
||||
|
|
@ -68,9 +69,13 @@ public partial class RoutingService
|
|||
|
||||
if (missingFields.Any())
|
||||
{
|
||||
var logger = _services.GetRequiredService<ILogger<RouteToAgentFn>>();
|
||||
|
||||
// Add field to args
|
||||
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "missing_fields", missingFields);
|
||||
message.Content = $"missing some information: {string.Join(", ", missingFields)}";
|
||||
reason = $"missing some information: {string.Join(", ", missingFields)}";
|
||||
// message.Content = reason;
|
||||
logger.LogWarning(reason);
|
||||
|
||||
// Handle redirect
|
||||
var routingRule = routingRules.FirstOrDefault(x => missingFields.Contains(x.Field));
|
||||
|
|
@ -82,7 +87,6 @@ public partial class RoutingService
|
|||
// Add redirected agent
|
||||
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", record.Name);
|
||||
agentId = routingRule.RedirectTo;
|
||||
var logger = _services.GetRequiredService<ILogger<RouteToAgentFn>>();
|
||||
#if DEBUG
|
||||
Console.WriteLine($"*** Routing redirect to {record.Name.ToUpper()} ***", Color.Yellow);
|
||||
#else
|
||||
|
|
@ -96,7 +100,7 @@ public partial class RoutingService
|
|||
}
|
||||
}
|
||||
|
||||
return missingFields.Any();
|
||||
return (missingFields.Any(), reason);
|
||||
}
|
||||
|
||||
private string AppendPropertyToArgs(string args, string key, string value)
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ namespace BotSharp.Core.Routing;
|
|||
|
||||
public partial class RoutingService
|
||||
{
|
||||
private List<FunctionCallingResponse> _functionCallStack = new List<FunctionCallingResponse>();
|
||||
public List<FunctionCallingResponse> FunctionCallStack => _functionCallStack;
|
||||
|
||||
public async Task<bool> InvokeFunction(string name, RoleDialogModel message)
|
||||
{
|
||||
var function = _services.GetServices<IFunctionCallback>().FirstOrDefault(x => x.Name == name);
|
||||
|
|
@ -38,14 +35,6 @@ public partial class RoutingService
|
|||
{
|
||||
result = await function.Execute(clonedMessage);
|
||||
|
||||
_functionCallStack.Add(new FunctionCallingResponse
|
||||
{
|
||||
Role = AgentRole.Function,
|
||||
FunctionName = clonedMessage.FunctionName,
|
||||
Args = JsonDocument.Parse(clonedMessage.FunctionArgs ?? "{}"),
|
||||
Content = clonedMessage.Content
|
||||
});
|
||||
|
||||
// After functions have been executed
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
}));
|
||||
prompt += $"{verbose}\r\n";
|
||||
|
||||
prompt += "\r\n[CONVERSATION]\r\n";
|
||||
verbose = string.Join("\r\n", chatCompletionsOptions.Messages
|
||||
.Where(x => x.Role != AgentRole.System).Select(x =>
|
||||
{
|
||||
|
|
@ -311,7 +312,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
else if (x.Role == ChatRole.User)
|
||||
{
|
||||
var m = x as ChatRequestUserMessage;
|
||||
return !string.IsNullOrEmpty(m.Name) ?
|
||||
return !string.IsNullOrEmpty(m.Name) && m.Name != "route_to_agent" ?
|
||||
$"{m.Name}: {m.Content}" :
|
||||
$"{m.Role}: {m.Content}";
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue