IFunctionCallback

This commit is contained in:
hchen2020 2023-07-30 13:22:07 -05:00
parent 323ce61eba
commit 9b917b05c9
9 changed files with 40 additions and 24 deletions

View file

@ -46,9 +46,9 @@ public abstract class ConversationCompletionHookBase : IConversationCompletionHo
return Task.CompletedTask;
}
public virtual async Task<string> OnFunctionExecution(string name, string args)
public virtual Task OnFunctionExecuting(string name, string args)
{
return "{}";
return Task.CompletedTask;
}
public virtual Task AfterCompletion(RoleDialogModel message)

View file

@ -18,6 +18,6 @@ public interface IConversationCompletionHook
IConversationCompletionHook SetChatCompletion(IChatCompletion chatCompletion);
Task BeforeCompletion();
Task<string> OnFunctionExecution(string name, string args);
Task OnFunctionExecuting(string name, string args);
Task AfterCompletion(RoleDialogModel message);
}

View file

@ -0,0 +1,7 @@
namespace BotSharp.Abstraction.Functions;
public interface IFunctionCallback
{
string Name { get; }
Task<string> Execute(string args);
}

View file

@ -1,6 +1,6 @@
using System.Text.Json;
namespace BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.Abstraction.Functions.Models;
public class FunctionDef
{

View file

@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.Abstraction.Functions.Models;
public class FunctionExecutionResult<T> where T : new()
{

View file

@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.Abstraction.Functions.Models;
public class FunctionExecutionValidationResult
{
@ -9,7 +9,7 @@ public class FunctionExecutionValidationResult
}
public FunctionExecutionValidationResult(string validationStatus, string validationMessage = "")
public FunctionExecutionValidationResult(string validationStatus, string? validationMessage = null)
{
ValidationStatus = validationStatus;
ValidationMessage = validationMessage;

View file

@ -1,10 +1,7 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Conversations.Settings;
using BotSharp.Abstraction.Functions;
using BotSharp.Abstraction.Knowledges.Models;
using BotSharp.Abstraction.MLTasks;
using MongoDB.Bson.IO;
using Newtonsoft.Json;
using System.Text.Json;
namespace BotSharp.Core.Conversations.Services;
@ -80,18 +77,25 @@ public class ConversationService : IConversationService
{
if (msg.Role == "function")
{
var result = msg.ExecutionResult.Replace("\r", " ").Replace("\n", " ");
var content = $"{result}";
Console.WriteLine($"{msg.Role}: {content}");
_storage.Append(agentId, conversationId, new RoleDialogModel(msg.Role, content)
// Invoke functions
var functions = _services.GetServices<IFunctionCallback>().Where(x => x.Name == msg.FunctionName);
foreach (var fn in functions)
{
FunctionName = msg.FunctionName,
});
msg.ExecutionResult = await fn.Execute(msg.Content);
var result = msg.ExecutionResult.Replace("\r", " ").Replace("\n", " ");
var content = $"{result}";
// Console.WriteLine($"{msg.Role}: {content}");
_storage.Append(agentId, conversationId, new RoleDialogModel(msg.Role, content)
{
FunctionName = msg.FunctionName,
});
}
}
else
{
var content = msg.Content.Replace("\r", " ").Replace("\n", " ");
Console.WriteLine($"{msg.Role}: {content}");
// Console.WriteLine($"{msg.Role}: {content}");
_storage.Append(agentId, conversationId, new RoleDialogModel(msg.Role, content));
await onMessageReceived(msg);
@ -135,10 +139,10 @@ public class ConversationService : IConversationService
{
if (msg.Role == "function")
{
// Execute functions
// Before executing functions
foreach (var hook in hooks)
{
msg.ExecutionResult = await hook.OnFunctionExecution(msg.FunctionName, msg.Content);
await hook.OnFunctionExecuting(msg.FunctionName, msg.Content);
}
}
else

View file

@ -2,6 +2,7 @@ using Azure;
using Azure.AI.OpenAI;
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.AzureOpenAI.Settings;
using System;
@ -108,10 +109,13 @@ public class ChatCompletionProvider : IChatCompletion
FunctionName = message.FunctionCall.Name
};
// Execute functions
await onMessageReceived(funcContextIn);
// After function is executed, pass the result to LLM
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, funcContextIn.ExecutionResult)
var fnResult = JsonSerializer.Deserialize<FunctionExecutionResult<object>>(funcContextIn.ExecutionResult);
var fnJsonResult = JsonSerializer.Serialize(fnResult.Result);
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, fnJsonResult)
{
Name = funcContextIn.FunctionName
});

View file

@ -56,9 +56,10 @@ namespace BotSharp.Plugin.WeChat
AgentId = AgentId
}))?.Id;
var result = await conversationService.SendMessage(AgentId, latestConversationId, new RoleDialogModel("user", message));
await ReplyTextMessageAsync(openid, result);
var result = await conversationService.SendMessage(AgentId, latestConversationId, new RoleDialogModel("user", message), async msg =>
{
await ReplyTextMessageAsync(openid, msg.Content);
});
}
private async Task<User> GetWeChatAccountUserAsync(string openId, IServiceProvider service)