diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/pom.xml b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/pom.xml
index f8f55f26d..eb8333f16 100644
--- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/pom.xml
+++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/pom.xml
@@ -103,5 +103,12 @@
${project.parent.version}
test
+
+
+ org.springframework.ai
+ spring-ai-advisors-vector-store
+ ${project.parent.version}
+ test
+
diff --git a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/src/test/java/org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfigurationIT.java b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/src/test/java/org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfigurationIT.java
index 62c2f87b5..a96073bfb 100644
--- a/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/src/test/java/org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfigurationIT.java
+++ b/auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/src/test/java/org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfigurationIT.java
@@ -28,6 +28,13 @@ import org.testcontainers.chromadb.ChromaDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
+import org.springframework.ai.chat.client.ChatClientRequest;
+import org.springframework.ai.chat.client.ChatClientResponse;
+import org.springframework.ai.chat.client.advisor.vectorstore.VectorStoreChatMemoryAdvisor;
+import org.springframework.ai.chat.messages.AssistantMessage;
+import org.springframework.ai.chat.model.ChatResponse;
+import org.springframework.ai.chat.model.Generation;
+import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chroma.vectorstore.ChromaVectorStore;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -68,6 +75,39 @@ public class ChromaVectorStoreAutoConfigurationIT {
"spring.ai.vectorstore.chroma.client.port=" + chroma.getMappedPort(8000),
"spring.ai.vectorstore.chroma.collectionName=TestCollection");
+ @Test
+ public void verifyThatChromaCanHandleComplexMetadataValues() {
+ this.contextRunner.withPropertyValues("spring.ai.vectorstore.chroma.initializeSchema=true").run(context -> {
+
+ VectorStore vectorStore = context.getBean(VectorStore.class);
+
+ VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
+ .defaultTopK(5)
+ .build();
+
+ assertThat(advisor.getName()).isEqualTo("VectorStoreChatMemoryAdvisor");
+
+ var req = ChatClientRequest.builder().prompt(Prompt.builder().content("UserPrompt").build()).build();
+
+ ChatClientRequest req2 = advisor.before(req, null);
+ assertThat(req2).isNotNull();
+
+ var response = ChatClientResponse.builder()
+ .chatResponse(ChatResponse.builder()
+ .generations(List
+ .of(new Generation(new AssistantMessage("AssistantMessage", Map.of("annotations", List.of())))))
+ .build())
+ .build();
+ var res2 = advisor.after(response, null);
+ assertThat(res2).isNotNull();
+
+ // Remove all documents from the store
+ List docs = vectorStore.similaritySearch("UserPrompt, AssistantMessage");
+ vectorStore.delete(docs.stream().map(doc -> doc.getId()).toList());
+
+ });
+ }
+
@Test
public void addAndSearchWithFilters() {
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java
index 58a0062ec..74c776e6d 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiChatModel.java
@@ -219,7 +219,7 @@ public class OpenAiChatModel implements ChatModel {
"index", choice.index(),
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "",
"refusal", StringUtils.hasText(choice.message().refusal()) ? choice.message().refusal() : "",
- "annotations", choice.message().annotations() != null ? choice.message().annotations() : List.of());
+ "annotations", choice.message().annotations() != null ? choice.message().annotations() : List.of(Map.of()));
return buildGeneration(choice, metadata, request);
}).toList();
// @formatter:on
diff --git a/pom.xml b/pom.xml
index 2cf8b7938..ca54365aa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -309,6 +309,7 @@
4.12.0
+ 4.1.0
0.10.0
diff --git a/vector-stores/spring-ai-chroma-store/pom.xml b/vector-stores/spring-ai-chroma-store/pom.xml
index d40a517f1..3d415a4e7 100644
--- a/vector-stores/spring-ai-chroma-store/pom.xml
+++ b/vector-stores/spring-ai-chroma-store/pom.xml
@@ -95,6 +95,14 @@
${project.parent.version}
test
+
+
+ net.javacrumbs.json-unit
+ json-unit-assertj
+ ${json-unit-assertj.version}
+ test
+
+
diff --git a/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaApi.java b/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaApi.java
index 9c55e6011..79166c0c2 100644
--- a/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaApi.java
+++ b/vector-stores/spring-ai-chroma-store/src/main/java/org/springframework/ai/chroma/vectorstore/ChromaApi.java
@@ -30,6 +30,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chroma.vectorstore.ChromaApi.QueryRequest.Include;
import org.springframework.ai.chroma.vectorstore.common.ChromaApiConstants;
+import org.springframework.ai.util.json.JsonParser;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
@@ -443,7 +444,27 @@ public class ChromaApi {
@JsonProperty("metadatas") List