Merge pull request #663 from Qtoss-AI/master
return not found if no records.
This commit is contained in:
commit
63fb864d5d
|
|
@ -2,6 +2,7 @@ namespace BotSharp.Abstraction.Browsing.Models;
|
|||
|
||||
public class BrowserActionResult
|
||||
{
|
||||
public int ResponseStatusCode { get; set; }
|
||||
public bool IsSuccess { get; set; }
|
||||
public string? Message { get; set; }
|
||||
public string? StackTrace { get; set; }
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@ public interface ICacheService
|
|||
Task<T?> GetAsync<T>(string key);
|
||||
Task<object> GetAsync(string key, Type type);
|
||||
Task SetAsync<T>(string key, T value, TimeSpan? expiry);
|
||||
Task RemoveAsync(string key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,13 @@ public class SharpCacheAttribute : MoAttribute
|
|||
var value = cache.GetAsync(key, context.TaskReturnType).Result;
|
||||
if (value != null)
|
||||
{
|
||||
context.ReplaceReturnValue(this, value);
|
||||
// check if the cache is out of date
|
||||
var isOutOfDate = IsOutOfDate(context, value).Result;
|
||||
|
||||
if (!isOutOfDate)
|
||||
{
|
||||
context.ReplaceReturnValue(this, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +64,11 @@ public class SharpCacheAttribute : MoAttribute
|
|||
}
|
||||
}
|
||||
|
||||
public virtual Task<bool> IsOutOfDate(MethodContext context, object value)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
private string GetCacheKey(SharpCacheSettings settings, MethodContext context)
|
||||
{
|
||||
var key = settings.Prefix + "-" + context.Method.Name;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public interface IBotSharpRepository
|
|||
void Add<TTableInterface>(object entity);
|
||||
|
||||
#region Plugin
|
||||
PluginConfig GetPluginConfig();
|
||||
PluginConfig GetPluginConfig();
|
||||
void SavePluginConfig(PluginConfig config);
|
||||
#endregion
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ public interface IBotSharpRepository
|
|||
User? GetUserByEmail(string email) => throw new NotImplementedException();
|
||||
User? GetUserByPhone(string phone) => throw new NotImplementedException();
|
||||
User? GetAffiliateUserByPhone(string phone) => throw new NotImplementedException();
|
||||
User? GetUserById(string id) => throw new NotImplementedException();
|
||||
User? GetUserById(string id) => throw new NotImplementedException();
|
||||
List<User> GetUserByIds(List<string> ids) => throw new NotImplementedException();
|
||||
User? GetUserByAffiliateId(string affiliateId) => throw new NotImplementedException();
|
||||
User? GetUserByUserName(string userName) => throw new NotImplementedException();
|
||||
|
|
@ -30,9 +30,10 @@ public interface IBotSharpRepository
|
|||
void UpdateUserVerified(string userId) => throw new NotImplementedException();
|
||||
void UpdateUserVerificationCode(string userId, string verficationCode) => throw new NotImplementedException();
|
||||
void UpdateUserPassword(string userId, string password) => throw new NotImplementedException();
|
||||
void UpdateUserEmail(string userId, string email)=> throw new NotImplementedException();
|
||||
void UpdateUserEmail(string userId, string email) => throw new NotImplementedException();
|
||||
void UpdateUserPhone(string userId, string Iphone) => throw new NotImplementedException();
|
||||
void UpdateUserIsDisable(string userId, bool isDisable) => throw new NotImplementedException();
|
||||
void UpdateUsersIsDisable(List<string> userIds, bool isDisable) => throw new NotImplementedException();
|
||||
#endregion
|
||||
|
||||
#region Agent
|
||||
|
|
@ -76,7 +77,7 @@ public interface IBotSharpRepository
|
|||
List<string> GetIdleConversations(int batchSize, int messageLimit, int bufferHours, IEnumerable<string> excludeAgentIds);
|
||||
IEnumerable<string> TruncateConversation(string conversationId, string messageId, bool cleanLog = false);
|
||||
#endregion
|
||||
|
||||
|
||||
#region Execution Log
|
||||
void AddExecutionLogs(string conversationId, List<string> logs);
|
||||
List<string> GetExecutionLogs(string conversationId);
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@ public interface IAuthenticationHook
|
|||
void BeforeSending(Token token);
|
||||
Task UserCreated(User user);
|
||||
Task VerificationCodeResetPassword(User user);
|
||||
Task DelUsers(List<string> userIds);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@ public interface IUserIdentity
|
|||
string FullName { get; }
|
||||
string? UserLanguage { get; }
|
||||
string? Phone { get; }
|
||||
string? AffiliateId { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,4 +19,5 @@ public interface IUserService
|
|||
Task<bool> ModifyUserPhone(string phone);
|
||||
Task<bool> UpdatePassword(string newPassword, string verificationCode);
|
||||
Task<DateTime> GetUserTokenExpires();
|
||||
Task<bool> UpdateUsersIsDisable(List<string> userIds, bool isDisable);
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ public interface IVectorDb
|
|||
Task<IEnumerable<VectorCollectionData>> GetCollectionData(string collectionName, IEnumerable<Guid> ids, bool withPayload = false, bool withVector = false);
|
||||
Task<bool> CreateCollection(string collectionName, int dimension);
|
||||
Task<bool> DeleteCollection(string collectionName);
|
||||
Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, string>? payload = null);
|
||||
Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, object>? payload = null);
|
||||
Task<IEnumerable<VectorCollectionData>> Search(string collectionName, float[] vector, IEnumerable<string>? fields, int limit = 5, float confidence = 0.5f, bool withVector = false);
|
||||
Task<bool> DeleteCollectionData(string collectionName, List<Guid> ids);
|
||||
Task<bool> DeleteCollectionAllData(string collectionName);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ namespace BotSharp.Abstraction.VectorStorage.Models;
|
|||
public class VectorCollectionData
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public Dictionary<string, string> Data { get; set; } = new();
|
||||
public Dictionary<string, object> Data { get; set; } = new();
|
||||
public double? Score { get; set; }
|
||||
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ public class VectorCreateModel
|
|||
{
|
||||
public string Text { get; set; }
|
||||
public string DataSource { get; set; } = VectorDataSource.Api;
|
||||
public Dictionary<string, string>? Payload { get; set; }
|
||||
public Dictionary<string, object>? Payload { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,4 +32,9 @@ public class MemoryCacheService : ICacheService
|
|||
AbsoluteExpirationRelativeToNow = expiry
|
||||
});
|
||||
}
|
||||
|
||||
public async Task RemoveAsync(string key)
|
||||
{
|
||||
_cache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,4 +76,20 @@ public class RedisCacheService : ICacheService
|
|||
var db = redis.GetDatabase();
|
||||
await db.StringSetAsync(key, JsonConvert.SerializeObject(value), expiry);
|
||||
}
|
||||
|
||||
public async Task RemoveAsync(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_settings.Redis))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (redis == null)
|
||||
{
|
||||
redis = ConnectionMultiplexer.Connect(_settings.Redis);
|
||||
}
|
||||
|
||||
var db = redis.GetDatabase();
|
||||
await db.KeyDeleteAsync(key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,4 +69,7 @@ public class UserIdentity : IUserIdentity
|
|||
|
||||
[JsonPropertyName("phone")]
|
||||
public string? Phone => _claims?.FirstOrDefault(x => x.Type == "phone")?.Value;
|
||||
|
||||
[JsonPropertyName("affiliateId")]
|
||||
public string? AffiliateId => _claims?.FirstOrDefault(x => x.Type == "affiliateId")?.Value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using BotSharp.Abstraction.Users.Enums;
|
||||
using BotSharp.Abstraction.Infrastructures;
|
||||
using BotSharp.Abstraction.Users.Enums;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using BotSharp.Abstraction.Users.Settings;
|
||||
using BotSharp.OpenAPI.ViewModels.Users;
|
||||
|
|
@ -9,7 +9,6 @@ using NanoidDotNet;
|
|||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Net;
|
||||
|
||||
namespace BotSharp.Core.Users.Services;
|
||||
|
||||
|
|
@ -112,7 +111,11 @@ public class UserService : IUserService
|
|||
var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization));
|
||||
var (id, password) = base64.SplitAsTuple(":");
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.GetUserByPhone(id);
|
||||
var record = db.GetAffiliateUserByPhone(id);
|
||||
if (record == null)
|
||||
{
|
||||
record = db.GetUserByPhone(id);
|
||||
}
|
||||
|
||||
var isCanLoginAffiliateRoleType = record != null && !record.IsDisabled && record.Type != UserType.Client;
|
||||
if (!isCanLoginAffiliateRoleType)
|
||||
|
|
@ -254,7 +257,8 @@ public class UserService : IUserService
|
|||
new Claim("type", user.Type ?? UserType.Client),
|
||||
new Claim("role", user.Role ?? UserRole.User),
|
||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new Claim("phone", user.Phone ?? string.Empty)
|
||||
new Claim("phone", user.Phone ?? string.Empty),
|
||||
new Claim("affiliateId", user.AffiliateId ?? string.Empty)
|
||||
};
|
||||
|
||||
var validators = _services.GetServices<IAuthenticationHook>();
|
||||
|
|
@ -280,14 +284,19 @@ public class UserService : IUserService
|
|||
};
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
SaveUserTokenExpiresCache(user.Id, expires).GetAwaiter().GetResult();
|
||||
SaveUserTokenExpiresCache(user.Id, expires, expireInMinutes).GetAwaiter().GetResult();
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
private async Task SaveUserTokenExpiresCache(string userId, DateTime expires)
|
||||
private async Task SaveUserTokenExpiresCache(string userId, DateTime expires, int expireInMinutes)
|
||||
{
|
||||
var _cacheService = _services.GetRequiredService<ICacheService>();
|
||||
await _cacheService.SetAsync<DateTime>(GetUserTokenExpiresCacheKey(userId), expires, null);
|
||||
var config = _services.GetService<IConfiguration>();
|
||||
var enableSingleLogin = bool.Parse(config["Jwt:EnableSingleLogin"] ?? "false");
|
||||
if (enableSingleLogin)
|
||||
{
|
||||
var _cacheService = _services.GetRequiredService<ICacheService>();
|
||||
await _cacheService.SetAsync(GetUserTokenExpiresCacheKey(userId), expires, TimeSpan.FromMinutes(expireInMinutes));
|
||||
}
|
||||
}
|
||||
|
||||
private string GetUserTokenExpiresCacheKey(string userId)
|
||||
|
|
@ -514,4 +523,23 @@ public class UserService : IUserService
|
|||
db.UpdateUserPhone(record.Id, phone);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateUsersIsDisable(List<string> userIds, bool isDisable)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
db.UpdateUsersIsDisable(userIds, isDisable);
|
||||
|
||||
if (!isDisable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// del membership
|
||||
var hooks = _services.GetServices<IAuthenticationHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
await hook.DelUsers(userIds);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class UserController : ControllerBase
|
|||
var token = await _userService.ActiveUser(model);
|
||||
if (token == null)
|
||||
{
|
||||
return Unauthorized();
|
||||
return BadRequest();
|
||||
}
|
||||
return Ok(token);
|
||||
}
|
||||
|
|
@ -143,6 +143,12 @@ public class UserController : ControllerBase
|
|||
return await _userService.ModifyUserPhone(phone);
|
||||
}
|
||||
|
||||
[HttpPost("/user/update/isdisable")]
|
||||
public async Task<bool> UpdateUsersIsDisable([FromQuery] List<string> userIds, [FromQuery] bool isDisable)
|
||||
{
|
||||
return await _userService.UpdateUsersIsDisable(userIds, isDisable);
|
||||
}
|
||||
|
||||
#region Avatar
|
||||
[HttpPost("/user/avatar")]
|
||||
public bool UploadUserAvatar([FromBody] UserAvatarModel input)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,14 @@ namespace BotSharp.OpenAPI.Filters
|
|||
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var isAllowAnonymous = context.ActionDescriptor.EndpointMetadata
|
||||
.Any(em => em.GetType() == typeof(AllowAnonymousAttribute));
|
||||
|
||||
if (isAllowAnonymous)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bearerToken = GetBearerToken(context);
|
||||
if (!string.IsNullOrWhiteSpace(bearerToken))
|
||||
{
|
||||
|
|
@ -37,7 +45,8 @@ namespace BotSharp.OpenAPI.Filters
|
|||
if (validTo != currentExpires)
|
||||
{
|
||||
Serilog.Log.Warning($"Token expired. Token expires at {validTo}, current expires at {currentExpires}");
|
||||
context.Result = new UnauthorizedResult();
|
||||
// login confict
|
||||
context.Result = new ConflictResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ public class VectorKnowledgeCreateRequest
|
|||
public string DataSource { get; set; } = VectorDataSource.Api;
|
||||
|
||||
[JsonPropertyName("payload")]
|
||||
public Dictionary<string, string>? Payload { get; set; }
|
||||
public Dictionary<string, object>? Payload { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public class VectorKnowledgeViewModel
|
|||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("data")]
|
||||
public IDictionary<string, string> Data { get; set; }
|
||||
public IDictionary<string, object> Data { get; set; }
|
||||
|
||||
[JsonPropertyName("score")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using BotSharp.Abstraction.Files.Utilities;
|
||||
using OpenAI.Chat;
|
||||
using System.ClientModel;
|
||||
|
||||
namespace BotSharp.Plugin.AzureOpenAI.Providers.Chat;
|
||||
|
||||
|
|
@ -37,43 +38,67 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
var chatClient = client.GetChatClient(_model);
|
||||
var (prompt, messages, options) = PrepareOptions(agent, conversations);
|
||||
|
||||
var response = chatClient.CompleteChat(messages, options);
|
||||
var value = response.Value;
|
||||
var reason = value.FinishReason;
|
||||
var content = value.Content;
|
||||
var text = content.FirstOrDefault()?.Text ?? string.Empty;
|
||||
|
||||
ChatCompletion value = default;
|
||||
RoleDialogModel responseMessage;
|
||||
if (reason == ChatFinishReason.FunctionCall)
|
||||
{
|
||||
responseMessage = new RoleDialogModel(AgentRole.Function, text)
|
||||
{
|
||||
CurrentAgentId = agent.Id,
|
||||
MessageId = conversations.LastOrDefault()?.MessageId ?? string.Empty,
|
||||
FunctionName = value.FunctionCall.FunctionName,
|
||||
FunctionArgs = value.FunctionCall.FunctionArguments
|
||||
};
|
||||
|
||||
// Somethings LLM will generate a function name with agent name.
|
||||
if (!string.IsNullOrEmpty(responseMessage.FunctionName))
|
||||
try
|
||||
{
|
||||
var response = chatClient.CompleteChat(messages, options);
|
||||
value = response.Value;
|
||||
|
||||
var reason = value.FinishReason;
|
||||
var content = value.Content;
|
||||
var text = content.FirstOrDefault()?.Text ?? string.Empty;
|
||||
|
||||
if (reason == ChatFinishReason.FunctionCall)
|
||||
{
|
||||
responseMessage.FunctionName = responseMessage.FunctionName.Split('.').Last();
|
||||
responseMessage = new RoleDialogModel(AgentRole.Function, text)
|
||||
{
|
||||
CurrentAgentId = agent.Id,
|
||||
MessageId = conversations.LastOrDefault()?.MessageId ?? string.Empty,
|
||||
FunctionName = value.FunctionCall.FunctionName,
|
||||
FunctionArgs = value.FunctionCall.FunctionArguments
|
||||
};
|
||||
|
||||
// Somethings LLM will generate a function name with agent name.
|
||||
if (!string.IsNullOrEmpty(responseMessage.FunctionName))
|
||||
{
|
||||
responseMessage.FunctionName = responseMessage.FunctionName.Split('.').Last();
|
||||
}
|
||||
}
|
||||
else if (reason == ChatFinishReason.ToolCalls)
|
||||
{
|
||||
var toolCall = value.ToolCalls.FirstOrDefault();
|
||||
responseMessage = new RoleDialogModel(AgentRole.Function, text)
|
||||
{
|
||||
CurrentAgentId = agent.Id,
|
||||
MessageId = conversations.LastOrDefault()?.MessageId ?? string.Empty,
|
||||
FunctionName = toolCall?.FunctionName,
|
||||
FunctionArgs = toolCall?.FunctionArguments
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage = new RoleDialogModel(AgentRole.Assistant, text)
|
||||
{
|
||||
CurrentAgentId = agent.Id,
|
||||
MessageId = conversations.LastOrDefault()?.MessageId ?? string.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (reason == ChatFinishReason.ToolCalls)
|
||||
catch (ClientResultException ex)
|
||||
{
|
||||
var toolCall = value.ToolCalls.FirstOrDefault();
|
||||
responseMessage = new RoleDialogModel(AgentRole.Function, text)
|
||||
_logger.LogError(ex, ex.Message);
|
||||
responseMessage = new RoleDialogModel(AgentRole.Assistant, "The response was filtered due to the prompt triggering our content management policy. Please modify your prompt and retry.")
|
||||
{
|
||||
CurrentAgentId = agent.Id,
|
||||
MessageId = conversations.LastOrDefault()?.MessageId ?? string.Empty,
|
||||
FunctionName = toolCall?.FunctionName,
|
||||
FunctionArgs = toolCall?.FunctionArguments
|
||||
};
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
responseMessage = new RoleDialogModel(AgentRole.Assistant, text)
|
||||
_logger.LogError(ex, ex.Message);
|
||||
responseMessage = new RoleDialogModel(AgentRole.Assistant, ex.Message)
|
||||
{
|
||||
CurrentAgentId = agent.Id,
|
||||
MessageId = conversations.LastOrDefault()?.MessageId ?? string.Empty,
|
||||
|
|
@ -88,8 +113,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Value.Usage.InputTokens,
|
||||
CompletionCount = response.Value.Usage.OutputTokens
|
||||
PromptCount = value?.Usage?.InputTokens ?? 0,
|
||||
CompletionCount = value?.Usage?.OutputTokens ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public class MemorizeKnowledgeFn : IFunctionCallback
|
|||
var result = await knowledgeService.CreateVectorCollectionData(collectionName, new VectorCreateModel
|
||||
{
|
||||
Text = args.Question,
|
||||
Payload = new Dictionary<string, string>
|
||||
Payload = new Dictionary<string, object>
|
||||
{
|
||||
{ KnowledgePayloadName.Answer, args.Answer }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public class MemoryVectorDb : IVectorDb
|
|||
.Take(limit)
|
||||
.Select(i => new VectorCollectionData
|
||||
{
|
||||
Data = new Dictionary<string, string> { { "text", _vectors[collectionName][i].Text } },
|
||||
Data = new Dictionary<string, object> { { "text", _vectors[collectionName][i].Text } },
|
||||
Score = similarities[i],
|
||||
Vector = withVector ? _vectors[collectionName][i].Vector : null,
|
||||
})
|
||||
|
|
@ -68,7 +68,7 @@ public class MemoryVectorDb : IVectorDb
|
|||
return await Task.FromResult(results);
|
||||
}
|
||||
|
||||
public async Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, string>? payload = null)
|
||||
public async Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, object>? payload = null)
|
||||
{
|
||||
_vectors[collectionName].Add(new VecRecord
|
||||
{
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ public partial class KnowledgeService
|
|||
var vectorDb = GetVectorDb();
|
||||
var textEmbedding = GetTextEmbedding(collectionName);
|
||||
|
||||
var payload = new Dictionary<string, string>
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
{ KnowledgePayloadName.DataSource, vectorDataSource },
|
||||
{ KnowledgePayloadName.FileId, fileId.ToString() },
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ public partial class KnowledgeService
|
|||
withPayload: true);
|
||||
if (!found.IsNullOrEmpty())
|
||||
{
|
||||
if (found.First().Data["text"] == update.Text)
|
||||
if (found.First().Data["text"].ToString() == update.Text)
|
||||
{
|
||||
// Only update payload
|
||||
return await db.Upsert(collectionName, guid, found.First().Vector, update.Text, update.Payload);
|
||||
|
|
|
|||
|
|
@ -126,4 +126,12 @@ public partial class MongoRepository
|
|||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
_dc.Users.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
public void UpdateUsersIsDisable(List<string> userIds, bool isDisable)
|
||||
{
|
||||
foreach (var userId in userIds)
|
||||
{
|
||||
UpdateUserIsDisable(userId, isDisable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,23 +19,23 @@ public class PrimaryStagePlanFn : IFunctionCallback
|
|||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
|
||||
var knowledgeSettings = _services.GetRequiredService<KnowledgeBaseSettings>();
|
||||
// var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
|
||||
// var knowledgeSettings = _services.GetRequiredService<KnowledgeBaseSettings>();
|
||||
|
||||
state.SetState("max_tokens", "4096");
|
||||
var task = JsonSerializer.Deserialize<PrimaryRequirementRequest>(message.FunctionArgs);
|
||||
var collectionName = knowledgeSettings.Default.CollectionName;
|
||||
// var collectionName = knowledgeSettings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp;
|
||||
|
||||
// Get knowledge from vectordb
|
||||
var hooks = _services.GetServices<IKnowledgeHook>();
|
||||
var knowledges = new List<string>();
|
||||
foreach (var question in task.Questions)
|
||||
{
|
||||
var list = await knowledgeService.SearchVectorKnowledge(question, collectionName, new VectorSearchOptions
|
||||
/*var list = await knowledgeService.SearchVectorKnowledge(question, collectionName, new VectorSearchOptions
|
||||
{
|
||||
Confidence = 0.4f
|
||||
});
|
||||
knowledges.Add(string.Join("\r\n\r\n=====\r\n", list.Select(x => x.ToQuestionAnswer())));
|
||||
knowledges.Add(string.Join("\r\n\r\n=====\r\n", list.Select(x => x.ToQuestionAnswer())));*/
|
||||
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
|
|
@ -43,6 +43,7 @@ public class PrimaryStagePlanFn : IFunctionCallback
|
|||
knowledges.AddRange(k);
|
||||
}
|
||||
}
|
||||
knowledges = knowledges.Distinct().ToList();
|
||||
|
||||
// Get first stage planning prompt
|
||||
var currentAgent = await agentService.LoadAgent(message.CurrentAgentId);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Qdrant.Client" Version="1.10.0" />
|
||||
<PackageReference Include="Qdrant.Client" Version="1.11.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -142,7 +142,13 @@ public class QdrantDb : IVectorDb
|
|||
var points = response?.Result?.Select(x => new VectorCollectionData
|
||||
{
|
||||
Id = x.Id?.Uuid ?? string.Empty,
|
||||
Data = x.Payload.ToDictionary(x => x.Key, x => x.Value.StringValue),
|
||||
Data = x.Payload.ToDictionary(p => p.Key, p => p.Value.KindCase switch
|
||||
{
|
||||
Value.KindOneofCase.StringValue => p.Value.StringValue,
|
||||
Value.KindOneofCase.BoolValue => p.Value.BoolValue,
|
||||
Value.KindOneofCase.IntegerValue => p.Value.IntegerValue,
|
||||
_ => new object()
|
||||
}),
|
||||
Vector = filter.WithVector ? x.Vectors?.Vector?.Data?.ToArray() : null
|
||||
})?.ToList() ?? new List<VectorCollectionData>();
|
||||
|
||||
|
|
@ -175,12 +181,18 @@ public class QdrantDb : IVectorDb
|
|||
return points.Select(x => new VectorCollectionData
|
||||
{
|
||||
Id = x.Id?.Uuid ?? string.Empty,
|
||||
Data = x.Payload?.ToDictionary(x => x.Key, x => x.Value.StringValue) ?? new(),
|
||||
Data = x.Payload?.ToDictionary(p => p.Key, p => p.Value.KindCase switch
|
||||
{
|
||||
Value.KindOneofCase.StringValue => p.Value.StringValue,
|
||||
Value.KindOneofCase.BoolValue => p.Value.BoolValue,
|
||||
Value.KindOneofCase.IntegerValue => p.Value.IntegerValue,
|
||||
_ => new object()
|
||||
}) ?? new(),
|
||||
Vector = x.Vectors?.Vector?.Data?.ToArray()
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, string>? payload = null)
|
||||
public async Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, object>? payload = null)
|
||||
{
|
||||
// Insert vectors
|
||||
var point = new PointStruct()
|
||||
|
|
@ -200,7 +212,42 @@ public class QdrantDb : IVectorDb
|
|||
{
|
||||
foreach (var item in payload)
|
||||
{
|
||||
point.Payload[item.Key] = item.Value;
|
||||
if (item.Value is string str)
|
||||
{
|
||||
point.Payload[item.Key] = str;
|
||||
}
|
||||
else if (item.Value is bool b)
|
||||
{
|
||||
point.Payload[item.Key] = b;
|
||||
}
|
||||
else if (item.Value is byte int8)
|
||||
{
|
||||
point.Payload[item.Key] = int8;
|
||||
}
|
||||
else if (item.Value is short int16)
|
||||
{
|
||||
point.Payload[item.Key] = int16;
|
||||
}
|
||||
else if (item.Value is int int32)
|
||||
{
|
||||
point.Payload[item.Key] = int32;
|
||||
}
|
||||
else if (item.Value is long int64)
|
||||
{
|
||||
point.Payload[item.Key] = int64;
|
||||
}
|
||||
else if (item.Value is float f32)
|
||||
{
|
||||
point.Payload[item.Key] = f32;
|
||||
}
|
||||
else if (item.Value is double f64)
|
||||
{
|
||||
point.Payload[item.Key] = f64;
|
||||
}
|
||||
else if (item.Value is DateTime dt)
|
||||
{
|
||||
point.Payload[item.Key] = dt.ToUniversalTime().ToString("o");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +288,13 @@ public class QdrantDb : IVectorDb
|
|||
results = points.Select(x => new VectorCollectionData
|
||||
{
|
||||
Id = x.Id.Uuid,
|
||||
Data = x.Payload.ToDictionary(x => x.Key, x => x.Value.StringValue),
|
||||
Data = x.Payload.ToDictionary(p => p.Key, p => p.Value.KindCase switch
|
||||
{
|
||||
Value.KindOneofCase.StringValue => p.Value.StringValue,
|
||||
Value.KindOneofCase.BoolValue => p.Value.BoolValue,
|
||||
Value.KindOneofCase.IntegerValue => p.Value.IntegerValue,
|
||||
_ => new object()
|
||||
}),
|
||||
Score = x.Score,
|
||||
Vector = x.Vectors?.Vector?.Data?.ToArray()
|
||||
}).ToList();
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace BotSharp.Plugin.SemanticKernel
|
|||
{
|
||||
resultTexts.Add(new VectorCollectionData
|
||||
{
|
||||
Data = new Dictionary<string, string> { { "text", record.Metadata.Text } },
|
||||
Data = new Dictionary<string, object> { { "text", record.Metadata.Text } },
|
||||
Score = score,
|
||||
Vector = withVector ? record.Embedding.ToArray() : null
|
||||
});
|
||||
|
|
@ -83,7 +83,7 @@ namespace BotSharp.Plugin.SemanticKernel
|
|||
return resultTexts;
|
||||
}
|
||||
|
||||
public async Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, string>? payload)
|
||||
public async Task<bool> Upsert(string collectionName, Guid id, float[] vector, string text, Dictionary<string, object>? payload)
|
||||
{
|
||||
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
await _memoryStore.UpsertAsync(collectionName, MemoryRecord.LocalRecord(id.ToString(), text, null, vector));
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ public class ExecuteQueryFn : IFunctionCallback
|
|||
"SqlServer" => RunQueryInSqlServer(args.SqlStatements),
|
||||
_ => throw new NotImplementedException($"Database type {settings.DatabaseType} is not supported.")
|
||||
};
|
||||
|
||||
if (results.Count() == 0)
|
||||
{
|
||||
message.Content = "No record found";
|
||||
return true;
|
||||
}
|
||||
|
||||
message.Content = JsonSerializer.Serialize(results);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class DbKnowledgeService
|
|||
await knowledgeService.CreateVectorCollectionData(collectionName, new VectorCreateModel
|
||||
{
|
||||
Text = item.Question,
|
||||
Payload = new Dictionary<string, string>
|
||||
Payload = new Dictionary<string, object>
|
||||
{
|
||||
{ KnowledgePayloadName.Answer, item.Answer }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public partial class PlaywrightWebDriver
|
|||
await Task.Delay(args.WaitTime * 1000);
|
||||
}
|
||||
|
||||
result.ResponseStatusCode = response.Status;
|
||||
if (response.Status == 200)
|
||||
{
|
||||
// Disable this due to performance issue, some page is too large
|
||||
|
|
@ -71,7 +72,7 @@ public partial class PlaywrightWebDriver
|
|||
result.IsSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
result.Message = response.StatusText;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue