Return reason from HasMissingRequiredField.

This commit is contained in:
Haiping Chen 2024-04-24 16:45:18 -05:00
parent a1ed7616d1
commit ce7b495475
9 changed files with 31 additions and 37 deletions

View file

@ -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);
}

View file

@ -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}>";

View file

@ -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}");
}
}

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)
{

View file

@ -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}";
}