GetUserById

This commit is contained in:
Haiping Chen 2023-11-13 19:25:25 -06:00
parent 57870ae63b
commit f3a17f1b34
18 changed files with 94 additions and 45 deletions

View file

@ -3,21 +3,7 @@ namespace BotSharp.Abstraction.Agents.Enums;
public class AgentRole
{
public const string System = "system";
/// <summary>
/// AI Assistant
/// </summary>
public const string Assistant = "assistant";
/// <summary>
/// Client
/// </summary>
public const string User = "user";
public const string Function = "function";
/// <summary>
/// Customer service representative (CSR)
/// </summary>
public const string CSR = "csr";
}

View file

@ -5,6 +5,7 @@ public class UserAgent
public string Id { get; set; } = string.Empty;
public string UserId { get; set; } = string.Empty;
public string AgentId { get; set; } = string.Empty;
public bool Editable { get; set; }
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
}

View file

@ -77,7 +77,7 @@ public abstract class ConversationHookBase : IConversationHook
return Task.CompletedTask;
}
public virtual Task OnConversationInitialized(Conversation message)
public virtual Task OnConversationInitialized(Conversation conversation)
{
return Task.CompletedTask;
}

View file

@ -9,7 +9,7 @@ public interface IBotSharpRepository
#region User
User? GetUserByEmail(string email);
User? GetUserByExternalId(string externalId);
User? GetUserById(string id);
void CreateUser(User user);
#endregion

View file

@ -4,6 +4,7 @@ namespace BotSharp.Abstraction.Users;
public interface IUserService
{
Task<User> GetUser(string id);
Task<User> CreateUser(User user);
Task<Token> GetToken(string authorization);
Task<User> GetMyProfile();

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Users.Enums;
namespace BotSharp.Abstraction.Users.Models;
public class User
@ -9,6 +11,7 @@ public class User
public string Salt { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string? ExternalId { get; set; }
public string Role { get; set; } = UserRole.Client;
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
}

View file

@ -42,7 +42,7 @@ public partial class AgentService
.SetResponses(foundAgent.Responses);
}
var user = _db.GetUserByExternalId(_user.Id);
var user = _db.GetUserById(_user.Id);
var userAgentRecord = new UserAgent
{
Id = Guid.NewGuid().ToString(),

View file

@ -13,7 +13,7 @@ public partial class AgentService
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
var agentDir = Path.Combine(dbSettings.FileRepository, _agentSettings.DataDir);
var user = _db.GetUserByExternalId(_user.Id);
var user = _db.GetUserById(_user.Id);
var agents = new List<Agent>();
var userAgents = new List<UserAgent>();

View file

@ -1,4 +1,6 @@
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Users.Enums;
using BotSharp.Abstraction.Users.Models;
namespace BotSharp.Core.Conversations.Services;
@ -46,15 +48,15 @@ public partial class ConversationService : IConversationService
public async Task<List<Conversation>> GetConversations()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserByExternalId(_user.Id);
var conversations = db.GetConversations(user?.Id);
var user = db.GetUserById(_user.Id);
var conversations = db.GetConversations(user.Role == UserRole.CSR ? null : user?.Id);
return conversations.OrderByDescending(x => x.CreatedTime).ToList();
}
public async Task<Conversation> NewConversation(Conversation sess)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserByExternalId(_user.Id);
var user = db.GetUserById(_user.Id);
var foundUserId = user?.Id ?? string.Empty;
var record = sess;

View file

@ -169,7 +169,7 @@ public class BotSharpDbContext : Database, IBotSharpRepository
throw new NotImplementedException();
}
public User? GetUserByExternalId(string externalId)
public User? GetUserById(string id)
{
throw new NotImplementedException();
}

View file

@ -726,7 +726,7 @@ public class FileRepository : IBotSharpRepository
var json = File.ReadAllText(path);
var record = JsonSerializer.Deserialize<Conversation>(json, _options);
if (record != null && record.UserId == userId)
if (record != null && (record.UserId == userId || userId == null))
{
records.Add(record);
}
@ -769,9 +769,9 @@ public class FileRepository : IBotSharpRepository
return Users.FirstOrDefault(x => x.Email == email);
}
public User? GetUserByExternalId(string externalId)
public User? GetUserById(string id = null)
{
return Users.FirstOrDefault(x => x.ExternalId == externalId);
return Users.FirstOrDefault(x => x.ExternalId == id || x.Id == id);
}
public void CreateUser(User user)

View file

@ -97,7 +97,15 @@ public class UserService : IUserService
public async Task<User> GetMyProfile()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserByExternalId(_user.Id);
var user = db.GetUserById(_user.Id);
return user;
}
[MemoryCache(60)]
public async Task<User> GetUser(string id)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserById(id);
return user;
}
}

View file

@ -2,6 +2,7 @@ using BotSharp.Abstraction.ApiAdapters;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Models;
using BotSharp.OpenAPI.ViewModels.Conversations;
using BotSharp.OpenAPI.ViewModels.Users;
using Microsoft.AspNetCore.Http;
using System.Net.Http.Headers;
@ -27,7 +28,8 @@ public class ConversationController : ControllerBase, IApiAdapter
var service = _services.GetRequiredService<IConversationService>();
var conv = new Conversation
{
AgentId = agentId
AgentId = agentId,
UserId = _user.Id
};
conv = await service.NewConversation(conv);
config.States.ForEach(x => conv.States[x.Split('=')[0]] = x.Split('=')[1]);
@ -35,6 +37,34 @@ public class ConversationController : ControllerBase, IApiAdapter
return ConversationViewModel.FromSession(conv);
}
[HttpGet("/conversations/{agentId}")]
public async Task<IEnumerable<ConversationViewModel>> GetConversations()
{
var service = _services.GetRequiredService<IConversationService>();
var conversations = await service.GetConversations();
var userService = _services.GetRequiredService<IUserService>();
var list = conversations.Select(x => new ConversationViewModel
{
Id = x.Id,
AgentId = x.AgentId,
Title = x.Title,
User = new UserViewModel
{
Id = x.UserId,
},
CreatedTime = x.CreatedTime,
UpdatedTime = x.UpdatedTime
}).ToList();
foreach (var item in list)
{
var user = await userService.GetUser(item.User.Id);
item.User = UserViewModel.FromUser(user);
}
return list;
}
[HttpDelete("/conversation/{agentId}/{conversationId}")]
public async Task DeleteConversation([FromRoute] string agentId, [FromRoute] string conversationId)
{

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.OpenAPI.ViewModels.Users;
namespace BotSharp.OpenAPI.ViewModels.Conversations;
@ -7,6 +8,7 @@ public class ConversationViewModel
public string Id { get; set; }
public string AgentId { get; set; }
public string Title { get; set; } = string.Empty;
public UserViewModel User { get; set; } = new UserViewModel();
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
@ -15,6 +17,10 @@ public class ConversationViewModel
return new ConversationViewModel
{
Id = sess.Id,
User = new UserViewModel
{
Id = sess.UserId
},
AgentId = sess.AgentId,
Title = sess.Title,
CreatedTime = sess.CreatedTime,

View file

@ -9,6 +9,8 @@ public class UserViewModel
public string LastName { get; set; }
public string Email { get; set; }
public string FullName => $"{FirstName} {LastName}";
public static UserViewModel FromUser(User user)
{
return new UserViewModel

View file

@ -768,9 +768,9 @@ public class MongoRepository : IBotSharpRepository
} : null;
}
public User? GetUserByExternalId(string externalId)
public User? GetUserById(string id)
{
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.ExternalId == externalId);
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.Id == id || x.ExternalId == id);
return user != null ? new User
{
Id = user.Id,

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Qdrant.Client" Version="0.1.0" />
<PackageReference Include="Qdrant.Client" Version="1.6.0-alpha.1" />
</ItemGroup>
<ItemGroup>

View file

@ -1,9 +1,8 @@
using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.VectorStorage;
using Microsoft.Extensions.DependencyInjection;
using QdrantCSharp;
using QdrantCSharp.Enums;
using QdrantCSharp.Models;
using Qdrant.Client;
using Qdrant.Client.Grpc;
using System;
using System.Collections.Generic;
using System.IO;
@ -14,7 +13,7 @@ namespace BotSharp.Plugin.Qdrant;
public class QdrantDb : IVectorDb
{
private readonly QdrantHttpClient _client;
private readonly QdrantClient _client;
private readonly QdrantSetting _setting;
private readonly IServiceProvider _services;
@ -23,9 +22,9 @@ public class QdrantDb : IVectorDb
{
_setting = setting;
_services = services;
_client = new QdrantHttpClient
_client = new QdrantClient
(
url: _setting.Url,
host: _setting.Url,
apiKey: _setting.ApiKey
);
}
@ -33,8 +32,8 @@ public class QdrantDb : IVectorDb
public async Task<List<string>> GetCollections()
{
// List all the collections
var collections = await _client.GetCollections();
return collections.Result.Collections.Select(x => x.Name).ToList();
var collections = await _client.ListCollectionsAsync();
return collections.ToList();
}
public async Task CreateCollection(string collectionName, int dim)
@ -43,7 +42,11 @@ public class QdrantDb : IVectorDb
if (!collections.Contains(collectionName))
{
// Create a new collection
await _client.CreateCollection(collectionName, new VectorParams(size: dim, distance: Distance.COSINE));
await _client.CreateCollectionAsync(collectionName, new VectorParams()
{
Size = (ulong)dim,
Distance = Distance.Cosine
});
var agentService = _services.GetRequiredService<IAgentService>();
var agentDataDir = agentService.GetAgentDataDir(collectionName);
@ -52,7 +55,7 @@ public class QdrantDb : IVectorDb
}
// Get collection info
var collectionInfo = await _client.GetCollection(collectionName);
var collectionInfo = await _client.GetCollectionInfoAsync(collectionName);
if (collectionInfo == null)
{
throw new Exception($"Create {collectionName} failed.");
@ -62,9 +65,16 @@ public class QdrantDb : IVectorDb
public async Task Upsert(string collectionName, int id, float[] vector, string text)
{
// Insert vectors
await _client.Upsert(collectionName, points: new List<PointStruct>
await _client.UpsertAsync(collectionName, points: new List<PointStruct>
{
new PointStruct(id: id, vector: vector)
new PointStruct()
{
Id = new PointId()
{
Num = (ulong)id,
},
Vectors = vector
}
});
// Store chunks in local file system
@ -76,13 +86,13 @@ public class QdrantDb : IVectorDb
public async Task<List<string>> Search(string collectionName, float[] vector, int limit = 5)
{
var result = await _client.Search(collectionName, vector, limit);
var result = await _client.SearchAsync(collectionName, vector, limit: (ulong)limit);
var agentService = _services.GetRequiredService<IAgentService>();
var agentDataDir = agentService.GetAgentDataDir(collectionName);
var knowledgePath = Path.Combine(agentDataDir, "knowledge.txt");
var texts = File.ReadAllLines(knowledgePath);
return result.Result.Select(x => texts[x.Id]).ToList();
return result.Select(x => texts[x.Id.Num]).ToList();
}
}