From d5232a6e9726210d1419b6e6053f32720e436848 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Mon, 1 Apr 2024 06:17:55 +0000 Subject: [PATCH] feat : convert endpoint to post --- README.md | 2 +- .../docker/docker-compose.yml | 2 +- .../controller/AiController.java | 25 ++++++----------- .../model/request/AIChatRequest.java | 13 +++++++++ .../model/response/AIChatResponse.java | 3 +++ .../src/main/resources/application.properties | 5 ++-- .../LlmRagWithSpringAiApplicationIntTest.java | 27 ++++++++++++------- .../TestLlmRagWithSpringAiApplication.java | 4 +-- 8 files changed, 47 insertions(+), 34 deletions(-) create mode 100644 rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/request/AIChatRequest.java create mode 100644 rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/response/AIChatResponse.java diff --git a/README.md b/README.md index d06a3dc..9a606f5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,6 @@ AI implementations using java, stores and either of Langchain4j or springai fram | [pgvector springai](./pgvector-springai) | Embeddings implementation using springai and pgvector | | [playground](./playground) | AI playground using Langchain4j | | [rag langchain4j AllMiniLmL6V2](./rag-langchain4j-AllMiniLmL6V2-llm) | RAG Implementation using Langchain4j, PGVector store and openai LLM | -| [rag springai ollama llm](./rag-springai-ollama-llm) | RAG Implementation using springai, PGVector store and ollama LLM with orca-mini model | +| [rag springai ollama llm](./rag-springai-ollama-llm) | RAG Implementation using springai, Redis store and ollama LLM with llama2 model | | [rag springai openai llm](./rag-springai-openai-llm) | RAG Implementation using springai, PGVector store and openai LLM | diff --git a/rag-springai-ollama-llm/docker/docker-compose.yml b/rag-springai-ollama-llm/docker/docker-compose.yml index 8a9782f..e54bfe6 100644 --- a/rag-springai-ollama-llm/docker/docker-compose.yml +++ b/rag-springai-ollama-llm/docker/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.7' services: ollama: - image: langchain4j/ollama-orca-mini:latest + image: langchain4j/ollama-llama2:latest ports: - '11434:11434' redis-stack: diff --git a/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java b/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java index 9345130..c70941a 100644 --- a/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java +++ b/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/controller/AiController.java @@ -1,17 +1,13 @@ package com.learning.ai.llmragwithspringai.controller; +import com.learning.ai.llmragwithspringai.model.request.AIChatRequest; +import com.learning.ai.llmragwithspringai.model.response.AIChatResponse; import com.learning.ai.llmragwithspringai.service.AIChatService; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; -import java.util.Map; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/ai") @@ -26,15 +22,10 @@ public AiController(AIChatService aiChatService) { this.aiChatService = aiChatService; } - @GetMapping("/chat") - Map ragService( - @RequestParam - @NotBlank(message = "Query cannot be empty") - @Size(max = 255, message = "Query exceeds maximum length") - @Pattern(regexp = "^[a-zA-Z0-9 ]*$", message = "Invalid characters in query") - String question) { - String chatResponse = aiChatService.chat(question); + @PostMapping("/chat") + AIChatResponse ragService(@RequestBody @Valid AIChatRequest aiChatRequest) { + String chatResponse = aiChatService.chat(aiChatRequest.question()); LOGGER.info("chatResponse :{}", chatResponse); - return Map.of("response", chatResponse); + return new AIChatResponse(chatResponse); } } diff --git a/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/request/AIChatRequest.java b/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/request/AIChatRequest.java new file mode 100644 index 0000000..ffc9efe --- /dev/null +++ b/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/request/AIChatRequest.java @@ -0,0 +1,13 @@ +package com.learning.ai.llmragwithspringai.model.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.io.Serializable; + +public record AIChatRequest( + @NotBlank(message = "Query cannot be empty") + @Size(max = 800, message = "Query exceeds maximum length") + @Pattern(regexp = "^[a-zA-Z0-9 ?]*$", message = "Invalid characters in query") + String question) + implements Serializable {} diff --git a/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/response/AIChatResponse.java b/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/response/AIChatResponse.java new file mode 100644 index 0000000..222732c --- /dev/null +++ b/rag-springai-ollama-llm/src/main/java/com/learning/ai/llmragwithspringai/model/response/AIChatResponse.java @@ -0,0 +1,3 @@ +package com.learning.ai.llmragwithspringai.model.response; + +public record AIChatResponse(String queryResponse) {} diff --git a/rag-springai-ollama-llm/src/main/resources/application.properties b/rag-springai-ollama-llm/src/main/resources/application.properties index ab8f62d..8f5d332 100644 --- a/rag-springai-ollama-llm/src/main/resources/application.properties +++ b/rag-springai-ollama-llm/src/main/resources/application.properties @@ -3,10 +3,9 @@ spring.application.name=rag-springai-ollama-llm spring.threads.virtual.enabled=true spring.mvc.problemdetails.enabled=true -spring.ai.ollama.chat.options.model=orca-mini -spring.ai.ollama.chat.options.responseFormat=json_object +spring.ai.ollama.chat.options.model=llama2 -spring.ai.ollama.embedding.options.model=orca-mini +spring.ai.ollama.embedding.options.model=llama2 spring.ai.vectorstore.redis.index=vector_store spring.ai.vectorstore.redis.prefix=ai diff --git a/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java b/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java index baf4233..c81492d 100644 --- a/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java +++ b/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/LlmRagWithSpringAiApplicationIntTest.java @@ -6,7 +6,9 @@ import static org.hamcrest.Matchers.is; import com.learning.ai.llmragwithspringai.config.AbstractIntegrationTest; +import com.learning.ai.llmragwithspringai.model.request.AIChatRequest; import io.restassured.RestAssured; +import io.restassured.http.ContentType; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; @@ -25,20 +27,23 @@ void setUp() { @Test void testRag() { - given().param("question", "Is Rohit Sharma batsman") + given().contentType(ContentType.JSON) + .body(new AIChatRequest("Is Rohit Sharma batsman?")) .when() - .get("/api/ai/chat") + .post("/api/ai/chat") .then() .statusCode(200) - .body("response", containsString("Yes")) - .log(); + .body("queryResponse", containsString("Yes")) + .log() + .all(); } @Test void testEmptyQuery() { - given().param("question", "") + given().contentType(ContentType.JSON) + .body(new AIChatRequest("")) .when() - .get("/api/ai/chat") + .post("/api/ai/chat") .then() .statusCode(400) .header("Content-Type", is("application/problem+json")) @@ -53,9 +58,10 @@ void testEmptyQuery() { @Test void testLongQueryString() { String longQuery = "a".repeat(1000); // Example of a very long query string - given().param("question", longQuery) + given().contentType(ContentType.JSON) + .body(new AIChatRequest(longQuery)) .when() - .get("/api/ai/chat") + .post("/api/ai/chat") .then() .statusCode(400) .header("Content-Type", is("application/problem+json")) @@ -69,9 +75,10 @@ void testLongQueryString() { @Test void testSpecialCharactersInQuery() { - given().param("question", "@#$%^&*()") + given().contentType(ContentType.JSON) + .body(new AIChatRequest("@#$%^&*()")) .when() - .get("/api/ai/chat") + .post("/api/ai/chat") .then() .statusCode(400) .header("Content-Type", is("application/problem+json")) diff --git a/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/TestLlmRagWithSpringAiApplication.java b/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/TestLlmRagWithSpringAiApplication.java index 5f45f51..c90c315 100644 --- a/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/TestLlmRagWithSpringAiApplication.java +++ b/rag-springai-ollama-llm/src/test/java/com/learning/ai/llmragwithspringai/TestLlmRagWithSpringAiApplication.java @@ -16,8 +16,8 @@ public class TestLlmRagWithSpringAiApplication { @Bean OllamaContainer ollama(DynamicPropertyRegistry properties) { - OllamaContainer ollama = new OllamaContainer(DockerImageName.parse("langchain4j/ollama-orca-mini:latest") - .asCompatibleSubstituteFor("ollama/ollama")); + OllamaContainer ollama = new OllamaContainer( + DockerImageName.parse("langchain4j/ollama-llama2:latest").asCompatibleSubstituteFor("ollama/ollama")); properties.add("spring.ai.ollama.base-url", ollama::getEndpoint); return ollama; }