Files
kontextwerk/frontend/src/lib/components/chatbotDemo/Chatbot.svelte
robin 02d184585f
Some checks failed
deploy to production / deploy (push) Failing after 9s
zwischenstand
2025-10-06 17:32:05 +00:00

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>