Add file as conversation storage.#76
This commit is contained in:
parent
a7b263e2eb
commit
29a65a0086
9
.gitignore
vendored
9
.gitignore
vendored
|
|
@ -283,12 +283,5 @@ __pycache__/
|
|||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
/BotSharp.WebHost/App_Data/BotSharp.db
|
||||
/BotSharp.UI
|
||||
/BotSharp.WebHost/App_Data/Projects
|
||||
/BotSharp.WebHost/PublishOutput
|
||||
/Data
|
||||
data
|
||||
/docs/_build
|
||||
*.RestApi.xml
|
||||
/BotSharp.WebHost/App_Data/AgentStorage
|
||||
/BotSharp.WebHost/App_Data/SessionStorage
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ public interface IAgentService
|
|||
{
|
||||
Task<Agent> CreateAgent(Agent agent);
|
||||
Task<List<Agent>> GetAgents();
|
||||
Task<Agent> GetAgent(string id);
|
||||
Task<bool> DeleteAgent(string id);
|
||||
Task UpdateAgent(Agent agent);
|
||||
string GetAgentDataDir(string agentId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,8 @@
|
|||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Infrastructures\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
using BotSharp.Abstraction.Infrastructures.ContentTransfers;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations;
|
||||
|
||||
/// <summary>
|
||||
/// IChatServiceZone is used to manage the chat function.
|
||||
/// When user send message to controller, all the registered service zone will process the message respectively.
|
||||
/// </summary>
|
||||
public interface IChatServiceZone : IServiceZone
|
||||
{
|
||||
}
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations;
|
||||
|
||||
public interface IConversationService
|
||||
{
|
||||
void AddDialog(RoleDialogModel dialog);
|
||||
List<RoleDialogModel> GetDialogHistory(string sessionId);
|
||||
void CleanHistory();
|
||||
Task<Conversation> NewConversation(Conversation conversation);
|
||||
Task<List<Conversation>> GetConversations();
|
||||
Task DeleteConversation(string id);
|
||||
Task<string> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog);
|
||||
Task<string> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs);
|
||||
List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId);
|
||||
Task CleanHistory(string agentId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations;
|
||||
|
||||
public interface IConversationStorage
|
||||
{
|
||||
void InitStorage(string agentId, string conversationId);
|
||||
void Append(string agentId, string conversationId, RoleDialogModel dialog);
|
||||
List<RoleDialogModel> GetDialogs(string agentId, string conversationId);
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations;
|
||||
|
||||
public interface ISessionService
|
||||
{
|
||||
Task<Session> NewSession(Session sess);
|
||||
Task<List<Session>> GetSessions();
|
||||
Task DeleteSession(string sessionId);
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class Session
|
||||
public class Conversation
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string AgentId { get; set; } = string.Empty;
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
|
||||
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class MessageModel
|
||||
{
|
||||
public string From { get; set; }
|
||||
public string Content { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class RoleDialogModel
|
||||
{
|
||||
/// <summary>
|
||||
/// user, system, assistant
|
||||
/// </summary>
|
||||
public string Role { get; set; }
|
||||
public string Text { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Role}: {Text}";
|
||||
}
|
||||
}
|
||||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Abstraction.Conversations.Settings;
|
|||
|
||||
public class ConversationSetting
|
||||
{
|
||||
|
||||
public string ChatCompletion { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
using BotSharp.Abstraction.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
|
||||
public class ContentContainer
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
public string SessionId { get; set; }
|
||||
public string AgentId { get; set; }
|
||||
public List<RoleDialogModel> Conversations { get; set; }
|
||||
public RoleDialogModel Output { get; set; }
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
using BotSharp.Abstraction.Infrastructures.ContentTransfers;
|
||||
|
||||
namespace BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
|
||||
public interface IContentTransfer
|
||||
{
|
||||
Task<TransportResult> Transport(ContentContainer input);
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
|
||||
namespace BotSharp.Abstraction.Infrastructures.ContentTransfers;
|
||||
|
||||
public interface IServiceZone
|
||||
{
|
||||
int Priority { get; }
|
||||
Task Serving(ContentContainer content);
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
namespace BotSharp.Abstraction.Infrastructures.ContentTransfers;
|
||||
|
||||
public class TransportResult
|
||||
{
|
||||
public bool IsSuccess { get; set; }
|
||||
public List<string> Messages { get; set; }
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.MLTasks;
|
||||
|
||||
public interface IChatCompletion
|
||||
{
|
||||
Task<string> GetChatCompletionsAsync(List<RoleDialogModel> conversations);
|
||||
Task<string> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
namespace BotSharp.Abstraction.Models;
|
||||
|
||||
public class RoleDialogModel
|
||||
{
|
||||
public string Role { get; set; }
|
||||
public string Text { get; set; }
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Abstraction.ApiAdapters;
|
||||
using BotSharp.Core.Agents.ViewModels;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
namespace BotSharp.Core.Agents.Services;
|
||||
|
||||
public partial class AgentService : IChatServiceZone
|
||||
{
|
||||
public int Priority => 10;
|
||||
|
||||
/// <summary>
|
||||
/// Prepare agent profile and configurations
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
public async Task Serving(ContentContainer content)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Agents.Services;
|
||||
|
||||
|
|
@ -12,4 +13,20 @@ public partial class AgentService
|
|||
select agent.ToAgent();
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
public async Task<Agent> GetAgent(string id)
|
||||
{
|
||||
var db = _services.GetRequiredService<AgentDbContext>();
|
||||
var query = from agent in db.Agent
|
||||
where agent.OwnerId == _user.Id && agent.Id == id
|
||||
select agent.ToAgent();
|
||||
|
||||
var profile = query.FirstOrDefault();
|
||||
var dir = GetAgentDataDir(id);
|
||||
|
||||
profile.Instruction = File.ReadAllText(Path.Combine(dir, "instruction.txt"));
|
||||
profile.Samples = File.ReadAllText(Path.Combine(dir, "samples.txt"));
|
||||
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ public partial class AgentService
|
|||
|
||||
record.Name = agent.Name;
|
||||
record.Description = agent.Description;
|
||||
record.Instruction = agent.Instruction;
|
||||
record.Samples = agent.Samples;
|
||||
record.UpdatedDateTime = DateTime.UtcNow;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Agents.Services;
|
||||
|
||||
public partial class AgentService : IAgentService
|
||||
|
|
@ -10,4 +12,14 @@ public partial class AgentService : IAgentService
|
|||
_services = services;
|
||||
_user = user;
|
||||
}
|
||||
|
||||
public string GetAgentDataDir(string agentId)
|
||||
{
|
||||
var dir = Path.Combine("data", agentId);
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Conversations.Settings;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
|
|
@ -11,14 +12,14 @@ public static class BotSharpServiceCollectionExtensions
|
|||
services.AddScoped<IUserService, UserService>();
|
||||
|
||||
services.AddScoped<IAgentService, AgentService>();
|
||||
services.AddScoped<IChatServiceZone, AgentService>();
|
||||
|
||||
services.AddScoped<ISessionService, SessionService>();
|
||||
var convsationSettings = new ConversationSetting();
|
||||
config.Bind("Conversation", convsationSettings);
|
||||
services.AddSingleton((IServiceProvider x) => convsationSettings);
|
||||
|
||||
services.AddScoped<IConversationStorage, ConversationStorage>();
|
||||
services.AddScoped<IConversationService, ConversationService>();
|
||||
|
||||
services.AddScoped<IContentTransfer, ContentTransfer>();
|
||||
|
||||
RegisterRepository(services, config);
|
||||
|
||||
RegisterPlugins(services, config);
|
||||
|
|
@ -46,17 +47,11 @@ public static class BotSharpServiceCollectionExtensions
|
|||
{
|
||||
var databaseSettings = new DatabaseSettings();
|
||||
config.Bind("Database", databaseSettings);
|
||||
services.AddSingleton((IServiceProvider x) =>
|
||||
{
|
||||
return databaseSettings;
|
||||
});
|
||||
services.AddSingleton((IServiceProvider x) => databaseSettings);
|
||||
|
||||
var myDatabaseSettings = new MyDatabaseSettings();
|
||||
config.Bind("Database", myDatabaseSettings);
|
||||
services.AddSingleton((IServiceProvider x) =>
|
||||
{
|
||||
return databaseSettings;
|
||||
});
|
||||
services.AddSingleton((IServiceProvider x) => databaseSettings);
|
||||
|
||||
services.AddScoped((IServiceProvider x) =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,50 +21,39 @@ public class ConversationController : ControllerBase, IApiAdapter
|
|||
}
|
||||
|
||||
[HttpPost("/conversation/{agentId}")]
|
||||
public async Task<SessionViewModel> NewSession([FromRoute] string agentId)
|
||||
public async Task<ConversationViewModel> NewConversation([FromRoute] string agentId)
|
||||
{
|
||||
var service = _services.GetRequiredService<ISessionService>();
|
||||
var sess = new Session
|
||||
var service = _services.GetRequiredService<IConversationService>();
|
||||
var sess = new Conversation
|
||||
{
|
||||
AgentId = agentId
|
||||
};
|
||||
sess = await service.NewSession(sess);
|
||||
return SessionViewModel.FromSession(sess);
|
||||
sess = await service.NewConversation(sess);
|
||||
return ConversationViewModel.FromSession(sess);
|
||||
}
|
||||
|
||||
[HttpDelete("/conversation/{agentId}/{sessionId}")]
|
||||
public async Task DeleteSession([FromRoute] string agentId, [FromRoute] string sessionId)
|
||||
[HttpDelete("/conversation/{agentId}/{conversationId}")]
|
||||
public async Task DeleteConversation([FromRoute] string agentId, [FromRoute] string conversationId)
|
||||
{
|
||||
var service = _services.GetRequiredService<ISessionService>();
|
||||
var service = _services.GetRequiredService<IConversationService>();
|
||||
}
|
||||
|
||||
[HttpPost("/conversation/{agentId}/{sessionId}")]
|
||||
[HttpPost("/conversation/{agentId}/{conversationId}")]
|
||||
public async Task<MessageResponseModel> SendMessage([FromRoute] string agentId,
|
||||
[FromRoute] string sessionId,
|
||||
[FromRoute] string conversationId,
|
||||
[FromBody] NewMessageModel input)
|
||||
{
|
||||
var transmitter = _services.GetRequiredService<IContentTransfer>();
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
|
||||
var container = new ContentContainer
|
||||
{
|
||||
AgentId = agentId,
|
||||
SessionId = sessionId,
|
||||
Conversations = new List<RoleDialogModel>
|
||||
{
|
||||
new RoleDialogModel
|
||||
var result = await conv.SendMessage(agentId, conversationId, new RoleDialogModel
|
||||
{
|
||||
Role = "user",
|
||||
Text = input.Text
|
||||
}
|
||||
},
|
||||
UserId = _user.Id
|
||||
};
|
||||
|
||||
var result = await transmitter.Transport(container);
|
||||
});
|
||||
|
||||
return new MessageResponseModel
|
||||
{
|
||||
Content = result.IsSuccess ? container.Output.Text : result.Messages.First()
|
||||
Content = result
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,52 +1,100 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Conversations.Settings;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
public class ConversationService : IConversationService
|
||||
{
|
||||
Dictionary<string, List<RoleDialogModel>> _history;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IUserIdentity _user;
|
||||
private readonly ConversationSetting _settings;
|
||||
private readonly IConversationStorage _storage;
|
||||
|
||||
public ConversationService()
|
||||
public ConversationService(IServiceProvider services,
|
||||
IUserIdentity user,
|
||||
ConversationSetting settings,
|
||||
IConversationStorage storage)
|
||||
{
|
||||
_history = new Dictionary<string, List<RoleDialogModel>>();
|
||||
_services = services;
|
||||
_user = user;
|
||||
_settings = settings;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public void AddDialog(RoleDialogModel dialog)
|
||||
{
|
||||
_history[Guid.Empty.ToString()].Add(dialog);
|
||||
}
|
||||
|
||||
public void CleanHistory()
|
||||
public Task DeleteConversation(string id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DeleteSession()
|
||||
public async Task<List<Conversation>> GetConversations()
|
||||
{
|
||||
var db = _services.GetRequiredService<AgentDbContext>();
|
||||
var query = from sess in db.Conversation
|
||||
where sess.UserId == _user.Id
|
||||
orderby sess.CreatedTime descending
|
||||
select sess.ToConversation();
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
public async Task<Conversation> NewConversation(Conversation sess)
|
||||
{
|
||||
var db = _services.GetRequiredService<AgentDbContext>();
|
||||
|
||||
var record = ConversationRecord.FromConversation(sess);
|
||||
record.Id = Guid.NewGuid().ToString();
|
||||
record.UserId = _user.Id;
|
||||
record.Title = "New Conversation";
|
||||
|
||||
db.Transaction<IAgentTable>(delegate
|
||||
{
|
||||
db.Add<IAgentTable>(record);
|
||||
});
|
||||
|
||||
_storage.InitStorage(sess.AgentId, record.Id);
|
||||
|
||||
return record.ToConversation();
|
||||
}
|
||||
|
||||
public async Task<string> SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog)
|
||||
{
|
||||
_storage.Append(agentId, conversationId, lastDalog);
|
||||
|
||||
var wholeDialogs = GetDialogHistory(agentId, conversationId);
|
||||
|
||||
var response = await SendMessage(agentId, conversationId, wholeDialogs);
|
||||
|
||||
_storage.Append(agentId, conversationId, new RoleDialogModel
|
||||
{
|
||||
Role = "assistant",
|
||||
Text = response
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public async Task<string> SendMessage(string agentId, string conversationId, List<RoleDialogModel> wholeDialogs)
|
||||
{
|
||||
var agent = await _services.GetRequiredService<IAgentService>().GetAgent(agentId);
|
||||
var chat = GetChatCompletion();
|
||||
var response = await chat.GetChatCompletionsAsync(agent, wholeDialogs);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public IChatCompletion GetChatCompletion()
|
||||
{
|
||||
var completions = _services.GetServices<IChatCompletion>();
|
||||
return completions.FirstOrDefault(x => x.GetType().FullName.Contains(_settings.ChatCompletion));
|
||||
}
|
||||
|
||||
public Task CleanHistory(string agentId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<string> GetAllSessions()
|
||||
public List<RoleDialogModel> GetDialogHistory(string agentId, string conversationId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetDialogHistory()
|
||||
{
|
||||
return _history[Guid.Empty.ToString()];
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetDialogHistory(string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string NewSession()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return _storage.GetDialogs(agentId, conversationId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
public class ConversationStorage : IConversationStorage
|
||||
{
|
||||
private readonly IAgentService _agent;
|
||||
public ConversationStorage(IAgentService agent)
|
||||
{
|
||||
_agent = agent;
|
||||
}
|
||||
|
||||
public void Append(string agentId, string conversationId, RoleDialogModel dialog)
|
||||
{
|
||||
var conversationFile = GetStorageFile(agentId, conversationId);
|
||||
File.AppendAllText(conversationFile, $"{dialog.Role}: {dialog.Text}\n");
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetDialogs(string agentId, string conversationId)
|
||||
{
|
||||
var conversationFile = GetStorageFile(agentId, conversationId);
|
||||
var dialogs = File.ReadAllLines(conversationFile);
|
||||
return dialogs.Select(x =>
|
||||
{
|
||||
var pos = x.IndexOf(':');
|
||||
var role = x.Substring(0, pos);
|
||||
var text = x.Substring(pos + 1);
|
||||
return new RoleDialogModel
|
||||
{
|
||||
Role = role,
|
||||
Text = text
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public void InitStorage(string agentId, string conversationId)
|
||||
{
|
||||
var dir = _agent.GetAgentDataDir(agentId);
|
||||
var dialogDir = Path.Combine(dir, "conversations");
|
||||
if (!Directory.Exists(dialogDir))
|
||||
{
|
||||
Directory.CreateDirectory(dialogDir);
|
||||
}
|
||||
|
||||
var conversationFile = Path.Combine(dialogDir, conversationId + ".txt");
|
||||
if (!File.Exists(conversationFile))
|
||||
{
|
||||
File.WriteAllLines(conversationFile, new string[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetStorageFile(string agentId, string conversationId)
|
||||
{
|
||||
var dir = _agent.GetAgentDataDir(agentId);
|
||||
var dialogDir = Path.Combine(dir, "conversations");
|
||||
return Path.Combine(dialogDir, conversationId + ".txt");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Users;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
public class SessionService : ISessionService
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IUserIdentity _user;
|
||||
|
||||
public SessionService(IServiceProvider services, IUserIdentity user)
|
||||
{
|
||||
_services = services;
|
||||
_user = user;
|
||||
}
|
||||
|
||||
public Task DeleteSession(string sessionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<List<Session>> GetSessions()
|
||||
{
|
||||
var db = _services.GetRequiredService<AgentDbContext>();
|
||||
var query = from sess in db.Session
|
||||
where sess.UserId == _user.Id
|
||||
orderby sess.CreatedTime descending
|
||||
select sess.ToSession();
|
||||
return query.ToList();
|
||||
}
|
||||
|
||||
public async Task<Session> NewSession(Session sess)
|
||||
{
|
||||
var db = _services.GetRequiredService<AgentDbContext>();
|
||||
|
||||
var record = SessionRecord.FromSession(sess);
|
||||
record.Id = Guid.NewGuid().ToString();
|
||||
record.UserId = _user.Id;
|
||||
record.Title = "New Session";
|
||||
|
||||
db.Transaction<IAgentTable>(delegate
|
||||
{
|
||||
db.Add<IAgentTable>(record);
|
||||
});
|
||||
|
||||
return record.ToSession();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
namespace BotSharp.Core.Conversations.ViewModels;
|
||||
|
||||
public class ConversationCreationModel
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ using BotSharp.Abstraction.Conversations.Models;
|
|||
|
||||
namespace BotSharp.Core.Conversations.ViewModels;
|
||||
|
||||
public class SessionViewModel
|
||||
public class ConversationViewModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string AgentId { get; set; }
|
||||
|
|
@ -10,9 +10,9 @@ public class SessionViewModel
|
|||
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
|
||||
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public static SessionViewModel FromSession(Session sess)
|
||||
public static ConversationViewModel FromSession(Conversation sess)
|
||||
{
|
||||
return new SessionViewModel
|
||||
return new ConversationViewModel
|
||||
{
|
||||
Id = sess.Id,
|
||||
AgentId = sess.AgentId,
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Core.Conversations.ViewModels;
|
||||
|
||||
public class SessionCreationModel
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
namespace BotSharp.Core.Infrastructures;
|
||||
|
||||
public class ContentTransfer : IContentTransfer
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public ContentTransfer(IServiceProvider services)
|
||||
{
|
||||
_services = services;
|
||||
}
|
||||
|
||||
public async Task<TransportResult> Transport(ContentContainer input)
|
||||
{
|
||||
input.Output = new RoleDialogModel();
|
||||
|
||||
var result = new TransportResult
|
||||
{
|
||||
IsSuccess = true,
|
||||
Messages = new List<string>()
|
||||
};
|
||||
|
||||
var zones = _services.GetServices<IChatServiceZone>()
|
||||
.OrderBy(x => x.Priority)
|
||||
.ToList();
|
||||
|
||||
foreach (var zone in zones)
|
||||
{
|
||||
try
|
||||
{
|
||||
await zone.Serving(input);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.IsSuccess = false;
|
||||
result.Messages.Add(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -9,14 +9,17 @@ public class KnowledgeService : IKnowledgeService
|
|||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly KnowledgeBaseSettings _settings;
|
||||
private readonly IAgentService _agentService;
|
||||
private readonly ITextChopper _textChopper;
|
||||
|
||||
public KnowledgeService(IServiceProvider services,
|
||||
KnowledgeBaseSettings settings,
|
||||
IAgentService agentService,
|
||||
ITextChopper textChopper)
|
||||
{
|
||||
_services = services;
|
||||
_settings = settings;
|
||||
_agentService = agentService;
|
||||
_textChopper = textChopper;
|
||||
}
|
||||
|
||||
|
|
@ -30,13 +33,8 @@ public class KnowledgeService : IKnowledgeService
|
|||
});
|
||||
|
||||
// Store chunks in local file system
|
||||
var knowledgeStoreDir = Path.Combine("knowledge_base");
|
||||
if (!Directory.Exists(knowledgeStoreDir))
|
||||
{
|
||||
Directory.CreateDirectory(knowledgeStoreDir);
|
||||
}
|
||||
|
||||
var knowledgePath = Path.Combine(knowledgeStoreDir, knowledge.AgentId + ".txt");
|
||||
var agentDataDir = _agentService.GetAgentDataDir(knowledge.AgentId);
|
||||
var knowledgePath = Path.Combine(agentDataDir, "knowledge.txt");
|
||||
File.WriteAllLines(knowledgePath, lines);
|
||||
|
||||
var db = GetVectorDb();
|
||||
|
|
@ -57,7 +55,8 @@ public class KnowledgeService : IKnowledgeService
|
|||
var vector = textEmbedding.GetVector(retrievalModel.Question);
|
||||
|
||||
// Scan local knowledge directory
|
||||
var chunks = File.ReadAllLines(Path.Combine("knowledge_base", retrievalModel.AgentId + ".txt"));
|
||||
var agentDataDir = _agentService.GetAgentDataDir(retrievalModel.AgentId);
|
||||
var chunks = File.ReadAllLines(Path.Combine(agentDataDir, "knowledge.txt"));
|
||||
|
||||
// Vector search
|
||||
var result = await GetVectorDb().Search(retrievalModel.AgentId, vector);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using LLama;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Plugins.LLamaSharp;
|
||||
|
||||
public class ChatCompletionProvider : IChatServiceZone
|
||||
public class ChatCompletionProvider : IChatCompletion
|
||||
{
|
||||
private readonly IChatModel _model;
|
||||
private readonly LlamaSharpSettings _settings;
|
||||
|
|
@ -42,6 +45,21 @@ public class ChatCompletionProvider : IChatServiceZone
|
|||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public Task<string> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations)
|
||||
{
|
||||
string totalResponse = "";
|
||||
var prompt = GetInstruction();
|
||||
var content = string.Join("\n ", conversations.Select(x => $"{x.Role}: {x.Text.Replace("user:", "")}")).Trim();
|
||||
content += "\n assistant: ";
|
||||
foreach (var response in _model.Chat(content, prompt, "UTF-8"))
|
||||
{
|
||||
Console.Write(response);
|
||||
totalResponse += response;
|
||||
}
|
||||
|
||||
return Task.FromResult(totalResponse);
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetChatSamples()
|
||||
{
|
||||
var samples = new List<RoleDialogModel>();
|
||||
|
|
@ -80,19 +98,4 @@ public class ChatCompletionProvider : IChatServiceZone
|
|||
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public async Task Serving(ContentContainer content)
|
||||
{
|
||||
string output = "";
|
||||
var prompt = GetInstruction();
|
||||
var conversations = string.Join("\n ", content.Conversations.Select(x => $"{x.Role}: {x.Text.Replace("user:", "")}")).Trim();
|
||||
conversations += "\n assistant: ";
|
||||
foreach (var response in _model.Chat(conversations, prompt, "UTF-8"))
|
||||
{
|
||||
Console.Write(response);
|
||||
output += response;
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.MLTasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace BotSharp.Core.Plugins.LLamaSharp;
|
||||
|
|
@ -10,6 +11,6 @@ public class LLamaSharpPlugin : IBotSharpPlugin
|
|||
config.Bind("LlamaSharp", llamaSharpSettings);
|
||||
services.AddSingleton(x => llamaSharpSettings);
|
||||
|
||||
services.AddScoped<IServiceZone, ChatCompletionProvider>();
|
||||
services.AddScoped<IChatCompletion, ChatCompletionProvider>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.VectorStorage;
|
||||
using Tensorflow;
|
||||
using Tensorflow.NumPy;
|
||||
|
||||
namespace BotSharp.Core.Plugins.MemVecDb;
|
||||
|
|
@ -21,15 +22,17 @@ public class MemVectorDatabase : IVectorDb
|
|||
|
||||
public Task<List<int>> Search(string collectionName, float[] vector, int limit = 10)
|
||||
{
|
||||
var cosineList = new List<double>();
|
||||
var similarities = new float[_vectors[collectionName].Count];
|
||||
for (int i = 0; i < _vectors[collectionName].Count; i++)
|
||||
{
|
||||
var p = CalCosineSimilarity(vector, _vectors[collectionName][i].Vector);
|
||||
cosineList.Add(p);
|
||||
similarities[i] = CalCosineSimilarity(vector, _vectors[collectionName][i].Vector);
|
||||
}
|
||||
var similarities = cosineList.ToArray();
|
||||
|
||||
var indice = np.argsort(similarities).ToArray<int>()
|
||||
.Reverse().Take(limit).ToList();
|
||||
.Reverse()
|
||||
.Take(limit)
|
||||
.ToList();
|
||||
|
||||
return Task.FromResult(indice);
|
||||
}
|
||||
|
||||
|
|
@ -44,24 +47,8 @@ public class MemVectorDatabase : IVectorDb
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private double CalCosineSimilarity(float[] vector1, float[] vector2)
|
||||
private float CalCosineSimilarity(float[] a, float[] b)
|
||||
{
|
||||
NDArray a = vector1;
|
||||
NDArray b = vector2;
|
||||
double num = np.dot(a, b);
|
||||
if(num == 0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
b = np.square(a);
|
||||
var x = np.sqrt(np.sum(b));
|
||||
var x3 = np.sum(np.square(vector2));
|
||||
double num2 = np.sqrt(x) * np.sqrt(x3);
|
||||
if(num2 == 0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
return num / num2;
|
||||
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ public class AgentDbContext : Database
|
|||
{
|
||||
public IQueryable<UserRecord> User => Table<UserRecord>();
|
||||
public IQueryable<AgentRecord> Agent => Table<AgentRecord>();
|
||||
public IQueryable<SessionRecord> Session => Table<SessionRecord>();
|
||||
public IQueryable<ConversationRecord> Conversation => Table<ConversationRecord>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using MongoDB.Bson.Serialization.IdGenerators;
|
|||
|
||||
namespace BotSharp.Core.Repository.Collections;
|
||||
|
||||
public class Conversation : IMongoDbCollection
|
||||
public class ConversationCollection : IMongoDbCollection
|
||||
{
|
||||
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||
public ObjectId Id { get; set; }
|
||||
|
|
@ -15,7 +15,7 @@ public class Conversation : IMongoDbCollection
|
|||
public string Model { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
public List<MessageModel> Messages { get; set; }
|
||||
public List<RoleDialogModel> Messages { get; set; }
|
||||
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
|
@ -18,18 +18,6 @@ public class AgentRecord : DbRecord, IAgentTable
|
|||
[MaxLength(512)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Instruction
|
||||
/// </summary>
|
||||
[StringLength(int.MaxValue)]
|
||||
public string Instruction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Samples
|
||||
/// </summary>
|
||||
[StringLength(int.MaxValue)]
|
||||
public string Samples { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime CreatedDateTime { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
|
||||
namespace BotSharp.Core.Repository.DbTables;
|
||||
|
||||
[Table("Session")]
|
||||
public class SessionRecord : DbRecord, IAgentTable
|
||||
[Table("Conversation")]
|
||||
public class ConversationRecord : DbRecord, IAgentTable
|
||||
{
|
||||
[Required]
|
||||
[MaxLength(36)]
|
||||
|
|
@ -24,22 +24,22 @@ public class SessionRecord : DbRecord, IAgentTable
|
|||
[Required]
|
||||
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public static SessionRecord FromSession(Session sess)
|
||||
public static ConversationRecord FromConversation(Conversation conv)
|
||||
{
|
||||
return new SessionRecord
|
||||
return new ConversationRecord
|
||||
{
|
||||
AgentId = sess.AgentId,
|
||||
UserId = sess.UserId,
|
||||
Id = sess.Id,
|
||||
Title = sess.Title,
|
||||
CreatedTime = sess.CreatedTime,
|
||||
UpdatedTime = sess.UpdatedTime
|
||||
AgentId = conv.AgentId,
|
||||
UserId = conv.UserId,
|
||||
Id = conv.Id,
|
||||
Title = conv.Title,
|
||||
CreatedTime = conv.CreatedTime,
|
||||
UpdatedTime = conv.UpdatedTime
|
||||
};
|
||||
}
|
||||
|
||||
public Session ToSession()
|
||||
public Conversation ToConversation()
|
||||
{
|
||||
return new Session
|
||||
return new Conversation
|
||||
{
|
||||
Id = Id,
|
||||
Title = Title,
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
using BotSharp.Core.Repository.Collections;
|
||||
using EntityFrameworkCore.BootKit;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace BotSharp.Core.Repository;
|
||||
|
||||
public class MongoDbContext : Database
|
||||
{
|
||||
public IMongoCollection<Conversation> Conversations
|
||||
=> Collection<Conversation>("conversations");
|
||||
public IMongoCollection<ConversationCollection> Conversations
|
||||
=> Collection<ConversationCollection>("conversations");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,8 @@ global using BotSharp.Abstraction.Plugins;
|
|||
global using EntityFrameworkCore.BootKit;
|
||||
global using BotSharp.Abstraction.Agents;
|
||||
global using BotSharp.Abstraction.Conversations;
|
||||
global using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
global using BotSharp.Abstraction.Infrastructures.ContentTransfers;
|
||||
global using BotSharp.Abstraction.Knowledges;
|
||||
global using BotSharp.Abstraction.Users;
|
||||
global using BotSharp.Abstraction.Models;
|
||||
global using BotSharp.Core.Repository;
|
||||
global using BotSharp.Core.Repository.Abstraction;
|
||||
global using BotSharp.Core.Repository.DbTables;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Abstraction.Plugins;
|
||||
using BotSharp.Plugin.AzureOpenAI.Providers;
|
||||
using BotSharp.Plugin.AzureOpenAI.Services;
|
||||
using BotSharp.Plugin.AzureOpenAI.Settings;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -19,6 +17,5 @@ public class AzureOpenAiPlugin : IBotSharpPlugin
|
|||
|
||||
services.AddSingleton<ITextCompletion, TextCompletionProvider>();
|
||||
services.AddScoped<IChatCompletion, ChatCompletionProvider>();
|
||||
services.AddScoped<IChatServiceZone, ChatService>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
using Azure;
|
||||
using Azure.AI.OpenAI;
|
||||
using BotSharp.Abstraction.Infrastructures.ContentTransfers;
|
||||
using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Plugin.AzureOpenAI.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -21,7 +20,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
_settings = settings;
|
||||
}
|
||||
|
||||
public async Task GetChatCompletionsAsync(List<RoleDialogModel> conversations,
|
||||
/*public async Task GetChatCompletionsAsync(List<RoleDialogModel> conversations,
|
||||
Func<string, Task> onChunkReceived)
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
|
||||
|
|
@ -44,14 +43,14 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}*/
|
||||
|
||||
public List<RoleDialogModel> GetChatSamples()
|
||||
public List<RoleDialogModel> GetChatSamples(string sampleText)
|
||||
{
|
||||
var samples = new List<RoleDialogModel>();
|
||||
if (!string.IsNullOrEmpty(_settings.ChatSampleFile))
|
||||
if (!string.IsNullOrEmpty(sampleText))
|
||||
{
|
||||
var lines = File.ReadAllLines(_settings.ChatSampleFile);
|
||||
var lines = sampleText.Split('\n');
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
|
|
@ -68,19 +67,11 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
return samples;
|
||||
}
|
||||
|
||||
public string GetInstruction()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_settings.InstructionFile))
|
||||
{
|
||||
return File.ReadAllText(_settings.InstructionFile);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public async Task<string> GetChatCompletionsAsync(List<RoleDialogModel> conversations)
|
||||
public async Task<string> GetChatCompletionsAsync(Agent agent, List<RoleDialogModel> conversations)
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
|
||||
var chatCompletionsOptions = PrepareOptions(conversations);
|
||||
var chatCompletionsOptions = PrepareOptions(agent, conversations);
|
||||
|
||||
var response = await client.GetChatCompletionsStreamingAsync(_settings.DeploymentModel.ChatCompletionModel, chatCompletionsOptions);
|
||||
using StreamingChatCompletions streaming = response.Value;
|
||||
|
|
@ -100,18 +91,17 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
return output;
|
||||
}
|
||||
|
||||
private ChatCompletionsOptions PrepareOptions(List<RoleDialogModel> conversations)
|
||||
private ChatCompletionsOptions PrepareOptions(Agent agent, List<RoleDialogModel> conversations)
|
||||
{
|
||||
var prompt = GetInstruction();
|
||||
var chatCompletionsOptions = new ChatCompletionsOptions()
|
||||
{
|
||||
Messages =
|
||||
{
|
||||
new ChatMessage(ChatRole.System, prompt)
|
||||
new ChatMessage(ChatRole.System, agent.Instruction)
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var message in GetChatSamples())
|
||||
foreach (var message in GetChatSamples(agent.Samples))
|
||||
{
|
||||
chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Text));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
using Azure.AI.OpenAI;
|
||||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BotSharp.Plugin.AzureOpenAI.Services;
|
||||
|
||||
public class ChatService : IChatServiceZone
|
||||
{
|
||||
private readonly IChatCompletion _chatCompletion;
|
||||
|
||||
public ChatService(IChatCompletion chatCompletion)
|
||||
{
|
||||
_chatCompletion = chatCompletion;
|
||||
}
|
||||
|
||||
public int Priority => 100;
|
||||
|
||||
public async Task Serving(ContentContainer content)
|
||||
{
|
||||
var output = await _chatCompletion.GetChatCompletionsAsync(content.Conversations);
|
||||
|
||||
content.Output = new RoleDialogModel
|
||||
{
|
||||
Role = ChatRole.Assistant.ToString(),
|
||||
Text = output
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,9 @@ using System;
|
|||
using Azure.AI.OpenAI;
|
||||
using BotSharp.Abstraction.ApiAdapters;
|
||||
using BotSharp.Plugin.ChatbotUI.ViewModels;
|
||||
using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
namespace BotSharp.Plugin.ChatbotUI.Controllers;
|
||||
|
||||
|
|
@ -64,22 +65,11 @@ public class ChatbotUiController : ControllerBase, IApiAdapter
|
|||
Text = x.Content
|
||||
}).ToList();
|
||||
|
||||
/*await _chatCompletionProvider.GetChatCompletionsAsync(conversations,
|
||||
async content =>
|
||||
{
|
||||
await OnChunkReceived(outputStream, content);
|
||||
});*/
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
|
||||
var transmitter = _services.GetRequiredService<IContentTransfer>();
|
||||
var result = await conv.SendMessage("", "", conversations.Last());
|
||||
|
||||
var container = new ContentContainer
|
||||
{
|
||||
Conversations = conversations
|
||||
};
|
||||
|
||||
var result = await transmitter.Transport(container);
|
||||
|
||||
await OnChunkReceived(outputStream, container.Output.Text);
|
||||
await OnChunkReceived(outputStream, result);
|
||||
await OnEventCompleted(outputStream);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Senparc.NeuChar.App.AppStore;
|
||||
using Senparc.NeuChar.Entities;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
|
@ -22,41 +22,23 @@ namespace BotSharp.Plugin.WeChat
|
|||
ILogger<WeChatBackgroundService> logger)
|
||||
{
|
||||
|
||||
this._service = service;
|
||||
this._logger = logger;
|
||||
this._queue = Channel.CreateUnbounded<WeChatMessage>();
|
||||
_service = service;
|
||||
_logger = logger;
|
||||
_queue = Channel.CreateUnbounded<WeChatMessage>();
|
||||
}
|
||||
|
||||
private async Task HandleTextMessageAsync(string openid, string message)
|
||||
{
|
||||
var scoped = _service.CreateScope().ServiceProvider;
|
||||
var conversationService = scoped.GetRequiredService<IConversationService>();
|
||||
var contentTransfer = scoped.GetRequiredService<IContentTransfer>();
|
||||
|
||||
var conversations = conversationService.GetDialogHistory(openid);
|
||||
conversations.Add(new RoleDialogModel
|
||||
var result = await conversationService.SendMessage(openid, Guid.Empty.ToString(), new RoleDialogModel
|
||||
{
|
||||
Role = "User",
|
||||
Role = "user",
|
||||
Text = message,
|
||||
});
|
||||
|
||||
var container = new ContentContainer
|
||||
{
|
||||
Conversations = conversations
|
||||
};
|
||||
|
||||
var result = await contentTransfer.Transport(container);
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
var output = container.Output.Text.Trim();
|
||||
await ReplyTextMessageAsync(openid, output);
|
||||
conversationService.AddDialog(new RoleDialogModel()
|
||||
{
|
||||
Role = "Assistant",
|
||||
Text = output,
|
||||
});
|
||||
}
|
||||
await ReplyTextMessageAsync(openid, result);
|
||||
}
|
||||
|
||||
private async Task ReplyTextMessageAsync(string openid, string content)
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
user: Hi
|
||||
assistant: Hello, I'm a AI assistant to help you schedule meeting.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
Transcript of a dialog, where the User interacts with an Assistant named Bob. Bob is helpful, kind, honest, good at writing, and never fails to answer the User's requests immediately and with precision.
|
||||
|
||||
User: Hello, Bob.
|
||||
Bob: Hello. How may I help you today?
|
||||
User: Please tell me the largest city in Europe.
|
||||
Bob: Sure. The largest city in Europe is Moscow, the capital of Russia.
|
||||
User:
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
|
|
@ -8,25 +8,22 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="data\**" />
|
||||
<Compile Remove="knowledge_chunks\**" />
|
||||
<Compile Remove="Prompts\**" />
|
||||
<Content Remove="data\**" />
|
||||
<Content Remove="knowledge_chunks\**" />
|
||||
<Content Remove="Prompts\**" />
|
||||
<EmbeddedResource Remove="data\**" />
|
||||
<EmbeddedResource Remove="knowledge_chunks\**" />
|
||||
<EmbeddedResource Remove="Prompts\**" />
|
||||
<None Remove="data\**" />
|
||||
<None Remove="knowledge_chunks\**" />
|
||||
<None Remove="Prompts\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="crawl-300d-2M-subword.bin" />
|
||||
<None Remove="Prompts\chat-samples.txt" />
|
||||
<None Remove="Prompts\chat-with-bob.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Prompts\chat-samples.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Prompts\chat-with-bob.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
},
|
||||
|
||||
"Conversation": {
|
||||
|
||||
"ChatCompletion": "AzureOpenAI.Providers.ChatCompletionProvider"
|
||||
},
|
||||
|
||||
"LlamaSharp": {
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
"Master": "mongodb://localhost:27017/chat-ui"
|
||||
},
|
||||
"Agent": {
|
||||
"Master": "Data Source=(localdb)\\ProjectModels;Initial Catalog=Agent;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False",
|
||||
"Master": "Data Source=(localdb)\\ProjectModels;Initial Catalog=BotSharp;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False",
|
||||
"Slavers": []
|
||||
},
|
||||
"UseCamelCase": true,
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
"KnowledgeBase": {
|
||||
"VectorDb": "MemVectorDatabase",
|
||||
"TextEmbedding": "fastTextEmbeddingProvider",
|
||||
"TextCompletion": "TextCompletionProvider"
|
||||
"TextCompletion": "AzureOpenAI.Providers.TextCompletionProvider"
|
||||
},
|
||||
|
||||
"PluginLoader": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue