diff --git a/.m2/settings.xml b/.m2/settings.xml new file mode 100644 index 0000000..3c5ffa4 --- /dev/null +++ b/.m2/settings.xml @@ -0,0 +1,84 @@ + + + + false + + + + dvb + ${env.NEXUS2_DEPLOYMENT_USER} + ${env.NEXUS2_DEPLOYMENT_PASSWORD} + + + dvb.snapshots + ${env.NEXUS2_DEPLOYMENT_USER} + ${env.NEXUS2_DEPLOYMENT_PASSWORD} + + + + + + dvbern.nexus + * + DV Bern NEXUS Repository Mirror + https://nexus.dvbern.ch/nexus/content/groups/allrepos/ + + + + + + dvbern.nexus + + https://nexus.dvbern.ch/nexus/content/repositories/dvb/ + https://nexus.dvbern.ch/nexus/content/repositories/dvb.snapshots/ + + + + central + http://central + + true + + + true + + + + + + central + http://central + + true + + + true + + + + + + mvnpm-repo + + + central + central + https://repo.maven.apache.org/maven2 + + + + false + + mvnpm.org + mvnpm + https://repo.mvnpm.org/maven2 + + + + + + + mvnpm-repo + + + diff --git a/pom.xml b/pom.xml index a826436..19a25d1 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,12 @@ 0.2.1 runtime + + + + + + io.quarkiverse.langchain4j quarkus-langchain4j-easy-rag diff --git a/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatSupportAgent.java b/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatSupportAgent.java new file mode 100644 index 0000000..3bc5bea --- /dev/null +++ b/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatSupportAgent.java @@ -0,0 +1,18 @@ +package dev.langchain4j.quarkus.workshop.deepchat; + +import dev.langchain4j.service.SystemMessage; +import io.quarkiverse.langchain4j.RegisterAiService; +import io.smallrye.mutiny.Multi; +import jakarta.enterprise.context.SessionScoped; + +@SessionScoped +@RegisterAiService +public interface DeepChatSupportAgent { + + @SystemMessage(""" + You are a customer support agent of the vaccination application 'vacme'. + You are friendly, polite and concise. + If the question is unrelated to the login process or the usage of the vacme page, you should politely redirect the customer to the support email. + """) + Multi chat(String userMessage); +} diff --git a/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatSupportAgentWebSocket.java b/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatSupportAgentWebSocket.java new file mode 100644 index 0000000..e6aff30 --- /dev/null +++ b/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatSupportAgentWebSocket.java @@ -0,0 +1,28 @@ +package dev.langchain4j.quarkus.workshop.deepchat; + +import io.quarkus.websockets.next.OnOpen; +import io.quarkus.websockets.next.OnTextMessage; +import io.quarkus.websockets.next.WebSocket; +import io.smallrye.mutiny.Multi; +import jakarta.inject.Inject; + +@WebSocket(path = "/deep-chat-support-agent") +public class DeepChatSupportAgentWebSocket { + + private final DeepChatSupportAgent deepChatSupportAgent; + @Inject + public DeepChatSupportAgentWebSocket(DeepChatSupportAgent deepChatSupportAgent) { + this.deepChatSupportAgent = deepChatSupportAgent; + } + @OnOpen + public DeepChatTextResponse onOpen() { + return new DeepChatTextResponse("Willkommen beim Vacme Support! Wie kann ich Ihnen Heute helfen?", false); + } + + @OnTextMessage + public Multi onTextMessage(String message) { + return deepChatSupportAgent.chat(message).map(text -> new DeepChatTextResponse(text, false)); + + } + +} diff --git a/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatTextResponse.java b/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatTextResponse.java new file mode 100644 index 0000000..74b3499 --- /dev/null +++ b/src/main/java/dev/langchain4j/quarkus/workshop/deepchat/DeepChatTextResponse.java @@ -0,0 +1,8 @@ +package dev.langchain4j.quarkus.workshop.deepchat; + +public record DeepChatTextResponse(String text, boolean overwrite) { + public DeepChatTextResponse(String text, boolean overwrite) { + this.text = text; + this.overwrite = overwrite; + } +} diff --git a/src/main/resources/META-INF/resources/components/demo-chat.js b/src/main/resources/META-INF/resources/components/demo-chat.js index 1781385..ecfeb52 100644 --- a/src/main/resources/META-INF/resources/components/demo-chat.js +++ b/src/main/resources/META-INF/resources/components/demo-chat.js @@ -26,33 +26,8 @@ export class DemoChat extends LitElement { const that = this; socket.onmessage = function (event) { - chatBot.hideLastLoading(); - // LLM response - let lastMessage; - if (chatBot.messages.length > 0) { - lastMessage = chatBot.messages[chatBot.messages.length - 1]; - } - if (lastMessage && lastMessage.sender.name === "Bot" && ! lastMessage.loading) { - if (! lastMessage.msg) { - lastMessage.msg = ""; - } - lastMessage.msg += event.data; - let bubbles = chatBot.shadowRoot.querySelectorAll("chat-bubble"); - let bubble = bubbles.item(bubbles.length - 1); - if (lastMessage.message) { - bubble.innerHTML = that._stripHtml(lastMessage.message) + lastMessage.msg; - } else { - bubble.innerHTML = lastMessage.msg; - } - chatBot.body.scrollTo({ top: chatBot.body.scrollHeight, behavior: 'smooth' }) - } else { - chatBot.sendMessage(event.data, { - right: false, - sender: { - name: "Bot" - } - }); - } + that.addToWsChat(chatBot, event, that); + // this.addToDeepchat() } chatBot.addEventListener("sent", function (e) { @@ -68,7 +43,35 @@ export class DemoChat extends LitElement { }); } - + addToWsChat(chatBot, event, that) { + chatBot.hideLastLoading(); + // LLM response + let lastMessage; + if (chatBot.messages.length > 0) { + lastMessage = chatBot.messages[chatBot.messages.length - 1]; + } + if (lastMessage && lastMessage.sender.name === "Bot" && !lastMessage.loading) { + if (!lastMessage.msg) { + lastMessage.msg = ""; + } + lastMessage.msg += event.data; + let bubbles = chatBot.shadowRoot.querySelectorAll("chat-bubble"); + let bubble = bubbles.item(bubbles.length - 1); + if (lastMessage.message) { + bubble.innerHTML = that._stripHtml(lastMessage.message) + lastMessage.msg; + } else { + bubble.innerHTML = lastMessage.msg; + } + chatBot.body.scrollTo({top: chatBot.body.scrollHeight, behavior: 'smooth'}) + } else { + chatBot.sendMessage(event.data, { + right: false, + sender: { + name: "Bot" + } + }); + } + } } customElements.define('demo-chat', DemoChat); \ No newline at end of file diff --git a/src/main/resources/META-INF/resources/components/demo-deep-chat.js b/src/main/resources/META-INF/resources/components/demo-deep-chat.js new file mode 100644 index 0000000..b762e7b --- /dev/null +++ b/src/main/resources/META-INF/resources/components/demo-deep-chat.js @@ -0,0 +1,66 @@ +import {css, LitElement} from 'lit'; +import '@vaadin/icon'; +import '@vaadin/button'; +import '@vaadin/text-field'; +import '@vaadin/text-area'; +import '@vaadin/form-layout'; +import '@vaadin/progress-bar'; +import '@vaadin/checkbox'; +import '@vaadin/horizontal-layout'; +import '@vaadin/grid'; +import '@vaadin/grid/vaadin-grid-sort-column.js'; + +export class DemoChat extends LitElement { + + _stripHtml(html) { + const div = document.createElement("div"); + div.innerHTML = html; + return div.textContent || div.innerText || ""; + } + + connectedCallback() { + + const chatElementRef = document.getElementsByTagName("deep-chat")[0]; + const protocol = (window.location.protocol === 'https:') ? 'wss' : 'ws'; + + const websocket = new WebSocket(protocol + '://' + window.location.host + '/customer-support-agent'); + // this handler is invoked when the component is loaded + + chatElementRef.onMessage = (body) => { + if (body.message && body.message.role === 'user') { + websocket.send(body.message.text); + }}; + + chatElementRef.connect = { + stream: true, + + handler: (_, signals) => { + try { + + signals.onOpen(); // enables the user to send messages + + websocket.onmessage = (message) => { + signals.onResponse({text: message.data}); + }; + websocket.onclose = () => { + signals.onClose(); // stops the user from sending messages + }; + websocket.onerror = () => { + // 'Connection error' is a special string that will also display in Deep Chat + signals.onResponse({error: 'Connection error'}); + }; + // triggered when the user sends a message + // signals.newUserMessage.listener = (body) => { + // websocket.send(JSON.stringify(body)); + // }; + } catch (e) { + signals.onResponse({error: 'error'}); // displays an error message + signals.onClose(); // stops the user from sending messages + } + }, + }; + } +} + + +customElements.define('demo-deep-chat', DemoChat); \ No newline at end of file diff --git a/src/main/resources/META-INF/resources/index.html b/src/main/resources/META-INF/resources/index.html index 9eb1b64..a9b8248 100644 --- a/src/main/resources/META-INF/resources/index.html +++ b/src/main/resources/META-INF/resources/index.html @@ -6,11 +6,16 @@ + @@ -71,12 +76,32 @@ + + + + + + + + + + + + + + + + +
+ + +