Support postback message.

This commit is contained in:
Haiping Chen 2024-03-16 09:43:00 -05:00
parent 010bcf82eb
commit 70fdec2d3e
14 changed files with 85 additions and 27 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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