90 lines
2.6 KiB
Svelte
90 lines
2.6 KiB
Svelte
<script lang="ts">
|
|
import { onDestroy } from "svelte"
|
|
import { WerkChatSession, type ChatMessage } from "@kontextwerk/web-sdk"
|
|
import InputRow from "./InputRow.svelte"
|
|
import Messages from "./Messages.svelte"
|
|
function generateUniqueId() {
|
|
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
|
|
}
|
|
let chat: WerkChatSession
|
|
let messages = $state<ChatMessage[]>([])
|
|
let isStreaming = $state(false)
|
|
|
|
const refreshFromSession = () => {
|
|
if (!chat) return
|
|
messages = [...chat.messages]
|
|
isStreaming = chat.isStreaming
|
|
}
|
|
|
|
const createSession = () =>
|
|
new WerkChatSession(generateUniqueId(), {
|
|
url: "https://2schat-server.kontextwerk.info/api/v1/chatbot/stream",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
events: {
|
|
onOpen: refreshFromSession,
|
|
onToken: refreshFromSession,
|
|
onHeartbeat: refreshFromSession,
|
|
onFinal: refreshFromSession,
|
|
onError: refreshFromSession,
|
|
onEvent: refreshFromSession,
|
|
},
|
|
})
|
|
|
|
chat = createSession()
|
|
refreshFromSession()
|
|
|
|
const sendMessage = (text: string) => {
|
|
const trimmed = text.trim()
|
|
if (!trimmed || !chat) return
|
|
const promise = chat.generateResponse(trimmed)
|
|
refreshFromSession()
|
|
void promise
|
|
.catch((err) => {
|
|
console.error("Chat response failed", err)
|
|
})
|
|
.finally(() => {
|
|
refreshFromSession()
|
|
})
|
|
}
|
|
|
|
onDestroy(() => {
|
|
chat?.abortActiveStream?.()
|
|
})
|
|
</script>
|
|
|
|
<div class="chat-wrapper">
|
|
<Messages
|
|
{messages}
|
|
streaming={isStreaming}
|
|
/>
|
|
<InputRow
|
|
onSend={sendMessage}
|
|
disabled={isStreaming}
|
|
quickMessages={messages.length
|
|
? []
|
|
: [
|
|
{
|
|
title: "Erzähl mir was über",
|
|
highlight: "Kontextwerk",
|
|
message: "Erzähl mir bitte mehr über Kontextwerk.",
|
|
},
|
|
{
|
|
title: "Ich möchte euch",
|
|
highlight: "kontaktieren",
|
|
message: "Ich möchte euch kontaktieren. Welche Möglichkeiten gibt es?",
|
|
},
|
|
]}
|
|
/>
|
|
</div>
|
|
|
|
<style lang="less">
|
|
.chat-wrapper {
|
|
min-height: 400px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
</style>
|