Function execution status.
This commit is contained in:
parent
842880dbbf
commit
60ce930d4c
|
|
@ -46,6 +46,11 @@ public abstract class ConversationCompletionHookBase : IConversationCompletionHo
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual async Task<IFunctionExecutionResult> OnFunctionExecution(string name, string args)
|
||||
{
|
||||
return new FunctionExecutionValidationResult("true", "");
|
||||
}
|
||||
|
||||
public virtual Task AfterCompletion(RoleDialogModel message)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
|
|
|
|||
|
|
@ -18,5 +18,6 @@ public interface IConversationCompletionHook
|
|||
IConversationCompletionHook SetChatCompletion(IChatCompletion chatCompletion);
|
||||
|
||||
Task BeforeCompletion();
|
||||
Task<IFunctionExecutionResult> OnFunctionExecution(string name, string args);
|
||||
Task AfterCompletion(RoleDialogModel message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,9 @@ public class FunctionDef
|
|||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public JsonDocument Parameters { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name}: {Description}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public enum FunctionExecutionStatus
|
||||
{
|
||||
Success = 1,
|
||||
Failure = 2
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class FunctionExecutionValidationResult : IFunctionExecutionResult
|
||||
{
|
||||
private string _validationStatus;
|
||||
public string _validationMessage;
|
||||
|
||||
public FunctionExecutionValidationResult(string validationStatus, string validationMessage = "")
|
||||
{
|
||||
_validationStatus = validationStatus;
|
||||
_validationMessage = validationMessage;
|
||||
}
|
||||
|
||||
[JsonPropertyName("validation_status")]
|
||||
public string ValidationStatus => _validationStatus;
|
||||
|
||||
[JsonPropertyName("validation_message")]
|
||||
public string ValidationMessage => _validationMessage;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class IFunctionExecutionResult
|
||||
{
|
||||
[JsonPropertyName("execution_status")]
|
||||
public FunctionExecutionStatus ExecutionStatus { get; set; }
|
||||
}
|
||||
|
|
@ -11,7 +11,12 @@ public class RoleDialogModel
|
|||
/// <summary>
|
||||
/// Function name if LLM response function call
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
public string? Function { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Function execution result
|
||||
/// </summary>
|
||||
public string? ExecutionResult { get; set; }
|
||||
|
||||
public RoleDialogModel(string role, string text)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ namespace BotSharp.Abstraction.MLTasks;
|
|||
public interface IChatCompletion
|
||||
{
|
||||
string GetChatCompletions(Agent agent, List<RoleDialogModel> conversations);
|
||||
Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived);
|
||||
Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using BotSharp.Abstraction.Conversations.Models;
|
|||
using BotSharp.Abstraction.Conversations.Settings;
|
||||
using BotSharp.Abstraction.Knowledges.Models;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
|
|
@ -75,8 +76,17 @@ public class ConversationService : IConversationService
|
|||
|
||||
var response = await SendMessage(agentId, conversationId, wholeDialogs, async msg =>
|
||||
{
|
||||
await onMessageReceived(msg);
|
||||
_storage.Append(agentId, conversationId, new RoleDialogModel(msg.Role, msg.Content));
|
||||
var content = msg.Content.Replace("\r", " ").Replace("\n", " ");
|
||||
if (msg.Role == "function")
|
||||
{
|
||||
content += $"[{msg.Function}] {content}";
|
||||
_storage.Append(agentId, conversationId, new RoleDialogModel(msg.Role, content));
|
||||
}
|
||||
else
|
||||
{
|
||||
await onMessageReceived(msg);
|
||||
_storage.Append(agentId, conversationId, new RoleDialogModel(msg.Role, content));
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
|
|
@ -100,23 +110,39 @@ public class ConversationService : IConversationService
|
|||
|
||||
var chatCompletion = GetChatCompletion();
|
||||
|
||||
// Before chat completion hook
|
||||
var hooks = _services.GetServices<IConversationCompletionHook>().ToList();
|
||||
|
||||
hooks.ForEach(hook =>
|
||||
// Before chat completion hook
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
hook.SetAgent(agent)
|
||||
await hook.SetAgent(agent)
|
||||
.SetConversation(converation)
|
||||
.SetDialogs(wholeDialogs)
|
||||
.SetChatCompletion(chatCompletion)
|
||||
.BeforeCompletion();
|
||||
});
|
||||
|
||||
var result = await chatCompletion.GetChatCompletionsStreamingAsync(agent, wholeDialogs, async msg =>
|
||||
}
|
||||
|
||||
var result = await chatCompletion.GetChatCompletionsAsync(agent, wholeDialogs, async msg =>
|
||||
{
|
||||
// After chat completion hook
|
||||
hooks.ForEach(async hook => await hook.AfterCompletion(msg));
|
||||
await onMessageReceived(msg);
|
||||
if (msg.Role == "function")
|
||||
{
|
||||
// Execute functions
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
var executionResult = await hook.OnFunctionExecution(msg.Function, msg.Content);
|
||||
msg.ExecutionResult = JsonSerializer.Serialize(executionResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// After chat completion hook
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
await hook.AfterCompletion(msg);
|
||||
}
|
||||
|
||||
await onMessageReceived(msg);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
|
||||
{
|
||||
string totalResponse = "";
|
||||
|
|
|
|||
|
|
@ -86,6 +86,41 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
return functions;
|
||||
}
|
||||
|
||||
public async Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
|
||||
var chatCompletionsOptions = PrepareOptions(agent, conversations);
|
||||
|
||||
var response = await client.GetChatCompletionsAsync(_settings.DeploymentModel.ChatCompletionModel, chatCompletionsOptions);
|
||||
var choice = response.Value.Choices[0];
|
||||
var message = choice.Message;
|
||||
|
||||
if (choice.FinishReason == CompletionsFinishReason.FunctionCall)
|
||||
{
|
||||
if (message.FunctionCall == null || message.FunctionCall.Arguments == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Console.Write(message.FunctionCall.Name);
|
||||
Console.Write(message.FunctionCall.Arguments);
|
||||
var funcContextIn = new RoleDialogModel(ChatRole.Function.ToString(), message.FunctionCall.Arguments)
|
||||
{
|
||||
Function = message.FunctionCall.Name
|
||||
};
|
||||
await onMessageReceived(funcContextIn);
|
||||
|
||||
// After function is executed, pass the result to LLM
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write(message.Content);
|
||||
await onMessageReceived(new RoleDialogModel(ChatRole.Assistant.ToString(), message.Content));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived)
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
|
||||
|
|
@ -99,6 +134,17 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
{
|
||||
if (choice.FinishReason == CompletionsFinishReason.FunctionCall)
|
||||
{
|
||||
var args = "";
|
||||
await foreach (var message in choice.GetMessageStreaming())
|
||||
{
|
||||
if (message.FunctionCall == null || message.FunctionCall.Arguments == null)
|
||||
continue;
|
||||
Console.Write(message.FunctionCall.Arguments);
|
||||
args += message.FunctionCall.Arguments;
|
||||
|
||||
}
|
||||
await onMessageReceived(new RoleDialogModel(ChatRole.Assistant.ToString(), args));
|
||||
continue;
|
||||
}
|
||||
|
||||
await foreach (var message in choice.GetMessageStreaming())
|
||||
|
|
|
|||
Loading…
Reference in a new issue