feat: add another component that can render md
This commit is contained in:
parent
af32f2d02f
commit
1033f49c8e
84
.m2/settings.xml
Normal file
84
.m2/settings.xml
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
|
||||||
|
|
||||||
|
<interactiveMode>false</interactiveMode>
|
||||||
|
|
||||||
|
<servers>
|
||||||
|
<server>
|
||||||
|
<id>dvb</id>
|
||||||
|
<username>${env.NEXUS2_DEPLOYMENT_USER}</username>
|
||||||
|
<password>${env.NEXUS2_DEPLOYMENT_PASSWORD}</password>
|
||||||
|
</server>
|
||||||
|
<server>
|
||||||
|
<id>dvb.snapshots</id>
|
||||||
|
<username>${env.NEXUS2_DEPLOYMENT_USER}</username>
|
||||||
|
<password>${env.NEXUS2_DEPLOYMENT_PASSWORD}</password>
|
||||||
|
</server>
|
||||||
|
</servers>
|
||||||
|
|
||||||
|
<mirrors>
|
||||||
|
<mirror>
|
||||||
|
<id>dvbern.nexus</id>
|
||||||
|
<mirrorOf>*</mirrorOf>
|
||||||
|
<name>DV Bern NEXUS Repository Mirror</name>
|
||||||
|
<url>https://nexus.dvbern.ch/nexus/content/groups/allrepos/</url>
|
||||||
|
</mirror>
|
||||||
|
</mirrors>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>dvbern.nexus</id>
|
||||||
|
<properties>
|
||||||
|
<maven.repo.releases.url>https://nexus.dvbern.ch/nexus/content/repositories/dvb/</maven.repo.releases.url>
|
||||||
|
<maven.repo.snapshots.url>https://nexus.dvbern.ch/nexus/content/repositories/dvb.snapshots/</maven.repo.snapshots.url>
|
||||||
|
</properties>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>central</id>
|
||||||
|
<url>http://central</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>central</id>
|
||||||
|
<url>http://central</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>mvnpm-repo</id>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>central</id>
|
||||||
|
<name>central</name>
|
||||||
|
<url>https://repo.maven.apache.org/maven2</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
<id>mvnpm.org</id>
|
||||||
|
<name>mvnpm</name>
|
||||||
|
<url>https://repo.mvnpm.org/maven2</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<activeProfiles>
|
||||||
|
<activeProfile>mvnpm-repo</activeProfile>
|
||||||
|
<!-- <activeProfile>dvbern.nexus</activeProfile>-->
|
||||||
|
</activeProfiles>
|
||||||
|
</settings>
|
||||||
6
pom.xml
6
pom.xml
@ -76,6 +76,12 @@
|
|||||||
<version>0.2.1</version>
|
<version>0.2.1</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>org.mvnpm</groupId>-->
|
||||||
|
<!-- <artifactId>deep-chat</artifactId>-->
|
||||||
|
<!-- <version>2.1.1</version>-->
|
||||||
|
<!-- <scope>runtime</scope>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.quarkiverse.langchain4j</groupId>
|
<groupId>io.quarkiverse.langchain4j</groupId>
|
||||||
<artifactId>quarkus-langchain4j-easy-rag</artifactId>
|
<artifactId>quarkus-langchain4j-easy-rag</artifactId>
|
||||||
|
|||||||
@ -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<String> chat(String userMessage);
|
||||||
|
}
|
||||||
@ -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<DeepChatTextResponse> onTextMessage(String message) {
|
||||||
|
return deepChatSupportAgent.chat(message).map(text -> new DeepChatTextResponse(text, false));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,33 +26,8 @@ export class DemoChat extends LitElement {
|
|||||||
|
|
||||||
const that = this;
|
const that = this;
|
||||||
socket.onmessage = function (event) {
|
socket.onmessage = function (event) {
|
||||||
chatBot.hideLastLoading();
|
that.addToWsChat(chatBot, event, that);
|
||||||
// LLM response
|
// this.addToDeepchat()
|
||||||
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"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chatBot.addEventListener("sent", function (e) {
|
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);
|
customElements.define('demo-chat', DemoChat);
|
||||||
@ -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);
|
||||||
@ -6,11 +6,16 @@
|
|||||||
<link rel="shortcut icon" type="image/png" href="favicon.ico">
|
<link rel="shortcut icon" type="image/png" href="favicon.ico">
|
||||||
|
|
||||||
<script src="/_importmap/dynamic-importmap.js"></script>
|
<script src="/_importmap/dynamic-importmap.js"></script>
|
||||||
|
<script
|
||||||
|
type="module"
|
||||||
|
src="https://unpkg.com/deep-chat@2.1.1/dist/deepChat.bundle.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import 'icons/font-awesome.js';
|
import 'icons/font-awesome.js';
|
||||||
import 'components/demo-title.js';
|
import 'components/demo-title.js';
|
||||||
import 'components/demo-chat.js';
|
import 'components/demo-chat.js';
|
||||||
|
import 'components/demo-deep-chat.js';
|
||||||
import 'wc-chatbot';
|
import 'wc-chatbot';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -71,12 +76,32 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<!--<deep-chat stream="true" connect='{"url": "ws://localhost:8080/deep-chat-support-agent", "websocket": true}'></deep-chat>-->
|
||||||
|
<!--<deep-chat avatars="true"></deep-chat>-->
|
||||||
|
<!--<deep-chat connect='{"url": "http://localhost:8686/openai-chat-stream", "stream": true}'></deep-chat>-->
|
||||||
|
<!--<deep-chat connect='{"stream": {"simulation": 6}}'></deep-chat>-->
|
||||||
|
<!--<deep-chat-->
|
||||||
|
<!-- remarkable='{"html": true, "typographer": true}'-->
|
||||||
|
<!-- history='[-->
|
||||||
|
<!-- {"text": "Text containing <button>html</button>", "role": "user"},-->
|
||||||
|
<!-- {"text": "Typographic text: (c)", "role": "user"},-->
|
||||||
|
<!-- {"text": " # title \n- list1", "role": "user"}-->
|
||||||
|
|
||||||
|
<!--]'-->
|
||||||
|
<!-- style="border-radius: 8px"-->
|
||||||
|
<!-- demo="true"-->
|
||||||
|
|
||||||
|
<!--></deep-chat>-->
|
||||||
|
|
||||||
<demo-title></demo-title>
|
<demo-title></demo-title>
|
||||||
|
|
||||||
<div class="middle">
|
<div class="middle">
|
||||||
<demo-chat>
|
<demo-chat>
|
||||||
<chat-bot></chat-bot>
|
<chat-bot></chat-bot>
|
||||||
</demo-chat>
|
</demo-chat>
|
||||||
|
<demo-deep-chat>
|
||||||
|
<deep-chat></deep-chat>
|
||||||
|
</demo-deep-chat>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user