diff --git a/pom.xml b/pom.xml
index 9122f98..2697180 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,14 +11,14 @@
17
- 24.4.0.beta1
- 0.30.0
+ 24.8.6
+ 1.3.0-beta9
org.springframework.boot
spring-boot-starter-parent
- 3.2.5
+ 3.5.4
diff --git a/src/main/java/com/vaadin/demo/AIConfig.java b/src/main/java/com/vaadin/demo/AIConfig.java
index c394b43..727fb54 100644
--- a/src/main/java/com/vaadin/demo/AIConfig.java
+++ b/src/main/java/com/vaadin/demo/AIConfig.java
@@ -4,9 +4,6 @@
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
-import dev.langchain4j.memory.chat.TokenWindowChatMemory;
-import dev.langchain4j.model.Tokenizer;
-import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
@@ -64,7 +61,7 @@ ApplicationRunner docImporter(EmbeddingStore embeddingStore) {
return;
}
log.info("Importing documents from {}", docsLocation);
- var docs = FileSystemDocumentLoader.loadDocuments(docsLocation);
+ var docs = FileSystemDocumentLoader.loadDocumentsRecursively(docsLocation);
EmbeddingStoreIngestor.ingest(docs, embeddingStore);
log.info("Imported {} documents", docs.size());
};
diff --git a/src/main/java/com/vaadin/demo/views/ChatView.java b/src/main/java/com/vaadin/demo/views/ChatView.java
index ce5456a..c4d9950 100644
--- a/src/main/java/com/vaadin/demo/views/ChatView.java
+++ b/src/main/java/com/vaadin/demo/views/ChatView.java
@@ -3,12 +3,13 @@
import com.vaadin.demo.AiAssistant;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.messages.MessageInput;
+import com.vaadin.flow.component.messages.MessageList;
+import com.vaadin.flow.component.messages.MessageListItem;
import com.vaadin.flow.component.orderedlayout.Scroller;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility;
-import org.vaadin.firitin.components.messagelist.MarkdownMessage;
import java.util.UUID;
@@ -16,56 +17,72 @@
@Route(value = "", layout = MainLayout.class)
public class ChatView extends VerticalLayout {
+ private final AiAssistant aiAssistant;
+
+ private final MessageList messageList = new MessageList();
+ private final MessageInput messageInput = new MessageInput();
+ private final Scroller scroller = new Scroller(messageList);
+
private String chatId = UUID.randomUUID().toString();
- private MessageInput messageInput = new MessageInput();
public ChatView(AiAssistant aiAssistant) {
- var newChatButton = new Button("New Chat");
- var messageList = new VerticalLayout();
- focusMessageInput();
-
- setPadding(false);
- setSpacing(false);
- messageList.setSpacing(true);
- messageList.addClassNames(LumoUtility.Padding.Horizontal.SMALL, LumoUtility.Margin.Horizontal.AUTO,
- LumoUtility.MaxWidth.SCREEN_MEDIUM);
+ this.aiAssistant = aiAssistant;
+ var newChatButton = new Button("New Chat");
newChatButton.addClassName("new-chat-button");
newChatButton.addClickListener(e -> {
chatId = UUID.randomUUID().toString();
- messageList.removeAll();
- focusMessageInput();
+ messageList.getItems().clear();
+ messageInput.focus();
});
+ add(newChatButton);
- messageInput.setWidthFull();
- messageInput.addClassNames(LumoUtility.Padding.Horizontal.LARGE, LumoUtility.Padding.Vertical.MEDIUM,
- LumoUtility.Margin.Horizontal.AUTO, LumoUtility.MaxWidth.SCREEN_MEDIUM);
- messageInput.addSubmitListener(e -> {
- var questionText = e.getValue();
- var question = new MarkdownMessage(questionText, "You");
- question.addClassName("you");
- var answer = new MarkdownMessage("Assistant");
- answer.getElement().executeJs("this.scrollIntoView()");
-
- messageList.add(question);
- messageList.add(answer);
+ messageList.addClassNames(LumoUtility.MaxWidth.SCREEN_MEDIUM);
+ messageList.setMarkdown(true);
- aiAssistant.chat(chatId, questionText)
- .onNext(answer::appendMarkdownAsync)
- .onError(err -> System.err.println("ooops" + e))
- .start();
- });
-
- add(newChatButton);
- var scroller = new Scroller(messageList);
+ scroller.addClassNames(LumoUtility.AlignContent.END, LumoUtility.MaxWidth.SCREEN_MEDIUM);
scroller.setWidthFull();
- scroller.addClassName(LumoUtility.AlignContent.END);
addAndExpand(scroller);
+
+ messageInput.addClassNames(LumoUtility.MaxWidth.SCREEN_MEDIUM);
+ messageInput.setWidthFull();
+ messageInput.addSubmitListener(this::onSubmit);
+ messageInput.focus();
add(messageInput);
- }
- private void focusMessageInput() {
- messageInput.getElement().executeJs("requestAnimationFrame(() => this.querySelector('vaadin-text-area').focus() )");
+ setAlignItems(Alignment.CENTER);
+ setPadding(false);
+ setSpacing(false);
}
+ private void onSubmit(MessageInput.SubmitEvent submitEvent) {
+
+ var uiOptional = submitEvent.getSource().getUI();
+
+ var questionText = submitEvent.getValue();
+ var question = new MessageListItem(questionText, "You");
+ question.setUserColorIndex(1);
+ question.addClassNames("you");
+
+ var answer = new MessageListItem("...", "Assistant");
+ answer.setUserColorIndex(0);
+
+ messageList.addItem(question);
+ messageList.addItem(answer);
+
+ aiAssistant.chat(chatId, questionText)
+ .onPartialResponse(answerToken ->
+ uiOptional.ifPresent(ui ->
+ ui.access(() -> {
+ if (answer.getText().equals("..."))
+ answer.setText("");
+ answer.appendText(answerToken);
+ scroller.scrollToBottom();
+ })
+ )
+ )
+ .onError(err -> System.err.println("ooops" + err.toString()))
+ .start();
+
+ }
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index a4061fe..b5dbe94 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -17,7 +17,8 @@ ai.docs.location=/Users/mhellber/Desktop/docs
# OpenAI API
# Better quality, requires sending data to OpenAI
langchain4j.open-ai.streaming-chat-model.api-key=${OPENAI_API_KEY}
-langchain4j.open-ai.streaming-chat-model.model-name=gpt-4o
+langchain4j.open-ai.streaming-chat-model.model-name=gpt-5
+langchain4j.open-ai.streaming-chat-model.temperature=1
# Local OpenAI compatible API (ollama)
# Not as performant, but your data does not leave your computer