using BotSharp.Abstraction.Files.Utilities; using BotSharp.Abstraction.Graph.Models; using BotSharp.Abstraction.Knowledges.Models; using BotSharp.Abstraction.VectorStorage.Models; using BotSharp.OpenAPI.ViewModels.Knowledges; namespace BotSharp.OpenAPI.Controllers; [Authorize] [ApiController] public class KnowledgeBaseController : ControllerBase { private readonly IKnowledgeService _knowledgeService; private readonly IServiceProvider _services; public KnowledgeBaseController(IKnowledgeService knowledgeService, IServiceProvider services) { _knowledgeService = knowledgeService; _services = services; } #region Vector [HttpGet("knowledge/vector/collections")] public async Task> GetVectorCollections([FromQuery] string type) { return await _knowledgeService.GetVectorCollections(type); } [HttpPost("knowledge/vector/create-collection")] public async Task CreateVectorCollection([FromBody] CreateVectorCollectionRequest request) { return await _knowledgeService.CreateVectorCollection(request.CollectionName, request.CollectionType, request.Dimension, request.Provider, request.Model); } [HttpDelete("knowledge/vector/{collection}/delete-collection")] public async Task DeleteVectorCollection([FromRoute] string collection) { return await _knowledgeService.DeleteVectorCollection(collection); } [HttpPost("/knowledge/vector/{collection}/search")] public async Task> SearchVectorKnowledge([FromRoute] string collection, [FromBody] SearchVectorKnowledgeRequest request) { var options = new VectorSearchOptions { Fields = request.Fields, Limit = request.Limit ?? 5, Confidence = request.Confidence ?? 0.5f, WithVector = request.WithVector }; var results = await _knowledgeService.SearchVectorKnowledge(request.Text, collection, options); return results.Select(x => VectorKnowledgeViewModel.From(x)).ToList(); } [HttpPost("/knowledge/vector/{collection}/page")] public async Task> GetPagedVectorCollectionData([FromRoute] string collection, [FromBody] VectorFilter filter) { var data = await _knowledgeService.GetPagedVectorCollectionData(collection, filter); var items = data.Items?.Select(x => VectorKnowledgeViewModel.From(x))? .ToList() ?? new List(); return new StringIdPagedItems { Count = data.Count, NextId = data.NextId, Items = items }; } [HttpPost("/knowledge/vector/{collection}/create")] public async Task CreateVectorKnowledge([FromRoute] string collection, [FromBody] VectorKnowledgeCreateRequest request) { var create = new VectorCreateModel { Text = request.Text, DataSource = request.DataSource, Payload = request.Payload }; var created = await _knowledgeService.CreateVectorCollectionData(collection, create); return created; } [HttpPut("/knowledge/vector/{collection}/update")] public async Task UpdateVectorKnowledge([FromRoute] string collection, [FromBody] VectorKnowledgeUpdateRequest request) { var update = new VectorUpdateModel { Id = request.Id, Text = request.Text, DataSource = request.DataSource, Payload = request.Payload }; var updated = await _knowledgeService.UpdateVectorCollectionData(collection, update); return updated; } [HttpDelete("/knowledge/vector/{collection}/data/{id}")] public async Task DeleteVectorCollectionData([FromRoute] string collection, [FromRoute] string id) { return await _knowledgeService.DeleteVectorCollectionData(collection, id); } [HttpDelete("/knowledge/vector/{collection}/data")] public async Task DeleteVectorCollectionAllData([FromRoute] string collection) { return await _knowledgeService.DeleteVectorCollectionAllData(collection); } #endregion #region Document [HttpPost("/knowledge/document/{collection}/upload")] public async Task UploadKnowledgeDocuments([FromRoute] string collection, [FromBody] VectorKnowledgeUploadRequest request) { var response = await _knowledgeService.UploadDocumentsToKnowledge(collection, request.Files); return response; } [HttpPost("/knowledge/document/{collection}/form-upload")] public async Task UploadKnowledgeDocuments([FromRoute] string collection, [FromForm] IEnumerable files) { if (files.IsNullOrEmpty()) { return new UploadKnowledgeResponse(); } var docs = new List(); foreach (var file in files) { var data = FileUtility.BuildFileDataFromFile(file); docs.Add(new ExternalFileModel { FileName = file.FileName, FileData = data }); } var response = await _knowledgeService.UploadDocumentsToKnowledge(collection, docs); return response; } [HttpDelete("/knowledge/document/{collection}/delete/{fileId}")] public async Task DeleteKnowledgeDocument([FromRoute] string collection, [FromRoute] Guid fileId) { var response = await _knowledgeService.DeleteKnowledgeDocument(collection, fileId); return response; } [HttpPost("/knowledge/document/{collection}/list")] public async Task> GetPagedKnowledgeDocuments([FromRoute] string collection, [FromBody] GetKnowledgeDocsRequest request) { var data = await _knowledgeService.GetPagedKnowledgeDocuments(collection, new KnowledgeFileFilter { Page = request.Page, Size = request.Size }); return new PagedItems { Items = data.Items.Select(x => KnowledgeFileViewModel.From(x)), Count = data.Count }; } [HttpGet("/knowledge/document/{collection}/file/{fileId}")] public async Task GetKnowledgeDocument([FromRoute] string collection, [FromRoute] Guid fileId) { var file = await _knowledgeService.GetKnowledgeDocumentBinaryData(collection, fileId); var stream = file.FileBinaryData.ToStream(); stream.Position = 0; return new FileStreamResult(stream, file.ContentType) { FileDownloadName = file.FileName }; } #endregion #region Graph [HttpPost("/knowledge/graph/search")] public async Task SearchGraphKnowledge([FromBody] SearchGraphKnowledgeRequest request) { var options = new GraphSearchOptions { Method = request.Method }; var result = await _knowledgeService.SearchGraphKnowledge(request.Query, options); return new GraphKnowledgeViewModel { Result = result.Result }; } #endregion #region Common [HttpPost("/knowledge/vector/refresh-configs")] public async Task RefreshVectorCollectionConfigs([FromBody] VectorCollectionConfigsModel request) { var saved = await _knowledgeService.RefreshVectorKnowledgeConfigs(request); return saved ? "Success" : "Fail"; } #endregion }