2024-09-09 22:42:09 +00:00
|
|
|
using BotSharp.Abstraction.Files;
|
|
|
|
|
using BotSharp.Abstraction.Files.Models;
|
|
|
|
|
using BotSharp.Abstraction.Files.Utilities;
|
2024-09-19 16:43:49 +00:00
|
|
|
using BotSharp.Abstraction.Knowledges.Helpers;
|
2024-09-13 22:23:05 +00:00
|
|
|
using BotSharp.Abstraction.VectorStorage.Enums;
|
2024-09-10 19:02:25 +00:00
|
|
|
using System.Net.Http;
|
2024-09-11 20:48:05 +00:00
|
|
|
using System.Net.Mime;
|
2024-09-09 22:42:09 +00:00
|
|
|
|
2024-09-09 15:00:46 +00:00
|
|
|
namespace BotSharp.Plugin.KnowledgeBase.Services;
|
|
|
|
|
|
|
|
|
|
public partial class KnowledgeService
|
|
|
|
|
{
|
2024-09-19 16:43:49 +00:00
|
|
|
public async Task<UploadKnowledgeResponse> UploadDocumentsToKnowledge(string collectionName, IEnumerable<ExternalFileModel> files)
|
2024-09-09 22:42:09 +00:00
|
|
|
{
|
2024-09-24 20:34:47 +00:00
|
|
|
var res = new UploadKnowledgeResponse
|
|
|
|
|
{
|
|
|
|
|
Success = [],
|
|
|
|
|
Failed = files?.Select(x => x.FileName) ?? new List<string>()
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-11 21:12:48 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(collectionName) || files.IsNullOrEmpty())
|
2024-09-09 22:42:09 +00:00
|
|
|
{
|
2024-09-24 20:34:47 +00:00
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var exist = await ExistVectorCollection(collectionName);
|
|
|
|
|
if (!exist)
|
|
|
|
|
{
|
|
|
|
|
return res;
|
2024-09-09 22:42:09 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-13 22:23:05 +00:00
|
|
|
var db = _services.GetRequiredService<IBotSharpRepository>();
|
2024-09-09 22:42:09 +00:00
|
|
|
var fileStoreage = _services.GetRequiredService<IFileStorageService>();
|
2024-09-10 19:02:25 +00:00
|
|
|
var userId = await GetUserId();
|
|
|
|
|
var vectorStoreProvider = _settings.VectorDb.Provider;
|
2024-09-09 22:42:09 +00:00
|
|
|
var successFiles = new List<string>();
|
|
|
|
|
var failedFiles = new List<string>();
|
|
|
|
|
|
|
|
|
|
foreach (var file in files)
|
|
|
|
|
{
|
2024-09-10 19:02:25 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(file.FileData)
|
|
|
|
|
&& string.IsNullOrWhiteSpace(file.FileUrl))
|
2024-09-09 22:42:09 +00:00
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-09-11 20:48:05 +00:00
|
|
|
// Get document info
|
2024-09-10 19:02:25 +00:00
|
|
|
var (contentType, bytes) = await GetFileInfo(file);
|
2024-09-11 20:48:05 +00:00
|
|
|
var contents = await GetFileContent(contentType, bytes);
|
|
|
|
|
|
|
|
|
|
// Save document
|
2024-09-17 17:50:39 +00:00
|
|
|
var fileId = Guid.NewGuid();
|
2024-09-11 20:48:05 +00:00
|
|
|
var saved = SaveDocument(collectionName, vectorStoreProvider, fileId, file.FileName, bytes);
|
2024-09-09 22:42:09 +00:00
|
|
|
if (!saved)
|
|
|
|
|
{
|
|
|
|
|
failedFiles.Add(file.FileName);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save to vector db
|
2024-09-13 22:23:05 +00:00
|
|
|
var dataIds = await SaveToVectorDb(collectionName, fileId, file.FileName, contents, file.FileSource);
|
2024-09-11 20:48:05 +00:00
|
|
|
if (!dataIds.IsNullOrEmpty())
|
2024-09-10 19:02:25 +00:00
|
|
|
{
|
2024-09-13 22:23:05 +00:00
|
|
|
db.SaveKnolwedgeBaseFileMeta(new KnowledgeDocMetaData
|
2024-09-10 19:02:25 +00:00
|
|
|
{
|
|
|
|
|
Collection = collectionName,
|
2024-09-10 19:33:42 +00:00
|
|
|
FileId = fileId,
|
2024-09-10 19:02:25 +00:00
|
|
|
FileName = file.FileName,
|
2024-09-13 22:23:05 +00:00
|
|
|
FileSource = file.FileSource,
|
2024-09-10 19:02:25 +00:00
|
|
|
ContentType = contentType,
|
2024-09-13 22:23:05 +00:00
|
|
|
VectorStoreProvider = vectorStoreProvider,
|
2024-09-10 19:02:25 +00:00
|
|
|
VectorDataIds = dataIds,
|
|
|
|
|
CreateDate = DateTime.UtcNow,
|
|
|
|
|
CreateUserId = userId
|
|
|
|
|
});
|
|
|
|
|
successFiles.Add(file.FileName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
failedFiles.Add(file.FileName);
|
|
|
|
|
}
|
2024-09-09 22:42:09 +00:00
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"Error when processing knowledge file ({file.FileName}). {ex.Message}\r\n{ex.InnerException}");
|
|
|
|
|
failedFiles.Add(file.FileName);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new UploadKnowledgeResponse
|
|
|
|
|
{
|
|
|
|
|
Success = successFiles,
|
|
|
|
|
Failed = failedFiles
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-09-19 16:43:49 +00:00
|
|
|
public async Task<bool> ImportDocumentContentToKnowledge(string collectionName, string fileName, string fileSource,
|
|
|
|
|
IEnumerable<string> contents, DocMetaRefData? refData = null)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(collectionName)
|
|
|
|
|
|| string.IsNullOrWhiteSpace(fileName)
|
|
|
|
|
|| contents.IsNullOrEmpty())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-09-24 20:34:47 +00:00
|
|
|
var exist = await ExistVectorCollection(collectionName);
|
|
|
|
|
if (!exist) return false;
|
|
|
|
|
|
2024-09-19 16:43:49 +00:00
|
|
|
var db = _services.GetRequiredService<IBotSharpRepository>();
|
|
|
|
|
var userId = await GetUserId();
|
|
|
|
|
var vectorStoreProvider = _settings.VectorDb.Provider;
|
|
|
|
|
var fileId = Guid.NewGuid();
|
|
|
|
|
var contentType = FileUtility.GetFileContentType(fileName);
|
|
|
|
|
|
|
|
|
|
var dataIds = await SaveToVectorDb(collectionName, fileId, fileName, contents, fileSource, fileUrl: refData?.Url);
|
|
|
|
|
db.SaveKnolwedgeBaseFileMeta(new KnowledgeDocMetaData
|
|
|
|
|
{
|
|
|
|
|
Collection = collectionName,
|
|
|
|
|
FileId = fileId,
|
|
|
|
|
FileName = fileName,
|
|
|
|
|
FileSource = fileSource,
|
|
|
|
|
ContentType = contentType,
|
|
|
|
|
VectorStoreProvider = vectorStoreProvider,
|
|
|
|
|
VectorDataIds = dataIds,
|
|
|
|
|
RefData = refData,
|
|
|
|
|
CreateDate = DateTime.UtcNow,
|
|
|
|
|
CreateUserId = userId
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogWarning($"Error when importing doc content to knowledgebase ({collectionName}-{fileName})" +
|
|
|
|
|
$"\r\n{ex.Message}" +
|
|
|
|
|
$"\r\n{ex.InnerException}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-09-17 17:50:39 +00:00
|
|
|
public async Task<bool> DeleteKnowledgeDocument(string collectionName, Guid fileId)
|
2024-09-10 19:02:25 +00:00
|
|
|
{
|
2024-09-17 17:50:39 +00:00
|
|
|
if (string.IsNullOrWhiteSpace(collectionName))
|
2024-09-10 19:02:25 +00:00
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-09-13 22:23:05 +00:00
|
|
|
var db = _services.GetRequiredService<IBotSharpRepository>();
|
2024-09-10 19:02:25 +00:00
|
|
|
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
|
|
|
|
var vectorDb = GetVectorDb();
|
|
|
|
|
var vectorStoreProvider = _settings.VectorDb.Provider;
|
|
|
|
|
|
2024-09-11 21:12:48 +00:00
|
|
|
// Get doc meta data
|
2024-09-17 17:50:39 +00:00
|
|
|
var pageData = db.GetKnowledgeBaseFileMeta(collectionName, vectorStoreProvider, new KnowledgeFileFilter
|
2024-09-13 22:23:05 +00:00
|
|
|
{
|
2024-09-20 18:42:08 +00:00
|
|
|
Size = 1,
|
|
|
|
|
FileIds = [ fileId ]
|
2024-09-13 22:23:05 +00:00
|
|
|
});
|
|
|
|
|
|
2024-09-11 21:12:48 +00:00
|
|
|
// Delete doc
|
2024-09-17 17:50:39 +00:00
|
|
|
fileStorage.DeleteKnowledgeFile(collectionName, vectorStoreProvider, fileId);
|
|
|
|
|
|
|
|
|
|
var found = pageData?.Items?.FirstOrDefault();
|
2024-09-13 22:23:05 +00:00
|
|
|
if (found != null && !found.VectorDataIds.IsNullOrEmpty())
|
2024-09-10 19:02:25 +00:00
|
|
|
{
|
2024-09-13 22:23:05 +00:00
|
|
|
var guids = found.VectorDataIds.Where(x => Guid.TryParse(x, out _)).Select(x => Guid.Parse(x)).ToList();
|
2024-09-10 19:02:25 +00:00
|
|
|
await vectorDb.DeleteCollectionData(collectionName, guids);
|
|
|
|
|
}
|
2024-09-17 17:50:39 +00:00
|
|
|
|
|
|
|
|
db.DeleteKnolwedgeBaseFileMeta(collectionName, vectorStoreProvider, fileId);
|
2024-09-10 19:02:25 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogWarning($"Error when deleting knowledge document " +
|
|
|
|
|
$"(Collection: {collectionName}, File id: {fileId})" +
|
|
|
|
|
$"\r\n{ex.Message}\r\n{ex.InnerException}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-20 18:42:08 +00:00
|
|
|
public async Task<bool> DeleteKnowledgeDocuments(string collectionName, KnowledgeFileFilter filter)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(collectionName)) return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var pageSize = filter.Size;
|
|
|
|
|
var innerFilter = new KnowledgeFileFilter
|
|
|
|
|
{
|
|
|
|
|
Page = 1,
|
|
|
|
|
Size = pageSize,
|
|
|
|
|
FileIds = filter.FileIds,
|
|
|
|
|
FileNames = filter.FileNames,
|
|
|
|
|
FileSources = filter.FileSources,
|
|
|
|
|
ContentTypes = filter.ContentTypes
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var pageData = await GetPagedKnowledgeDocuments(collectionName, innerFilter);
|
|
|
|
|
|
|
|
|
|
var total = pageData.Count;
|
|
|
|
|
if (total == 0) return false;
|
|
|
|
|
|
|
|
|
|
var page = 1;
|
|
|
|
|
var totalPages = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
|
|
|
|
|
|
|
|
|
|
while (page <= totalPages)
|
|
|
|
|
{
|
|
|
|
|
if (page > 1)
|
|
|
|
|
{
|
|
|
|
|
pageData = await GetPagedKnowledgeDocuments(collectionName, innerFilter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var fileIds = pageData.Items.Select(x => x.FileId).ToList();
|
|
|
|
|
foreach (var fileId in fileIds)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await DeleteKnowledgeDocument(collectionName, fileId);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
page++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-09-13 22:23:05 +00:00
|
|
|
public async Task<PagedItems<KnowledgeFileModel>> GetPagedKnowledgeDocuments(string collectionName, KnowledgeFileFilter filter)
|
2024-09-10 19:33:42 +00:00
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(collectionName))
|
|
|
|
|
{
|
2024-09-13 22:23:05 +00:00
|
|
|
return new PagedItems<KnowledgeFileModel>();
|
2024-09-10 19:33:42 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-13 22:23:05 +00:00
|
|
|
var db = _services.GetRequiredService<IBotSharpRepository>();
|
2024-09-10 19:33:42 +00:00
|
|
|
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
|
|
|
|
var vectorStoreProvider = _settings.VectorDb.Provider;
|
2024-09-11 21:12:48 +00:00
|
|
|
|
|
|
|
|
// Get doc meta data
|
2024-09-20 18:42:08 +00:00
|
|
|
var pagedData = db.GetKnowledgeBaseFileMeta(collectionName, vectorStoreProvider, filter);
|
2024-09-13 22:23:05 +00:00
|
|
|
|
2024-09-18 15:35:28 +00:00
|
|
|
var files = pagedData.Items?.Select(x => new KnowledgeFileModel
|
2024-09-13 22:23:05 +00:00
|
|
|
{
|
2024-09-18 15:35:28 +00:00
|
|
|
FileId = x.FileId,
|
|
|
|
|
FileName = x.FileName,
|
2024-09-19 16:43:49 +00:00
|
|
|
FileSource = x.FileSource,
|
2024-09-18 15:35:28 +00:00
|
|
|
FileExtension = Path.GetExtension(x.FileName),
|
|
|
|
|
ContentType = x.ContentType,
|
|
|
|
|
FileUrl = fileStorage.GetKnowledgeBaseFileUrl(collectionName, vectorStoreProvider, x.FileId, x.FileName),
|
|
|
|
|
RefData = x.RefData
|
2024-09-13 22:23:05 +00:00
|
|
|
})?.ToList() ?? new List<KnowledgeFileModel>();
|
|
|
|
|
|
|
|
|
|
return new PagedItems<KnowledgeFileModel>
|
|
|
|
|
{
|
|
|
|
|
Items = files,
|
|
|
|
|
Count = pagedData.Count
|
|
|
|
|
};
|
2024-09-10 19:33:42 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-18 15:35:28 +00:00
|
|
|
public async Task<FileBinaryDataModel> GetKnowledgeDocumentBinaryData(string collectionName, Guid fileId)
|
2024-09-10 20:07:56 +00:00
|
|
|
{
|
2024-09-17 17:50:39 +00:00
|
|
|
var db = _services.GetRequiredService<IBotSharpRepository>();
|
2024-09-10 20:07:56 +00:00
|
|
|
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
|
|
|
|
var vectorStoreProvider = _settings.VectorDb.Provider;
|
2024-09-11 21:12:48 +00:00
|
|
|
|
|
|
|
|
// Get doc binary data
|
2024-09-17 17:50:39 +00:00
|
|
|
var pageData = db.GetKnowledgeBaseFileMeta(collectionName, vectorStoreProvider, new KnowledgeFileFilter
|
|
|
|
|
{
|
2024-09-20 18:42:08 +00:00
|
|
|
Size = 1,
|
|
|
|
|
FileIds = [ fileId ]
|
2024-09-17 17:50:39 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var metaData = pageData?.Items?.FirstOrDefault();
|
2024-09-18 15:35:28 +00:00
|
|
|
if (metaData == null)
|
|
|
|
|
{
|
|
|
|
|
return new FileBinaryDataModel
|
|
|
|
|
{
|
|
|
|
|
FileName = "error.txt",
|
|
|
|
|
ContentType = "text/plain",
|
|
|
|
|
FileBinaryData = BinaryData.Empty
|
|
|
|
|
};
|
|
|
|
|
};
|
2024-09-17 17:50:39 +00:00
|
|
|
|
|
|
|
|
var binaryData = fileStorage.GetKnowledgeBaseFileBinaryData(collectionName, vectorStoreProvider, fileId, metaData.FileName);
|
|
|
|
|
return new FileBinaryDataModel
|
|
|
|
|
{
|
|
|
|
|
FileName = metaData.FileName,
|
|
|
|
|
ContentType = metaData.ContentType,
|
|
|
|
|
FileBinaryData = binaryData
|
|
|
|
|
};
|
2024-09-10 20:07:56 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-10 19:33:42 +00:00
|
|
|
|
2024-09-20 18:42:08 +00:00
|
|
|
|
2024-09-09 22:42:09 +00:00
|
|
|
#region Private methods
|
2024-09-10 19:02:25 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Get file content type and file bytes
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task<(string, byte[])> GetFileInfo(ExternalFileModel file)
|
|
|
|
|
{
|
|
|
|
|
if (file == null)
|
|
|
|
|
{
|
|
|
|
|
return (string.Empty, new byte[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(file.FileUrl))
|
|
|
|
|
{
|
|
|
|
|
var http = _services.GetRequiredService<IHttpClientFactory>();
|
|
|
|
|
var contentType = FileUtility.GetFileContentType(file.FileName);
|
|
|
|
|
using var client = http.CreateClient();
|
|
|
|
|
var bytes = await client.GetByteArrayAsync(file.FileUrl);
|
|
|
|
|
return (contentType, bytes);
|
|
|
|
|
}
|
|
|
|
|
else if (!string.IsNullOrWhiteSpace(file.FileData))
|
|
|
|
|
{
|
|
|
|
|
var (contentType, bytes) = FileUtility.GetFileInfoFromData(file.FileData);
|
|
|
|
|
return (contentType, bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (string.Empty, new byte[0]);
|
|
|
|
|
}
|
2024-09-11 20:48:05 +00:00
|
|
|
|
2024-09-12 16:51:23 +00:00
|
|
|
#region Read doc content
|
2024-09-11 20:48:05 +00:00
|
|
|
private async Task<IEnumerable<string>> GetFileContent(string contentType, byte[] bytes)
|
|
|
|
|
{
|
2024-09-12 16:51:23 +00:00
|
|
|
IEnumerable<string> results = new List<string>();
|
2024-09-11 20:48:05 +00:00
|
|
|
|
|
|
|
|
if (contentType.IsEqualTo(MediaTypeNames.Text.Plain))
|
|
|
|
|
{
|
2024-09-12 16:51:23 +00:00
|
|
|
results = await ReadTxt(bytes);
|
2024-09-11 20:48:05 +00:00
|
|
|
}
|
|
|
|
|
else if (contentType.IsEqualTo(MediaTypeNames.Application.Pdf))
|
|
|
|
|
{
|
2024-09-12 16:51:23 +00:00
|
|
|
results = await ReadPdf(bytes);
|
2024-09-11 20:48:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-12 16:51:23 +00:00
|
|
|
private async Task<IEnumerable<string>> ReadTxt(byte[] bytes)
|
|
|
|
|
{
|
|
|
|
|
using var stream = new MemoryStream(bytes);
|
|
|
|
|
using var reader = new StreamReader(stream);
|
|
|
|
|
var content = await reader.ReadToEndAsync();
|
|
|
|
|
reader.Close();
|
|
|
|
|
stream.Close();
|
|
|
|
|
|
|
|
|
|
var lines = TextChopper.Chop(content, new ChunkOption
|
|
|
|
|
{
|
|
|
|
|
Size = 1024,
|
2024-09-19 16:43:49 +00:00
|
|
|
Conjunction = 12,
|
2024-09-12 16:51:23 +00:00
|
|
|
SplitByWord = true,
|
|
|
|
|
});
|
|
|
|
|
return lines;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<IEnumerable<string>> ReadPdf(byte[] bytes)
|
|
|
|
|
{
|
|
|
|
|
return Enumerable.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
2024-09-17 17:50:39 +00:00
|
|
|
private bool SaveDocument(string collectionName, string vectorStoreProvider, Guid fileId, string fileName, byte[] bytes)
|
2024-09-11 20:48:05 +00:00
|
|
|
{
|
|
|
|
|
var fileStoreage = _services.GetRequiredService<IFileStorageService>();
|
2024-09-12 01:03:54 +00:00
|
|
|
var data = BinaryData.FromBytes(bytes);
|
2024-09-17 17:50:39 +00:00
|
|
|
var saved = fileStoreage.SaveKnowledgeBaseFile(collectionName, vectorStoreProvider, fileId, fileName, data);
|
2024-09-11 20:48:05 +00:00
|
|
|
return saved;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-13 22:23:05 +00:00
|
|
|
private async Task<IEnumerable<string>> SaveToVectorDb(
|
2024-09-17 17:50:39 +00:00
|
|
|
string collectionName, Guid fileId, string fileName, IEnumerable<string> contents,
|
2024-09-19 16:43:49 +00:00
|
|
|
string fileSource = KnowledgeDocSource.Api, string vectorDataSource = VectorDataSource.File, string? fileUrl = null)
|
2024-09-11 20:48:05 +00:00
|
|
|
{
|
|
|
|
|
if (contents.IsNullOrEmpty())
|
|
|
|
|
{
|
|
|
|
|
return Enumerable.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dataIds = new List<string>();
|
|
|
|
|
var vectorDb = GetVectorDb();
|
|
|
|
|
var textEmbedding = GetTextEmbedding(collectionName);
|
|
|
|
|
|
2024-09-29 01:00:35 +00:00
|
|
|
var payload = new Dictionary<string, object>
|
2024-09-19 16:43:49 +00:00
|
|
|
{
|
|
|
|
|
{ KnowledgePayloadName.DataSource, vectorDataSource },
|
|
|
|
|
{ KnowledgePayloadName.FileId, fileId.ToString() },
|
|
|
|
|
{ KnowledgePayloadName.FileName, fileName },
|
|
|
|
|
{ KnowledgePayloadName.FileSource, fileSource }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(fileUrl))
|
|
|
|
|
{
|
|
|
|
|
payload[KnowledgePayloadName.FileUrl] = fileUrl;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-11 20:48:05 +00:00
|
|
|
for (int i = 0; i < contents.Count(); i++)
|
|
|
|
|
{
|
|
|
|
|
var content = contents.ElementAt(i);
|
|
|
|
|
var vector = await textEmbedding.GetVectorAsync(content);
|
|
|
|
|
var dataId = Guid.NewGuid();
|
2024-09-19 16:43:49 +00:00
|
|
|
var saved = await vectorDb.Upsert(collectionName, dataId, vector, content, payload);
|
2024-09-11 20:48:05 +00:00
|
|
|
|
|
|
|
|
if (!saved) continue;
|
|
|
|
|
|
|
|
|
|
dataIds.Add(dataId.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dataIds;
|
|
|
|
|
}
|
2024-09-09 22:42:09 +00:00
|
|
|
#endregion
|
2024-09-09 15:00:46 +00:00
|
|
|
}
|