Share one message instance through the conversation.
This commit is contained in:
parent
492a1d70ee
commit
933fc3febd
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
|
@ -38,6 +39,8 @@ public class RoleDialogModel : ITrackableMessage
|
|||
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
|
||||
public bool StopCompletion { get; set; }
|
||||
|
||||
public FunctionCallFromLlm Instruction { get; set; }
|
||||
|
||||
private RoleDialogModel()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Routing;
|
||||
|
||||
|
|
@ -19,5 +18,5 @@ public interface IRoutingHandler
|
|||
|
||||
void SetDialogs(List<RoleDialogModel> dialogs) { }
|
||||
|
||||
Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst);
|
||||
Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public interface IRoutingService
|
|||
void ResetRecursiveCounter();
|
||||
void RefreshDialogs();
|
||||
Task<FunctionCallFromLlm> GetNextInstruction();
|
||||
Task<RoleDialogModel> InvokeAgent(string agentId);
|
||||
Task<RoleDialogModel> InstructLoop();
|
||||
Task<RoleDialogModel> ExecuteOnce(Agent agent);
|
||||
Task<bool> InvokeAgent(string agentId, RoleDialogModel message);
|
||||
Task<bool> InstructLoop(RoleDialogModel message);
|
||||
Task<bool> ExecuteOnce(Agent agent, RoleDialogModel message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
namespace BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
public class RoutingArgs : ITrackableMessage
|
||||
public class RoutingArgs
|
||||
{
|
||||
[JsonPropertyName("message_id")]
|
||||
public string MessageId { get; set; }
|
||||
|
||||
[JsonPropertyName("function")]
|
||||
public string Function { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace BotSharp.Core.Conversations.Services;
|
|||
public partial class ConversationService
|
||||
{
|
||||
public async Task<bool> SendMessage(string agentId,
|
||||
RoleDialogModel incoming,
|
||||
RoleDialogModel message,
|
||||
Func<RoleDialogModel, Task> onMessageReceived,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuting,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuted)
|
||||
|
|
@ -18,16 +18,16 @@ public partial class ConversationService
|
|||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
Agent agent = await agentService.LoadAgent(agentId);
|
||||
|
||||
var message = $"Received [{agent.Name}] {incoming.Role}: {incoming.Content}";
|
||||
var content = $"Received [{agent.Name}] {message.Role}: {message.Content}";
|
||||
#if DEBUG
|
||||
Console.WriteLine(message, Color.OrangeRed);
|
||||
Console.WriteLine(content, Color.OrangeRed);
|
||||
#else
|
||||
_logger.LogInformation(message);
|
||||
_logger.LogInformation(content);
|
||||
#endif
|
||||
|
||||
incoming.CurrentAgentId = agent.Id;
|
||||
message.CurrentAgentId = agent.Id;
|
||||
|
||||
_storage.Append(_conversationId, incoming);
|
||||
_storage.Append(_conversationId, message);
|
||||
|
||||
var hooks = _services.GetServices<IConversationHook>().ToList();
|
||||
|
||||
|
|
@ -37,13 +37,13 @@ public partial class ConversationService
|
|||
hook.SetAgent(agent)
|
||||
.SetConversation(conversation);
|
||||
|
||||
await hook.OnMessageReceived(incoming);
|
||||
await hook.OnMessageReceived(message);
|
||||
|
||||
// Interrupted by hook
|
||||
if (incoming.StopCompletion)
|
||||
if (message.StopCompletion)
|
||||
{
|
||||
await onMessageReceived(incoming);
|
||||
_storage.Append(_conversationId, incoming);
|
||||
await onMessageReceived(message);
|
||||
_storage.Append(_conversationId, message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -52,11 +52,11 @@ public partial class ConversationService
|
|||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
var settings = _services.GetRequiredService<RoutingSettings>();
|
||||
|
||||
var response = agentId == settings.RouterId ?
|
||||
await routing.InstructLoop() :
|
||||
await routing.ExecuteOnce(agent);
|
||||
var ret = agentId == settings.RouterId ?
|
||||
await routing.InstructLoop(message) :
|
||||
await routing.ExecuteOnce(agent, message);
|
||||
|
||||
await HandleAssistantMessage(response, onMessageReceived);
|
||||
await HandleAssistantMessage(message, onMessageReceived);
|
||||
|
||||
var statistics = _services.GetRequiredService<ITokenStatistics>();
|
||||
statistics.PrintStatistics();
|
||||
|
|
@ -64,7 +64,7 @@ public partial class ConversationService
|
|||
routing.ResetRecursiveCounter();
|
||||
routing.RefreshDialogs();
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private async Task<Conversation> GetConversationRecord(string agentId)
|
||||
|
|
|
|||
|
|
@ -66,14 +66,11 @@ public class RouteToAgentFn : IFunctionCallback
|
|||
else
|
||||
{
|
||||
message.CurrentAgentId = targetAgent.Id;
|
||||
message.Content = $"Routing to {args.AgentName}";
|
||||
}
|
||||
}
|
||||
|
||||
_context.Push(message.CurrentAgentId);
|
||||
|
||||
// Set default execution data
|
||||
message.Data = JsonSerializer.Deserialize<JsonElement>(message.FunctionArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,19 +26,15 @@ public class ContinueExecuteTaskRoutingHandler : RoutingHandlerBase, IRoutingHan
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.GetAgents(inst.AgentName).FirstOrDefault();
|
||||
|
||||
var result = new RoleDialogModel(AgentRole.Function, inst.Question)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
FunctionName = inst.Function,
|
||||
FunctionArgs = JsonSerializer.Serialize(inst.Arguments),
|
||||
CurrentAgentId = record.Id
|
||||
};
|
||||
message.FunctionName = inst.Function;
|
||||
message.CurrentAgentId = record.Id;
|
||||
message.FunctionArgs = JsonSerializer.Serialize(inst.Arguments);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,11 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
CurrentAgentId = _settings.RouterId,
|
||||
FunctionName = inst.Function,
|
||||
Data = inst
|
||||
};
|
||||
message.Content = inst.Response;
|
||||
message.FunctionName = inst.Function;
|
||||
|
||||
var hooks = _services.GetServices<IConversationHook>()
|
||||
.OrderBy(x => x.Priority)
|
||||
|
|
@ -40,9 +36,9 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
await hook.OnConversationEnding(result);
|
||||
await hook.OnConversationEnding(message);
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ public class HumanInterventionNeededHandler : RoutingHandlerBase, IRoutingHandle
|
|||
|
||||
public string Description => "Reach out to human being, customer service or customer representative.";
|
||||
|
||||
private readonly RoutingSettings _settings;
|
||||
|
||||
public List<NameDesc> Parameters => new List<NameDesc>
|
||||
{
|
||||
new NameDesc("reason", "why need customer service"),
|
||||
|
|
@ -22,18 +20,13 @@ public class HumanInterventionNeededHandler : RoutingHandlerBase, IRoutingHandle
|
|||
public HumanInterventionNeededHandler(IServiceProvider services, ILogger<HumanInterventionNeededHandler> logger, RoutingSettings settings)
|
||||
: base(services, logger, settings)
|
||||
{
|
||||
_settings = settings;
|
||||
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
CurrentAgentId = _settings.RouterId,
|
||||
FunctionName = inst.Function,
|
||||
Data = inst
|
||||
};
|
||||
message.Role = AgentRole.Assistant;
|
||||
message.Content = inst.Response;
|
||||
|
||||
var hooks = _services.GetServices<IConversationHook>()
|
||||
.OrderBy(x => x.Priority)
|
||||
|
|
@ -41,9 +34,9 @@ public class HumanInterventionNeededHandler : RoutingHandlerBase, IRoutingHandle
|
|||
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
await hook.OnHumanInterventionNeeded(result);
|
||||
await hook.OnHumanInterventionNeeded(message);
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,11 @@ public class InterruptTaskExecutionRoutingHandler : RoutingHandlerBase, IRouting
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.User, inst.Reason)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
FunctionName = inst.Function,
|
||||
StopCompletion = true
|
||||
};
|
||||
message.FunctionName = inst.Function;
|
||||
message.StopCompletion = true;
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,16 +24,11 @@ public class ResponseToUserRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
CurrentAgentId = _settings.RouterId,
|
||||
FunctionName = inst.Function,
|
||||
Data = inst,
|
||||
StopCompletion = true
|
||||
};
|
||||
return result;
|
||||
message.Content = inst.Response;
|
||||
message.StopCompletion = true;
|
||||
message.Role = AgentRole.Assistant;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,12 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
// Retrieve information from specific agent
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.GetAgents(inst.AgentName).FirstOrDefault();
|
||||
var response = await routing.InvokeAgent(record.Id);
|
||||
|
||||
inst.Response = response.Content;
|
||||
var ret = await routing.InvokeAgent(record.Id, message);
|
||||
|
||||
/*_dialogs.Add(new RoleDialogModel(AgentRole.Assistant, inst.Parameters.Question)
|
||||
{
|
||||
|
|
@ -53,11 +51,11 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
|
|||
CurrentAgentId = record.Id
|
||||
});*/
|
||||
|
||||
_router.Instruction += $"\r\n{AgentRole.Function}: {response.Content}";
|
||||
_router.Instruction += $"\r\n{AgentRole.Function}: {message.Content}";
|
||||
|
||||
// Got the response from agent, then send to reasoner again to make the decision
|
||||
// inst = await GetNextInstructionFromReasoner($"What's the next step based on user's original goal and function result?");
|
||||
|
||||
return null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,26 +28,15 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var context = _services.GetRequiredService<RoutingContext>();
|
||||
|
||||
var function = _services.GetServices<IFunctionCallback>().FirstOrDefault(x => x.Name == inst.Function);
|
||||
var message = new RoleDialogModel(AgentRole.Function, inst.Question)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
FunctionName = inst.Function,
|
||||
FunctionArgs = JsonSerializer.Serialize(inst),
|
||||
CurrentAgentId = context.GetCurrentAgentId(),
|
||||
};
|
||||
|
||||
message.FunctionArgs = JsonSerializer.Serialize(inst);
|
||||
var ret = await function.Execute(message);
|
||||
|
||||
var result = await routing.InvokeAgent(context.GetCurrentAgentId());
|
||||
// Keep last message data for debug
|
||||
result.Data = result.Data ?? message.Data;
|
||||
result.FunctionName = result.FunctionName ?? message.FunctionName;
|
||||
ret = await routing.InvokeAgent(context.GetCurrentAgentId(), message);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,25 +23,17 @@ public class TaskEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
{
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> Handle(IRoutingService routing, FunctionCallFromLlm inst)
|
||||
public async Task<bool> Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
|
||||
{
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, inst.Response)
|
||||
{
|
||||
MessageId = inst.MessageId,
|
||||
CurrentAgentId = _settings.RouterId,
|
||||
FunctionName = inst.Function,
|
||||
Data = inst
|
||||
};
|
||||
|
||||
var hooks = _services.GetServices<IConversationHook>()
|
||||
.OrderBy(x => x.Priority)
|
||||
.ToList();
|
||||
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
await hook.OnCurrentTaskEnding(result);
|
||||
await hook.OnCurrentTaskEnding(message);
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public partial class RoutingService
|
|||
|
||||
int retryCount = 0;
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var dialogs = Dialogs;
|
||||
|
||||
while (retryCount < 3)
|
||||
{
|
||||
|
|
@ -64,7 +65,7 @@ public partial class RoutingService
|
|||
{
|
||||
var conversation = "";
|
||||
|
||||
foreach (var dialog in _dialogs.TakeLast(20))
|
||||
foreach (var dialog in dialogs.TakeLast(50))
|
||||
{
|
||||
var role = dialog.Role;
|
||||
if (role != AgentRole.User)
|
||||
|
|
@ -120,9 +121,6 @@ public partial class RoutingService
|
|||
return args;
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
[MemoryCache(10 * 60)]
|
||||
#endif
|
||||
private string GetNextStepPrompt()
|
||||
{
|
||||
var template = _routerInstance.Router.Templates.First(x => x.Name == "next_step_prompt").Content;
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ public partial class RoutingService
|
|||
{
|
||||
const int MAXIMUM_RECURSION_DEPTH = 3;
|
||||
private int _currentRecursionDepth = 0;
|
||||
public async Task<RoleDialogModel> InvokeAgent(string agentId)
|
||||
public async Task<bool> InvokeAgent(string agentId, RoleDialogModel message)
|
||||
{
|
||||
_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();
|
||||
return false;
|
||||
}
|
||||
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
|
|
@ -23,50 +23,56 @@ public partial class RoutingService
|
|||
var settings = _services.GetRequiredService<ChatCompletionSetting>();
|
||||
var chatCompletion = CompletionProvider.GetChatCompletion(_services, provider: settings.Provider, model: settings.Model);
|
||||
RoleDialogModel response = chatCompletion.GetChatCompletions(agent, Dialogs);
|
||||
message.Role = response.Role;
|
||||
|
||||
if (response.Role == AgentRole.Function)
|
||||
{
|
||||
return await InvokeFunction(agent, response);
|
||||
message.FunctionName = response.FunctionName;
|
||||
message.FunctionArgs = response.FunctionArgs;
|
||||
|
||||
await InvokeFunction(agent, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
return response;
|
||||
message.Content = response.Content;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<RoleDialogModel> InvokeFunction(Agent agent, RoleDialogModel response)
|
||||
private async Task<RoleDialogModel> InvokeFunction(Agent agent, RoleDialogModel message)
|
||||
{
|
||||
// execute function
|
||||
// Save states
|
||||
SaveStateByArgs(JsonSerializer.Deserialize<JsonDocument>(response.FunctionArgs));
|
||||
SaveStateByArgs(JsonSerializer.Deserialize<JsonDocument>(message.FunctionArgs));
|
||||
|
||||
var conversationService = _services.GetRequiredService<IConversationService>();
|
||||
// Call functions
|
||||
await conversationService.CallFunctions(response);
|
||||
await conversationService.CallFunctions(message);
|
||||
|
||||
Dialogs.Add(response);
|
||||
Dialogs.Add(message);
|
||||
|
||||
// Pass execution result to LLM to get response
|
||||
if (!response.StopCompletion)
|
||||
if (!message.StopCompletion)
|
||||
{
|
||||
// Find response template
|
||||
var templateService = _services.GetRequiredService<IResponseTemplateService>();
|
||||
var responseTemplate = await templateService.RenderFunctionResponse(agent.Id, response);
|
||||
var responseTemplate = await templateService.RenderFunctionResponse(agent.Id, message);
|
||||
if (!string.IsNullOrEmpty(responseTemplate))
|
||||
{
|
||||
response.Role = AgentRole.Assistant;
|
||||
response.Content = responseTemplate.Trim();
|
||||
message.Role = AgentRole.Assistant;
|
||||
message.Content = responseTemplate.Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
response = await InvokeAgent(response.CurrentAgentId);
|
||||
await InvokeAgent(message.CurrentAgentId, message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response.Role = AgentRole.Assistant;
|
||||
message.Role = AgentRole.Assistant;
|
||||
}
|
||||
|
||||
return response;
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,38 +46,29 @@ public partial class RoutingService : IRoutingService
|
|||
_routerInstance = routerInstance;
|
||||
}
|
||||
|
||||
|
||||
public async Task<RoleDialogModel> ExecuteOnce(Agent agent)
|
||||
public async Task<bool> ExecuteOnce(Agent agent, RoleDialogModel message)
|
||||
{
|
||||
var message = Dialogs.Last().Content;
|
||||
|
||||
var handlers = _services.GetServices<IRoutingHandler>();
|
||||
|
||||
var handler = handlers.FirstOrDefault(x => x.Name == "route_to_agent");
|
||||
handler.SetDialogs(Dialogs);
|
||||
|
||||
var result = await handler.Handle(this, new FunctionCallFromLlm
|
||||
{
|
||||
Function = "route_to_agent",
|
||||
Question = message,
|
||||
Reason = message,
|
||||
Question = message.Content,
|
||||
Reason = message.Content,
|
||||
AgentName = agent.Name
|
||||
});
|
||||
}, message);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> InstructLoop()
|
||||
public async Task<bool> InstructLoop(RoleDialogModel message)
|
||||
{
|
||||
_routerInstance.Load();
|
||||
var router = _routerInstance.Router;
|
||||
|
||||
var result = new RoleDialogModel(AgentRole.Assistant, "Can you repeat your request again?")
|
||||
{
|
||||
CurrentAgentId = router.Id
|
||||
};
|
||||
|
||||
var inputMsg = Dialogs.Last();
|
||||
|
||||
var handlers = _services.GetServices<IRoutingHandler>();
|
||||
|
||||
int loopCount = 0;
|
||||
|
|
@ -87,8 +78,8 @@ public partial class RoutingService : IRoutingService
|
|||
loopCount++;
|
||||
|
||||
var inst = await GetNextInstruction();
|
||||
inst.MessageId = inputMsg.MessageId;
|
||||
inst.Question = inst.Question ?? inputMsg.Content;
|
||||
message.Instruction = inst;
|
||||
inst.Question = message.Content;
|
||||
|
||||
var handler = handlers.FirstOrDefault(x => x.Name == inst.Function);
|
||||
if (handler == null)
|
||||
|
|
@ -99,13 +90,18 @@ public partial class RoutingService : IRoutingService
|
|||
handler.SetRouter(router);
|
||||
handler.SetDialogs(Dialogs);
|
||||
|
||||
result = await handler.Handle(this, inst);
|
||||
result.MessageId = inputMsg.MessageId;
|
||||
message.FunctionName = inst.Function;
|
||||
message.Role = AgentRole.Function;
|
||||
message.FunctionArgs = inst.Arguments == null ? "{}" : JsonSerializer.Serialize(inst.Arguments);
|
||||
|
||||
await handler.Handle(this, inst, message);
|
||||
|
||||
inst.Response = message.Content;
|
||||
|
||||
stop = !_settings.EnableReasoning;
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void SaveStateByArgs(JsonDocument args)
|
||||
|
|
|
|||
|
|
@ -53,12 +53,11 @@ public class ConversationController : ControllerBase, IApiAdapter
|
|||
.SetState("sampling_factor", input.SamplingFactor);
|
||||
|
||||
var response = new MessageResponseModel();
|
||||
var stackMsg = new List<RoleDialogModel>();
|
||||
var inputMsg = new RoleDialogModel("user", input.Text);
|
||||
await conv.SendMessage(agentId, inputMsg,
|
||||
async msg =>
|
||||
{
|
||||
stackMsg.Add(msg);
|
||||
|
||||
},
|
||||
async fnExecuting =>
|
||||
{
|
||||
|
|
@ -66,14 +65,14 @@ public class ConversationController : ControllerBase, IApiAdapter
|
|||
},
|
||||
async fnExecuted =>
|
||||
{
|
||||
response.Function = fnExecuted.FunctionName;
|
||||
response.Data = fnExecuted.Data;
|
||||
|
||||
});
|
||||
|
||||
response.Text = string.Join("\r\n", stackMsg.Select(x => x.Content));
|
||||
response.Data = response.Data ?? stackMsg.Last().Data;
|
||||
response.Function = stackMsg.Last().FunctionName;
|
||||
response.MessageId = inputMsg.MessageId;
|
||||
response.Text = inputMsg.Content;
|
||||
response.Data = inputMsg.Data;
|
||||
response.Function = inputMsg.FunctionName;
|
||||
response.Instruction = inputMsg.Instruction;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Conversations;
|
||||
|
||||
|
|
@ -8,4 +10,5 @@ public class MessageResponseModel : ITrackableMessage
|
|||
public string Text { get; set; }
|
||||
public string Function { get; set; }
|
||||
public object Data { get; set; }
|
||||
public FunctionCallFromLlm Instruction { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>4fb8c9df-7975-4926-ba73-46c8ca440691</UserSecretsId>
|
||||
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ You're {{router.name}} ({{router.description}}). Follow these steps to handle us
|
|||
1. Read the [CONVERSATION] content.
|
||||
2. Select a appropriate function from [FUNCTIONS].
|
||||
3. Determine which agent is suitable to handle this conversation.
|
||||
4. If user wants to talk with human being, you will transfer to customer representative.
|
||||
4. Re-think on whether the function you chose matches the reason.
|
||||
5. For agent required arguments, leave it as blank object if user doesn't provide it.
|
||||
|
||||
[FUNCTIONS]
|
||||
|
|
|
|||
|
|
@ -1 +1,4 @@
|
|||
What is the next step based on the CONVERSATION? Response must be in appropriate JSON format. Route to the Agent that last handled the conversation if necessary.
|
||||
What is the next step based on the CONVERSATION?
|
||||
Response must be in appropriate JSON format.
|
||||
Route to the Agent that last handled the conversation if necessary.
|
||||
If user wants to speak to customer service, use function human_intervention_needed.
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace BotSharp.Plugin.PizzaBot.Functions;
|
||||
|
||||
|
|
@ -14,6 +15,7 @@ public class GetPizzaPricesFn : IFunctionCallback
|
|||
cheese_unit_price = 3.5,
|
||||
margherita_unit_price = 3.8,
|
||||
};
|
||||
message.Content = JsonSerializer.Serialize(message.Data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue