diff --git a/chatbot/chatbot-openai-springai/pom.xml b/chatbot/chatbot-openai-springai/pom.xml index 98717fd..430de12 100644 --- a/chatbot/chatbot-openai-springai/pom.xml +++ b/chatbot/chatbot-openai-springai/pom.xml @@ -18,7 +18,7 @@ 17 2.43.0 - 1.0.0-SNAPSHOT + 1.0.0-M1 @@ -122,22 +122,22 @@ - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + false - + - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + false - + diff --git a/chatbot/chatbot-openai-springai/src/main/resources/application.properties b/chatbot/chatbot-openai-springai/src/main/resources/application.properties index bab13b3..366ef9d 100644 --- a/chatbot/chatbot-openai-springai/src/main/resources/application.properties +++ b/chatbot/chatbot-openai-springai/src/main/resources/application.properties @@ -8,6 +8,8 @@ spring.ai.openai.base-url=http://langchain4j.dev/demo/openai spring.ai.openai.chat.options.model=gpt-3.5-turbo spring.ai.openai.chat.options.temperature=0.7 +spring.ai.vectorstore.milvus.collectionName=SpringAiCollection + spring.ai.openai.embedding.enabled=true spring.testcontainers.beans.startup=parallel diff --git a/embeddingstores/neo4j-springai/pom.xml b/embeddingstores/neo4j-springai/pom.xml index 9bec4a4..2cca29b 100644 --- a/embeddingstores/neo4j-springai/pom.xml +++ b/embeddingstores/neo4j-springai/pom.xml @@ -18,7 +18,7 @@ UTF-8 21 - 0.8.1 + 1.0.0-M1 2.43.0 @@ -57,8 +57,8 @@ test - org.springframework.boot - spring-boot-testcontainers + org.springframework.ai + spring-ai-spring-boot-testcontainers test @@ -98,7 +98,7 @@ - 2.40.0 + 2.47.0 diff --git a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/Neo4jVectorEmbeddingStoreExample.java b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/Neo4jVectorEmbeddingStoreExample.java index 8a90ccc..ced04fe 100644 --- a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/Neo4jVectorEmbeddingStoreExample.java +++ b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/Neo4jVectorEmbeddingStoreExample.java @@ -4,7 +4,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class Neo4jVectorEmbeddingStoreExample { +class Neo4jVectorEmbeddingStoreExample { public static void main(String[] args) { SpringApplication.run(Neo4jVectorEmbeddingStoreExample.class, args); diff --git a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/Initializer.java b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/Initializer.java index 893a82b..5d69ca5 100644 --- a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/Initializer.java +++ b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/Initializer.java @@ -5,7 +5,7 @@ import org.springframework.stereotype.Component; @Component -public class Initializer implements CommandLineRunner { +class Initializer implements CommandLineRunner { private final Neo4jVectorStoreService neo4jVectorStoreService; diff --git a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java index ce86d3c..879acaf 100644 --- a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java +++ b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java @@ -16,7 +16,7 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnProperty(value = "spring.ai.openai.api-key", havingValue = "demo") -public class ResponseHeadersModification { +class ResponseHeadersModification { @Bean RestClient.Builder restClientBuilder() { diff --git a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java index c543547..b84b15e 100644 --- a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java +++ b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java @@ -7,4 +7,4 @@ @Configuration(proxyBeanMethods = false) @OpenAPIDefinition(info = @Info(title = "pgvector-springai", version = "v1.0.0"), servers = @Server(url = "/")) -public class SwaggerConfig {} +class SwaggerConfig {} diff --git a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/controller/QueryController.java b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/controller/QueryController.java index 371ab29..dc1ee5c 100644 --- a/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/controller/QueryController.java +++ b/embeddingstores/neo4j-springai/src/main/java/com/learning/ai/controller/QueryController.java @@ -10,7 +10,7 @@ @RestController @RequestMapping("/api/ai") -public class QueryController { +class QueryController { private final Neo4jVectorStoreService neo4jVectorStoreService; diff --git a/embeddingstores/pgvector-springai/pom.xml b/embeddingstores/pgvector-springai/pom.xml index 3658758..b43682d 100644 --- a/embeddingstores/pgvector-springai/pom.xml +++ b/embeddingstores/pgvector-springai/pom.xml @@ -17,8 +17,10 @@ UTF-8 - 17 - 0.8.1 + 21 + 1.0.0-M1 + + 2.43.0 @@ -56,8 +58,8 @@ test - org.springframework.boot - spring-boot-testcontainers + org.springframework.ai + spring-ai-spring-boot-testcontainers test @@ -90,6 +92,29 @@ org.springframework.boot spring-boot-maven-plugin + + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} + + + + 2.47.0 + + + + + + + + + compile + + check + + + + diff --git a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/Initializer.java b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/Initializer.java index eb3507c..b6cd99c 100644 --- a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/Initializer.java +++ b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/Initializer.java @@ -5,7 +5,7 @@ import org.springframework.stereotype.Component; @Component -public class Initializer implements CommandLineRunner { +class Initializer implements CommandLineRunner { private final PgVectorStoreService pgVectorStoreService; diff --git a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java index ce86d3c..879acaf 100644 --- a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java +++ b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/ResponseHeadersModification.java @@ -16,7 +16,7 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnProperty(value = "spring.ai.openai.api-key", havingValue = "demo") -public class ResponseHeadersModification { +class ResponseHeadersModification { @Bean RestClient.Builder restClientBuilder() { diff --git a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java index c543547..b84b15e 100644 --- a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java +++ b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/config/SwaggerConfig.java @@ -7,4 +7,4 @@ @Configuration(proxyBeanMethods = false) @OpenAPIDefinition(info = @Info(title = "pgvector-springai", version = "v1.0.0"), servers = @Server(url = "/")) -public class SwaggerConfig {} +class SwaggerConfig {} diff --git a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/controller/QueryController.java b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/controller/QueryController.java index c36d6a5..20935d5 100644 --- a/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/controller/QueryController.java +++ b/embeddingstores/pgvector-springai/src/main/java/com/learning/ai/controller/QueryController.java @@ -9,7 +9,7 @@ @RestController @RequestMapping("/api/ai") -public class QueryController { +class QueryController { private final PgVectorStoreService pgVectorStoreService; diff --git a/rag/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java b/rag/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java index d3b4090..7e4db2b 100644 --- a/rag/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java +++ b/rag/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java @@ -2,6 +2,7 @@ import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.containsStringIgnoringCase; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; @@ -70,7 +71,7 @@ void testRag() { .post("/api/ai/chat") .then() .statusCode(200) - .body("queryResponse", containsString("yes")) + .body("queryResponse", containsStringIgnoringCase("yes")) .log() .all(); } @@ -84,7 +85,7 @@ void testRag2() { .post("/api/ai/chat") .then() .statusCode(200) - .body("queryResponse", containsString("No")) + .body("queryResponse", containsStringIgnoringCase("No")) .log() .all(); } diff --git a/rag/rag-springai-openai-llm/pom.xml b/rag/rag-springai-openai-llm/pom.xml index 1b90732..f0a07bd 100644 --- a/rag/rag-springai-openai-llm/pom.xml +++ b/rag/rag-springai-openai-llm/pom.xml @@ -16,7 +16,7 @@ 21 - 0.8.1 + 1.0.0-M1 2.43.0 diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplication.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplication.java index 076804c..cb1894d 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplication.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplication.java @@ -4,7 +4,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class LlmRagWithSpringAiApplication { +class LlmRagWithSpringAiApplication { public static void main(String[] args) { SpringApplication.run(LlmRagWithSpringAiApplication.class, args); diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/AppConfig.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/AppConfig.java index 1d8a11e..9823127 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/AppConfig.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/AppConfig.java @@ -14,7 +14,7 @@ import org.springframework.jdbc.core.JdbcTemplate; @Configuration(proxyBeanMethods = false) -public class AppConfig { +class AppConfig { private static final Logger log = LoggerFactory.getLogger(AppConfig.class); @Value("classpath:Rohit_Gurunath_Sharma.docx") diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/FunctionConfiguration.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/FunctionConfiguration.java index 9aa1a4e..9059a53 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/FunctionConfiguration.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/FunctionConfiguration.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.Description; @Configuration(proxyBeanMethods = false) -public class FunctionConfiguration { +class FunctionConfiguration { private static final Logger log = LoggerFactory.getLogger(FunctionConfiguration.class); diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/GlobalExceptionHandler.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/GlobalExceptionHandler.java index c2a2c76..30e1b1f 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/GlobalExceptionHandler.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/GlobalExceptionHandler.java @@ -17,7 +17,7 @@ @Order(Ordered.HIGHEST_PRECEDENCE) @ControllerAdvice -public class GlobalExceptionHandler { +class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/ResponseHeadersModification.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/ResponseHeadersModification.java index 3aedccb..2fb9e2c 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/ResponseHeadersModification.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/ResponseHeadersModification.java @@ -26,7 +26,7 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnProperty(value = "spring.ai.openai.api-key", havingValue = "demo") -public class ResponseHeadersModification { +class ResponseHeadersModification { private static final Logger LOGGER = LoggerFactory.getLogger(ResponseHeadersModification.class); diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/SwaggerConfig.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/SwaggerConfig.java index a949602..18a1dc1 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/SwaggerConfig.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/config/SwaggerConfig.java @@ -7,4 +7,4 @@ @Configuration(proxyBeanMethods = false) @OpenAPIDefinition(info = @Info(title = "rag-springai-openai-llm", version = "v1.0.0"), servers = @Server(url = "/")) -public class SwaggerConfig {} +class SwaggerConfig {} diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java index 1945559..5795593 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java @@ -13,7 +13,7 @@ @RestController @RequestMapping("/api/ai") @Validated -public class AiController { +class AiController { private final AIChatService aiChatService; diff --git a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/service/AIChatService.java b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/service/AIChatService.java index 403e5cb..05656d8 100644 --- a/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/service/AIChatService.java +++ b/rag/rag-springai-openai-llm/src/main/java/com/learning/ai/llmragwithspringai/service/AIChatService.java @@ -1,17 +1,17 @@ package com.learning.ai.llmragwithspringai.service; +import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY; + import java.util.List; -import java.util.Map; import java.util.stream.Collectors; -import org.springframework.ai.chat.ChatClient; -import org.springframework.ai.chat.ChatResponse; -import org.springframework.ai.chat.Generation; -import org.springframework.ai.chat.messages.Message; -import org.springframework.ai.chat.messages.UserMessage; -import org.springframework.ai.chat.prompt.Prompt; -import org.springframework.ai.chat.prompt.SystemPromptTemplate; +import org.springframework.ai.chat.client.ChatClient; +import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor; +import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor; +import org.springframework.ai.chat.memory.InMemoryChatMemory; +import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.chat.model.Generation; import org.springframework.ai.document.Document; -import org.springframework.ai.openai.OpenAiChatOptions; +import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.stereotype.Service; @@ -40,8 +40,15 @@ with one player from the fielding team (the bowler) bowling the ball towards the private final ChatClient aiClient; private final VectorStore vectorStore; - public AIChatService(ChatClient aiClient, VectorStore vectorStore) { - this.aiClient = aiClient; + public AIChatService(ChatClient.Builder modelBuilder, VectorStore vectorStore) { + this.aiClient = modelBuilder + .defaultSystem(template) + .defaultAdvisors( + new PromptChatMemoryAdvisor(new InMemoryChatMemory()), + // new MessageChatMemoryAdvisor(chatMemory), // CHAT MEMORY + new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())) // RAG + .defaultFunctions("currentDateFunction") // FUNCTION CALLING + .build(); this.vectorStore = vectorStore; } @@ -53,12 +60,12 @@ public String chat(String searchQuery) { .collect(Collectors.joining(System.lineSeparator())); // Constructing the systemMessage to indicate the AI model to use the passed information // to answer the question. - Message systemMessage = new SystemPromptTemplate(template).createMessage(Map.of("documents", documents)); - UserMessage userMessage = new UserMessage(searchQuery); - OpenAiChatOptions chatOptions = - OpenAiChatOptions.builder().withFunction("currentDateFunction").build(); - Prompt prompt = new Prompt(List.of(systemMessage, userMessage), chatOptions); - ChatResponse aiResponse = aiClient.call(prompt); + ChatResponse aiResponse = aiClient.prompt() + .system(sp -> sp.param("documents", documents)) + .user(searchQuery) + .advisors(a -> a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)) + .call() + .chatResponse(); Generation generation = aiResponse.getResult(); return (generation != null) ? generation.getOutput().getContent() : ""; } diff --git a/rag/rag-springai-openai-llm/src/main/resources/application-local.properties b/rag/rag-springai-openai-llm/src/main/resources/application-local.properties index 98a3d3d..5768bcb 100644 --- a/rag/rag-springai-openai-llm/src/main/resources/application-local.properties +++ b/rag/rag-springai-openai-llm/src/main/resources/application-local.properties @@ -1,3 +1,6 @@ spring.datasource.password=secret spring.datasource.username=appuser spring.datasource.url=jdbc:postgresql://localhost/appdb + +# default value of openai is 1536 +spring.ai.vectorstore.pgvector.dimensions=384 \ No newline at end of file diff --git a/rag/rag-springai-openai-llm/src/main/resources/application.properties b/rag/rag-springai-openai-llm/src/main/resources/application.properties index fe4dfac..c09e460 100644 --- a/rag/rag-springai-openai-llm/src/main/resources/application.properties +++ b/rag/rag-springai-openai-llm/src/main/resources/application.properties @@ -9,4 +9,6 @@ spring.ai.openai.chat.options.model=gpt-3.5-turbo spring.ai.openai.chat.options.temperature=0.2 spring.ai.openai.chat.options.responseFormat=json_object +spring.ai.openai.embedding.options.model=text-embedding-ada-002 + #spring.ai.openai.image.model=dall-e-3