Add IChatCompletion to IConversationCompletionHook

This commit is contained in:
hchen2020 2023-07-20 20:55:40 -05:00
parent 12e7d32be1
commit 2904c92513
12 changed files with 105 additions and 59 deletions

View file

@ -1,8 +1,9 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.MLTasks;
namespace BotSharp.Abstraction.Conversations;
public abstract class ConversationCompletionHookBase
public abstract class ConversationCompletionHookBase : IConversationCompletionHook
{
protected Agent _agent;
public Agent Agent => _agent;
@ -13,11 +14,40 @@ public abstract class ConversationCompletionHookBase
protected List<RoleDialogModel> _dialogs;
public List<RoleDialogModel> Dialogs => _dialogs;
public IConversationCompletionHook SetContexts(Agent agent, Conversation conversation, List<RoleDialogModel> dialogs)
protected IChatCompletion _chatCompletion;
public IChatCompletion ChatCompletion => _chatCompletion;
public IConversationCompletionHook SetAgent(Agent agent)
{
_agent = agent;
return this;
}
public IConversationCompletionHook SetConversation(Conversation conversation)
{
_conversation = conversation;
return this;
}
public IConversationCompletionHook SetDialogs(List<RoleDialogModel> dialogs)
{
_dialogs = dialogs;
return this as IConversationCompletionHook;
return this;
}
public IConversationCompletionHook SetChatCompletion(IChatCompletion chatCompletion)
{
_chatCompletion = chatCompletion;
return this;
}
public virtual Task BeforeCompletion()
{
return Task.CompletedTask;
}
public virtual Task<string> AfterCompletion(string response)
{
return Task.FromResult(response);
}
}

View file

@ -1,13 +1,22 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.MLTasks;
namespace BotSharp.Abstraction.Conversations;
public interface IConversationCompletionHook
{
Agent Agent { get; }
IConversationCompletionHook SetAgent(Agent agent);
Conversation Conversation { get; }
IConversationCompletionHook SetConversation(Conversation conversation);
List<RoleDialogModel> Dialogs { get; }
IConversationCompletionHook SetContexts(Agent agent, Conversation conversation, List<RoleDialogModel> dialogs);
IConversationCompletionHook SetDialogs(List<RoleDialogModel> dialogs);
IChatCompletion ChatCompletion { get; }
IConversationCompletionHook SetChatCompletion(IChatCompletion chatCompletion);
Task BeforeCompletion();
Task<string> AfterCompletion(string response);
}

View file

@ -8,6 +8,12 @@ public class RoleDialogModel
public string Role { get; set; }
public string Text { get; set; }
public RoleDialogModel(string role, string text)
{
Role = role;
Text = text;
}
public override string ToString()
{
return $"{Role}: {Text}";

View file

@ -45,11 +45,7 @@ public class ConversationController : ControllerBase, IApiAdapter
{
var conv = _services.GetRequiredService<IConversationService>();
var result = await conv.SendMessage(agentId, conversationId, new RoleDialogModel
{
Role = "user",
Text = input.Text
});
var result = await conv.SendMessage(agentId, conversationId, new RoleDialogModel("user", input.Text));
return new MessageResponseModel
{

View file

@ -53,8 +53,8 @@ public class ConversationService : IConversationService
var db = _services.GetRequiredService<AgentDbContext>();
var record = ConversationRecord.FromConversation(sess);
record.Id = Guid.NewGuid().ToString();
record.UserId = _user.Id;
record.Id = sess.Id ?? Guid.NewGuid().ToString();
record.UserId = sess.UserId ?? _user.Id;
record.Title = "New Conversation";
db.Transaction<IAgentTable>(delegate
@ -75,11 +75,7 @@ public class ConversationService : IConversationService
var response = await SendMessage(agentId, conversationId, wholeDialogs);
_storage.Append(agentId, conversationId, new RoleDialogModel
{
Role = "assistant",
Text = response
});
_storage.Append(agentId, conversationId, new RoleDialogModel("assistant", response));
return response;
}
@ -107,7 +103,10 @@ public class ConversationService : IConversationService
hooks.ForEach(hook =>
{
hook.SetContexts(agent, converation, wholeDialogs)
hook.SetAgent(agent)
.SetConversation(converation)
.SetDialogs(wholeDialogs)
.SetChatCompletion(chatCompletion)
.BeforeCompletion();
});

View file

@ -26,11 +26,7 @@ public class ConversationStorage : IConversationStorage
var pos = x.IndexOf(':');
var role = x.Substring(0, pos);
var text = x.Substring(pos + 1);
return new RoleDialogModel
{
Role = role,
Text = text
};
return new RoleDialogModel(role, text);
}).ToList();
}

View file

@ -30,10 +30,10 @@ public static class DataContextHelper
dc.BindDbContext<IAgentTable, DbContext4SqlServer2>(new DatabaseBind
{
ServiceProvider = serviceProvider,
MasterConnection = new SqlConnection(settings.Agent.Master),
SlaveConnections = settings.Agent.Slavers.Length == 0 ?
new List<DbConnection> { new SqlConnection(settings.Agent.Master) } :
settings.Agent.Slavers.Select(x => new SqlConnection(x) as DbConnection).ToList(),
MasterConnection = new SqlConnection(settings.BotSharp.Master),
SlaveConnections = settings.BotSharp.Slavers.Length == 0 ?
new List<DbConnection> { new SqlConnection(settings.BotSharp.Master) } :
settings.BotSharp.Slavers.Select(x => new SqlConnection(x) as DbConnection).ToList(),
CreateDbIfNotExist = true
});
}

View file

@ -1,10 +1,8 @@
using EntityFrameworkCore.BootKit;
namespace BotSharp.Core.Repository;
public class MyDatabaseSettings : DatabaseSettings
{
public string[] Assemblies { get; set; }
public DbConnectionSetting MongoDb { get; set; }
public DbConnectionSetting Agent { get; set; }
public DbConnectionSetting BotSharp { get; set; }
}

View file

@ -15,7 +15,7 @@ public class AzureOpenAiPlugin : IBotSharpPlugin
config.Bind("AzureOpenAi", settings);
services.AddSingleton(x => settings);
services.AddSingleton<ITextCompletion, TextCompletionProvider>();
services.AddScoped<ITextCompletion, TextCompletionProvider>();
services.AddScoped<IChatCompletion, ChatCompletionProvider>();
}
}

View file

@ -48,22 +48,31 @@ public class ChatCompletionProvider : IChatCompletion
public List<RoleDialogModel> GetChatSamples(string sampleText)
{
var samples = new List<RoleDialogModel>();
if (!string.IsNullOrEmpty(sampleText))
if (string.IsNullOrEmpty(sampleText))
{
var lines = sampleText.Split('\n');
for (int i = 0; i < lines.Length; i += 3)
{
var line = lines[i];
var role = line.Substring(0, line.IndexOf(' ') - 1).Trim();
var content = line.Substring(line.IndexOf(' ') + 1).Trim();
samples.Add(new RoleDialogModel
{
Role = role,
Text = content
});
}
return samples;
}
var lines = sampleText.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
var line = lines[i];
if (string.IsNullOrEmpty(line.Trim()))
{
continue;
}
var role = line.Substring(0, line.IndexOf(' ') - 1).Trim();
var content = line.Substring(line.IndexOf(' ') + 1).Trim();
// comments
if (role == "##")
{
continue;
}
samples.Add(new RoleDialogModel(role, content));
}
return samples;
}
@ -104,8 +113,9 @@ public class ChatCompletionProvider : IChatCompletion
{
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.System, agent.Knowledges));
}
foreach (var message in GetChatSamples(agent.Samples))
var samples = GetChatSamples(agent.Samples);
foreach (var message in samples)
{
chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Text));
}

View file

@ -59,23 +59,26 @@ public class ChatbotUiController : ControllerBase, IApiAdapter
Response.Headers.Add(HeaderNames.Connection, "keep-alive");
var outputStream = Response.Body;
var conversations = input.Messages.Select(x => new RoleDialogModel
{
Role = x.Role,
Text = x.Content
}).ToList();
var conversations = input.Messages
.Select(x => new RoleDialogModel(x.Role, x.Content))
.ToList();
var conv = _services.GetRequiredService<IConversationService>();
var conversationService = _services.GetRequiredService<IConversationService>();
// Check if this conversation exists
var converation = await conv.GetConversation(input.ConversationId);
var sess = new Conversation
var converation = await conversationService.GetConversation(input.ConversationId);
if(converation == null)
{
AgentId = input.AgentId
};
sess = await conv.NewConversation(sess);
var sess = new Conversation
{
Id = input.ConversationId,
UserId = Guid.Empty.ToString(),
AgentId = input.AgentId
};
converation = await conversationService.NewConversation(sess);
}
var result = await conv.SendMessage(input.AgentId, input.ConversationId, conversations);
var result = await conversationService.SendMessage(input.AgentId, input.ConversationId, conversations);
await OnChunkReceived(outputStream, result);
await OnEventCompleted(outputStream);

View file

@ -13,7 +13,6 @@ public class OpenAiMessageInput
[JsonPropertyName("max_tokens")]
public int MaxTokens { get; set; } = 4000;
public bool Stream { get; set; } = true;
public string? SystemPrompt { get; set; }
public float Temperature { get; set; } = 0.9f;
public override string ToString()