commit
dec1fba4b5
|
|
@ -59,6 +59,9 @@ public abstract class ConversationHookBase : IConversationHook
|
|||
public virtual Task OnMessageReceived(RoleDialogModel message)
|
||||
=> Task.CompletedTask;
|
||||
|
||||
public virtual Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg)
|
||||
=> Task.CompletedTask;
|
||||
|
||||
public virtual Task OnResponseGenerated(RoleDialogModel message)
|
||||
=> Task.CompletedTask;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public interface IConversationHook
|
|||
Task OnStateChanged(string name, string preValue, string currentValue);
|
||||
|
||||
Task OnMessageReceived(RoleDialogModel message);
|
||||
Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg);
|
||||
|
||||
/// <summary>
|
||||
/// Triggered before LLM calls function.
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public interface IConversationService
|
|||
/// <returns></returns>
|
||||
Task<bool> SendMessage(string agentId,
|
||||
RoleDialogModel lastDalog,
|
||||
PostbackMessageModel? replyMessage,
|
||||
Func<RoleDialogModel, Task> onResponseReceived,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuting,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuted);
|
||||
|
|
|
|||
|
|
@ -4,4 +4,9 @@ public class IncomingMessageModel : MessageConfig
|
|||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
public virtual string Channel { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Postback message
|
||||
/// </summary>
|
||||
public PostbackMessageModel? Postback { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class PostbackMessageModel
|
||||
{
|
||||
public string FunctionName { get; set; } = string.Empty;
|
||||
public string Payload { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// Parent message id
|
||||
/// </summary>
|
||||
public string ParentId { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ public interface IRoutingService
|
|||
List<RoutingHandlerDef> GetHandlers(Agent router);
|
||||
void ResetRecursiveCounter();
|
||||
Task<bool> InvokeAgent(string agentId, List<RoleDialogModel> dialogs);
|
||||
Task<bool> InvokeFunction(string name, RoleDialogModel message, bool restoreOriginalFunctionName = true);
|
||||
Task<bool> InvokeFunction(string name, RoleDialogModel message);
|
||||
Task<RoleDialogModel> InstructLoop(RoleDialogModel message);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ public partial class ConversationService
|
|||
{
|
||||
public async Task<bool> SendMessage(string agentId,
|
||||
RoleDialogModel message,
|
||||
PostbackMessageModel? replyMessage,
|
||||
Func<RoleDialogModel, Task> onMessageReceived,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuting,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuted)
|
||||
|
|
@ -51,7 +52,14 @@ public partial class ConversationService
|
|||
hook.SetAgent(agent)
|
||||
.SetConversation(conversation);
|
||||
|
||||
await hook.OnMessageReceived(message);
|
||||
if (replyMessage == null)
|
||||
{
|
||||
await hook.OnMessageReceived(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
await hook.OnPostbackMessageReceived(message, replyMessage);
|
||||
}
|
||||
|
||||
// Interrupted by hook
|
||||
if (message.StopCompletion)
|
||||
|
|
|
|||
|
|
@ -97,9 +97,10 @@ public class EvaluatingService : IEvaluatingService
|
|||
|
||||
await conv.SendMessage(agentId,
|
||||
new RoleDialogModel(AgentRole.User, text),
|
||||
replyMessage: null,
|
||||
async msg => response = msg,
|
||||
fnExecuting => Task.CompletedTask,
|
||||
fnExecuted => Task.CompletedTask);
|
||||
_ => Task.CompletedTask,
|
||||
_ => Task.CompletedTask);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
|
||||
public List<ParameterPropertyDef> Parameters => new List<ParameterPropertyDef>
|
||||
{
|
||||
new ParameterPropertyDef("next_action_reason", "the reason why route to this agent")
|
||||
new ParameterPropertyDef("next_action_reason", "the reason why route to this agent, if user is replying last agent's question, you must route to this agent")
|
||||
{
|
||||
Required = true
|
||||
},
|
||||
new ParameterPropertyDef("next_action_agent", "agent for next action based on user latest response")
|
||||
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
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Amazon.Runtime.Internal.Transform;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories.Filters;
|
||||
|
|
@ -111,9 +112,11 @@ public class NaivePlanner : IPlaner
|
|||
{
|
||||
var template = router.Templates.First(x => x.Name == "planner_prompt.naive").Content;
|
||||
|
||||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
{
|
||||
{ "expected_next_action_agent", states.GetState("expected_next_action_agent")}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace BotSharp.Core.Routing;
|
|||
|
||||
public partial class RoutingService
|
||||
{
|
||||
public async Task<bool> InvokeFunction(string name, RoleDialogModel message, bool restoreOriginalFunctionName = true)
|
||||
public async Task<bool> InvokeFunction(string name, RoleDialogModel message)
|
||||
{
|
||||
var function = _services.GetServices<IFunctionCallback>().FirstOrDefault(x => x.Name == name);
|
||||
if (function == null)
|
||||
|
|
@ -57,8 +57,7 @@ public partial class RoutingService
|
|||
|
||||
// restore original function name
|
||||
if (!message.StopCompletion &&
|
||||
message.FunctionName != originalFunctionName &&
|
||||
restoreOriginalFunctionName)
|
||||
message.FunctionName != originalFunctionName)
|
||||
{
|
||||
message.FunctionName = originalFunctionName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
What is the next step based on the CONVERSATION?
|
||||
Route to the Agent that last handled the conversation if necessary.
|
||||
What is the next step based on the CONVERSATION?
|
||||
Route to the appropriate agent last handled agent based on the context.
|
||||
{% if expected_next_action_agent != empty -%}
|
||||
Expected next action agent is {{ expected_next_action_agent }}.
|
||||
{%- endif %}
|
||||
Try to keep the User Goal Agent be consistent as previous goal agent.
|
||||
If user wants to speak to customer service, use function human_intervention_needed.
|
||||
|
|
@ -171,6 +171,7 @@ public class ConversationController : ControllerBase
|
|||
var response = new ChatResponseModel();
|
||||
|
||||
await conv.SendMessage(agentId, inputMsg,
|
||||
replyMessage: input.Postback,
|
||||
async msg =>
|
||||
{
|
||||
response.Text = msg.Content;
|
||||
|
|
@ -179,14 +180,8 @@ public class ConversationController : ControllerBase
|
|||
response.Instruction = msg.Instruction;
|
||||
response.Data = msg.Data;
|
||||
},
|
||||
async fnExecuting =>
|
||||
{
|
||||
|
||||
},
|
||||
async fnExecuted =>
|
||||
{
|
||||
|
||||
});
|
||||
_ => Task.CompletedTask,
|
||||
_ => Task.CompletedTask);
|
||||
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
response.States = state.GetStates();
|
||||
|
|
|
|||
|
|
@ -59,6 +59,22 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated", BuildContentLog(input));
|
||||
}
|
||||
|
||||
public override async Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg)
|
||||
{
|
||||
var conversationId = _state.GetConversationId();
|
||||
var log = $"{message.Content}";
|
||||
var replyContent = JsonSerializer.Serialize(replyMsg, _serializerOptions);
|
||||
log += $"\r\n```json\r\n{replyContent}\r\n```";
|
||||
|
||||
var input = new ContentLogInputModel(conversationId, message)
|
||||
{
|
||||
Name = _user.UserName,
|
||||
Source = ContentLogSource.UserInput,
|
||||
Log = log
|
||||
};
|
||||
await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated", BuildContentLog(input));
|
||||
}
|
||||
|
||||
public async Task BeforeGenerating(Agent agent, List<RoleDialogModel> conversations)
|
||||
{
|
||||
if (!_convSettings.ShowVerboseLog) return;
|
||||
|
|
|
|||
|
|
@ -80,13 +80,12 @@ public class ChatbotUiController : ControllerBase
|
|||
.SetState("sampling_factor", input.SamplingFactor);
|
||||
|
||||
var result = await conv.SendMessage(input.AgentId,
|
||||
message,
|
||||
message,
|
||||
replyMessage: null,
|
||||
async msg =>
|
||||
await OnChunkReceived(outputStream, msg),
|
||||
async fn
|
||||
=> await Task.CompletedTask,
|
||||
async fn
|
||||
=> await Task.CompletedTask);
|
||||
_ => Task.CompletedTask,
|
||||
_ => Task.CompletedTask);
|
||||
|
||||
await OnEventCompleted(outputStream);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,9 @@ public class MessageHandleService
|
|||
|
||||
var replies = new List<IRichMessage>();
|
||||
var result = await conv.SendMessage(agentId,
|
||||
new RoleDialogModel(AgentRole.User, message), async msg =>
|
||||
new RoleDialogModel(AgentRole.User, message),
|
||||
replyMessage: null,
|
||||
async msg =>
|
||||
{
|
||||
if (msg.RichContent != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public class TwilioVoiceController : TwilioController
|
|||
|
||||
var result = await conv.SendMessage(agentId,
|
||||
new RoleDialogModel(AgentRole.User, input.SpeechResult),
|
||||
replyMessage: null,
|
||||
async msg =>
|
||||
{
|
||||
response = twilio.ReturnInstructions(msg.Content);
|
||||
|
|
|
|||
|
|
@ -61,16 +61,15 @@ namespace BotSharp.Plugin.WeChat
|
|||
AgentId = AgentId
|
||||
}))?.Id;
|
||||
|
||||
var result = await conversationService.SendMessage(AgentId, new RoleDialogModel("user", message), async msg =>
|
||||
{
|
||||
await ReplyTextMessageAsync(openid, msg.Content);
|
||||
}, async functionExecuting =>
|
||||
{
|
||||
|
||||
}, async functionExecuted =>
|
||||
{
|
||||
|
||||
});
|
||||
var result = await conversationService.SendMessage(AgentId,
|
||||
new RoleDialogModel("user", message),
|
||||
replyMessage: null,
|
||||
async msg =>
|
||||
{
|
||||
await ReplyTextMessageAsync(openid, msg.Content);
|
||||
},
|
||||
_ => Task.CompletedTask,
|
||||
_ => Task.CompletedTask);
|
||||
}
|
||||
|
||||
private async Task<User> GetWeChatAccountUserAsync(string openId, IServiceProvider service)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Plugin.PizzaBot.Hooks;
|
||||
|
||||
public class PizzaTypeConversationHook : ConversationHookBase
|
||||
{
|
||||
public override async Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg)
|
||||
{
|
||||
if (replyMsg.FunctionName == "get_pizza_types")
|
||||
{
|
||||
// message.StopCompletion = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue