diff --git a/advisors/spring-ai-advisors/pom.xml b/advisors/spring-ai-advisors/pom.xml new file mode 100644 index 000000000..75402280d --- /dev/null +++ b/advisors/spring-ai-advisors/pom.xml @@ -0,0 +1,100 @@ + + + + + 4.0.0 + + org.springframework.ai + spring-ai + 1.0.0-SNAPSHOT + ../../pom.xml + + spring-ai-advisors + jar + Spring AI Advisors + Chat client advisors for Spring AI + https://github.com/spring-projects/spring-ai + + + https://github.com/spring-projects/spring-ai + git://github.com/spring-projects/spring-ai.git + git@github.com:spring-projects/spring-ai.git + + + + 17 + 17 + + + + + + org.springframework.ai + spring-ai-core + ${project.parent.version} + + + + org.springframework.ai + spring-ai-vector-store + ${project.parent.version} + + + + + org.springframework + spring-context + + + + com.fasterxml.jackson.core + jackson-databind + + + + io.projectreactor + reactor-core + + + + org.jetbrains.kotlin + kotlin-stdlib + true + + + + org.jetbrains.kotlin + kotlin-reflect + true + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.fasterxml.jackson.module + jackson-module-kotlin + test + + + + diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisor.java b/advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisor.java similarity index 100% rename from spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisor.java rename to advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisor.java diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java b/advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java similarity index 100% rename from spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java rename to advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/VectorStoreChatMemoryAdvisor.java diff --git a/advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/package-info.java b/advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/package-info.java new file mode 100644 index 000000000..66e95c047 --- /dev/null +++ b/advisors/spring-ai-advisors/src/main/java/org/springframework/ai/chat/client/advisor/package-info.java @@ -0,0 +1,25 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Spring AI chat client advisors package. + */ +@NonNullApi +@NonNullFields +package org.springframework.ai.chat.client.advisor; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisorTests.java b/advisors/spring-ai-advisors/src/test/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisorTests.java similarity index 80% rename from spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisorTests.java rename to advisors/spring-ai-advisors/src/test/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisorTests.java index 220479c5c..048d35475 100644 --- a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisorTests.java +++ b/advisors/spring-ai-advisors/src/test/java/org/springframework/ai/chat/client/advisor/QuestionAnswerAdvisorTests.java @@ -20,6 +20,7 @@ import java.time.Duration; import java.util.List; import java.util.Map; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -128,19 +129,19 @@ public class QuestionAnswerAdvisorTests { //formatter:on // Ensure the metadata is correctly copied over - assertThat(response.getMetadata().getModel()).isEqualTo("model1"); - assertThat(response.getMetadata().getId()).isEqualTo("678"); - assertThat(response.getMetadata().getRateLimit().getRequestsLimit()).isEqualTo(5L); - assertThat(response.getMetadata().getRateLimit().getRequestsRemaining()).isEqualTo(6L); - assertThat(response.getMetadata().getRateLimit().getRequestsReset()).isEqualTo(Duration.ofSeconds(7)); - assertThat(response.getMetadata().getRateLimit().getTokensLimit()).isEqualTo(8L); - assertThat(response.getMetadata().getRateLimit().getTokensRemaining()).isEqualTo(8L); - assertThat(response.getMetadata().getRateLimit().getTokensReset()).isEqualTo(Duration.ofSeconds(9)); - assertThat(response.getMetadata().getUsage().getPromptTokens()).isEqualTo(6L); - assertThat(response.getMetadata().getUsage().getCompletionTokens()).isEqualTo(7L); - assertThat(response.getMetadata().getUsage().getTotalTokens()).isEqualTo(6L + 7L); - assertThat(response.getMetadata().get("key6").toString()).isEqualTo("value6"); - assertThat(response.getMetadata().get("key1").toString()).isEqualTo("value1"); + Assertions.assertThat(response.getMetadata().getModel()).isEqualTo("model1"); + Assertions.assertThat(response.getMetadata().getId()).isEqualTo("678"); + Assertions.assertThat(response.getMetadata().getRateLimit().getRequestsLimit()).isEqualTo(5L); + Assertions.assertThat(response.getMetadata().getRateLimit().getRequestsRemaining()).isEqualTo(6L); + Assertions.assertThat(response.getMetadata().getRateLimit().getRequestsReset()).isEqualTo(Duration.ofSeconds(7)); + Assertions.assertThat(response.getMetadata().getRateLimit().getTokensLimit()).isEqualTo(8L); + Assertions.assertThat(response.getMetadata().getRateLimit().getTokensRemaining()).isEqualTo(8L); + Assertions.assertThat(response.getMetadata().getRateLimit().getTokensReset()).isEqualTo(Duration.ofSeconds(9)); + Assertions.assertThat(response.getMetadata().getUsage().getPromptTokens()).isEqualTo(6L); + Assertions.assertThat(response.getMetadata().getUsage().getCompletionTokens()).isEqualTo(7L); + Assertions.assertThat(response.getMetadata().getUsage().getTotalTokens()).isEqualTo(6L + 7L); + Assertions.assertThat(response.getMetadata().get("key6").toString()).isEqualTo("value6"); + Assertions.assertThat(response.getMetadata().get("key1").toString()).isEqualTo("value1"); String content = response.getResult().getOutput().getText(); @@ -171,9 +172,9 @@ public class QuestionAnswerAdvisorTests { the user that you can't answer the question. """); - assertThat(this.vectorSearchCaptor.getValue().getFilterExpression()).isEqualTo(new FilterExpressionBuilder().eq("type", "Spring").build()); - assertThat(this.vectorSearchCaptor.getValue().getSimilarityThreshold()).isEqualTo(0.99d); - assertThat(this.vectorSearchCaptor.getValue().getTopK()).isEqualTo(6); + Assertions.assertThat(this.vectorSearchCaptor.getValue().getFilterExpression()).isEqualTo(new FilterExpressionBuilder().eq("type", "Spring").build()); + Assertions.assertThat(this.vectorSearchCaptor.getValue().getSimilarityThreshold()).isEqualTo(0.99d); + Assertions.assertThat(this.vectorSearchCaptor.getValue().getTopK()).isEqualTo(6); } @Test @@ -201,7 +202,7 @@ public class QuestionAnswerAdvisorTests { var userPrompt = this.promptCaptor.getValue().getInstructions().get(0).getText(); assertThat(userPrompt).doesNotContain(userTextTemplate); assertThat(userPrompt).contains(expectedQuery); - assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery); + Assertions.assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery); } @Test @@ -230,7 +231,7 @@ public class QuestionAnswerAdvisorTests { var userPrompt = this.promptCaptor.getValue().getInstructions().get(0).getText(); assertThat(userPrompt).doesNotContain(userTextTemplate); assertThat(userPrompt).contains(expectedQuery); - assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery); + Assertions.assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery); } } diff --git a/pom.xml b/pom.xml index 794633983..5e69fa184 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ spring-ai-model spring-ai-test spring-ai-vector-store + advisors/spring-ai-advisors auto-configurations/common/spring-ai-autoconfigure-retry diff --git a/vector-stores/spring-ai-pgvector-store/pom.xml b/vector-stores/spring-ai-pgvector-store/pom.xml index 3afcdcdbd..8df1a966d 100644 --- a/vector-stores/spring-ai-pgvector-store/pom.xml +++ b/vector-stores/spring-ai-pgvector-store/pom.xml @@ -48,6 +48,13 @@ ${project.parent.version} + + org.springframework.ai + spring-ai-advisors + ${project.parent.version} + + + com.zaxxer HikariCP