Compare commits
8 Commits
d647bedb33
...
b5db4bc1e4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5db4bc1e4 | ||
| 0f599a49d0 | |||
|
|
4fe6b4a112 | ||
| 16efe447a2 | |||
| 6a7bdf585c | |||
| 31c784f0ab | |||
| 625019f9f4 | |||
| c3dfe1a964 |
@@ -34,24 +34,44 @@ public class Client
|
|||||||
this.searchdomain = searchdomain ?? "";
|
this.searchdomain = searchdomain ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<EntityListResults> EntityListAsync(bool returnEmbeddings = false)
|
||||||
|
{
|
||||||
|
return await EntityListAsync(searchdomain, returnEmbeddings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EntityListResults> EntityListAsync(string searchdomain, bool returnEmbeddings = false)
|
||||||
|
{
|
||||||
|
var url = $"{baseUri}/Entities?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&returnEmbeddings={HttpUtility.UrlEncode(returnEmbeddings.ToString())}";
|
||||||
|
return await GetUrlAndProcessJson<EntityListResults>(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EntityIndexResult> EntityIndexAsync(List<JSONEntity> jsonEntity)
|
||||||
|
{
|
||||||
|
return await EntityIndexAsync(JsonSerializer.Serialize(jsonEntity));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EntityIndexResult> EntityIndexAsync(string jsonEntity)
|
||||||
|
{
|
||||||
|
var content = new StringContent(jsonEntity, Encoding.UTF8, "application/json");
|
||||||
|
return await PutUrlAndProcessJson<EntityIndexResult>(GetUrl($"{baseUri}", "Entities", apiKey, []), content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EntityDeleteResults> EntityDeleteAsync(string entityName)
|
||||||
|
{
|
||||||
|
return await EntityDeleteAsync(searchdomain, entityName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EntityDeleteResults> EntityDeleteAsync(string searchdomain, string entityName)
|
||||||
|
{
|
||||||
|
var url = $"{baseUri}/Entity?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&entity={HttpUtility.UrlEncode(entityName)}";
|
||||||
|
return await DeleteUrlAndProcessJson<EntityDeleteResults>(url);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<SearchdomainListResults> SearchdomainListAsync()
|
public async Task<SearchdomainListResults> SearchdomainListAsync()
|
||||||
{
|
{
|
||||||
return await GetUrlAndProcessJson<SearchdomainListResults>(GetUrl($"{baseUri}", "Searchdomains", apiKey, []));
|
return await GetUrlAndProcessJson<SearchdomainListResults>(GetUrl($"{baseUri}", "Searchdomains", apiKey, []));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync()
|
|
||||||
{
|
|
||||||
return await SearchdomainDeleteAsync(searchdomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync(string searchdomain)
|
|
||||||
{
|
|
||||||
return await DeleteUrlAndProcessJson<SearchdomainDeleteResults>(GetUrl($"{baseUri}", "Searchdomain", apiKey, new Dictionary<string, string>()
|
|
||||||
{
|
|
||||||
{"searchdomain", searchdomain}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<SearchdomainCreateResults> SearchdomainCreateAsync()
|
public async Task<SearchdomainCreateResults> SearchdomainCreateAsync()
|
||||||
{
|
{
|
||||||
return await SearchdomainCreateAsync(searchdomain);
|
return await SearchdomainCreateAsync(searchdomain);
|
||||||
@@ -65,6 +85,19 @@ public class Client
|
|||||||
}), new StringContent(JsonSerializer.Serialize(searchdomainSettings), Encoding.UTF8, "application/json"));
|
}), new StringContent(JsonSerializer.Serialize(searchdomainSettings), Encoding.UTF8, "application/json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync()
|
||||||
|
{
|
||||||
|
return await SearchdomainDeleteAsync(searchdomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync(string searchdomain)
|
||||||
|
{
|
||||||
|
return await DeleteUrlAndProcessJson<SearchdomainDeleteResults>(GetUrl($"{baseUri}", "Searchdomain", apiKey, new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<SearchdomainUpdateResults> SearchdomainUpdateAsync(string newName, string settings = "{}")
|
public async Task<SearchdomainUpdateResults> SearchdomainUpdateAsync(string newName, string settings = "{}")
|
||||||
{
|
{
|
||||||
SearchdomainUpdateResults updateResults = await SearchdomainUpdateAsync(searchdomain, newName, settings);
|
SearchdomainUpdateResults updateResults = await SearchdomainUpdateAsync(searchdomain, newName, settings);
|
||||||
@@ -86,51 +119,109 @@ public class Client
|
|||||||
}), new StringContent(settings, Encoding.UTF8, "application/json"));
|
}), new StringContent(settings, Encoding.UTF8, "application/json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityQueryResults> EntityQueryAsync(string query)
|
public async Task<SearchdomainSearchesResults> SearchdomainGetQueriesAsync(string searchdomain)
|
||||||
{
|
{
|
||||||
return await EntityQueryAsync(searchdomain, query);
|
Dictionary<string, string> parameters = new()
|
||||||
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
};
|
||||||
|
return await GetUrlAndProcessJson<SearchdomainSearchesResults>(GetUrl($"{baseUri}/Searchdomain", "Queries", apiKey, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityQueryResults> EntityQueryAsync(string searchdomain, string query)
|
public async Task<EntityQueryResults> SearchdomainQueryAsync(string query)
|
||||||
{
|
{
|
||||||
return await PostUrlAndProcessJson<EntityQueryResults>(GetUrl($"{baseUri}/Searchdomain", "Query", apiKey, new Dictionary<string, string>()
|
return await SearchdomainQueryAsync(searchdomain, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EntityQueryResults> SearchdomainQueryAsync(string searchdomain, string query, int? topN = null, bool returnAttributes = false)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> parameters = new()
|
||||||
{
|
{
|
||||||
{"searchdomain", searchdomain},
|
{"searchdomain", searchdomain},
|
||||||
{"query", query}
|
{"query", query}
|
||||||
}), null);
|
};
|
||||||
|
if (topN is not null) parameters.Add("topN", ((int)topN).ToString());
|
||||||
|
if (returnAttributes) parameters.Add("returnAttributes", returnAttributes.ToString());
|
||||||
|
|
||||||
|
return await PostUrlAndProcessJson<EntityQueryResults>(GetUrl($"{baseUri}/Searchdomain", "Query", apiKey, parameters), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityIndexResult> EntityIndexAsync(List<JSONEntity> jsonEntity)
|
public async Task<SearchdomainDeleteSearchResult> SearchdomainDeleteQueryAsync(string searchdomain, string query)
|
||||||
{
|
{
|
||||||
return await EntityIndexAsync(JsonSerializer.Serialize(jsonEntity));
|
Dictionary<string, string> parameters = new()
|
||||||
|
{
|
||||||
|
{"searchdomain", searchdomain},
|
||||||
|
{"query", query}
|
||||||
|
};
|
||||||
|
return await DeleteUrlAndProcessJson<SearchdomainDeleteSearchResult>(GetUrl($"{baseUri}/Searchdomain", "Query", apiKey, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityIndexResult> EntityIndexAsync(string jsonEntity)
|
public async Task<SearchdomainUpdateSearchResult> SearchdomainUpdateQueryAsync(string searchdomain, string query, List<ResultItem> results)
|
||||||
{
|
{
|
||||||
var content = new StringContent(jsonEntity, Encoding.UTF8, "application/json");
|
Dictionary<string, string> parameters = new()
|
||||||
return await PutUrlAndProcessJson<EntityIndexResult>(GetUrl($"{baseUri}", "Entity", apiKey, []), content);
|
{
|
||||||
|
{"searchdomain", searchdomain},
|
||||||
|
{"query", query}
|
||||||
|
};
|
||||||
|
return await PatchUrlAndProcessJson<SearchdomainUpdateSearchResult>(
|
||||||
|
GetUrl($"{baseUri}/Searchdomain", "Query", apiKey, parameters),
|
||||||
|
new StringContent(JsonSerializer.Serialize(results), Encoding.UTF8, "application/json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityListResults> EntityListAsync(bool returnEmbeddings = false)
|
public async Task<SearchdomainSettingsResults> SearchdomainGetSettingsAsync(string searchdomain)
|
||||||
{
|
{
|
||||||
return await EntityListAsync(searchdomain, returnEmbeddings);
|
Dictionary<string, string> parameters = new()
|
||||||
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
};
|
||||||
|
return await GetUrlAndProcessJson<SearchdomainSettingsResults>(GetUrl($"{baseUri}/Searchdomain", "Settings", apiKey, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityListResults> EntityListAsync(string searchdomain, bool returnEmbeddings = false)
|
public async Task<SearchdomainUpdateResults> SearchdomainUpdateSettingsAsync(string searchdomain, SearchdomainSettings searchdomainSettings)
|
||||||
{
|
{
|
||||||
var url = $"{baseUri}/Entities?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&returnEmbeddings={HttpUtility.UrlEncode(returnEmbeddings.ToString())}";
|
Dictionary<string, string> parameters = new()
|
||||||
return await GetUrlAndProcessJson<EntityListResults>(url);
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
};
|
||||||
|
StringContent content = new(JsonSerializer.Serialize(searchdomainSettings), Encoding.UTF8, "application/json");
|
||||||
|
return await PutUrlAndProcessJson<SearchdomainUpdateResults>(GetUrl($"{baseUri}/Searchdomain", "Settings", apiKey, parameters), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityDeleteResults> EntityDeleteAsync(string entityName)
|
public async Task<SearchdomainSearchCacheSizeResults> SearchdomainGetQueryCacheSizeAsync(string searchdomain)
|
||||||
{
|
{
|
||||||
return await EntityDeleteAsync(searchdomain, entityName);
|
Dictionary<string, string> parameters = new()
|
||||||
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
};
|
||||||
|
return await GetUrlAndProcessJson<SearchdomainSearchCacheSizeResults>(GetUrl($"{baseUri}/Searchdomain/QueryCache", "Size", apiKey, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EntityDeleteResults> EntityDeleteAsync(string searchdomain, string entityName)
|
public async Task<SearchdomainInvalidateCacheResults> SearchdomainClearQueryCache(string searchdomain)
|
||||||
{
|
{
|
||||||
var url = $"{baseUri}/Entity?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&entity={HttpUtility.UrlEncode(entityName)}";
|
Dictionary<string, string> parameters = new()
|
||||||
return await DeleteUrlAndProcessJson<EntityDeleteResults>(url);
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
};
|
||||||
|
return await PostUrlAndProcessJson<SearchdomainInvalidateCacheResults>(GetUrl($"{baseUri}/Searchdomain/QueryCache", "Clear", apiKey, parameters), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<SearchdomainGetDatabaseSizeResult> SearchdomainGetDatabaseSizeAsync(string searchdomain)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> parameters = new()
|
||||||
|
{
|
||||||
|
{"searchdomain", searchdomain}
|
||||||
|
};
|
||||||
|
return await GetUrlAndProcessJson<SearchdomainGetDatabaseSizeResult>(GetUrl($"{baseUri}/Searchdomain/Database", "Size", apiKey, parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServerGetModelsResult> ServerGetModelsAsync()
|
||||||
|
{
|
||||||
|
return await GetUrlAndProcessJson<ServerGetModelsResult>(GetUrl($"{baseUri}/Server", "Models", apiKey, []));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ServerGetEmbeddingCacheSizeResult> ServerGetEmbeddingCacheSizeAsync()
|
||||||
|
{
|
||||||
|
return await GetUrlAndProcessJson<ServerGetEmbeddingCacheSizeResult>(GetUrl($"{baseUri}/Server/EmbeddingCache", "Size", apiKey, []));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<T> GetUrlAndProcessJson<T>(string url)
|
private static async Task<T> GetUrlAndProcessJson<T>(string url)
|
||||||
@@ -163,6 +254,16 @@ public class Client
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<T> PatchUrlAndProcessJson<T>(string url, HttpContent content)
|
||||||
|
{
|
||||||
|
using var client = new HttpClient();
|
||||||
|
var response = await client.PatchAsync(url, content);
|
||||||
|
string responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
var result = JsonSerializer.Deserialize<T>(responseContent)
|
||||||
|
?? throw new Exception($"Failed to deserialize JSON to type {typeof(T).Name}");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task<T> DeleteUrlAndProcessJson<T>(string url)
|
private static async Task<T> DeleteUrlAndProcessJson<T>(string url)
|
||||||
{
|
{
|
||||||
using var client = new HttpClient();
|
using var client = new HttpClient();
|
||||||
|
|||||||
@@ -24,44 +24,17 @@ public class EntityController : ControllerBase
|
|||||||
_databaseHelper = databaseHelper;
|
_databaseHelper = databaseHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut]
|
/// <summary>
|
||||||
public ActionResult<EntityIndexResult> Index([FromBody] List<JSONEntity>? jsonEntities)
|
/// List the entities in a searchdomain
|
||||||
{
|
/// </summary>
|
||||||
try
|
/// <remarks>
|
||||||
{
|
/// With returnModels = false expect: "Datapoints": [..., "Embeddings": null]<br/>
|
||||||
List<Entity>? entities = _searchdomainHelper.EntitiesFromJSON(
|
/// With returnModels = true expect: "Datapoints": [..., "Embeddings": [{"Model": "...", "Embeddings": []}, ...]]<br/>
|
||||||
_domainManager,
|
/// With returnEmbeddings = true expect: "Datapoints": [..., "Embeddings": [{"Model": "...", "Embeddings": [0.007384672,0.01309805,0.0012528514,...]}, ...]]
|
||||||
_logger,
|
/// </remarks>
|
||||||
JsonSerializer.Serialize(jsonEntities));
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
if (entities is not null && jsonEntities is not null)
|
/// <param name="returnModels">Include the models in the response</param>
|
||||||
{
|
/// <param name="returnEmbeddings">Include the embeddings in the response (requires returnModels)</param>
|
||||||
List<string> invalidatedSearchdomains = [];
|
|
||||||
foreach (var jsonEntity in jsonEntities)
|
|
||||||
{
|
|
||||||
string jsonEntityName = jsonEntity.Name;
|
|
||||||
string jsonEntitySearchdomainName = jsonEntity.Searchdomain;
|
|
||||||
if (entities.Select(x => x.name == jsonEntityName).Any()
|
|
||||||
&& !invalidatedSearchdomains.Contains(jsonEntitySearchdomainName))
|
|
||||||
{
|
|
||||||
invalidatedSearchdomains.Add(jsonEntitySearchdomainName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Ok(new EntityIndexResult() { Success = true });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.LogError("Unable to deserialize an entity");
|
|
||||||
return Ok(new EntityIndexResult() { Success = false, Message = "Unable to deserialize an entity"});
|
|
||||||
}
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (ex.InnerException is not null) ex = ex.InnerException;
|
|
||||||
_logger.LogError("Unable to index the provided entities. {ex.Message} - {ex.StackTrace}", [ex.Message, ex.StackTrace]);
|
|
||||||
return Ok(new EntityIndexResult() { Success = false, Message = ex.Message });
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("/Entities")]
|
[HttpGet("/Entities")]
|
||||||
public ActionResult<EntityListResults> List(string searchdomain, bool returnModels = false, bool returnEmbeddings = false)
|
public ActionResult<EntityListResults> List(string searchdomain, bool returnModels = false, bool returnEmbeddings = false)
|
||||||
{
|
{
|
||||||
@@ -109,6 +82,56 @@ public class EntityController : ControllerBase
|
|||||||
return Ok(entityListResults);
|
return Ok(entityListResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Index entities
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Behavior: Creates new entities, but overwrites existing entities that have the same name
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="jsonEntities">Entities to index</param>
|
||||||
|
[HttpPut("/Entities")]
|
||||||
|
public ActionResult<EntityIndexResult> Index([FromBody] List<JSONEntity>? jsonEntities)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<Entity>? entities = _searchdomainHelper.EntitiesFromJSON(
|
||||||
|
_domainManager,
|
||||||
|
_logger,
|
||||||
|
JsonSerializer.Serialize(jsonEntities));
|
||||||
|
if (entities is not null && jsonEntities is not null)
|
||||||
|
{
|
||||||
|
List<string> invalidatedSearchdomains = [];
|
||||||
|
foreach (var jsonEntity in jsonEntities)
|
||||||
|
{
|
||||||
|
string jsonEntityName = jsonEntity.Name;
|
||||||
|
string jsonEntitySearchdomainName = jsonEntity.Searchdomain;
|
||||||
|
if (entities.Select(x => x.name == jsonEntityName).Any()
|
||||||
|
&& !invalidatedSearchdomains.Contains(jsonEntitySearchdomainName))
|
||||||
|
{
|
||||||
|
invalidatedSearchdomains.Add(jsonEntitySearchdomainName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(new EntityIndexResult() { Success = true });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogError("Unable to deserialize an entity");
|
||||||
|
return Ok(new EntityIndexResult() { Success = false, Message = "Unable to deserialize an entity"});
|
||||||
|
}
|
||||||
|
} catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (ex.InnerException is not null) ex = ex.InnerException;
|
||||||
|
_logger.LogError("Unable to index the provided entities. {ex.Message} - {ex.StackTrace}", [ex.Message, ex.StackTrace]);
|
||||||
|
return Ok(new EntityIndexResult() { Success = false, Message = ex.Message });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes an entity
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
/// <param name="entityName">Name of the entity</param>
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
public ActionResult<EntityDeleteResults> Delete(string searchdomain, string entityName)
|
public ActionResult<EntityDeleteResults> Delete(string searchdomain, string entityName)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Server.Models;
|
|||||||
namespace Server.Controllers;
|
namespace Server.Controllers;
|
||||||
|
|
||||||
[ApiExplorerSettings(IgnoreApi = true)]
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
[Route("/")]
|
[Route("[Controller]")]
|
||||||
public class HomeController : Controller
|
public class HomeController : Controller
|
||||||
{
|
{
|
||||||
private readonly ILogger<EntityController> _logger;
|
private readonly ILogger<EntityController> _logger;
|
||||||
@@ -23,6 +23,13 @@ public class HomeController : Controller
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
[HttpGet("/")]
|
[HttpGet("/")]
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("Searchdomains")]
|
||||||
|
public IActionResult Searchdomains()
|
||||||
{
|
{
|
||||||
HomeIndexViewModel viewModel = new()
|
HomeIndexViewModel viewModel = new()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using ElmahCore;
|
using ElmahCore;
|
||||||
using Microsoft.AspNetCore.Http.HttpResults;
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
@@ -23,6 +24,9 @@ public class SearchdomainController : ControllerBase
|
|||||||
_domainManager = domainManager;
|
_domainManager = domainManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lists all searchdomains
|
||||||
|
/// </summary>
|
||||||
[HttpGet("/Searchdomains")]
|
[HttpGet("/Searchdomains")]
|
||||||
public ActionResult<SearchdomainListResults> List()
|
public ActionResult<SearchdomainListResults> List()
|
||||||
{
|
{
|
||||||
@@ -40,8 +44,13 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(searchdomainListResults);
|
return Ok(searchdomainListResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
/// <param name="settings">Optional initial settings</param>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult<SearchdomainCreateResults> Create(string searchdomain, [FromBody]SearchdomainSettings settings = new())
|
public ActionResult<SearchdomainCreateResults> Create([Required]string searchdomain, [FromBody]SearchdomainSettings settings = new())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -54,8 +63,12 @@ public class SearchdomainController : ControllerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
public ActionResult<SearchdomainDeleteResults> Delete(string searchdomain)
|
public ActionResult<SearchdomainDeleteResults> Delete([Required]string searchdomain)
|
||||||
{
|
{
|
||||||
bool success;
|
bool success;
|
||||||
int deletedEntries;
|
int deletedEntries;
|
||||||
@@ -84,8 +97,14 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new SearchdomainDeleteResults(){Success = success, DeletedEntities = deletedEntries, Message = message});
|
return Ok(new SearchdomainDeleteResults(){Success = success, DeletedEntities = deletedEntries, Message = message});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates name and settings of a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
/// <param name="newName">Updated name of the searchdomain</param>
|
||||||
|
/// <param name="settings">Updated settings of searchdomain</param>
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
public ActionResult<SearchdomainUpdateResults> Update(string searchdomain, string newName, [FromBody]string? settings = "{}")
|
public ActionResult<SearchdomainUpdateResults> Update([Required]string searchdomain, string newName, [FromBody]SearchdomainSettings? settings)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -110,8 +129,29 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new SearchdomainUpdateResults(){Success = true});
|
return Ok(new SearchdomainUpdateResults(){Success = true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the query cache of a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
[HttpGet("Queries")]
|
||||||
|
public ActionResult<SearchdomainSearchesResults> GetQueries([Required]string searchdomain)
|
||||||
|
{
|
||||||
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
|
Dictionary<string, DateTimedSearchResult> searchCache = searchdomain_.searchCache;
|
||||||
|
|
||||||
|
return Ok(new SearchdomainSearchesResults() { Searches = searchCache, Success = true });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a query in the searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
/// <param name="query">Query to execute</param>
|
||||||
|
/// <param name="topN">Return only the top N results</param>
|
||||||
|
/// <param name="returnAttributes">Return the attributes of the object</param>
|
||||||
[HttpPost("Query")]
|
[HttpPost("Query")]
|
||||||
public ActionResult<EntityQueryResults> Query(string searchdomain, string query, int? topN, bool returnAttributes = false)
|
public ActionResult<EntityQueryResults> Query([Required]string searchdomain, [Required]string query, int? topN, bool returnAttributes = false)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -125,33 +165,13 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new EntityQueryResults(){Results = queryResults, Success = true });
|
return Ok(new EntityQueryResults(){Results = queryResults, Success = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("Settings")]
|
/// <summary>
|
||||||
public ActionResult<SearchdomainUpdateResults> UpdateSettings(string searchdomain, [FromBody] SearchdomainSettings request)
|
/// Deletes a query from the query cache
|
||||||
{
|
/// </summary>
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
/// <param name="query">Query to delete</param>
|
||||||
Dictionary<string, dynamic> parameters = new()
|
|
||||||
{
|
|
||||||
{"settings", JsonSerializer.Serialize(request)},
|
|
||||||
{"id", searchdomain_.id}
|
|
||||||
};
|
|
||||||
searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set settings = @settings WHERE id = @id", parameters);
|
|
||||||
searchdomain_.settings = request;
|
|
||||||
return Ok(new SearchdomainUpdateResults(){Success = true});
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("Queries")]
|
|
||||||
public ActionResult<SearchdomainSearchesResults> GetQueries(string searchdomain)
|
|
||||||
{
|
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
|
||||||
Dictionary<string, DateTimedSearchResult> searchCache = searchdomain_.searchCache;
|
|
||||||
|
|
||||||
return Ok(new SearchdomainSearchesResults() { Searches = searchCache, Success = true });
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete("Query")]
|
[HttpDelete("Query")]
|
||||||
public ActionResult<SearchdomainDeleteSearchResult> DeleteQuery(string searchdomain, string query)
|
public ActionResult<SearchdomainDeleteSearchResult> DeleteQuery([Required]string searchdomain, [Required]string query)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -165,8 +185,14 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new SearchdomainDeleteSearchResult() {Success = false, Message = "Query not found in search cache"});
|
return Ok(new SearchdomainDeleteSearchResult() {Success = false, Message = "Query not found in search cache"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates a query from the query cache
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
/// <param name="query">Query to update</param>
|
||||||
|
/// <param name="results">List of results to apply to the query</param>
|
||||||
[HttpPatch("Query")]
|
[HttpPatch("Query")]
|
||||||
public ActionResult<SearchdomainUpdateSearchResult> UpdateQuery(string searchdomain, string query, [FromBody]List<ResultItem> results)
|
public ActionResult<SearchdomainUpdateSearchResult> UpdateQuery([Required]string searchdomain, [Required]string query, [Required][FromBody]List<ResultItem> results)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -182,8 +208,12 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new SearchdomainUpdateSearchResult() {Success = false, Message = "Query not found in search cache"});
|
return Ok(new SearchdomainUpdateSearchResult() {Success = false, Message = "Query not found in search cache"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the settings of a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
[HttpGet("Settings")]
|
[HttpGet("Settings")]
|
||||||
public ActionResult<SearchdomainSettingsResults> GetSettings(string searchdomain)
|
public ActionResult<SearchdomainSettingsResults> GetSettings([Required]string searchdomain)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -191,8 +221,31 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new SearchdomainSettingsResults() { Settings = settings, Success = true });
|
return Ok(new SearchdomainSettingsResults() { Settings = settings, Success = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("SearchCache/Size")]
|
/// <summary>
|
||||||
public ActionResult<SearchdomainSearchCacheSizeResults> GetSearchCacheSize(string searchdomain)
|
/// Update the settings of a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
[HttpPut("Settings")]
|
||||||
|
public ActionResult<SearchdomainUpdateResults> UpdateSettings([Required]string searchdomain, [Required][FromBody] SearchdomainSettings request)
|
||||||
|
{
|
||||||
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
|
Dictionary<string, dynamic> parameters = new()
|
||||||
|
{
|
||||||
|
{"settings", JsonSerializer.Serialize(request)},
|
||||||
|
{"id", searchdomain_.id}
|
||||||
|
};
|
||||||
|
searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set settings = @settings WHERE id = @id", parameters);
|
||||||
|
searchdomain_.settings = request;
|
||||||
|
return Ok(new SearchdomainUpdateResults(){Success = true});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the query cache size of a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
[HttpGet("QueryCache/Size")]
|
||||||
|
public ActionResult<SearchdomainSearchCacheSizeResults> GetSearchCacheSize([Required]string searchdomain)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -204,11 +257,15 @@ public class SearchdomainController : ControllerBase
|
|||||||
sizeInBytes += entry.Key.Length * sizeof(char); // string characters
|
sizeInBytes += entry.Key.Length * sizeof(char); // string characters
|
||||||
sizeInBytes += entry.Value.EstimateSize();
|
sizeInBytes += entry.Value.EstimateSize();
|
||||||
}
|
}
|
||||||
return Ok(new SearchdomainSearchCacheSizeResults() { SearchCacheSizeBytes = sizeInBytes, Success = true });
|
return Ok(new SearchdomainSearchCacheSizeResults() { QueryCacheSizeBytes = sizeInBytes, Success = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("SearchCache/Clear")]
|
/// <summary>
|
||||||
public ActionResult<SearchdomainInvalidateCacheResults> InvalidateSearchCache(string searchdomain)
|
/// Clear the query cache of a searchdomain
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
|
[HttpPost("QueryCache/Clear")]
|
||||||
|
public ActionResult<SearchdomainInvalidateCacheResults> InvalidateSearchCache([Required]string searchdomain)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
@@ -216,8 +273,12 @@ public class SearchdomainController : ControllerBase
|
|||||||
return Ok(new SearchdomainInvalidateCacheResults(){Success = true});
|
return Ok(new SearchdomainInvalidateCacheResults(){Success = true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the disk size of a searchdomain in bytes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchdomain">Name of the searchdomain</param>
|
||||||
[HttpGet("Database/Size")]
|
[HttpGet("Database/Size")]
|
||||||
public ActionResult<SearchdomainGetDatabaseSizeResult> GetDatabaseSize(string searchdomain)
|
public ActionResult<SearchdomainGetDatabaseSizeResult> GetDatabaseSize([Required]string searchdomain)
|
||||||
{
|
{
|
||||||
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
|
||||||
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
namespace Server.Controllers;
|
namespace Server.Controllers;
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using AdaptiveExpressions;
|
||||||
using ElmahCore;
|
using ElmahCore;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Server.Exceptions;
|
using Server.Exceptions;
|
||||||
@@ -14,14 +16,22 @@ public class ServerController : ControllerBase
|
|||||||
private readonly ILogger<ServerController> _logger;
|
private readonly ILogger<ServerController> _logger;
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfiguration _config;
|
||||||
private AIProvider _aIProvider;
|
private AIProvider _aIProvider;
|
||||||
|
private readonly SearchdomainManager _searchdomainManager;
|
||||||
|
|
||||||
public ServerController(ILogger<ServerController> logger, IConfiguration config, AIProvider aIProvider)
|
public ServerController(ILogger<ServerController> logger, IConfiguration config, AIProvider aIProvider, SearchdomainManager searchdomainManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_config = config;
|
_config = config;
|
||||||
_aIProvider = aIProvider;
|
_aIProvider = aIProvider;
|
||||||
|
_searchdomainManager = searchdomainManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lists the models available to the server
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Returns ALL models available to the server - not only the embedding models.
|
||||||
|
/// </remarks>
|
||||||
[HttpGet("Models")]
|
[HttpGet("Models")]
|
||||||
public ActionResult<ServerGetModelsResult> GetModels()
|
public ActionResult<ServerGetModelsResult> GetModels()
|
||||||
{
|
{
|
||||||
@@ -35,4 +45,51 @@ public class ServerController : ControllerBase
|
|||||||
return new ServerGetModelsResult() { Success = false, Message = ex.Message};
|
return new ServerGetModelsResult() { Success = false, Message = ex.Message};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total memory size of the embedding cache
|
||||||
|
/// </summary>
|
||||||
|
[HttpGet("EmbeddingCache/Size")]
|
||||||
|
public ActionResult<ServerGetEmbeddingCacheSizeResult> GetEmbeddingCacheSize()
|
||||||
|
{
|
||||||
|
long size = 0;
|
||||||
|
long elementCount = 0;
|
||||||
|
long embeddingsCount = 0;
|
||||||
|
LRUCache<string, Dictionary<string, float[]>> embeddingCache = _searchdomainManager.embeddingCache;
|
||||||
|
var cacheListField = embeddingCache.GetType()
|
||||||
|
.GetField("_cacheList", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new InvalidOperationException("_cacheList field not found"); // TODO Remove this unsafe reflection atrocity
|
||||||
|
LinkedList<string> cacheListOriginal = (LinkedList<string>)cacheListField.GetValue(embeddingCache)!;
|
||||||
|
LinkedList<string> cacheList = new(cacheListOriginal);
|
||||||
|
|
||||||
|
foreach (string key in cacheList)
|
||||||
|
{
|
||||||
|
if (!embeddingCache.TryGet(key, out var entry))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// estimate size
|
||||||
|
size += EstimateEntrySize(key, entry);
|
||||||
|
elementCount++;
|
||||||
|
embeddingsCount += entry.Keys.Count;
|
||||||
|
}
|
||||||
|
return new ServerGetEmbeddingCacheSizeResult() { Success = true, SizeInBytes = size, MaxElementCount = _searchdomainManager.EmbeddingCacheMaxCount, ElementCount = elementCount, EmbeddingsCount = embeddingsCount};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long EstimateEntrySize(string key, Dictionary<string, float[]> value)
|
||||||
|
{
|
||||||
|
int stringOverhead = MemorySizes.Align(MemorySizes.ObjectHeader + sizeof(int));
|
||||||
|
int arrayOverhead = MemorySizes.ArrayHeader;
|
||||||
|
int dictionaryOverhead = MemorySizes.ObjectHeader;
|
||||||
|
long size = 0;
|
||||||
|
|
||||||
|
size += stringOverhead + key.Length * sizeof(char);
|
||||||
|
size += dictionaryOverhead;
|
||||||
|
|
||||||
|
foreach (var kv in value)
|
||||||
|
{
|
||||||
|
size += stringOverhead + kv.Key.Length * sizeof(char);
|
||||||
|
size += arrayOverhead + kv.Value.Length * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Server.Helper;
|
|||||||
using Server.Models;
|
using Server.Models;
|
||||||
using Server.Services;
|
using Server.Services;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -37,7 +38,12 @@ builder.Services.AddScoped<LocalizationService>();
|
|||||||
|
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen();
|
builder.Services.AddSwaggerGen(c =>
|
||||||
|
{
|
||||||
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||||
|
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||||
|
c.IncludeXmlComments(xmlPath);
|
||||||
|
});
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.ReadFrom.Configuration(builder.Configuration)
|
.ReadFrom.Configuration(builder.Configuration)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
@@ -47,8 +53,8 @@ builder.Services.AddSingleton<SearchdomainHelper>();
|
|||||||
builder.Services.AddSingleton<SearchdomainManager>();
|
builder.Services.AddSingleton<SearchdomainManager>();
|
||||||
builder.Services.AddSingleton<AIProvider>();
|
builder.Services.AddSingleton<AIProvider>();
|
||||||
builder.Services.AddHealthChecks()
|
builder.Services.AddHealthChecks()
|
||||||
.AddCheck<DatabaseHealthCheck>("DatabaseHealthCheck")
|
.AddCheck<DatabaseHealthCheck>("DatabaseHealthCheck", tags: ["Database"])
|
||||||
.AddCheck<AIProviderHealthCheck>("AIProviderHealthCheck");
|
.AddCheck<AIProviderHealthCheck>("AIProviderHealthCheck", tags: ["AIProvider"]);
|
||||||
|
|
||||||
builder.Services.AddElmah<XmlFileErrorLog>(Options =>
|
builder.Services.AddElmah<XmlFileErrorLog>(Options =>
|
||||||
{
|
{
|
||||||
@@ -103,6 +109,15 @@ app.Use(async (context, next) =>
|
|||||||
app.UseElmah();
|
app.UseElmah();
|
||||||
|
|
||||||
app.MapHealthChecks("/healthz");
|
app.MapHealthChecks("/healthz");
|
||||||
|
app.MapHealthChecks("/healthz/Database", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
|
||||||
|
{
|
||||||
|
Predicate = c => c.Name.Contains("Database")
|
||||||
|
});
|
||||||
|
|
||||||
|
app.MapHealthChecks("/healthz/AIProvider", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
|
||||||
|
{
|
||||||
|
Predicate = c => c.Name.Contains("AIProvider")
|
||||||
|
});
|
||||||
|
|
||||||
bool IsDevelopment = app.Environment.IsDevelopment();
|
bool IsDevelopment = app.Environment.IsDevelopment();
|
||||||
bool useSwagger = app.Configuration.GetValue<bool>("UseSwagger");
|
bool useSwagger = app.Configuration.GetValue<bool>("UseSwagger");
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AdaptiveExpressions" Version="4.23.0" />
|
<PackageReference Include="AdaptiveExpressions" Version="4.23.0" />
|
||||||
<PackageReference Include="ElmahCore" Version="2.1.2" />
|
<PackageReference Include="ElmahCore" Version="2.1.2" />
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1685
src/Server/Views/Home/Searchdomains.cshtml
Normal file
1685
src/Server/Views/Home/Searchdomains.cshtml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>@ViewData["Title"] - embeddingsearch</title>
|
<title>@ViewData["Title"] - embeddingsearch</title>
|
||||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||||
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||||
<script>
|
<script>
|
||||||
window.appTranslations = {
|
window.appTranslations = {
|
||||||
@@ -29,16 +30,19 @@
|
|||||||
@if (User.Identity?.IsAuthenticated == true)
|
@if (User.Identity?.IsAuthenticated == true)
|
||||||
{
|
{
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
|
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">@T["Home"]</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Logout">Logout</a>
|
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Searchdomains">@T["Searchdomains"]</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Logout">@T["Logout"]</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">Login</a>
|
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">@T["Login"]</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"172.17.0.1"
|
"172.17.0.1"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"EmbeddingCacheMaxCount": 5,
|
"EmbeddingCacheMaxCount": 10000000,
|
||||||
"AiProviders": {
|
"AiProviders": {
|
||||||
"ollama": {
|
"ollama": {
|
||||||
"handler": "ollama",
|
"handler": "ollama",
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public struct SearchdomainSettings(bool cacheReconciliation = false)
|
|||||||
public bool CacheReconciliation { get; set; } = cacheReconciliation;
|
public bool CacheReconciliation { get; set; } = cacheReconciliation;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class MemorySizes
|
public static class MemorySizes
|
||||||
{
|
{
|
||||||
public static readonly int PointerSize = IntPtr.Size;
|
public static readonly int PointerSize = IntPtr.Size;
|
||||||
public static readonly int ObjectHeader = PointerSize * 2;
|
public static readonly int ObjectHeader = PointerSize * 2;
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ public class SearchdomainSettingsResults : SuccesMessageBaseModel
|
|||||||
|
|
||||||
public class SearchdomainSearchCacheSizeResults : SuccesMessageBaseModel
|
public class SearchdomainSearchCacheSizeResults : SuccesMessageBaseModel
|
||||||
{
|
{
|
||||||
[JsonPropertyName("SearchCacheSizeBytes")]
|
[JsonPropertyName("QueryCacheSizeBytes")]
|
||||||
public required long? SearchCacheSizeBytes { get; set; }
|
public required long? QueryCacheSizeBytes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchdomainInvalidateCacheResults : SuccesMessageBaseModel {}
|
public class SearchdomainInvalidateCacheResults : SuccesMessageBaseModel {}
|
||||||
|
|||||||
@@ -6,4 +6,16 @@ public class ServerGetModelsResult : SuccesMessageBaseModel
|
|||||||
{
|
{
|
||||||
[JsonPropertyName("Models")]
|
[JsonPropertyName("Models")]
|
||||||
public string[]? Models { get; set; }
|
public string[]? Models { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ServerGetEmbeddingCacheSizeResult : SuccesMessageBaseModel
|
||||||
|
{
|
||||||
|
[JsonPropertyName("SizeInBytes")]
|
||||||
|
public required long? SizeInBytes { get; set; }
|
||||||
|
[JsonPropertyName("MaxElementCount")]
|
||||||
|
public required long? MaxElementCount { get; set; }
|
||||||
|
[JsonPropertyName("ElementCount")]
|
||||||
|
public required long? ElementCount { get; set; }
|
||||||
|
[JsonPropertyName("EmbeddingsCount")]
|
||||||
|
public required long? EmbeddingsCount { get; set; }
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user