-
Notifications
You must be signed in to change notification settings - Fork 70
Implement embedders, vector search and similar documents #638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
68ba575
4f8d55b
bac47c4
fc8e4c7
0247ac1
e1ba052
3e97224
256de5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| using System; | ||
| using System.Text.Json; | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace Meilisearch.Converters | ||
| { | ||
| internal class EmbedderSourceConverter : JsonConverter<EmbedderSource> | ||
| { | ||
| public override EmbedderSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
| { | ||
| if (reader.TokenType == JsonTokenType.String) | ||
| { | ||
| var enumValue = reader.GetString(); | ||
| if (Enum.TryParse<EmbedderSource>(enumValue, true, out var embedderSource)) | ||
| { | ||
| return embedderSource; | ||
| } | ||
|
|
||
| throw new JsonException($"Invalid EmbedderSource value: '{enumValue}'."); | ||
| } | ||
|
|
||
| throw new JsonException($"Expected string for EmbedderSource, but found {reader.TokenType}."); | ||
| } | ||
|
|
||
| public override void Write(Utf8JsonWriter writer, EmbedderSource value, JsonSerializerOptions options) | ||
| { | ||
| string source; | ||
| switch (value) | ||
| { | ||
| case EmbedderSource.OpenAi: | ||
| source = "openAi"; | ||
| break; | ||
| case EmbedderSource.HuggingFace: | ||
| source = "huggingFace"; | ||
| break; | ||
| case EmbedderSource.Ollama: | ||
| source = "ollama"; | ||
| break; | ||
| case EmbedderSource.Rest: | ||
| source = "rest"; | ||
| break; | ||
| case EmbedderSource.UserProvided: | ||
| source = "userProvided"; | ||
| break; | ||
| default: | ||
| throw new ArgumentOutOfRangeException(nameof(value), value, null); | ||
| } | ||
|
|
||
| writer.WriteStringValue(source); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,83 @@ | ||||||||||||||||
| using System.Collections.Generic; | ||||||||||||||||
| using System.Text.Json.Serialization; | ||||||||||||||||
|
|
||||||||||||||||
| namespace Meilisearch | ||||||||||||||||
| { | ||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Embedder configuration. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| public class Embedder | ||||||||||||||||
| { | ||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the source. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("source")] | ||||||||||||||||
| public EmbedderSource Source { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the URL. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("url")] | ||||||||||||||||
| public string Url { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the API key. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("apiKey")] | ||||||||||||||||
| public string ApiKey { get; set; } | ||||||||||||||||
|
Comment on lines
+26
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainConsider security implications for ApiKey property The ApiKey property likely contains sensitive information. Consider:
Also, consider adding documentation to warn users about the sensitivity of this property. 🏁 Script executed: #!/bin/bash
# Check for any existing security measures for API keys in the codebase
grep -r --include="*.cs" "ApiKey" --include="*.cs" "api key" src/Length of output: 1890 Secure handling of Embedder.ApiKey Ensure the
Example diff: --- a/src/Meilisearch/Embedder.cs
+++ b/src/Meilisearch/Embedder.cs
@@ -25,8 +25,11 @@ namespace Meilisearch
- [JsonPropertyName("apiKey")]
- public string ApiKey { get; set; }
+ /// <summary>
+ /// API key for authentication (Sensitive: excluded from JSON; only sent via HTTP header).
+ /// </summary>
+ [JsonIgnore]
+ public string ApiKey { get; internal set; }📝 Committable suggestion
Suggested change
|
||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the model. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("model")] | ||||||||||||||||
| public string Model { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the document template. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("documentTemplate")] | ||||||||||||||||
| public string DocumentTemplate { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the document template max bytes. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("documentTemplateMaxBytes")] | ||||||||||||||||
| public int? DocumentTemplateMaxBytes { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the dimensions. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("dimensions")] | ||||||||||||||||
| public int? Dimensions { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the revision. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("revision")] | ||||||||||||||||
| public string Revision { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the distribution. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("distribution")] | ||||||||||||||||
| public EmbedderDistribution Distribution { get; set; } | ||||||||||||||||
philipproplesch marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the request. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("request")] | ||||||||||||||||
| public Dictionary<string, object> Request { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets the response. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("response")] | ||||||||||||||||
| public Dictionary<string, object> Response { get; set; } | ||||||||||||||||
|
|
||||||||||||||||
| /// <summary> | ||||||||||||||||
| /// Gets or sets whether the vectors should be compressed. | ||||||||||||||||
| /// </summary> | ||||||||||||||||
| [JsonPropertyName("binaryQuantized")] | ||||||||||||||||
| public bool? BinaryQuantized { get; set; } | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| using System; | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace Meilisearch | ||
| { | ||
| /// <summary> | ||
| /// Embedder distribution. | ||
| /// </summary> | ||
| public class EmbedderDistribution | ||
| { | ||
| private double _mean; | ||
| private double _sigma; | ||
|
|
||
| /// <summary> | ||
| /// Creates a new instance of <see cref="EmbedderDistribution"/>. | ||
| /// </summary> | ||
| /// <param name="mean">Mean value between 0 and 1.</param> | ||
| /// <param name="sigma">Sigma value between 0 and 1.</param> | ||
| public EmbedderDistribution(double mean, double sigma) | ||
| { | ||
| Mean = mean; | ||
| Sigma = sigma; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the mean. | ||
| /// </summary> | ||
| [JsonPropertyName("mean")] | ||
| public double Mean | ||
| { | ||
| get => _mean; | ||
| set | ||
| { | ||
| if (value < 0 || value > 1) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(Mean), "Mean must be between 0 and 1."); | ||
| } | ||
|
|
||
| _mean = value; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the sigma. | ||
| /// </summary> | ||
| [JsonPropertyName("sigma")] | ||
| public double Sigma | ||
| { | ||
| get => _sigma; | ||
| set | ||
| { | ||
| if (value < 0 || value > 1) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(Sigma), "Sigma must be between 0 and 1."); | ||
| } | ||
|
|
||
| _sigma = value; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Creates a new instance of <see cref="EmbedderDistribution"/> with a uniform distribution. | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| public static EmbedderDistribution Uniform() => new EmbedderDistribution(0.5, 0.5); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| using Meilisearch.Converters; | ||
|
|
||
| namespace Meilisearch | ||
| { | ||
| /// <summary> | ||
| /// Embedder source. | ||
| /// </summary> | ||
| [JsonConverter(typeof(EmbedderSourceConverter))] | ||
| public enum EmbedderSource | ||
| { | ||
| /// <summary> | ||
| /// OpenAI | ||
| /// </summary> | ||
| OpenAi, | ||
|
|
||
| /// <summary> | ||
| /// Hugging Face | ||
| /// </summary> | ||
| HuggingFace, | ||
|
|
||
| /// <summary> | ||
| /// Ollama | ||
| /// </summary> | ||
| Ollama, | ||
|
|
||
| /// <summary> | ||
| /// REST | ||
| /// </summary> | ||
| Rest, | ||
|
|
||
| /// <summary> | ||
| /// User-provided | ||
| /// </summary> | ||
| UserProvided, | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace Meilisearch | ||
| { | ||
| public class HybridSearch | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the embedder. | ||
| /// </summary> | ||
| [JsonPropertyName("embedder")] | ||
| public string Embedder { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the semantic ratio. | ||
| /// </summary> | ||
| [JsonPropertyName("semanticRatio")] | ||
| public double SemanticRatio { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| using System.Collections.Generic; | ||
| using System.Net.Http.Json; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| using Meilisearch.Extensions; | ||
|
|
||
| namespace Meilisearch | ||
| { | ||
| public partial class Index | ||
| { | ||
| /// <summary> | ||
| /// Gets the embedders setting. | ||
| /// </summary> | ||
| /// <param name="cancellationToken">The cancellation token for this call.</param> | ||
| /// <returns>Returns the embedders setting.</returns> | ||
| public async Task<Dictionary<string, Embedder>> GetEmbeddersAsync(CancellationToken cancellationToken = default) | ||
| { | ||
| return await _http | ||
| .GetFromJsonAsync<Dictionary<string, Embedder>>( | ||
| $"indexes/{Uid}/settings/embedders", | ||
| cancellationToken: cancellationToken) | ||
| .ConfigureAwait(false); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Updates the embedders setting. | ||
| /// </summary> | ||
| /// <param name="embedders">Collection of embedders.</param> | ||
| /// <param name="cancellationToken">The cancellation token for this call.</param> | ||
| /// <returns>Returns the task info of the asynchronous task.</returns> | ||
| public async Task<TaskInfo> UpdateEmbeddersAsync(Dictionary<string, Embedder> embedders, CancellationToken cancellationToken = default) | ||
| { | ||
| var responseMessage = | ||
| await _http.PatchAsJsonAsync( | ||
| $"indexes/{Uid}/settings/embedders", | ||
| embedders, | ||
| Constants.JsonSerializerOptionsRemoveNulls, | ||
| cancellationToken: cancellationToken) | ||
| .ConfigureAwait(false); | ||
|
|
||
| return await responseMessage.Content | ||
| .ReadFromJsonAsync<TaskInfo>(cancellationToken: cancellationToken) | ||
| .ConfigureAwait(false); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Resets the embedders setting. | ||
| /// </summary> | ||
| /// <param name="cancellationToken">The cancellation token for this call.</param> | ||
| /// <returns>Returns the task info of the asynchronous task.</returns> | ||
| public async Task<TaskInfo> ResetEmbeddersAsync(CancellationToken cancellationToken = default) | ||
| { | ||
| var response = await _http | ||
| .DeleteAsync($"indexes/{Uid}/settings/embedders", cancellationToken) | ||
| .ConfigureAwait(false); | ||
|
|
||
| return await response.Content | ||
| .ReadFromJsonAsync<TaskInfo>(cancellationToken: cancellationToken) | ||
| .ConfigureAwait(false); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| using System.Net.Http.Json; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace Meilisearch | ||
| { | ||
| public partial class Index | ||
| { | ||
| /// <summary> | ||
| /// Search for similar documents. | ||
| /// </summary> | ||
| /// <param name="query">The query to search for similar documents.</param> | ||
| /// <param name="cancellationToken">The cancellation token for this call.</param> | ||
| /// <typeparam name="T">The type of the documents to return.</typeparam> | ||
| /// <returns>Returns the similar documents.</returns> | ||
| public async Task<SimilarDocumentsResult<T>> SearchSimilarDocumentsAsync<T>( | ||
| SimilarDocumentsQuery query, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| var responseMessage = await _http | ||
| .PostAsJsonAsync( | ||
| $"indexes/{Uid}/similar", | ||
| query, | ||
| Constants.JsonSerializerOptionsRemoveNulls, | ||
| cancellationToken: cancellationToken) | ||
| .ConfigureAwait(false); | ||
|
|
||
| return await responseMessage.Content | ||
| .ReadFromJsonAsync<SimilarDocumentsResult<T>>(cancellationToken: cancellationToken) | ||
| .ConfigureAwait(false); | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.