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>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.mvnpm</groupId>-->
|
||||
<!-- <artifactId>deep-chat</artifactId>-->
|
||||
<!-- <version>2.1.1</version>-->
|
||||
<!-- <scope>runtime</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>io.quarkiverse.langchain4j</groupId>
|
||||
<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;
|
||||
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);
|
||||
@ -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">
|
||||
|
||||
<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">
|
||||
import 'icons/font-awesome.js';
|
||||
import 'components/demo-title.js';
|
||||
import 'components/demo-chat.js';
|
||||
import 'components/demo-deep-chat.js';
|
||||
import 'wc-chatbot';
|
||||
</script>
|
||||
|
||||
@ -71,12 +76,32 @@
|
||||
|
||||
<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>
|
||||
|
||||
<div class="middle">
|
||||
<demo-chat>
|
||||
<chat-bot></chat-bot>
|
||||
</demo-chat>
|
||||
<demo-deep-chat>
|
||||
<deep-chat></deep-chat>
|
||||
</demo-deep-chat>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user