diff --git a/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj b/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj
new file mode 100644
index 00000000..921dcdcf
--- /dev/null
+++ b/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.1
+ enable
+ 10
+
+
+
+
+
+
+
+
+
+
diff --git a/BotSharp.Plugin.Qdrant/QdrantDb.cs b/BotSharp.Plugin.Qdrant/QdrantDb.cs
new file mode 100644
index 00000000..2846cf85
--- /dev/null
+++ b/BotSharp.Plugin.Qdrant/QdrantDb.cs
@@ -0,0 +1,64 @@
+using BotSharp.Abstraction.Knowledges;
+using QdrantCSharp;
+using QdrantCSharp.Enums;
+using QdrantCSharp.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace BotSharp.Plugin.Qdrant;
+
+public class QdrantDb : IVectorDb
+{
+ private readonly QdrantHttpClient _client;
+ private readonly QdrantSetting _setting;
+ public QdrantDb(QdrantSetting setting)
+ {
+ _setting = setting;
+ _client = new QdrantHttpClient
+ (
+ url: _setting.Url,
+ apiKey: _setting.ApiKey
+ );
+ }
+
+ public async Task> GetCollections()
+ {
+ // List all the collections
+ var collections = await _client.GetCollections();
+ return collections.Result.Collections.Select(x => x.Name).ToList();
+ }
+
+ public async Task CreateCollection(string collectionName)
+ {
+ var collections = await GetCollections();
+ if (!collections.Contains(collectionName))
+ {
+ // Create a new collection
+ await _client.CreateCollection(collectionName, new VectorParams(size: 300, distance: Distance.COSINE));
+ }
+
+ // Get collection info
+ var collectionInfo = await _client.GetCollection(collectionName);
+ if(collectionInfo == null)
+ {
+ throw new Exception($"Create {collectionName} failed.");
+ }
+ }
+
+ public async Task Upsert(string collectionName, int id, float[] vector)
+ {
+ // Insert vectors
+ await _client.Upsert(collectionName, points: new List
+ {
+ new PointStruct(id: id, vector: vector)
+ });
+ }
+
+ public async Task> Search(string collectionName, float[] vector, int limit = 10)
+ {
+ var result = await _client.Search(collectionName, vector, limit);
+ return result.Result.Select(x => x.Id).ToList();
+ }
+}
diff --git a/BotSharp.Plugin.Qdrant/QdrantPlugin.cs b/BotSharp.Plugin.Qdrant/QdrantPlugin.cs
new file mode 100644
index 00000000..6d372215
--- /dev/null
+++ b/BotSharp.Plugin.Qdrant/QdrantPlugin.cs
@@ -0,0 +1,18 @@
+using BotSharp.Abstraction.Knowledges;
+using BotSharp.Abstraction.Plugins;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace BotSharp.Plugin.Qdrant;
+
+public class QdrantPlugin : IBotSharpPlugin
+{
+ public void RegisterDI(IServiceCollection services, IConfiguration config)
+ {
+ var settings = new QdrantSetting();
+ config.Bind("Qdrant", settings);
+ services.AddSingleton(x => settings);
+
+ services.AddSingleton();
+ }
+}
diff --git a/BotSharp.Plugin.Qdrant/QdrantSetting.cs b/BotSharp.Plugin.Qdrant/QdrantSetting.cs
new file mode 100644
index 00000000..eed08792
--- /dev/null
+++ b/BotSharp.Plugin.Qdrant/QdrantSetting.cs
@@ -0,0 +1,7 @@
+namespace BotSharp.Plugin.Qdrant;
+
+public class QdrantSetting
+{
+ public string Url { get; set; }
+ public string ApiKey { get; set; }
+}
diff --git a/BotSharp.sln b/BotSharp.sln
index 1f03d0eb..154f8b3c 100644
--- a/BotSharp.sln
+++ b/BotSharp.sln
@@ -35,6 +35,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "tests\UnitTest\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.MetaAI", "src\Plugins\BotSharp.Plugin.MetaAI\BotSharp.Plugin.MetaAI.csproj", "{6D8D18A9-86D7-455E-81EC-9682C30AB7E7}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Databases", "Databases", "{53E7CD86-0D19-40D9-A0FA-AB4613837E89}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.Qdrant", "BotSharp.Plugin.Qdrant\BotSharp.Plugin.Qdrant.csproj", "{9686D771-CA9F-41B0-8508-C5B4E6E457A3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -123,6 +127,14 @@ Global
{6D8D18A9-86D7-455E-81EC-9682C30AB7E7}.Release|Any CPU.Build.0 = Release|Any CPU
{6D8D18A9-86D7-455E-81EC-9682C30AB7E7}.Release|x64.ActiveCfg = Release|Any CPU
{6D8D18A9-86D7-455E-81EC-9682C30AB7E7}.Release|x64.Build.0 = Release|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Debug|x64.Build.0 = Debug|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Release|x64.ActiveCfg = Release|Any CPU
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -140,6 +152,8 @@ Global
{2323A7A3-E938-488D-A57E-638638054BC4} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
{0B6E1D7F-ABDE-47F6-8B2D-4483C2CFF2D6} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
{6D8D18A9-86D7-455E-81EC-9682C30AB7E7} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
+ {53E7CD86-0D19-40D9-A0FA-AB4613837E89} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C}
+ {9686D771-CA9F-41B0-8508-C5B4E6E457A3} = {53E7CD86-0D19-40D9-A0FA-AB4613837E89}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeBase.cs b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeBase.cs
deleted file mode 100644
index 840e625e..00000000
--- a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeBase.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace BotSharp.Abstraction.Knowledges;
-
-public interface IKnowledgeBase
-{
-}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IVectorDb.cs b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IVectorDb.cs
new file mode 100644
index 00000000..7fe53c75
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IVectorDb.cs
@@ -0,0 +1,9 @@
+namespace BotSharp.Abstraction.Knowledges;
+
+public interface IVectorDb
+{
+ Task> GetCollections();
+ Task CreateCollection(string collectionName);
+ Task Upsert(string collectionName, int id, float[] vector);
+ Task> Search(string collectionName, float[] vector, int limit = 10);
+}
diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
index 4944dfce..cdbe9243 100644
--- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
+++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
@@ -67,7 +67,6 @@
-
diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs
index 8214df65..82c09c38 100644
--- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs
+++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs
@@ -1,15 +1,3 @@
-using BotSharp.Abstraction.Agents;
-using BotSharp.Abstraction.Conversations;
-using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
-using BotSharp.Abstraction.Knowledges;
-using BotSharp.Abstraction.Users;
-using BotSharp.Core.Agents.Services;
-using BotSharp.Core.Conversations.Services;
-using BotSharp.Core.Infrastructures;
-using BotSharp.Core.Knowledges.Services;
-using BotSharp.Core.Plugins;
-using BotSharp.Core.Users.Services;
-using BotSharp.Plugins.LLamaSharp;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
diff --git a/src/Infrastructure/BotSharp.Core/Knowledges/KnowledgeBase.cs b/src/Infrastructure/BotSharp.Core/Knowledges/KnowledgeBase.cs
index 1b074d59..5b0335c2 100644
--- a/src/Infrastructure/BotSharp.Core/Knowledges/KnowledgeBase.cs
+++ b/src/Infrastructure/BotSharp.Core/Knowledges/KnowledgeBase.cs
@@ -1,7 +1,24 @@
-using BotSharp.Abstraction.Knowledges;
-
namespace BotSharp.Core.Knowledges;
-public class KnowledgeBase : IKnowledgeBase
+public class KnowledgeBase : IVectorDb
{
+ public Task CreateCollection(string collectionName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetCollections()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> Search(string collectionName, float[] vector, int limit = 10)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task Upsert(string collectionName, int id, float[] vector)
+ {
+ throw new NotImplementedException();
+ }
}
diff --git a/src/Infrastructure/BotSharp.Core/Knowledges/Services/KnowledgeService.cs b/src/Infrastructure/BotSharp.Core/Knowledges/Services/KnowledgeService.cs
index db2b7378..81ba2d26 100644
--- a/src/Infrastructure/BotSharp.Core/Knowledges/Services/KnowledgeService.cs
+++ b/src/Infrastructure/BotSharp.Core/Knowledges/Services/KnowledgeService.cs
@@ -1,8 +1,5 @@
using BotSharp.Abstraction.Knowledges;
using BotSharp.Abstraction.Knowledges.Models;
-using QdrantCSharp.Enums;
-using QdrantCSharp.Models;
-using QdrantCSharp;
using System.IO;
using System.Collections;
using BotSharp.Abstraction.MLTasks;
@@ -13,37 +10,19 @@ public class KnowledgeService : IKnowledgeService
{
private readonly ITextEmbedding _textEmbedding;
private readonly ITextCompletion _textCompletion;
+ private readonly IVectorDb _db;
string collectionName = "my_collection";
- public KnowledgeService(ITextEmbedding textEmbedding, ITextCompletion textCompletion)
+ public KnowledgeService(ITextEmbedding textEmbedding,
+ ITextCompletion textCompletion,
+ IVectorDb db)
{
_textEmbedding = textEmbedding;
_textCompletion = textCompletion;
- }
-
- public QdrantHttpClient GetClient()
- {
- var client = new QdrantHttpClient
- (
- url: "",
- apiKey: ""
- );
- return client;
+ _db = db;
}
public async Task Feed(KnowledgeFeedModel knowledge)
{
- var client = GetClient();
-
- // List all the collections
- var collections = await client.GetCollections();
- if (!collections.Result.Collections.Select(x => x.Name).Contains(collectionName))
- {
- // Create a new collection
- await client.CreateCollection(collectionName, new VectorParams(size: 300, distance: Distance.COSINE));
- }
-
- // Get collection info
- var collectionInfo = await client.GetCollection(collectionName);
var idStart = 0;
var lines = knowledge.Content.Split(". ");
lines = lines.Select((x, i) => $"{i+1} {x}").ToArray();
@@ -52,33 +31,22 @@ public class KnowledgeService : IKnowledgeService
foreach (var line in lines)
{
idStart++;
-
- // Insert vectors
- /*await client.Upsert(collectionName, points: new List
- {
- new PointStruct(id: idStart, vector: _textEmbedding.GetVector(line))
- });*/
+ await _db.Upsert(collectionName, idStart, _textEmbedding.GetVector(line));
}
}
public async Task GetAnswer(string question)
{
- var client = GetClient();
var vector = _textEmbedding.GetVector(question);
// Vector search
- var result = await client.Search
- (
- collectionName,
- vector,
- limit: 10
- );
+ var result = await _db.Search(collectionName, vector);
var prompt = "";
var lines = File.ReadAllLines(collectionName + ".txt");
- foreach (var r in result.Result)
+ foreach (var r in result)
{
- prompt += lines[r.Id - 1] + "\n";
+ prompt += lines[r - 1] + "\n";
}
prompt += "###\r\n";
diff --git a/src/Infrastructure/BotSharp.Core/Users/UserController.cs b/src/Infrastructure/BotSharp.Core/Users/UserController.cs
index 6be3be23..c03d82bc 100644
--- a/src/Infrastructure/BotSharp.Core/Users/UserController.cs
+++ b/src/Infrastructure/BotSharp.Core/Users/UserController.cs
@@ -1,5 +1,4 @@
using BotSharp.Abstraction.ApiAdapters;
-using BotSharp.Abstraction.Users;
using BotSharp.Abstraction.Users.Models;
using BotSharp.Core.Users.ViewModels;
using Microsoft.AspNetCore.Authorization;
diff --git a/src/Infrastructure/BotSharp.Core/Using.cs b/src/Infrastructure/BotSharp.Core/Using.cs
index 0e2fb894..4244f10d 100644
--- a/src/Infrastructure/BotSharp.Core/Using.cs
+++ b/src/Infrastructure/BotSharp.Core/Using.cs
@@ -6,7 +6,17 @@ global using System.Linq;
global using Microsoft.Extensions.DependencyInjection;
global using BotSharp.Abstraction.Plugins;
global using EntityFrameworkCore.BootKit;
-global using BotSharp.Abstraction;
+global using BotSharp.Abstraction.Agents;
+global using BotSharp.Abstraction.Conversations;
+global using BotSharp.Abstraction.Infrastructures.ContentTransmitters;
+global using BotSharp.Abstraction.Knowledges;
+global using BotSharp.Abstraction.Users;
global using BotSharp.Core.Repository;
global using BotSharp.Core.Repository.Abstraction;
-global using BotSharp.Core.Repository.DbTables;
\ No newline at end of file
+global using BotSharp.Core.Repository.DbTables;
+global using BotSharp.Core.Agents.Services;
+global using BotSharp.Core.Conversations.Services;
+global using BotSharp.Core.Infrastructures;
+global using BotSharp.Core.Knowledges.Services;
+global using BotSharp.Core.Plugins;
+global using BotSharp.Core.Users.Services;
\ No newline at end of file
diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj b/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj
index 4183f4bc..5ea98423 100644
--- a/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj
+++ b/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj
@@ -6,17 +6,12 @@
10
-
-
-
-
-
-
+
diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/MetaAiPlugin.cs b/src/Plugins/BotSharp.Plugin.MetaAI/MetaAiPlugin.cs
index 4d3ec9a5..e7437837 100644
--- a/src/Plugins/BotSharp.Plugin.MetaAI/MetaAiPlugin.cs
+++ b/src/Plugins/BotSharp.Plugin.MetaAI/MetaAiPlugin.cs
@@ -1,3 +1,4 @@
+using BotSharp.Abstraction.Knowledges;
using BotSharp.Abstraction.MLTasks;
using BotSharp.Abstraction.Plugins;
using BotSharp.Plugin.MetaAI.Providers;
@@ -18,5 +19,6 @@ public class MetaAiPlugin : IBotSharpPlugin
services.AddSingleton(x => settings.fastText);
services.AddSingleton();
+ services.AddSingleton();
}
}
diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs b/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs
new file mode 100644
index 00000000..6110fbe5
--- /dev/null
+++ b/src/Plugins/BotSharp.Plugin.MetaAI/Providers/FaissDb.cs
@@ -0,0 +1,29 @@
+using BotSharp.Abstraction.Knowledges;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace BotSharp.Plugin.MetaAI.Providers;
+
+public class FaissDb : IVectorDb
+{
+ public Task CreateCollection(string collectionName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetCollections()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> Search(string collectionName, float[] vector, int limit = 10)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task Upsert(string collectionName, int id, float[] vector)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/Providers/fastTextEmbeddingProvider.cs b/src/Plugins/BotSharp.Plugin.MetaAI/Providers/fastTextEmbeddingProvider.cs
index 0e2a27a1..1d0c5b1e 100644
--- a/src/Plugins/BotSharp.Plugin.MetaAI/Providers/fastTextEmbeddingProvider.cs
+++ b/src/Plugins/BotSharp.Plugin.MetaAI/Providers/fastTextEmbeddingProvider.cs
@@ -1,6 +1,7 @@
using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.MetaAI.Settings;
using FastText.NetWrapper;
+using System.IO;
namespace BotSharp.Plugin.MetaAI.Providers;
@@ -14,6 +15,11 @@ public class fastTextEmbeddingProvider : ITextEmbedding
_settings = settings;
_fastText = new FastTextWrapper();
+ if (!File.Exists(settings.ModelPath))
+ {
+ throw new FileNotFoundException($"Can't load pre-trained word vectors from {settings.ModelPath}.\n Try to download from https://fasttext.cc/docs/en/english-vectors.html.");
+ }
+
if (!_fastText.IsModelReady())
{
_fastText.LoadModel(settings.ModelPath);
diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj
index 304e16d9..4d8be7ab 100644
--- a/src/WebStarter/WebStarter.csproj
+++ b/src/WebStarter/WebStarter.csproj
@@ -27,6 +27,7 @@
+
diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json
index f3c049c0..f791ff88 100644
--- a/src/WebStarter/appsettings.json
+++ b/src/WebStarter/appsettings.json
@@ -48,11 +48,17 @@
"Assemblies": [ "BotSharp.Core" ]
},
+ "Qdrant": {
+ "Url": "",
+ "ApiKey": ""
+ },
+
"PluginLoader": {
"Assemblies": [
"BotSharp.Core",
"BotSharp.Plugin.AzureOpenAI",
- "BotSharp.Plugin.MetaAI"
+ "BotSharp.Plugin.MetaAI",
+ "BotSharp.Plugin.Qdrant"
]
}
}