Skip to content

merge latest code #345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ public virtual Task OnFunctionExecuted(RoleDialogModel message)
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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -51,7 +52,14 @@ public async Task<bool> SendMessage(string agentId,
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ private async Task<RoleDialogModel> SendMessage(string agentId, string conversat

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Amazon.Runtime.Internal.Transform;
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories.Filters;
Expand Down Expand Up @@ -111,9 +112,11 @@ private string GetNextStepPrompt(Agent router)
{
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")}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -57,8 +57,7 @@ public async Task<bool> InvokeFunction(string name, RoleDialogModel message, boo

// restore original function name
if (!message.StopCompletion &&
message.FunctionName != originalFunctionName &&
restoreOriginalFunctionName)
message.FunctionName != originalFunctionName)
{
message.FunctionName = originalFunctionName;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ public async Task<ChatResponseModel> SendMessage([FromRoute] string agentId,
var response = new ChatResponseModel();

await conv.SendMessage(agentId, inputMsg,
replyMessage: input.Postback,
async msg =>
{
response.Text = msg.Content;
Expand All @@ -179,14 +180,8 @@ await conv.SendMessage(agentId, inputMsg,
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();
Expand Down
16 changes: 16 additions & 0 deletions src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ public override async Task OnMessageReceived(RoleDialogModel message)
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;
Expand Down
9 changes: 4 additions & 5 deletions src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,12 @@ public async Task SendMessage([FromBody] OpenAiMessageInput input)
.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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ await messenger.SendMessage(setting.ApiVersion, setting.PageId,

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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public async Task<TwiMLResult> ReceivedVoiceMessage([FromRoute] string agentId,

var result = await conv.SendMessage(agentId,
new RoleDialogModel(AgentRole.User, input.SpeechResult),
replyMessage: null,
async msg =>
{
response = twilio.ReturnInstructions(msg.Content);
Expand Down
19 changes: 9 additions & 10 deletions src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,15 @@ private async Task HandleTextMessageAsync(string openid, string message)
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)
Expand Down
16 changes: 16 additions & 0 deletions tests/BotSharp.Plugin.PizzaBot/Hooks/PizzaTypeConversationHook.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}