commit
893acaa493
|
|
@ -0,0 +1,40 @@
|
||||||
|
namespace BotSharp.Abstraction.Agents;
|
||||||
|
|
||||||
|
public abstract class AgentHookBase : IAgentHook
|
||||||
|
{
|
||||||
|
protected Agent _agent;
|
||||||
|
public Agent Agent => _agent;
|
||||||
|
|
||||||
|
public void SetAget(Agent agent)
|
||||||
|
{
|
||||||
|
_agent = agent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnAgentLoading(ref string id)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnInstructionLoaded(ref string instruction)
|
||||||
|
{
|
||||||
|
_agent.Instruction = instruction;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnFunctionsLoaded(ref string functions)
|
||||||
|
{
|
||||||
|
_agent.Functions = functions;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnSamplesLoaded(ref string samples)
|
||||||
|
{
|
||||||
|
_agent.Samples = samples;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Agent OnAgentLoaded()
|
||||||
|
{
|
||||||
|
return _agent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace BotSharp.Abstraction.Agents.Enums;
|
||||||
|
|
||||||
|
public class AgentRole
|
||||||
|
{
|
||||||
|
public const string System = "system";
|
||||||
|
public const string Assistant = "assistant";
|
||||||
|
public const string User = "user";
|
||||||
|
public const string Function = "function";
|
||||||
|
}
|
||||||
28
src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs
Normal file
28
src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace BotSharp.Abstraction.Agents;
|
||||||
|
|
||||||
|
public interface IAgentHook
|
||||||
|
{
|
||||||
|
Agent Agent { get; }
|
||||||
|
void SetAget(Agent agent);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered before loading, you can change the returned id to switch agent.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Agent Id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool OnAgentLoading(ref string id);
|
||||||
|
|
||||||
|
|
||||||
|
bool OnInstructionLoaded(ref string instruction);
|
||||||
|
|
||||||
|
bool OnFunctionsLoaded(ref string functions);
|
||||||
|
|
||||||
|
bool OnSamplesLoaded(ref string samples);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered when agent is loaded completely.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agent"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Agent OnAgentLoaded();
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,14 @@ public interface IAgentService
|
||||||
{
|
{
|
||||||
Task<Agent> CreateAgent(Agent agent);
|
Task<Agent> CreateAgent(Agent agent);
|
||||||
Task<List<Agent>> GetAgents();
|
Task<List<Agent>> GetAgents();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load agent configurations and triggher hooks
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<Agent> LoadAgent(string id);
|
||||||
|
|
||||||
Task<Agent> GetAgent(string id);
|
Task<Agent> GetAgent(string id);
|
||||||
Task<bool> DeleteAgent(string id);
|
Task<bool> DeleteAgent(string id);
|
||||||
Task UpdateAgent(Agent agent);
|
Task UpdateAgent(Agent agent);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
using BotSharp.Abstraction.Conversations.Models;
|
using BotSharp.Abstraction.Conversations.Models;
|
||||||
using BotSharp.Abstraction.MLTasks;
|
|
||||||
|
|
||||||
namespace BotSharp.Abstraction.Conversations;
|
namespace BotSharp.Abstraction.Conversations;
|
||||||
|
|
||||||
public abstract class ConversationCompletionHookBase : IConversationCompletionHook
|
public abstract class ConversationHookBase : IConversationHook
|
||||||
{
|
{
|
||||||
protected Agent _agent;
|
protected Agent _agent;
|
||||||
public Agent Agent => _agent;
|
public Agent Agent => _agent;
|
||||||
|
|
@ -14,34 +13,24 @@ public abstract class ConversationCompletionHookBase : IConversationCompletionHo
|
||||||
protected List<RoleDialogModel> _dialogs;
|
protected List<RoleDialogModel> _dialogs;
|
||||||
public List<RoleDialogModel> Dialogs => _dialogs;
|
public List<RoleDialogModel> Dialogs => _dialogs;
|
||||||
|
|
||||||
protected IChatCompletion _chatCompletion;
|
public IConversationHook SetAgent(Agent agent)
|
||||||
public IChatCompletion ChatCompletion => _chatCompletion;
|
|
||||||
|
|
||||||
public IConversationCompletionHook SetAgent(Agent agent)
|
|
||||||
{
|
{
|
||||||
_agent = agent;
|
_agent = agent;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IConversationCompletionHook SetConversation(Conversation conversation)
|
public IConversationHook SetConversation(Conversation conversation)
|
||||||
{
|
{
|
||||||
_conversation = conversation;
|
_conversation = conversation;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IConversationCompletionHook SetDialogs(List<RoleDialogModel> dialogs)
|
public virtual Task OnStateLoaded(ConversationState state)
|
||||||
{
|
{
|
||||||
_dialogs = dialogs;
|
return Task.CompletedTask;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IConversationCompletionHook SetChatCompletion(IChatCompletion chatCompletion)
|
public virtual Task OnStateChanged(string name, string preValue, string currentValue)
|
||||||
{
|
|
||||||
_chatCompletion = chatCompletion;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Task OnStateLoaded(ConversationState state, Action<Agent>? onAgentSwitched = null)
|
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +40,12 @@ public abstract class ConversationCompletionHookBase : IConversationCompletionHo
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Task OnFunctionExecuting(string name, string args)
|
public virtual Task OnFunctionExecuting(RoleDialogModel message)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Task OnFunctionExecuted(RoleDialogModel message)
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
@ -60,4 +54,10 @@ public abstract class ConversationCompletionHookBase : IConversationCompletionHo
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual Task OnDialogsLoaded(List<RoleDialogModel> dialogs)
|
||||||
|
{
|
||||||
|
_dialogs = dialogs;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
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 SetDialogs(List<RoleDialogModel> dialogs);
|
|
||||||
|
|
||||||
IChatCompletion ChatCompletion { get; }
|
|
||||||
IConversationCompletionHook SetChatCompletion(IChatCompletion chatCompletion);
|
|
||||||
|
|
||||||
Task OnStateLoaded(ConversationState state, Action<Agent>? onAgentSwitched = null);
|
|
||||||
Task BeforeCompletion();
|
|
||||||
Task OnFunctionExecuting(string name, string args);
|
|
||||||
Task AfterCompletion(RoleDialogModel message);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
using BotSharp.Abstraction.Conversations.Models;
|
||||||
|
using BotSharp.Abstraction.MLTasks;
|
||||||
|
|
||||||
|
namespace BotSharp.Abstraction.Conversations;
|
||||||
|
|
||||||
|
public interface IConversationHook
|
||||||
|
{
|
||||||
|
Agent Agent { get; }
|
||||||
|
IConversationHook SetAgent(Agent agent);
|
||||||
|
|
||||||
|
Conversation Conversation { get; }
|
||||||
|
IConversationHook SetConversation(Conversation conversation);
|
||||||
|
|
||||||
|
List<RoleDialogModel> Dialogs { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered when dialog history is loaded
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dialogs"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task OnDialogsLoaded(List<RoleDialogModel> dialogs);
|
||||||
|
|
||||||
|
Task OnStateLoaded(ConversationState state);
|
||||||
|
Task OnStateChanged(string name, string preValue, string currentValue);
|
||||||
|
|
||||||
|
Task BeforeCompletion();
|
||||||
|
Task OnFunctionExecuting(RoleDialogModel message);
|
||||||
|
Task OnFunctionExecuted(RoleDialogModel message);
|
||||||
|
Task AfterCompletion(RoleDialogModel message);
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,9 @@ namespace BotSharp.Abstraction.Conversations;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IConversationStateService
|
public interface IConversationStateService
|
||||||
{
|
{
|
||||||
ConversationState Load(string conversationId);
|
void SetConversation(string conversationId);
|
||||||
|
ConversationState Load();
|
||||||
string GetState(string name);
|
string GetState(string name);
|
||||||
|
void SetState(string name, string value);
|
||||||
void Save();
|
void Save();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,17 @@ public class RoleDialogModel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ExecutionResult { get; set; }
|
public string? ExecutionResult { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When function callback has been executed, system will pass result to LLM again,
|
||||||
|
/// Set this property to True to stop calling LLM.
|
||||||
|
/// </summary>
|
||||||
|
public bool StopSubsequentInteraction { get;set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Channel name
|
||||||
|
/// </summary>
|
||||||
|
public string Channel { get; set; }
|
||||||
|
|
||||||
public RoleDialogModel(string role, string text)
|
public RoleDialogModel(string role, string text)
|
||||||
{
|
{
|
||||||
Role = role;
|
Role = role;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
using BotSharp.Abstraction.Agents.Models;
|
||||||
|
|
||||||
|
namespace BotSharp.Core.Agents.Services;
|
||||||
|
|
||||||
|
public partial class AgentService
|
||||||
|
{
|
||||||
|
public async Task<Agent> LoadAgent(string id)
|
||||||
|
{
|
||||||
|
var hooks = _services.GetServices<IAgentHook>();
|
||||||
|
|
||||||
|
// Before agent is loaded.
|
||||||
|
foreach (var hook in hooks)
|
||||||
|
{
|
||||||
|
hook.OnAgentLoading(ref id);
|
||||||
|
}
|
||||||
|
|
||||||
|
var agent = await GetAgent(id);
|
||||||
|
|
||||||
|
// After agent is loaded
|
||||||
|
foreach (var hook in hooks)
|
||||||
|
{
|
||||||
|
hook.SetAget(agent);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||||
|
{
|
||||||
|
var instruction = agent.Instruction;
|
||||||
|
hook.OnInstructionLoaded(ref instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(agent.Functions))
|
||||||
|
{
|
||||||
|
var functions = agent.Functions;
|
||||||
|
hook.OnFunctionsLoaded(ref functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(agent.Samples))
|
||||||
|
{
|
||||||
|
var samples = agent.Samples;
|
||||||
|
hook.OnSamplesLoaded(ref samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
hook.OnAgentLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
return agent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using BotSharp.Abstraction.Agents.Enums;
|
||||||
using BotSharp.Abstraction.Conversations;
|
using BotSharp.Abstraction.Conversations;
|
||||||
using BotSharp.Abstraction.Conversations.Models;
|
using BotSharp.Abstraction.Conversations.Models;
|
||||||
using BotSharp.Abstraction.Functions;
|
using BotSharp.Abstraction.Functions;
|
||||||
|
|
@ -117,9 +118,6 @@ public class ConversationService : IConversationService
|
||||||
|
|
||||||
public async Task<bool> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs, Func<RoleDialogModel, Task> onMessageReceived)
|
public async Task<bool> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs, Func<RoleDialogModel, Task> onMessageReceived)
|
||||||
{
|
{
|
||||||
var agent = await _services.GetRequiredService<IAgentService>()
|
|
||||||
.GetAgent(agentId);
|
|
||||||
|
|
||||||
var converation = await GetConversation(conversationId);
|
var converation = await GetConversation(conversationId);
|
||||||
|
|
||||||
// Create conversation if this conversation not exists
|
// Create conversation if this conversation not exists
|
||||||
|
|
@ -133,13 +131,18 @@ public class ConversationService : IConversationService
|
||||||
converation = await NewConversation(sess);
|
converation = await NewConversation(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load state
|
// conversation state
|
||||||
var stateService = _services.GetRequiredService<IConversationStateService>();
|
var stateService = _services.GetRequiredService<IConversationStateService>();
|
||||||
var state = stateService.Load(conversationId);
|
stateService.SetConversation(conversationId);
|
||||||
state["agentId"] = agentId;
|
stateService.Load();
|
||||||
|
stateService.SetState("agentId", agentId);
|
||||||
|
|
||||||
|
// load agent
|
||||||
|
var agentService = _services.GetRequiredService<IAgentService>();
|
||||||
|
var agent = await agentService.LoadAgent(agentId);
|
||||||
|
|
||||||
// Get relevant domain knowledge
|
// Get relevant domain knowledge
|
||||||
if (_settings.EnableKnowledgeBase)
|
/*if (_settings.EnableKnowledgeBase)
|
||||||
{
|
{
|
||||||
var knowledge = _services.GetRequiredService<IKnowledgeService>();
|
var knowledge = _services.GetRequiredService<IKnowledgeService>();
|
||||||
agent.Knowledges = await knowledge.GetKnowledges(new KnowledgeRetrievalModel
|
agent.Knowledges = await knowledge.GetKnowledges(new KnowledgeRetrievalModel
|
||||||
|
|
@ -147,21 +150,19 @@ public class ConversationService : IConversationService
|
||||||
AgentId = agentId,
|
AgentId = agentId,
|
||||||
Question = string.Join("\n", wholeDialogs.Select(x => x.Content))
|
Question = string.Join("\n", wholeDialogs.Select(x => x.Content))
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
|
|
||||||
var chatCompletion = GetChatCompletion();
|
var chatCompletion = GetChatCompletion();
|
||||||
|
|
||||||
var hooks = _services.GetServices<IConversationCompletionHook>().ToList();
|
var hooks = _services.GetServices<IConversationHook>().ToList();
|
||||||
|
|
||||||
// Before chat completion hook
|
// Before chat completion hook
|
||||||
foreach (var hook in hooks)
|
foreach (var hook in hooks)
|
||||||
{
|
{
|
||||||
hook.SetAgent(agent)
|
hook.SetAgent(agent)
|
||||||
.SetConversation(converation)
|
.SetConversation(converation);
|
||||||
.SetDialogs(wholeDialogs)
|
|
||||||
.SetChatCompletion(chatCompletion);
|
|
||||||
|
|
||||||
await hook.OnStateLoaded(state, onAgentSwitched: x => agent = x);
|
await hook.OnDialogsLoaded(wholeDialogs);
|
||||||
await hook.BeforeCompletion();
|
await hook.BeforeCompletion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +173,7 @@ public class ConversationService : IConversationService
|
||||||
// Before executing functions
|
// Before executing functions
|
||||||
foreach (var hook in hooks)
|
foreach (var hook in hooks)
|
||||||
{
|
{
|
||||||
await hook.OnFunctionExecuting(msg.FunctionName, msg.Content);
|
await hook.OnFunctionExecuting(msg);
|
||||||
}
|
}
|
||||||
// Save states
|
// Save states
|
||||||
var jo = JsonSerializer.Deserialize<object>(msg.Content);
|
var jo = JsonSerializer.Deserialize<object>(msg.Content);
|
||||||
|
|
@ -180,11 +181,7 @@ public class ConversationService : IConversationService
|
||||||
{
|
{
|
||||||
foreach (JsonProperty property in root.EnumerateObject())
|
foreach (JsonProperty property in root.EnumerateObject())
|
||||||
{
|
{
|
||||||
string propertyName = property.Name;
|
stateService.SetState(property.Name, property.Value.ToString());
|
||||||
string propertyValue = property.Value.ToString();
|
|
||||||
|
|
||||||
_logger.LogInformation($"Set conversation state: {propertyName} - {propertyValue}");
|
|
||||||
state[propertyName] = propertyValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,6 +194,15 @@ public class ConversationService : IConversationService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await onMessageReceived(msg);
|
await onMessageReceived(msg);
|
||||||
|
|
||||||
|
if (msg.Role == AgentRole.Function)
|
||||||
|
{
|
||||||
|
// After functions have been executed
|
||||||
|
foreach (var hook in hooks)
|
||||||
|
{
|
||||||
|
await hook.OnFunctionExecuted(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using BotSharp.Abstraction.Conversations.Models;
|
using BotSharp.Abstraction.Conversations.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace BotSharp.Core.Conversations.Services;
|
namespace BotSharp.Core.Conversations.Services;
|
||||||
|
|
@ -8,27 +10,44 @@ namespace BotSharp.Core.Conversations.Services;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConversationStateService : IConversationStateService, IDisposable
|
public class ConversationStateService : IConversationStateService, IDisposable
|
||||||
{
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly IServiceProvider _services;
|
||||||
private ConversationState _state;
|
private ConversationState _state;
|
||||||
private MyDatabaseSettings _dbSettings;
|
private MyDatabaseSettings _dbSettings;
|
||||||
private string _conversationId;
|
private string _conversationId;
|
||||||
private string _file;
|
private string _file;
|
||||||
|
|
||||||
public ConversationStateService(MyDatabaseSettings dbSettings)
|
public ConversationStateService(ILogger<ConversationStateService> logger,
|
||||||
|
IServiceProvider services,
|
||||||
|
MyDatabaseSettings dbSettings)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_services = services;
|
||||||
_dbSettings = dbSettings;
|
_dbSettings = dbSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetState(string name, string value)
|
public void SetState(string name, string value)
|
||||||
{
|
{
|
||||||
_state[name] = value;
|
var hooks = _services.GetServices<IConversationHook>();
|
||||||
}
|
string preValue = _state.ContainsKey(name) ? _state[name] : "";
|
||||||
|
if (!_state.ContainsKey(name) || _state[name] != value)
|
||||||
public void Dispose()
|
|
||||||
{
|
{
|
||||||
Save();
|
var currentValue = value;
|
||||||
|
_state[name] = currentValue;
|
||||||
|
_logger.LogInformation($"Set state: {name} - {value}");
|
||||||
|
foreach (var hook in hooks)
|
||||||
|
{
|
||||||
|
hook.OnStateChanged(name, preValue, currentValue).Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConversationState Load(string conversationId)
|
public void SetConversation(string conversationId)
|
||||||
|
{
|
||||||
|
_conversationId = conversationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConversationState Load()
|
||||||
{
|
{
|
||||||
if (_state != null)
|
if (_state != null)
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +55,6 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
_state = new ConversationState();
|
_state = new ConversationState();
|
||||||
_conversationId = conversationId;
|
|
||||||
|
|
||||||
_file = GetStorageFile(_conversationId);
|
_file = GetStorageFile(_conversationId);
|
||||||
|
|
||||||
|
|
@ -45,10 +63,17 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
||||||
var dict = File.ReadAllLines(_file);
|
var dict = File.ReadAllLines(_file);
|
||||||
foreach (var line in dict)
|
foreach (var line in dict)
|
||||||
{
|
{
|
||||||
_state[line.Split(':')[0]] = line.Split(':')[1];
|
_state[line.Split('=')[0]] = line.Split('=')[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation($"Loaded state {_conversationId}");
|
||||||
|
var hooks = _services.GetServices<IConversationHook>();
|
||||||
|
foreach (var hook in hooks)
|
||||||
|
{
|
||||||
|
hook.OnStateLoaded(_state).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
return _state;
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,9 +83,10 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
||||||
|
|
||||||
foreach (var dic in _state)
|
foreach (var dic in _state)
|
||||||
{
|
{
|
||||||
states.Add($"{dic.Key}:{dic.Value}");
|
states.Add($"{dic.Key}={dic.Value}");
|
||||||
}
|
}
|
||||||
File.WriteAllLines(_file, states);
|
File.WriteAllLines(_file, states);
|
||||||
|
_logger.LogInformation($"Saved state {_conversationId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetStorageFile(string conversationId)
|
private string GetStorageFile(string conversationId)
|
||||||
|
|
@ -81,4 +107,9 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
||||||
}
|
}
|
||||||
return _state[name];
|
return _state[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,13 @@ public class ChatCompletionProvider : IChatCompletion
|
||||||
// Execute functions
|
// Execute functions
|
||||||
await onMessageReceived(funcContextIn);
|
await onMessageReceived(funcContextIn);
|
||||||
|
|
||||||
|
if (funcContextIn.StopSubsequentInteraction)
|
||||||
|
{
|
||||||
|
// Emit a fake message that should be populated by whom set StopSubsequentInteraction as True.
|
||||||
|
await onMessageReceived(new RoleDialogModel(ChatRole.Assistant.ToString(), ""));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// After function is executed, pass the result to LLM
|
// After function is executed, pass the result to LLM
|
||||||
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, funcContextIn.ExecutionResult)
|
chatCompletionsOptions.Messages.Add(new ChatMessage(ChatRole.Function, funcContextIn.ExecutionResult)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Refit;
|
using Refit;
|
||||||
|
using BotSharp.Abstraction.Agents.Enums;
|
||||||
|
|
||||||
namespace BotSharp.Plugin.MetaMessenger.Controllers;
|
namespace BotSharp.Plugin.MetaMessenger.Controllers;
|
||||||
|
|
||||||
|
|
@ -94,8 +95,15 @@ public class WebhookController : ControllerBase
|
||||||
});
|
});
|
||||||
|
|
||||||
// Go to LLM
|
// Go to LLM
|
||||||
var result = await conv.SendMessage(agentId, senderId, new RoleDialogModel("user", input), async msg =>
|
var result = await conv.SendMessage(agentId, senderId, new RoleDialogModel("user", input)
|
||||||
{
|
{
|
||||||
|
Channel = "messenger"
|
||||||
|
}, async msg =>
|
||||||
|
{
|
||||||
|
if (msg.Role == AgentRole.Function)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
content = msg.Content;
|
content = msg.Content;
|
||||||
}, async fn =>
|
}, async fn =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue