Skip to content

Adjust conversation history format. #93

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 3 commits into from
Aug 8, 2023
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 @@ -8,7 +8,7 @@ public interface IConversationService
Task<Conversation> GetConversation(string id);
Task<List<Conversation>> GetConversations();
Task DeleteConversation(string id);
Task<bool> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func<RoleDialogModel, Task> onMessageReceived);
Task<bool> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func<RoleDialogModel, Task> onMessageReceived, Func<RoleDialogModel, Task> onFunctionExecuting);
Task<bool> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs, Func<RoleDialogModel, Task> onMessageReceived);
List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId, int lastCount = 20);
Task CleanHistory(string agentId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class RoleDialogModel
/// user, system, assistant, function
/// </summary>
public string Role { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public string Content { get; set; }

/// <summary>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ public FunctionExecutionValidationResult(string validationStatus, string? valida
public string ValidationStatus { get; set; }

[JsonPropertyName("validation_message")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string ValidationMessage { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public async Task<MessageResponseModel> SendMessage([FromRoute] string agentId,
await conv.SendMessage(agentId, conversationId, new RoleDialogModel("user", input.Text), async msg =>
{
response.Text += msg.Content;
}, async fn =>
{

});

return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ public async Task<Conversation> NewConversation(Conversation sess)
return record.ToConversation();
}

public async Task<bool> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func<RoleDialogModel, Task> onMessageReceived)
public async Task<bool> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog,
Func<RoleDialogModel, Task> onMessageReceived,
Func<RoleDialogModel, Task> onFunctionExecuting)
{
_storage.Append(agentId, conversationId, lastDalog);

Expand All @@ -81,6 +83,8 @@ public async Task<bool> SendMessage(string agentId, string conversationId, RoleD
var functions = _services.GetServices<IFunctionCallback>().Where(x => x.Name == msg.FunctionName);
foreach (var fn in functions)
{
await onFunctionExecuting(msg);

msg.ExecutionResult = await fn.Execute(msg.Content);

var result = msg.ExecutionResult.Replace("\r", " ").Replace("\n", " ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,34 @@ public ConversationStorage(IAgentService agent)
public void Append(string agentId, string conversationId, RoleDialogModel dialog)
{
var conversationFile = GetStorageFile(agentId, conversationId);
File.AppendAllText(conversationFile, $"{dialog.Role}: {dialog.Content}\n");
var sb = new StringBuilder();
sb.AppendLine($"{dialog.Role}|{dialog.CreatedAt}|{dialog.FunctionName}");
sb.AppendLine($" - {dialog.Content}");
var conversation = sb.ToString();
File.AppendAllText(conversationFile, conversation);
}

public List<RoleDialogModel> GetDialogs(string agentId, string conversationId)
{
var conversationFile = GetStorageFile(agentId, conversationId);
var dialogs = File.ReadAllLines(conversationFile);
return dialogs.Select(x =>

var results = new List<RoleDialogModel>();
for (int i = 0; i < dialogs.Length; i += 2)
{
var pos = x.IndexOf(':');
var role = x.Substring(0, pos);
var text = x.Substring(pos + 1);
return new RoleDialogModel(role, text);
}).ToList();
var meta = dialogs[i];
var dialog = dialogs[i + 1];
var role = meta.Split('|')[0];
var createdAt = DateTime.Parse(meta.Split('|')[1]);
var text = dialog.Substring(4);
var funcName = meta.Split('|')[2];
results.Add(new RoleDialogModel(role, text)
{
FunctionName = funcName,
CreatedAt = createdAt
});
}
return results;
}

public void InitStorage(string agentId, string conversationId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.AzureOpenAI.Settings;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

Expand All @@ -15,10 +17,12 @@ namespace BotSharp.Plugin.AzureOpenAI.Providers;
public class ChatCompletionProvider : IChatCompletion
{
private readonly AzureOpenAiSettings _settings;
private readonly ILogger _logger;

public ChatCompletionProvider(AzureOpenAiSettings settings)
public ChatCompletionProvider(AzureOpenAiSettings settings, ILogger<ChatCompletionProvider> logger)
{
_settings = settings;
_logger = logger;
}

public string GetChatCompletions(Agent agent, List<RoleDialogModel> conversations)
Expand All @@ -38,6 +42,8 @@ public string GetChatCompletions(Agent agent, List<RoleDialogModel> conversation
output += message.Content;
}

_logger.LogInformation(output);

return output.Trim();
}

Expand Down Expand Up @@ -113,9 +119,7 @@ public async Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogMode
await onMessageReceived(funcContextIn);

// After function is executed, pass the result to LLM
var fnResult = JsonSerializer.Deserialize<FunctionExecutionResult<object>>(funcContextIn.ExecutionResult);
var fnJsonResult = JsonSerializer.Serialize(fnResult.Result);
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, fnJsonResult)
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, funcContextIn.ExecutionResult)
{
Name = funcContextIn.FunctionName
});
Expand All @@ -124,6 +128,9 @@ public async Task<bool> GetChatCompletionsAsync(Agent agent, List<RoleDialogMode

choice = response.Value.Choices[0];
message = choice.Message;

_logger.LogInformation(message.Content);

await onMessageReceived(new RoleDialogModel(ChatRole.Assistant.ToString(), message.Content));

return true;
Expand Down Expand Up @@ -161,6 +168,9 @@ public async Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleD
continue;
Console.Write(message.Content);
output += message.Content;

_logger.LogInformation(message.Content);

await onMessageReceived(new RoleDialogModel(message.Role.ToString(), message.Content));
}

Expand Down Expand Up @@ -205,10 +215,9 @@ private ChatCompletionsOptions PrepareOptions(Agent agent, List<RoleDialogModel>
{
if (message.Role == ChatRole.Function)
{
var funcContext = JsonSerializer.Deserialize<FunctionExecutionResult<object>>(message.Content);
chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Content)
{
Name = funcContext.Name
Name = message.FunctionName
});
}
else
Expand All @@ -217,6 +226,7 @@ private ChatCompletionsOptions PrepareOptions(Agent agent, List<RoleDialogModel>
}
}

_logger.LogInformation(string.Join("\n", chatCompletionsOptions.Messages.Select(x => $"{x.Role}: {x.Content}")));
return chatCompletionsOptions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Refit;

namespace BotSharp.Plugin.MetaMessenger.Controllers;

Expand Down Expand Up @@ -58,7 +59,6 @@ public async Task<ActionResult<WebhookResponse>> Messages([FromRoute] string age

// TODO validate request
// https://developers.facebook.com/docs/messenger-platform/webhooks#verification-requests

try
{
// received message
Expand All @@ -69,25 +69,72 @@ public async Task<ActionResult<WebhookResponse>> Messages([FromRoute] string age
string content = "";
var sessionId = req.Entry[0].Messaging[0].Sender.Id;
var input = req.Entry[0].Messaging[0].Message.Text;
var result = await conv.SendMessage(agentId, sessionId, new RoleDialogModel("user", input), async msg =>
{
content = msg.Content;
});

var setting = _services.GetRequiredService<MetaMessengerSetting>();
var messenger = _services.GetRequiredService<IMessengerGraphAPI>();
var jsonOpt = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

// Marking seen
/*await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
SenderAction = SenderActionEnum.MarkSeen
});*/

// Typing on
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
SenderAction = SenderActionEnum.TypingOn
});

// Go to LLM
var result = await conv.SendMessage(agentId, sessionId, new RoleDialogModel("user", input), async msg =>
{
content = msg.Content;
}, async fn =>
{
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
Message = JsonSerializer.Serialize(new { Text = "I'm pulling the relevent information, please wait a second ..." }, jsonOpt)
});

await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
SenderAction = SenderActionEnum.TypingOn
});
});

// Response to user
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
Message = JsonSerializer.Serialize(new { Text = content }, jsonOpt)
});

// Typing off
await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest
{
AccessToken = setting.PageAccessToken,
Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt),
SenderAction = SenderActionEnum.TypingOff
});
}
}
catch (ApiException ex)
{
Console.WriteLine(ex.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Runtime.Serialization;

namespace BotSharp.Plugin.MetaMessenger.MessagingModels;

public enum SenderActionEnum
{
[EnumMember(Value = "typing_on")]
TypingOn,
[EnumMember(Value = "typing_off")]
TypingOff,
[EnumMember(Value = "mark_seen")]
MarkSeen
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ public class SendingMessageRequest

[AliasAs("messaging_type")]
public string MessagingType { get; set; } = "RESPONSE";

[AliasAs("sender_action")]
public SenderActionEnum? SenderAction { get; set; }
}
3 changes: 3 additions & 0 deletions src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ private async Task HandleTextMessageAsync(string openid, string message)
var result = await conversationService.SendMessage(AgentId, latestConversationId, new RoleDialogModel("user", message), async msg =>
{
await ReplyTextMessageAsync(openid, msg.Content);
}, async fn =>
{

});
}

Expand Down