From d656dbb0608e83c56b3e9801a91716990cb1228a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Oct 2026 08:31:21 +0000
Subject: [PATCH 1/4] Remove migrated .NET Chroma provider
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
---
dotnet/MEVD.slnx | 2 -
dotnet/src/VectorData/Chroma/AssemblyInfo.cs | 6 -
dotnet/src/VectorData/Chroma/Chroma.csproj | 25 --
dotnet/src/VectorData/Chroma/ChromaClient.cs | 210 -----------
.../Chroma/ChromaMemoryBuilderExtensions.cs | 55 ---
.../VectorData/Chroma/ChromaMemoryStore.cs | 337 ------------------
.../Http/ApiSchema/ChromaCollectionModel.cs | 23 --
.../Http/ApiSchema/ChromaEmbeddingsModel.cs | 30 --
.../Http/ApiSchema/ChromaQueryResultModel.cs | 36 --
.../Internal/CreateCollectionRequest.cs | 34 --
.../Internal/DeleteCollectionRequest.cs | 31 --
.../Internal/DeleteEmbeddingsRequest.cs | 35 --
.../Internal/GetCollectionRequest.cs | 31 --
.../Internal/GetEmbeddingsRequest.cs | 39 --
.../Internal/ListCollectionsRequest.cs | 25 --
.../Internal/QueryEmbeddingsRequest.cs | 44 ---
.../Internal/UpsertEmbeddingsRequest.cs | 44 ---
dotnet/src/VectorData/Chroma/IChromaClient.cs | 82 -----
dotnet/src/VectorData/Chroma/README.md | 35 +-
.../Chroma.UnitTests/Chroma.UnitTests.csproj | 38 --
.../ChromaMemoryStoreTests.cs | 335 -----------------
21 files changed, 2 insertions(+), 1495 deletions(-)
delete mode 100644 dotnet/src/VectorData/Chroma/AssemblyInfo.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Chroma.csproj
delete mode 100644 dotnet/src/VectorData/Chroma/ChromaClient.cs
delete mode 100644 dotnet/src/VectorData/Chroma/ChromaMemoryBuilderExtensions.cs
delete mode 100644 dotnet/src/VectorData/Chroma/ChromaMemoryStore.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaCollectionModel.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaEmbeddingsModel.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaQueryResultModel.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/CreateCollectionRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteCollectionRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteEmbeddingsRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetCollectionRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetEmbeddingsRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/ListCollectionsRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/QueryEmbeddingsRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/UpsertEmbeddingsRequest.cs
delete mode 100644 dotnet/src/VectorData/Chroma/IChromaClient.cs
delete mode 100644 dotnet/test/VectorData/Chroma.UnitTests/Chroma.UnitTests.csproj
delete mode 100644 dotnet/test/VectorData/Chroma.UnitTests/ChromaMemoryStoreTests.cs
diff --git a/dotnet/MEVD.slnx b/dotnet/MEVD.slnx
index 46b584ee589a..da53ff8db8d6 100644
--- a/dotnet/MEVD.slnx
+++ b/dotnet/MEVD.slnx
@@ -20,12 +20,10 @@
-
-
diff --git a/dotnet/src/VectorData/Chroma/AssemblyInfo.cs b/dotnet/src/VectorData/Chroma/AssemblyInfo.cs
deleted file mode 100644
index d174fc92303c..000000000000
--- a/dotnet/src/VectorData/Chroma/AssemblyInfo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Diagnostics.CodeAnalysis;
-
-// This assembly is currently experimental.
-[assembly: Experimental("SKEXP0020")]
diff --git a/dotnet/src/VectorData/Chroma/Chroma.csproj b/dotnet/src/VectorData/Chroma/Chroma.csproj
deleted file mode 100644
index d283d594dcb3..000000000000
--- a/dotnet/src/VectorData/Chroma/Chroma.csproj
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
- Microsoft.SemanticKernel.Connectors.Chroma
- $(AssemblyName)
- net10.0;net8.0;netstandard2.0;net462
- alpha
-
-
-
-
-
-
-
-
- Semantic Kernel - Chroma Connector
- Chroma connector for Semantic Kernel plugins and semantic memory
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dotnet/src/VectorData/Chroma/ChromaClient.cs b/dotnet/src/VectorData/Chroma/ChromaClient.cs
deleted file mode 100644
index 1dae0d846ab5..000000000000
--- a/dotnet/src/VectorData/Chroma/ChromaClient.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using Microsoft.SemanticKernel.Http;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// An implementation of a client for the Chroma Vector DB. This class is used to
-/// create, delete, and get embeddings data from Chroma Vector DB instance.
-///
-#pragma warning disable CA1001 // Types that own disposable fields should be disposable. Explanation - In this case, there is no need to dispose because either the NonDisposableHttpClientHandler or a custom HTTP client is being used.
-public class ChromaClient : IChromaClient
-#pragma warning restore CA1001 // Types that own disposable fields should be disposable. Explanation - In this case, there is no need to dispose because either the NonDisposableHttpClientHandler or a custom HTTP client is being used.
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// Chroma server endpoint URL.
- /// The to use for logging. If null, no logging will be performed.
- public ChromaClient(string endpoint, ILoggerFactory? loggerFactory = null)
- {
- Verify.NotNull(endpoint);
-
- this._httpClient = HttpClientProvider.GetHttpClient();
- this._endpoint = endpoint;
- this._logger = loggerFactory?.CreateLogger(typeof(ChromaClient)) ?? NullLogger.Instance;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The instance used for making HTTP requests.
- /// Chroma server endpoint URL.
- /// The to use for logging. If null, no logging will be performed.
- /// Occurs when doesn't have base address and endpoint parameter is not provided.
- public ChromaClient(HttpClient httpClient, string? endpoint = null, ILoggerFactory? loggerFactory = null)
- {
- if (string.IsNullOrEmpty(httpClient.BaseAddress?.AbsoluteUri) && string.IsNullOrEmpty(endpoint))
- {
- throw new ArgumentException($"The {nameof(httpClient)}.{nameof(HttpClient.BaseAddress)} and {nameof(endpoint)} are both null or empty. Please ensure at least one is provided.");
- }
-
- this._httpClient = httpClient;
- this._endpoint = endpoint;
- this._logger = loggerFactory?.CreateLogger(typeof(ChromaClient)) ?? NullLogger.Instance;
- }
-
- ///
- public async Task CreateCollectionAsync(string collectionName, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Creating collection {0}", collectionName);
-
- using var request = CreateCollectionRequest.Create(collectionName).Build();
-
- await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async Task GetCollectionAsync(string collectionName, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Getting collection {0}", collectionName);
-
- using var request = GetCollectionRequest.Create(collectionName).Build();
-
- (HttpResponseMessage response, string responseContent) = await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
-
- var collection = JsonSerializer.Deserialize(responseContent);
-
- return collection;
- }
-
- ///
- public async Task DeleteCollectionAsync(string collectionName, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Deleting collection {0}", collectionName);
-
- using var request = DeleteCollectionRequest.Create(collectionName).Build();
-
- await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async IAsyncEnumerable ListCollectionsAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Listing collections");
-
- using var request = ListCollectionsRequest.Create().Build();
-
- (HttpResponseMessage response, string responseContent) = await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
-
- var collections = JsonSerializer.Deserialize>(responseContent);
-
- foreach (var collection in collections!)
- {
- yield return collection.Name;
- }
- }
-
- ///
- public async Task UpsertEmbeddingsAsync(string collectionId, string[] ids, ReadOnlyMemory[] embeddings, object[]? metadatas = null, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Upserting embeddings to collection with id: {0}", collectionId);
-
- using var request = UpsertEmbeddingsRequest.Create(collectionId, ids, embeddings, metadatas).Build();
-
- await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async Task GetEmbeddingsAsync(string collectionId, string[] ids, string[]? include = null, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Getting embeddings from collection with id: {0}", collectionId);
-
- using var request = GetEmbeddingsRequest.Create(collectionId, ids, include).Build();
-
- (HttpResponseMessage response, string responseContent) = await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
-
- var embeddings = JsonSerializer.Deserialize(responseContent);
-
- return embeddings ?? new ChromaEmbeddingsModel();
- }
-
- ///
- public async Task DeleteEmbeddingsAsync(string collectionId, string[] ids, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Deleting embeddings from collection with id: {0}", collectionId);
-
- using var request = DeleteEmbeddingsRequest.Create(collectionId, ids).Build();
-
- await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async Task QueryEmbeddingsAsync(string collectionId, ReadOnlyMemory[] queryEmbeddings, int nResults, string[]? include = null, CancellationToken cancellationToken = default)
- {
- this._logger.LogDebug("Query embeddings in collection with id: {0}", collectionId);
-
- using var request = QueryEmbeddingsRequest.Create(collectionId, queryEmbeddings, nResults, include).Build();
-
- (HttpResponseMessage response, string responseContent) = await this.ExecuteHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
-
- var queryResult = JsonSerializer.Deserialize(responseContent);
-
- return queryResult ?? new ChromaQueryResultModel();
- }
-
- #region private ================================================================================
-
- private const string ApiRoute = "api/v1/";
-
- private readonly ILogger _logger;
- private readonly HttpClient _httpClient;
- private readonly string? _endpoint = null;
-
- private async Task<(HttpResponseMessage response, string responseContent)> ExecuteHttpRequestAsync(
- HttpRequestMessage request,
- CancellationToken cancellationToken = default)
- {
- string endpoint = this._endpoint ?? this._httpClient.BaseAddress!.ToString();
- endpoint = this.SanitizeEndpoint(endpoint);
-
- string operationName = request.RequestUri!.ToString();
-
- request.RequestUri = new Uri(new Uri(endpoint), operationName);
-
- HttpResponseMessage? response = null;
-
- string? responseContent = null;
-
- try
- {
- response = await this._httpClient.SendWithSuccessCheckAsync(request, cancellationToken).ConfigureAwait(false);
-
- responseContent = await response.Content.ReadAsStringWithExceptionMappingAsync(cancellationToken).ConfigureAwait(false);
- }
- catch (HttpOperationException e)
- {
- this._logger.LogError(e, "{Method} {Path} operation failed: {Message}, {Response}", request.Method.Method, operationName, e.Message, e.ResponseContent);
- throw;
- }
-
- return (response, responseContent);
- }
-
- private string SanitizeEndpoint(string endpoint)
- {
- StringBuilder builder = new(endpoint);
-
- if (!endpoint.EndsWith("/", StringComparison.Ordinal))
- {
- builder.Append('/');
- }
-
- builder.Append(ApiRoute);
-
- return builder.ToString();
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/ChromaMemoryBuilderExtensions.cs b/dotnet/src/VectorData/Chroma/ChromaMemoryBuilderExtensions.cs
deleted file mode 100644
index 67476dd72f19..000000000000
--- a/dotnet/src/VectorData/Chroma/ChromaMemoryBuilderExtensions.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-using Microsoft.SemanticKernel.Http;
-using Microsoft.SemanticKernel.Memory;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// Provides extension methods for the class to configure Chroma memory connector.
-///
-public static class ChromaMemoryBuilderExtensions
-{
- ///
- /// Registers Chroma memory connector.
- ///
- /// The instance.
- /// Chroma server endpoint URL.
- /// Updated Memory builder including Chroma memory connector.
- public static MemoryBuilder WithChromaMemoryStore(this MemoryBuilder builder, string endpoint)
- {
- builder.WithMemoryStore((loggerFactory, injectedClient) =>
- {
- return new ChromaMemoryStore(
- HttpClientProvider.GetHttpClient(injectedClient),
- endpoint,
- loggerFactory);
- });
-
- return builder;
- }
-
- ///
- /// Registers Chroma memory connector.
- ///
- /// The instance.
- /// The instance used for making HTTP requests.
- /// Chroma server endpoint URL. If not specified, the base address of the HTTP client is used.
- /// Updated Memory builder including Chroma memory connector.
- public static MemoryBuilder WithChromaMemoryStore(
- this MemoryBuilder builder,
- HttpClient httpClient,
- string? endpoint = null)
- {
- builder.WithMemoryStore((loggerFactory, injectedClient) =>
- {
- return new ChromaMemoryStore(
- HttpClientProvider.GetHttpClient(httpClient ?? injectedClient),
- endpoint,
- loggerFactory);
- });
-
- return builder;
- }
-}
diff --git a/dotnet/src/VectorData/Chroma/ChromaMemoryStore.cs b/dotnet/src/VectorData/Chroma/ChromaMemoryStore.cs
deleted file mode 100644
index 958ebce207f3..000000000000
--- a/dotnet/src/VectorData/Chroma/ChromaMemoryStore.cs
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net.Http;
-using System.Runtime.CompilerServices;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
-using Microsoft.SemanticKernel.Memory;
-using Microsoft.SemanticKernel.Text;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// An implementation of for Chroma.
-///
-public class ChromaMemoryStore : IMemoryStore
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// Chroma server endpoint URL.
- /// The to use for logging. If null, no logging will be performed.
- public ChromaMemoryStore(string endpoint, ILoggerFactory? loggerFactory = null)
- : this(new ChromaClient(endpoint, loggerFactory), loggerFactory)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The instance used for making HTTP requests.
- /// Chroma server endpoint URL.
- /// The to use for logging. If null, no logging will be performed.
- public ChromaMemoryStore(HttpClient httpClient, string? endpoint = null, ILoggerFactory? loggerFactory = null)
- : this(new ChromaClient(httpClient, endpoint, loggerFactory), loggerFactory)
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Instance of implementation.
- /// The to use for logging. If null, no logging will be performed.
- public ChromaMemoryStore(IChromaClient client, ILoggerFactory? loggerFactory = null)
- {
- this._chromaClient = client;
- this._logger = loggerFactory?.CreateLogger(typeof(ChromaMemoryStore)) ?? NullLogger.Instance;
- }
-
- ///
- public async Task CreateCollectionAsync(string collectionName, CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- await this._chromaClient.CreateCollectionAsync(collectionName, cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async Task DeleteCollectionAsync(string collectionName, CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- try
- {
- await this._chromaClient.DeleteCollectionAsync(collectionName, cancellationToken).ConfigureAwait(false);
- }
- catch (HttpOperationException e) when (VerifyCollectionDoesNotExistMessage(e.ResponseContent, collectionName))
- {
- this._logger.LogError("Cannot delete non-existent collection {0}", collectionName);
- throw new KernelException($"Cannot delete non-existent collection {collectionName}", e);
- }
- }
-
- ///
- public async Task DoesCollectionExistAsync(string collectionName, CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- var collection = await this.GetCollectionAsync(collectionName, cancellationToken).ConfigureAwait(false);
-
- return collection is not null;
- }
-
- ///
- public async Task GetAsync(string collectionName, string key, bool withEmbedding = false, CancellationToken cancellationToken = default)
- {
- return await this.GetBatchAsync(collectionName, [key], withEmbedding, cancellationToken)
- .FirstOrDefaultAsync(cancellationToken)
- .ConfigureAwait(false);
- }
-
- ///
- public async IAsyncEnumerable GetBatchAsync(string collectionName, IEnumerable keys, bool withEmbeddings = false, [EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- var collection = await this.GetCollectionOrThrowAsync(collectionName, cancellationToken).ConfigureAwait(false);
-
- var ids = keys.ToArray();
- var include = this.GetEmbeddingIncludeTypes(withEmbeddings: withEmbeddings);
-
- var embeddingsModel = await this._chromaClient.GetEmbeddingsAsync(collection.Id, ids, include, cancellationToken).ConfigureAwait(false);
-
- var recordCount = embeddingsModel.Ids?.Count ?? 0;
-
- for (var recordIndex = 0; recordIndex < recordCount; recordIndex++)
- {
- yield return this.GetMemoryRecordFromEmbeddingsModel(embeddingsModel, recordIndex);
- }
- }
-
- ///
- public IAsyncEnumerable GetCollectionsAsync(CancellationToken cancellationToken = default)
- {
- return this._chromaClient.ListCollectionsAsync(cancellationToken);
- }
-
- ///
- public async Task<(MemoryRecord, double)?> GetNearestMatchAsync(string collectionName, ReadOnlyMemory embedding, double minRelevanceScore = 0, bool withEmbedding = false, CancellationToken cancellationToken = default)
- {
- var results = this.GetNearestMatchesAsync(
- collectionName,
- embedding,
- minRelevanceScore: minRelevanceScore,
- limit: 1,
- withEmbeddings: withEmbedding,
- cancellationToken: cancellationToken);
-
- (MemoryRecord memoryRecord, double similarityScore) = await results.FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
-
- return (memoryRecord, similarityScore);
- }
-
- ///
- public async IAsyncEnumerable<(MemoryRecord, double)> GetNearestMatchesAsync(string collectionName, ReadOnlyMemory embedding, int limit, double minRelevanceScore = 0, bool withEmbeddings = false, [EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- var collection = await this.GetCollectionOrThrowAsync(collectionName, cancellationToken).ConfigureAwait(false);
-
- ReadOnlyMemory[] queryEmbeddings = [embedding];
- var include = this.GetEmbeddingIncludeTypes(withEmbeddings: withEmbeddings, withDistances: true);
-
- var queryResultModel = await this._chromaClient.QueryEmbeddingsAsync(collection.Id, queryEmbeddings, limit, include, cancellationToken).ConfigureAwait(false);
-
- var recordCount = queryResultModel.Ids?.FirstOrDefault()?.Count ?? 0;
-
- for (var recordIndex = 0; recordIndex < recordCount; recordIndex++)
- {
- (MemoryRecord memoryRecord, double similarityScore) = this.GetMemoryRecordFromQueryResultModel(queryResultModel, recordIndex);
-
- if (similarityScore >= minRelevanceScore)
- {
- yield return (memoryRecord, similarityScore);
- }
- }
- }
-
- ///
- public async Task RemoveAsync(string collectionName, string key, CancellationToken cancellationToken = default)
- {
- await this.RemoveBatchAsync(collectionName, [key], cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async Task RemoveBatchAsync(string collectionName, IEnumerable keys, CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- var collection = await this.GetCollectionOrThrowAsync(collectionName, cancellationToken).ConfigureAwait(false);
-
- await this._chromaClient.DeleteEmbeddingsAsync(collection.Id, keys.ToArray(), cancellationToken).ConfigureAwait(false);
- }
-
- ///
- public async Task UpsertAsync(string collectionName, MemoryRecord record, CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- var key = await this.UpsertBatchAsync(collectionName, [record], cancellationToken)
- .FirstOrDefaultAsync(cancellationToken)
- .ConfigureAwait(false);
-
- return key ?? string.Empty;
- }
-
- ///
- public async IAsyncEnumerable UpsertBatchAsync(string collectionName, IEnumerable records, [EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- Verify.NotNullOrWhiteSpace(collectionName);
-
- var collection = await this.GetCollectionOrThrowAsync(collectionName, cancellationToken).ConfigureAwait(false);
-
- var recordsArray = records.ToArray();
- var recordsLength = recordsArray.Length;
-
- var ids = new string[recordsLength];
- var embeddings = new ReadOnlyMemory[recordsLength];
- var metadatas = new object[recordsLength];
-
- for (var i = 0; i < recordsLength; i++)
- {
- ids[i] = recordsArray[i].Metadata.Id;
- embeddings[i] = recordsArray[i].Embedding;
- metadatas[i] = recordsArray[i].Metadata;
- }
-
- await this._chromaClient.UpsertEmbeddingsAsync(collection.Id, ids, embeddings, metadatas, cancellationToken).ConfigureAwait(false);
-
- foreach (var record in recordsArray)
- {
- yield return record.Metadata.Id;
- }
- }
-
- #region private ================================================================================
-
- private const string IncludeMetadatas = "metadatas";
- private const string IncludeEmbeddings = "embeddings";
- private const string IncludeDistances = "distances";
-
- private readonly ILogger _logger;
- private readonly IChromaClient _chromaClient;
- private readonly List _defaultEmbeddingIncludeTypes = [IncludeMetadatas];
-
- private async Task GetCollectionOrThrowAsync(string collectionName, CancellationToken cancellationToken)
- {
- return
- await this.GetCollectionAsync(collectionName, cancellationToken).ConfigureAwait(false) ??
- throw new KernelException($"Collection {collectionName} does not exist");
- }
-
- private async Task GetCollectionAsync(string collectionName, CancellationToken cancellationToken)
- {
- try
- {
- return await this._chromaClient.GetCollectionAsync(collectionName, cancellationToken).ConfigureAwait(false);
- }
- catch (HttpOperationException e) when (VerifyCollectionDoesNotExistMessage(e.ResponseContent, collectionName))
- {
- this._logger.LogDebug("Collection {0} does not exist", collectionName);
-
- return null;
- }
- }
-
- private string[] GetEmbeddingIncludeTypes(bool withEmbeddings = false, bool withDistances = false)
- {
- var includeList = new List(this._defaultEmbeddingIncludeTypes);
-
- if (withEmbeddings)
- {
- includeList.Add(IncludeEmbeddings);
- }
-
- if (withDistances)
- {
- includeList.Add(IncludeDistances);
- }
-
- return [.. includeList];
- }
-
- private MemoryRecord GetMemoryRecordFromEmbeddingsModel(ChromaEmbeddingsModel embeddingsModel, int recordIndex)
- {
- return this.GetMemoryRecordFromModel(embeddingsModel.Metadatas, embeddingsModel.Embeddings, embeddingsModel.Ids, recordIndex);
- }
-
- private (MemoryRecord, double) GetMemoryRecordFromQueryResultModel(ChromaQueryResultModel queryResultModel, int recordIndex)
- {
- var ids = queryResultModel.Ids?.FirstOrDefault();
- var embeddings = queryResultModel.Embeddings?.FirstOrDefault();
- var metadatas = queryResultModel.Metadatas?.FirstOrDefault();
- var distances = queryResultModel.Distances?.FirstOrDefault();
-
- var memoryRecord = this.GetMemoryRecordFromModel(metadatas, embeddings, ids, recordIndex);
- var similarityScore = this.GetSimilarityScore(distances, recordIndex);
-
- return (memoryRecord, similarityScore);
- }
-
- private MemoryRecord GetMemoryRecordFromModel(List>? metadatas, List? embeddings, List? ids, int recordIndex)
- {
- var metadata = this.GetMetadataForMemoryRecord(metadatas, recordIndex);
- var embeddingsVector = this.GetEmbeddingForMemoryRecord(embeddings, recordIndex);
- var key = ids?[recordIndex];
-
- return MemoryRecord.FromMetadata(
- metadata: metadata,
- embedding: embeddingsVector,
- key: key);
- }
-
- private MemoryRecordMetadata GetMetadataForMemoryRecord(List>? metadatas, int recordIndex)
- {
- var serializedMetadata = metadatas is not null ? JsonSerializer.Serialize(metadatas[recordIndex], JsonOptionsCache.Default) : string.Empty;
-
- return
- JsonSerializer.Deserialize(serializedMetadata, JsonOptionsCache.Default) ??
- throw new KernelException("Unable to deserialize memory record metadata.");
- }
-
- private ReadOnlyMemory GetEmbeddingForMemoryRecord(List? embeddings, int recordIndex)
- {
- return embeddings is not null ? embeddings[recordIndex] : ReadOnlyMemory.Empty;
- }
-
- private double GetSimilarityScore(List? distances, int recordIndex)
- {
- var similarityScore = distances is not null ? 1.0 / (1.0 + distances[recordIndex]) : default;
-
- if (similarityScore < 0)
- {
- similarityScore = 0;
- }
-
- return similarityScore;
- }
-
- ///
- /// Checks if Chroma API error means that collection does not exist.
- ///
- /// Response content.
- /// Collection name.
- private static bool VerifyCollectionDoesNotExistMessage(string? responseContent, string collectionName)
- {
- return responseContent?.Contains(string.Format(CultureInfo.InvariantCulture, "Collection {0} does not exist", collectionName)) ?? false;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaCollectionModel.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaCollectionModel.cs
deleted file mode 100644
index 40a8b1f4c1e2..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaCollectionModel.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// Chroma collection model.
-///
-public class ChromaCollectionModel
-{
- ///
- /// Identifier of collection generated by Chroma.
- ///
- [JsonPropertyName("id")]
- public string Id { get; set; } = string.Empty;
-
- ///
- /// Collection name provided by client.
- ///
- [JsonPropertyName("name")]
- public string Name { get; set; } = string.Empty;
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaEmbeddingsModel.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaEmbeddingsModel.cs
deleted file mode 100644
index ea53cb9cd03f..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaEmbeddingsModel.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// Chroma embeddings model.
-///
-public class ChromaEmbeddingsModel
-{
- ///
- /// Embedding identifiers.
- ///
- [JsonPropertyName("ids")]
- public List Ids { get; set; } = [];
-
- ///
- /// Embedding vectors.
- ///
- [JsonPropertyName("embeddings")]
- public List Embeddings { get; set; } = [];
-
- ///
- /// Embedding metadatas.
- ///
- [JsonPropertyName("metadatas")]
- public List> Metadatas { get; set; } = [];
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaQueryResultModel.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaQueryResultModel.cs
deleted file mode 100644
index fddebeb8b063..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/ChromaQueryResultModel.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// Chroma query result model. Contains result sets after search operation.
-///
-public class ChromaQueryResultModel
-{
- ///
- /// List of embedding identifiers.
- ///
- [JsonPropertyName("ids")]
- public List> Ids { get; set; } = [];
-
- ///
- /// List of embedding vectors.
- ///
- [JsonPropertyName("embeddings")]
- public List> Embeddings { get; set; } = [];
-
- ///
- /// List of embedding metadatas.
- ///
- [JsonPropertyName("metadatas")]
- public List>> Metadatas { get; set; } = [];
-
- ///
- /// List of embedding distances.
- ///
- [JsonPropertyName("distances")]
- public List> Distances { get; set; } = [];
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/CreateCollectionRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/CreateCollectionRequest.cs
deleted file mode 100644
index 40cf511ef629..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/CreateCollectionRequest.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class CreateCollectionRequest
-{
- [JsonPropertyName("name")]
- public string CollectionName { get; set; }
-
- [JsonPropertyName("get_or_create")]
- public bool GetOrCreate => true;
-
- public static CreateCollectionRequest Create(string collectionName)
- {
- return new CreateCollectionRequest(collectionName);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreatePostRequest("collections", this);
- }
-
- #region private ================================================================================
-
- private CreateCollectionRequest(string collectionName)
- {
- this.CollectionName = collectionName;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteCollectionRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteCollectionRequest.cs
deleted file mode 100644
index 4e8ed2066aaf..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteCollectionRequest.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class DeleteCollectionRequest
-{
- [JsonIgnore]
- public string CollectionName { get; set; }
-
- public static DeleteCollectionRequest Create(string collectionName)
- {
- return new DeleteCollectionRequest(collectionName);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreateDeleteRequest($"collections/{this.CollectionName}");
- }
-
- #region private ================================================================================
-
- private DeleteCollectionRequest(string collectionName)
- {
- this.CollectionName = collectionName;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteEmbeddingsRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteEmbeddingsRequest.cs
deleted file mode 100644
index 4d2a20a1988d..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/DeleteEmbeddingsRequest.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class DeleteEmbeddingsRequest
-{
- [JsonIgnore]
- public string CollectionId { get; set; }
-
- [JsonPropertyName("ids")]
- public string[] Ids { get; set; }
-
- public static DeleteEmbeddingsRequest Create(string collectionId, string[] ids)
- {
- return new DeleteEmbeddingsRequest(collectionId, ids);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreatePostRequest($"collections/{this.CollectionId}/delete", this);
- }
-
- #region private ================================================================================
-
- private DeleteEmbeddingsRequest(string collectionId, string[] ids)
- {
- this.CollectionId = collectionId;
- this.Ids = ids;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetCollectionRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetCollectionRequest.cs
deleted file mode 100644
index 08f9bb6d9482..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetCollectionRequest.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class GetCollectionRequest
-{
- [JsonIgnore]
- public string CollectionName { get; set; }
-
- public static GetCollectionRequest Create(string collectionName)
- {
- return new GetCollectionRequest(collectionName);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreateGetRequest($"collections/{this.CollectionName}");
- }
-
- #region private ================================================================================
-
- private GetCollectionRequest(string collectionName)
- {
- this.CollectionName = collectionName;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetEmbeddingsRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetEmbeddingsRequest.cs
deleted file mode 100644
index db1437ff5781..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/GetEmbeddingsRequest.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class GetEmbeddingsRequest
-{
- [JsonIgnore]
- public string CollectionId { get; set; }
-
- [JsonPropertyName("ids")]
- public string[] Ids { get; set; }
-
- [JsonPropertyName("include")]
- public string[]? Include { get; set; }
-
- public static GetEmbeddingsRequest Create(string collectionId, string[] ids, string[]? include = null)
- {
- return new GetEmbeddingsRequest(collectionId, ids, include);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreatePostRequest($"collections/{this.CollectionId}/get", this);
- }
-
- #region private ================================================================================
-
- private GetEmbeddingsRequest(string collectionId, string[] ids, string[]? include = null)
- {
- this.CollectionId = collectionId;
- this.Ids = ids;
- this.Include = include;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/ListCollectionsRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/ListCollectionsRequest.cs
deleted file mode 100644
index 55275b910e8a..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/ListCollectionsRequest.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.Net.Http;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class ListCollectionsRequest
-{
- public static ListCollectionsRequest Create()
- {
- return new ListCollectionsRequest();
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreateGetRequest("collections");
- }
-
- #region private ================================================================================
-
- private ListCollectionsRequest()
- { }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/QueryEmbeddingsRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/QueryEmbeddingsRequest.cs
deleted file mode 100644
index 64e0cec50056..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/QueryEmbeddingsRequest.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class QueryEmbeddingsRequest
-{
- [JsonIgnore]
- public string CollectionId { get; set; }
-
- [JsonPropertyName("query_embeddings")]
- public ReadOnlyMemory[] QueryEmbeddings { get; set; }
-
- [JsonPropertyName("n_results")]
- public int NResults { get; set; }
-
- [JsonPropertyName("include")]
- public string[]? Include { get; set; }
-
- public static QueryEmbeddingsRequest Create(string collectionId, ReadOnlyMemory[] queryEmbeddings, int nResults, string[]? include = null)
- {
- return new QueryEmbeddingsRequest(collectionId, queryEmbeddings, nResults, include);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreatePostRequest($"collections/{this.CollectionId}/query", this);
- }
-
- #region private ================================================================================
-
- private QueryEmbeddingsRequest(string collectionId, ReadOnlyMemory[] queryEmbeddings, int nResults, string[]? include = null)
- {
- this.CollectionId = collectionId;
- this.QueryEmbeddings = queryEmbeddings;
- this.NResults = nResults;
- this.Include = include;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/UpsertEmbeddingsRequest.cs b/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/UpsertEmbeddingsRequest.cs
deleted file mode 100644
index cba49003d7af..000000000000
--- a/dotnet/src/VectorData/Chroma/Http/ApiSchema/Internal/UpsertEmbeddingsRequest.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Net.Http;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-internal sealed class UpsertEmbeddingsRequest
-{
- [JsonIgnore]
- public string CollectionId { get; set; }
-
- [JsonPropertyName("ids")]
- public string[] Ids { get; set; }
-
- [JsonPropertyName("embeddings")]
- public ReadOnlyMemory[] Embeddings { get; set; }
-
- [JsonPropertyName("metadatas")]
- public object[]? Metadatas { get; set; }
-
- public static UpsertEmbeddingsRequest Create(string collectionId, string[] ids, ReadOnlyMemory[] embeddings, object[]? metadatas = null)
- {
- return new UpsertEmbeddingsRequest(collectionId, ids, embeddings, metadatas);
- }
-
- public HttpRequestMessage Build()
- {
- return HttpRequest.CreatePostRequest($"collections/{this.CollectionId}/upsert", this);
- }
-
- #region private ================================================================================
-
- private UpsertEmbeddingsRequest(string collectionId, string[] ids, ReadOnlyMemory[] embeddings, object[]? metadatas = null)
- {
- this.CollectionId = collectionId;
- this.Ids = ids;
- this.Embeddings = embeddings;
- this.Metadatas = metadatas;
- }
-
- #endregion
-}
diff --git a/dotnet/src/VectorData/Chroma/IChromaClient.cs b/dotnet/src/VectorData/Chroma/IChromaClient.cs
deleted file mode 100644
index fbecb112acf2..000000000000
--- a/dotnet/src/VectorData/Chroma/IChromaClient.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Microsoft.SemanticKernel.Connectors.Chroma;
-
-///
-/// Interface for client to make requests to Chroma API.
-///
-public interface IChromaClient
-{
- ///
- /// Creates Chroma collection.
- ///
- /// Collection name.
- /// The to monitor for cancellation requests. The default is .
- Task CreateCollectionAsync(string collectionName, CancellationToken cancellationToken = default);
-
- ///
- /// Returns collection model instance by name.
- ///
- /// Collection name.
- /// The to monitor for cancellation requests. The default is .
- /// Instance of model.
- Task GetCollectionAsync(string collectionName, CancellationToken cancellationToken = default);
-
- ///
- /// Removes collection by name.
- ///
- /// Collection name.
- /// The to monitor for cancellation requests. The default is .
- Task DeleteCollectionAsync(string collectionName, CancellationToken cancellationToken = default);
-
- ///
- /// Returns all collection names.
- ///
- /// The to monitor for cancellation requests. The default is .
- /// An asynchronous list of collection names.
- IAsyncEnumerable ListCollectionsAsync(CancellationToken cancellationToken = default);
-
- ///
- /// Upserts embedding to specified collection.
- ///
- /// Collection identifier generated by Chroma.
- /// Array of embedding identifiers.
- /// Array of embedding vectors.
- /// Array of embedding metadatas.
- /// The to monitor for cancellation requests. The default is .
- Task UpsertEmbeddingsAsync(string collectionId, string[] ids, ReadOnlyMemory[] embeddings, object[]? metadatas = null, CancellationToken cancellationToken = default);
-
- ///
- /// Returns embeddings from specified collection.
- ///
- /// Collection identifier generated by Chroma.
- /// Array of embedding identifiers.
- /// Array of entities to include in response (e.g. "embeddings", "metadatas" "documents"). For more information see: https://github.com/chroma-core/chroma/blob/main/chromadb/api/types.py
- /// The to monitor for cancellation requests. The default is .
- /// Instance of model.
- Task GetEmbeddingsAsync(string collectionId, string[] ids, string[]? include = null, CancellationToken cancellationToken = default);
-
- ///
- /// Removes embeddings from specified collection.
- ///
- /// Collection identifier generated by Chroma.
- /// Array of embedding identifiers.
- /// The to monitor for cancellation requests. The default is .
- Task DeleteEmbeddingsAsync(string collectionId, string[] ids, CancellationToken cancellationToken = default);
-
- ///
- /// Searches nearest embeddings by distance in specified collection.
- ///
- /// Collection identifier generated by Chroma.
- /// Embeddings to search for.
- /// Number of results to return.
- /// Array of entities to include in response (e.g. "embeddings", "metadatas" "documents"). For more information see: https://github.com/chroma-core/chroma/blob/main/chromadb/api/types.py
- /// The to monitor for cancellation requests. The default is .
- /// Instance of model.
- Task QueryEmbeddingsAsync(string collectionId, ReadOnlyMemory[] queryEmbeddings, int nResults, string[]? include = null, CancellationToken cancellationToken = default);
-}
diff --git a/dotnet/src/VectorData/Chroma/README.md b/dotnet/src/VectorData/Chroma/README.md
index 47b9037200c6..f67abcc1ee5b 100644
--- a/dotnet/src/VectorData/Chroma/README.md
+++ b/dotnet/src/VectorData/Chroma/README.md
@@ -1,34 +1,3 @@
-# Microsoft.SemanticKernel.Connectors.Chroma
+# The Chroma connector has moved
-This assembly contains implementation of Semantic Kernel Memory Store using [Chroma](https://www.trychroma.com/), open-source embedding database.
-
-**Note:** Chroma connector is verified using Chroma version **0.4.10**. Any higher versions may introduce incompatibility.
-
-## Quickstart using local Chroma server
-
-1. Clone Chroma:
-
-```bash
-git clone https://github.com/chroma-core/chroma.git
-cd chroma
-```
-
-2. Run local Chroma server with Docker within Chroma repository root:
-
-```bash
-docker-compose up -d --build
-```
-
-3. Use Semantic Kernel with Chroma, using server local endpoint `http://localhost:8000`:
-
-```csharp
-const string endpoint = "http://localhost:8000";
-
-var memoryWithChroma = new MemoryBuilder()
- .WithChromaMemoryStore(endpoint)
- .WithLoggerFactory(loggerFactory)
- .WithOpenAITextEmbeddingGeneration("text-embedding-ada-002", apiKey)
- .Build();
-
-var memoryPlugin = kernel.ImportPluginFromObject(new TextMemoryPlugin(memoryWithChroma));
-```
+The code for the Chroma connector can now be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma).
diff --git a/dotnet/test/VectorData/Chroma.UnitTests/Chroma.UnitTests.csproj b/dotnet/test/VectorData/Chroma.UnitTests/Chroma.UnitTests.csproj
deleted file mode 100644
index c1458d3f560d..000000000000
--- a/dotnet/test/VectorData/Chroma.UnitTests/Chroma.UnitTests.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- SemanticKernel.Connectors.Chroma.UnitTests
- SemanticKernel.Connectors.Chroma.UnitTests
- net10.0
- true
- enable
- disable
- false
- $(NoWarn);CA2007,CA1806,CA1869,CA1861,IDE0300,VSTHRD111,SKEXP0001,SKEXP0010,SKEXP0050
-
-
-
-
-
-
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/dotnet/test/VectorData/Chroma.UnitTests/ChromaMemoryStoreTests.cs b/dotnet/test/VectorData/Chroma.UnitTests/ChromaMemoryStoreTests.cs
deleted file mode 100644
index bf2da33d900c..000000000000
--- a/dotnet/test/VectorData/Chroma.UnitTests/ChromaMemoryStoreTests.cs
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Net.Http;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.SemanticKernel;
-using Microsoft.SemanticKernel.Connectors.Chroma;
-using Microsoft.SemanticKernel.Memory;
-using Moq;
-using Xunit;
-
-namespace SemanticKernel.Connectors.UnitTests.Chroma;
-
-///
-/// Unit tests for class.
-///
-[Experimental("SKEXP0020")]
-public sealed class ChromaMemoryStoreTests : IDisposable
-{
- private const string CollectionId = "fake-collection-id";
- private const string CollectionName = "fake-collection-name";
-
- private readonly HttpMessageHandlerStub _messageHandlerStub;
- private readonly HttpClient _httpClient;
- private readonly Mock _chromaClientMock;
-
- public ChromaMemoryStoreTests()
- {
- this._messageHandlerStub = new HttpMessageHandlerStub();
- this._httpClient = this.GetHttpClientStub();
- this._chromaClientMock = new Mock();
-
- this._chromaClientMock
- .Setup(client => client.GetCollectionAsync(CollectionName, CancellationToken.None))
- .ReturnsAsync(new ChromaCollectionModel { Id = CollectionId, Name = CollectionName });
- }
-
- [Fact]
- public async Task ItUsesProvidedEndpointFromConstructorAsync()
- {
- // Arrange
- const string Endpoint = "https://fake-random-test-host/fake-path/";
- var store = new ChromaMemoryStore(this._httpClient, Endpoint);
-
- // Act
- await store.GetAsync("fake-collection", "fake-key");
-
- // Assert
- Assert.StartsWith(Endpoint, this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase);
- }
-
- [Fact]
- public async Task ItUsesBaseAddressFromHttpClientAsync()
- {
- // Arrange
- const string BaseAddress = "https://fake-random-test-host/fake-path/";
-
- using var httpClient = this.GetHttpClientStub();
- httpClient.BaseAddress = new Uri(BaseAddress);
-
- var store = new ChromaMemoryStore(httpClient);
-
- // Act
- await store.GetAsync("fake-collection", "fake-key");
-
- // Assert
- Assert.StartsWith(BaseAddress, this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase);
- }
-
- [Fact]
- public async Task ItCanCreateCollectionAsync()
- {
- // Arrange
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- await store.CreateCollectionAsync(CollectionName);
-
- // Assert
- this._chromaClientMock.Verify(client => client.CreateCollectionAsync(CollectionName, CancellationToken.None), Times.Once());
- }
-
- [Fact]
- public async Task ItCanDeleteCollectionAsync()
- {
- // Arrange
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- await store.DeleteCollectionAsync(CollectionName);
-
- // Assert
- this._chromaClientMock.Verify(client => client.DeleteCollectionAsync(CollectionName, CancellationToken.None), Times.Once());
- }
-
- [Fact]
- public async Task ItThrowsExceptionOnNonExistentCollectionDeletionAsync()
- {
- // Arrange
- const string CollectionName = "non-existent-collection";
- const string CollectionDoesNotExistErrorMessage = $"Collection {CollectionName} does not exist";
- const string ExpectedExceptionMessage = $"Cannot delete non-existent collection {CollectionName}";
-
- this._chromaClientMock
- .Setup(client => client.DeleteCollectionAsync(CollectionName, CancellationToken.None))
- .Throws(new HttpOperationException { ResponseContent = CollectionDoesNotExistErrorMessage });
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var exception = await Record.ExceptionAsync(() => store.DeleteCollectionAsync(CollectionName));
-
- // Assert
- Assert.IsType(exception);
- Assert.Equal(ExpectedExceptionMessage, exception.Message);
- }
-
- [Fact]
- public async Task ItReturnsTrueWhenCollectionExistsAsync()
- {
- // Arrange
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var doesCollectionExist = await store.DoesCollectionExistAsync(CollectionName);
-
- // Assert
- Assert.True(doesCollectionExist);
- }
-
- [Fact]
- public async Task ItReturnsFalseWhenCollectionDoesNotExistAsync()
- {
- // Arrange
- const string CollectionName = "non-existent-collection";
- const string CollectionDoesNotExistErrorMessage = $"Collection {CollectionName} does not exist";
-
- this._chromaClientMock
- .Setup(client => client.GetCollectionAsync(CollectionName, CancellationToken.None))
- .Throws(new HttpOperationException { ResponseContent = CollectionDoesNotExistErrorMessage });
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var doesCollectionExist = await store.DoesCollectionExistAsync(CollectionName);
-
- // Assert
- Assert.False(doesCollectionExist);
- }
-
- [Fact]
- public async Task ItCanGetMemoryRecordFromCollectionAsync()
- {
- // Arrange
- var expectedMemoryRecord = this.GetRandomMemoryRecord();
- var embeddingsModel = this.GetEmbeddingsModelFromMemoryRecord(expectedMemoryRecord);
-
- this._chromaClientMock
- .Setup(client => client.GetEmbeddingsAsync(CollectionId, new[] { expectedMemoryRecord.Key }, It.IsAny(), CancellationToken.None))
- .ReturnsAsync(embeddingsModel);
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var actualMemoryRecord = await store.GetAsync(CollectionName, expectedMemoryRecord.Key, withEmbedding: true);
-
- // Assert
- Assert.NotNull(actualMemoryRecord);
- this.AssertMemoryRecordEqual(expectedMemoryRecord, actualMemoryRecord);
- }
-
- [Fact]
- public async Task ItReturnsNullWhenMemoryRecordDoesNotExistAsync()
- {
- // Arrange
- const string MemoryRecordKey = "fake-record-key";
-
- this._chromaClientMock
- .Setup(client => client.GetEmbeddingsAsync(CollectionId, new[] { MemoryRecordKey }, It.IsAny(), CancellationToken.None))
- .ReturnsAsync(new ChromaEmbeddingsModel());
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var actualMemoryRecord = await store.GetAsync(CollectionName, MemoryRecordKey, withEmbedding: true);
-
- // Assert
- Assert.Null(actualMemoryRecord);
- }
-
- [Fact]
- public async Task ItThrowsExceptionOnGettingMemoryRecordFromNonExistingCollectionAsync()
- {
- // Arrange
- const string CollectionName = "non-existent-collection";
- const string MemoryRecordKey = "fake-record-key";
- const string CollectionDoesNotExistErrorMessage = $"Collection {CollectionName} does not exist";
-
- this._chromaClientMock
- .Setup(client => client.GetCollectionAsync(CollectionName, CancellationToken.None))
- .Throws(new KernelException(CollectionDoesNotExistErrorMessage));
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var exception = await Record.ExceptionAsync(() => store.GetAsync(CollectionName, MemoryRecordKey, withEmbedding: true));
-
- // Assert
- Assert.IsType(exception);
- Assert.Equal(CollectionDoesNotExistErrorMessage, exception.Message);
- }
-
- [Fact]
- public async Task ItCanGetMemoryRecordBatchFromCollectionAsync()
- {
- // Arrange
- var memoryRecord1 = this.GetRandomMemoryRecord();
- var memoryRecord2 = this.GetRandomMemoryRecord();
- var memoryRecord3 = this.GetRandomMemoryRecord();
-
- MemoryRecord[] expectedMemoryRecords = [memoryRecord1, memoryRecord2, memoryRecord3];
- var memoryRecordKeys = expectedMemoryRecords.Select(l => l.Key).ToArray();
-
- var embeddingsModel = this.GetEmbeddingsModelFromMemoryRecords(expectedMemoryRecords);
-
- this._chromaClientMock
- .Setup(client => client.GetEmbeddingsAsync(CollectionId, memoryRecordKeys, It.IsAny(), CancellationToken.None))
- .ReturnsAsync(embeddingsModel);
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var actualMemoryRecords = await store.GetBatchAsync(CollectionName, memoryRecordKeys, withEmbeddings: true).ToListAsync();
-
- // Assert
- Assert.Equal(expectedMemoryRecords.Length, actualMemoryRecords.Count);
-
- for (var i = 0; i < expectedMemoryRecords.Length; i++)
- {
- this.AssertMemoryRecordEqual(expectedMemoryRecords[i], actualMemoryRecords[i]);
- }
- }
-
- [Fact]
- public async Task ItCanReturnCollectionsAsync()
- {
- // Arrange
- var expectedCollections = new List { "fake-collection-1", "fake-collection-2", "fake-collection-3" };
-
- this._chromaClientMock
- .Setup(client => client.ListCollectionsAsync(CancellationToken.None))
- .Returns(expectedCollections.ToAsyncEnumerable());
-
- var store = new ChromaMemoryStore(this._chromaClientMock.Object);
-
- // Act
- var actualCollections = await store.GetCollectionsAsync().ToListAsync();
-
- // Assert
- Assert.Equal(expectedCollections.Count, actualCollections.Count);
-
- for (var i = 0; i < expectedCollections.Count; i++)
- {
- Assert.Equal(expectedCollections[i], actualCollections[i]);
- }
- }
-
- public void Dispose()
- {
- this._httpClient.Dispose();
- this._messageHandlerStub.Dispose();
- }
-
- #region private ================================================================================
-
- private void AssertMemoryRecordEqual(MemoryRecord expectedRecord, MemoryRecord actualRecord)
- {
- Assert.Equal(expectedRecord.Key, actualRecord.Key);
- Assert.True(expectedRecord.Embedding.Span.SequenceEqual(actualRecord.Embedding.Span));
- Assert.Equal(expectedRecord.Metadata.Id, actualRecord.Metadata.Id);
- Assert.Equal(expectedRecord.Metadata.Text, actualRecord.Metadata.Text);
- Assert.Equal(expectedRecord.Metadata.Description, actualRecord.Metadata.Description);
- Assert.Equal(expectedRecord.Metadata.AdditionalMetadata, actualRecord.Metadata.AdditionalMetadata);
- Assert.Equal(expectedRecord.Metadata.IsReference, actualRecord.Metadata.IsReference);
- Assert.Equal(expectedRecord.Metadata.ExternalSourceName, actualRecord.Metadata.ExternalSourceName);
- }
-
- private HttpClient GetHttpClientStub()
- {
- return new HttpClient(this._messageHandlerStub, false);
- }
-
- private MemoryRecord GetRandomMemoryRecord(ReadOnlyMemory? embedding = null)
- {
- var id = Guid.NewGuid().ToString();
- var memoryEmbedding = embedding ?? new[] { 1f, 3f, 5f };
-
- return MemoryRecord.LocalRecord(
- id: id,
- text: "text-" + Guid.NewGuid().ToString(),
- description: "description-" + Guid.NewGuid().ToString(),
- embedding: memoryEmbedding,
- additionalMetadata: "metadata-" + Guid.NewGuid().ToString(),
- key: id);
- }
-
- private Dictionary GetEmbeddingMetadataFromMemoryRecord(MemoryRecord memoryRecord)
- {
- var serialized = JsonSerializer.Serialize(memoryRecord.Metadata);
- return JsonSerializer.Deserialize>(serialized)!;
- }
-
- private ChromaEmbeddingsModel GetEmbeddingsModelFromMemoryRecords(MemoryRecord[] memoryRecords)
- {
- var embeddingsModel = new ChromaEmbeddingsModel();
-
- embeddingsModel.Ids.AddRange(memoryRecords.Select(l => l.Key));
- embeddingsModel.Embeddings.AddRange(memoryRecords.Select(l => l.Embedding.ToArray()));
- embeddingsModel.Metadatas.AddRange(memoryRecords.Select(this.GetEmbeddingMetadataFromMemoryRecord));
-
- return embeddingsModel;
- }
-
- private ChromaEmbeddingsModel GetEmbeddingsModelFromMemoryRecord(MemoryRecord memoryRecord)
- {
- return this.GetEmbeddingsModelFromMemoryRecords([memoryRecord]);
- }
-
- #endregion
-}
From 69ac1a3b89430c5530cc2766d00ee4614084316d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Oct 2026 08:31:55 +0000
Subject: [PATCH 2/4] Match Chroma migration notice style
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
---
dotnet/src/VectorData/Chroma/README.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dotnet/src/VectorData/Chroma/README.md b/dotnet/src/VectorData/Chroma/README.md
index f67abcc1ee5b..4f456e46c3d6 100644
--- a/dotnet/src/VectorData/Chroma/README.md
+++ b/dotnet/src/VectorData/Chroma/README.md
@@ -1,3 +1 @@
-# The Chroma connector has moved
-
-The code for the Chroma connector can now be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma).
+The code for Microsoft.SemanticKernel.Connectors.Chroma can now be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma)
From c6fbffd79a8309c23e67790b3959246adb6dae74 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 12 Oct 2026 08:48:25 +0000
Subject: [PATCH 3/4] Remove Chroma from experimental feature tracking
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
---
dotnet/docs/EXPERIMENTS.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/dotnet/docs/EXPERIMENTS.md b/dotnet/docs/EXPERIMENTS.md
index e51bfd54b04a..34f61029ee10 100644
--- a/dotnet/docs/EXPERIMENTS.md
+++ b/dotnet/docs/EXPERIMENTS.md
@@ -47,7 +47,6 @@ You can use the following diagnostic IDs to ignore warnings or errors for a part
| SKEXP0010 | OpenAI file service |
| | | | | | | |
| SKEXP0020 | Azure AI Search memory connector |
-| SKEXP0020 | Chroma memory connector |
| SKEXP0020 | DuckDB memory connector |
| SKEXP0020 | Kusto memory connector |
| SKEXP0020 | Milvus memory connector |
From 64c9921f9397d068e38d725b770d37ae6b4ba565 Mon Sep 17 00:00:00 2001
From: Adam Sitnik
Date: Tue, 13 Oct 2026 13:29:23 +0200
Subject: [PATCH 4/4] Apply suggestion from @westey-m
Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
---
dotnet/src/VectorData/Chroma/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dotnet/src/VectorData/Chroma/README.md b/dotnet/src/VectorData/Chroma/README.md
index 4f456e46c3d6..2e862fa4adff 100644
--- a/dotnet/src/VectorData/Chroma/README.md
+++ b/dotnet/src/VectorData/Chroma/README.md
@@ -1 +1 @@
-The code for Microsoft.SemanticKernel.Connectors.Chroma can now be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma)
+Microsoft.SemanticKernel.Connectors.Chroma and the MemoryStore abstraction has been deprecated. Please use the new Microsoft.Extensions.VectorData abstractions with the Chroma implementation that can be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma)