diff --git a/.github/workflows/chatbot-ollama-springai.yml b/.github/workflows/chatbot-ollama-springai.yml
index 5562dee..f09824a 100644
--- a/.github/workflows/chatbot-ollama-springai.yml
+++ b/.github/workflows/chatbot-ollama-springai.yml
@@ -3,11 +3,11 @@ name: chatbot-ollama-springai CI Build
on:
push:
paths:
- - "chatbot-ollama-springai/**"
+ - "chatbot/chatbot-ollama-springai/**"
branches: [main]
pull_request:
paths:
- - "chatbot-ollama-springai/**"
+ - "chatbot/chatbot-ollama-springai/**"
types:
- opened
- synchronize
@@ -19,10 +19,9 @@ jobs:
runs-on: ubuntu-latest
defaults:
run:
- working-directory: chatbot-ollama-springai
+ working-directory: chatbot/chatbot-ollama-springai
strategy:
matrix:
- distribution: [ 'temurin' ]
java: [ '21' ]
steps:
- uses: actions/checkout@v4
@@ -33,7 +32,7 @@ jobs:
uses: actions/setup-java@v4.2.1
with:
java-version: ${{ matrix.java }}
- distribution: ${{ matrix.distribution }}
+ distribution: temurin
cache: 'maven'
- name: Build and analyze
run: ./mvnw clean verify
\ No newline at end of file
diff --git a/chatbot-ollama-springai/src/main/java/com/example/chatbot/config/ChatConfig.java b/chatbot-ollama-springai/src/main/java/com/example/chatbot/config/ChatConfig.java
deleted file mode 100644
index 74525be..0000000
--- a/chatbot-ollama-springai/src/main/java/com/example/chatbot/config/ChatConfig.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.example.chatbot.config;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.springframework.ai.chat.memory.ChatMemory;
-import org.springframework.ai.chat.memory.ChatMemoryChatServiceListener;
-import org.springframework.ai.chat.memory.ChatMemoryRetriever;
-import org.springframework.ai.chat.memory.InMemoryChatMemory;
-import org.springframework.ai.chat.memory.LastMaxTokenSizeContentTransformer;
-import org.springframework.ai.chat.memory.SystemPromptChatMemoryAugmentor;
-import org.springframework.ai.chat.memory.VectorStoreChatMemoryChatServiceListener;
-import org.springframework.ai.chat.memory.VectorStoreChatMemoryRetriever;
-import org.springframework.ai.chat.model.ChatModel;
-import org.springframework.ai.chat.prompt.transformer.QuestionContextAugmentor;
-import org.springframework.ai.chat.prompt.transformer.TransformerContentType;
-import org.springframework.ai.chat.prompt.transformer.VectorStoreRetriever;
-import org.springframework.ai.chat.service.ChatService;
-import org.springframework.ai.chat.service.PromptTransformingChatService;
-import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
-import org.springframework.ai.tokenizer.TokenCountEstimator;
-import org.springframework.ai.vectorstore.SearchRequest;
-import org.springframework.ai.vectorstore.VectorStore;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration(proxyBeanMethods = false)
-public class ChatConfig {
-
- @Bean
- ChatMemory chatHistory() {
- return new InMemoryChatMemory();
- }
-
- @Bean
- TokenCountEstimator tokenCountEstimator() {
- return new JTokkitTokenCountEstimator();
- }
-
- @Bean
- ChatService chatService(
- ChatModel chatModel,
- ChatMemory chatMemory,
- TokenCountEstimator tokenCountEstimator,
- VectorStore vectorStore) {
- return PromptTransformingChatService.builder(chatModel)
- .withRetrievers(List.of(
- new VectorStoreRetriever(vectorStore, SearchRequest.defaults()),
- ChatMemoryRetriever.builder()
- .withChatHistory(chatMemory)
- .withMetadata(Map.of(TransformerContentType.SHORT_TERM_MEMORY, ""))
- .build(),
- new VectorStoreChatMemoryRetriever(
- vectorStore, 10, Map.of(TransformerContentType.LONG_TERM_MEMORY, ""))))
- .withContentPostProcessors(List.of(
- new LastMaxTokenSizeContentTransformer(
- tokenCountEstimator, 1000, Set.of(TransformerContentType.SHORT_TERM_MEMORY)),
- new LastMaxTokenSizeContentTransformer(
- tokenCountEstimator, 1000, Set.of(TransformerContentType.LONG_TERM_MEMORY)),
- new LastMaxTokenSizeContentTransformer(
- tokenCountEstimator, 2000, Set.of(TransformerContentType.EXTERNAL_KNOWLEDGE))))
- .withAugmentors(List.of(
- new QuestionContextAugmentor(),
- new SystemPromptChatMemoryAugmentor(
- """
- Use the long term conversation history from the LONG TERM HISTORY section to provide accurate answers.
-
- LONG TERM HISTORY:
- {history}
- """,
- Set.of(TransformerContentType.LONG_TERM_MEMORY)),
- new SystemPromptChatMemoryAugmentor(Set.of(TransformerContentType.SHORT_TERM_MEMORY))))
- .withChatServiceListeners(List.of(
- new ChatMemoryChatServiceListener(chatMemory),
- new VectorStoreChatMemoryChatServiceListener(
- vectorStore, Map.of(TransformerContentType.LONG_TERM_MEMORY, ""))))
- .build();
- }
-}
diff --git a/chatbot-ollama-springai/src/main/java/com/example/chatbot/service/ChatbotService.java b/chatbot-ollama-springai/src/main/java/com/example/chatbot/service/ChatbotService.java
deleted file mode 100644
index 7c828db..0000000
--- a/chatbot-ollama-springai/src/main/java/com/example/chatbot/service/ChatbotService.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.example.chatbot.service;
-
-import com.example.chatbot.model.request.AIChatRequest;
-import com.example.chatbot.model.response.AIChatResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.ai.chat.messages.UserMessage;
-import org.springframework.ai.chat.prompt.Prompt;
-import org.springframework.ai.chat.prompt.transformer.ChatServiceContext;
-import org.springframework.ai.chat.service.ChatService;
-import org.springframework.ai.chat.service.ChatServiceResponse;
-import org.springframework.stereotype.Service;
-
-@Service
-public class ChatbotService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ChatbotService.class);
-
- private final ChatService chatService;
-
- public ChatbotService(ChatService chatService) {
- this.chatService = chatService;
- }
-
- public AIChatResponse chat(AIChatRequest request) {
- Prompt prompt = new Prompt(new UserMessage(request.query()));
- String conversationId = request.conversationId() == null ? "default" : request.conversationId();
- ChatServiceResponse chatServiceResponse = this.chatService.call(new ChatServiceContext(prompt, conversationId));
- LOGGER.info("Response :{}", chatServiceResponse.getChatResponse().getResult());
- return new AIChatResponse(
- chatServiceResponse.getChatResponse().getResult().getOutput().getContent(),
- chatServiceResponse.getPromptContext().getConversationId());
- }
-}
diff --git a/chatbot-ollama-springai/.gitignore b/chatbot/chatbot-ollama-springai/.gitignore
similarity index 100%
rename from chatbot-ollama-springai/.gitignore
rename to chatbot/chatbot-ollama-springai/.gitignore
diff --git a/chatbot-ollama-springai/.mvn/wrapper/maven-wrapper.properties b/chatbot/chatbot-ollama-springai/.mvn/wrapper/maven-wrapper.properties
similarity index 100%
rename from chatbot-ollama-springai/.mvn/wrapper/maven-wrapper.properties
rename to chatbot/chatbot-ollama-springai/.mvn/wrapper/maven-wrapper.properties
diff --git a/chatbot-ollama-springai/ReadMe.md b/chatbot/chatbot-ollama-springai/ReadMe.md
similarity index 100%
rename from chatbot-ollama-springai/ReadMe.md
rename to chatbot/chatbot-ollama-springai/ReadMe.md
diff --git a/chatbot/chatbot-ollama-springai/docker/docker-compose.yml b/chatbot/chatbot-ollama-springai/docker/docker-compose.yml
new file mode 100644
index 0000000..6ec9ab6
--- /dev/null
+++ b/chatbot/chatbot-ollama-springai/docker/docker-compose.yml
@@ -0,0 +1,15 @@
+version: '3.7'
+services:
+ chroma:
+ container_name: chroma
+ image: chromadb/chroma:0.5.0
+ extra_hosts: [ 'host.docker.internal:host-gateway' ]
+ restart: always
+ ports:
+ - "8000:8000"
+ healthcheck:
+ # Adjust below to match your container port
+ test: [ "CMD", "curl", "-f", "http://localhost:8000/api/v1/heartbeat" ]
+ interval: 30s
+ timeout: 10s
+ retries: 3
\ No newline at end of file
diff --git a/chatbot-ollama-springai/mvnw b/chatbot/chatbot-ollama-springai/mvnw
similarity index 100%
rename from chatbot-ollama-springai/mvnw
rename to chatbot/chatbot-ollama-springai/mvnw
diff --git a/chatbot-ollama-springai/mvnw.cmd b/chatbot/chatbot-ollama-springai/mvnw.cmd
similarity index 100%
rename from chatbot-ollama-springai/mvnw.cmd
rename to chatbot/chatbot-ollama-springai/mvnw.cmd
diff --git a/chatbot-ollama-springai/pom.xml b/chatbot/chatbot-ollama-springai/pom.xml
similarity index 70%
rename from chatbot-ollama-springai/pom.xml
rename to chatbot/chatbot-ollama-springai/pom.xml
index 279e116..66b4f2a 100644
--- a/chatbot-ollama-springai/pom.xml
+++ b/chatbot/chatbot-ollama-springai/pom.xml
@@ -18,7 +18,7 @@
21
2.43.0
- 1.0.0-SNAPSHOT
+ 1.0.0-M1
@@ -90,50 +90,50 @@
spring-boot-maven-plugin
- com.diffplug.spotless
- spotless-maven-plugin
- ${spotless.version}
-
-
-
- 2.47.0
-
-
-
-
-
-
-
-
- compile
-
- check
-
-
-
-
-
+ com.diffplug.spotless
+ spotless-maven-plugin
+ ${spotless.version}
+
+
+
+ 2.47.0
+
+
+
+
+
+
+
+
+ compile
+
+ check
+
+
+
+
+
- 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-ollama-springai/src/main/java/com/example/chatbot/ChatbotOllamaApplication.java b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/ChatbotOllamaApplication.java
similarity index 100%
rename from chatbot-ollama-springai/src/main/java/com/example/chatbot/ChatbotOllamaApplication.java
rename to chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/ChatbotOllamaApplication.java
diff --git a/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/config/ChatConfig.java b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/config/ChatConfig.java
new file mode 100644
index 0000000..1fbe4af
--- /dev/null
+++ b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/config/ChatConfig.java
@@ -0,0 +1,31 @@
+package com.example.chatbot.config;
+
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
+import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
+import org.springframework.ai.chat.client.advisor.VectorStoreChatMemoryAdvisor;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.memory.InMemoryChatMemory;
+import org.springframework.ai.vectorstore.SearchRequest;
+import org.springframework.ai.vectorstore.VectorStore;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration(proxyBeanMethods = false)
+public class ChatConfig {
+
+ @Bean
+ ChatMemory chatMemory() {
+ return new InMemoryChatMemory();
+ }
+
+ @Bean
+ ChatClient chatClient(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory, VectorStore vectorStore) {
+ return chatClientBuilder
+ .defaultAdvisors(
+ new MessageChatMemoryAdvisor(chatMemory),
+ new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()), // RAG
+ new VectorStoreChatMemoryAdvisor(vectorStore))
+ .build();
+ }
+}
diff --git a/chatbot-ollama-springai/src/main/java/com/example/chatbot/controller/ChatbotController.java b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/controller/ChatbotController.java
similarity index 100%
rename from chatbot-ollama-springai/src/main/java/com/example/chatbot/controller/ChatbotController.java
rename to chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/controller/ChatbotController.java
diff --git a/chatbot-ollama-springai/src/main/java/com/example/chatbot/model/request/AIChatRequest.java b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/model/request/AIChatRequest.java
similarity index 100%
rename from chatbot-ollama-springai/src/main/java/com/example/chatbot/model/request/AIChatRequest.java
rename to chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/model/request/AIChatRequest.java
diff --git a/chatbot-ollama-springai/src/main/java/com/example/chatbot/model/response/AIChatResponse.java b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/model/response/AIChatResponse.java
similarity index 100%
rename from chatbot-ollama-springai/src/main/java/com/example/chatbot/model/response/AIChatResponse.java
rename to chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/model/response/AIChatResponse.java
diff --git a/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/service/ChatbotService.java b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/service/ChatbotService.java
new file mode 100644
index 0000000..af6e8a5
--- /dev/null
+++ b/chatbot/chatbot-ollama-springai/src/main/java/com/example/chatbot/service/ChatbotService.java
@@ -0,0 +1,37 @@
+package com.example.chatbot.service;
+
+import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
+import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;
+
+import com.example.chatbot.model.request.AIChatRequest;
+import com.example.chatbot.model.response.AIChatResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.model.ChatResponse;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ChatbotService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChatbotService.class);
+
+ private final ChatClient chatClient;
+
+ public ChatbotService(ChatClient chatClient) {
+ this.chatClient = chatClient;
+ }
+
+ public AIChatResponse chat(AIChatRequest request) {
+
+ ChatResponse chatResponse = this.chatClient
+ .prompt()
+ .user(request.query())
+ .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, request.conversationId())
+ .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
+ .call()
+ .chatResponse();
+ LOGGER.info("Response :{}", chatResponse.getResult());
+ return new AIChatResponse(chatResponse.getResult().getOutput().getContent(), request.conversationId());
+ }
+}
diff --git a/chatbot-ollama-springai/src/main/resources/application.properties b/chatbot/chatbot-ollama-springai/src/main/resources/application.properties
similarity index 100%
rename from chatbot-ollama-springai/src/main/resources/application.properties
rename to chatbot/chatbot-ollama-springai/src/main/resources/application.properties
diff --git a/chatbot-ollama-springai/src/test/java/com/example/chatbot/ChatbotOllamaApplicationTests.java b/chatbot/chatbot-ollama-springai/src/test/java/com/example/chatbot/ChatbotOllamaApplicationTests.java
similarity index 86%
rename from chatbot-ollama-springai/src/test/java/com/example/chatbot/ChatbotOllamaApplicationTests.java
rename to chatbot/chatbot-ollama-springai/src/test/java/com/example/chatbot/ChatbotOllamaApplicationTests.java
index bee559e..9de3c62 100644
--- a/chatbot-ollama-springai/src/test/java/com/example/chatbot/ChatbotOllamaApplicationTests.java
+++ b/chatbot/chatbot-ollama-springai/src/test/java/com/example/chatbot/ChatbotOllamaApplicationTests.java
@@ -43,7 +43,7 @@ void chat() throws StreamReadException, DatabindException, IOException {
Response response = given().contentType(ContentType.JSON)
.body(new AIChatRequest(
"As a cricketer, how many centuries did Sachin Tendulkar scored adding up both One Day International (ODI) and Test centuries ?",
- null))
+ "junit1"))
.when()
.post("/api/ai/chat")
.then()
@@ -56,18 +56,15 @@ void chat() throws StreamReadException, DatabindException, IOException {
.response();
AIChatResponse aiChatResponse = objectMapper.readValue(response.asByteArray(), AIChatResponse.class);
- System.out.println("conversationalId :: " + aiChatResponse.conversationId());
given().contentType(ContentType.JSON)
- .body(new AIChatRequest(
- "How many One Day International (ODI) centuries did he scored ?",
- aiChatResponse.conversationId()))
+ .body(new AIChatRequest("Who scored 100 centuries ?", aiChatResponse.conversationId()))
.when()
.post("/api/ai/chat")
.then()
.statusCode(HttpStatus.SC_OK)
.contentType(ContentType.JSON)
- .body("answer", containsString("49"))
+ .body("answer", containsString("Sachin"))
.log()
.all(true);
}
diff --git a/chatbot-ollama-springai/src/test/java/com/example/chatbot/TestChatbotOllamaApplication.java b/chatbot/chatbot-ollama-springai/src/test/java/com/example/chatbot/TestChatbotOllamaApplication.java
similarity index 100%
rename from chatbot-ollama-springai/src/test/java/com/example/chatbot/TestChatbotOllamaApplication.java
rename to chatbot/chatbot-ollama-springai/src/test/java/com/example/chatbot/TestChatbotOllamaApplication.java