diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 91b29738..033b4388 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -6,17 +6,19 @@ import type { PageData } from './$types'; import { ENDPOINT } from '$lib/contants'; + import { tick } from 'svelte'; export let data: PageData; $: ({ models } = data); + let textareaElement; let selectedModel = ''; let prompt = ''; - let context = ''; + let messages = []; - let chatHistory = {}; - - let textareaElement = ''; + ////////////////////////// + // Helper functions + ////////////////////////// const splitStream = (splitOn) => { let buffer = ''; @@ -33,93 +35,6 @@ }); }; - const submitPrompt = async () => { - console.log('submitPrompt'); - - if (selectedModel === '') { - toast.error('Model not selected'); - } else if ( - Object.keys(chatHistory).length != 0 && - chatHistory[Object.keys(chatHistory).length - 1].done != true - ) { - console.log('wait'); - } else { - console.log(prompt); - - let user_prompt = prompt; - - chatHistory[Object.keys(chatHistory).length] = { - role: 'user', - content: user_prompt - }; - - prompt = ''; - textareaElement.style.height = ''; - - setTimeout(() => { - window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); - }, 50); - - chatHistory[Object.keys(chatHistory).length] = { - role: 'assistant', - content: '' - }; - window.scrollTo({ top: document.body.scrollHeight }); - - const res = await fetch(`${ENDPOINT}/api/generate`, { - method: 'POST', - headers: { - 'Content-Type': 'text/event-stream' - }, - body: JSON.stringify({ - model: selectedModel, - prompt: user_prompt, - context: context != '' ? context : undefined - }) - }); - - const reader = res.body - .pipeThrough(new TextDecoderStream()) - .pipeThrough(splitStream('\n')) - .getReader(); - while (true) { - const { value, done } = await reader.read(); - if (done) break; - - try { - let lines = value.split('\n'); - - for (const line of lines) { - if (line !== '') { - console.log(line); - let data = JSON.parse(line); - - if (data.done == false) { - if ( - chatHistory[Object.keys(chatHistory).length - 1].content == '' && - data.response == '\n' - ) { - continue; - } else { - chatHistory[Object.keys(chatHistory).length - 1].content += data.response; - } - } else { - context = data.context; - console.log(context); - chatHistory[Object.keys(chatHistory).length - 1].done = true; - } - } - } - } catch (error) { - console.log(error); - } - window.scrollTo({ top: document.body.scrollHeight }); - } - - window.scrollTo({ top: document.body.scrollHeight }); - } - }; - const copyToClipboard = (text) => { if (!navigator.clipboard) { var textArea = document.createElement('textarea'); @@ -155,6 +70,172 @@ } ); }; + + ////////////////////////// + // Ollama functions + ////////////////////////// + + const submitPrompt = async () => { + console.log('submitPrompt'); + + if (selectedModel === '') { + toast.error('Model not selected'); + } else if (messages.length != 0 && messages.at(-1).done != true) { + console.log('wait'); + } else { + console.log(prompt); + + let user_prompt = prompt; + messages = [ + ...messages, + { + role: 'user', + content: user_prompt + } + ]; + prompt = ''; + + textareaElement.style.height = ''; + setTimeout(() => { + window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); + }, 50); + + let responseMessage = { + role: 'assistant', + content: '' + }; + + messages = [...messages, responseMessage]; + window.scrollTo({ top: document.body.scrollHeight }); + + const res = await fetch(`${ENDPOINT}/api/generate`, { + method: 'POST', + headers: { + 'Content-Type': 'text/event-stream' + }, + body: JSON.stringify({ + model: selectedModel, + prompt: user_prompt, + context: + messages.length > 3 && messages.at(-3).context != undefined + ? messages.at(-3).context + : undefined + }) + }); + + const reader = res.body + .pipeThrough(new TextDecoderStream()) + .pipeThrough(splitStream('\n')) + .getReader(); + + while (true) { + const { value, done } = await reader.read(); + if (done) break; + + try { + let lines = value.split('\n'); + + for (const line of lines) { + if (line !== '') { + console.log(line); + let data = JSON.parse(line); + if (data.done == false) { + if (responseMessage.content == '' && data.response == '\n') { + continue; + } else { + responseMessage.content += data.response; + messages = messages; + } + } else { + responseMessage.done = true; + responseMessage.context = data.context; + messages = messages; + } + } + } + } catch (error) { + console.log(error); + } + window.scrollTo({ top: document.body.scrollHeight }); + } + + window.scrollTo({ top: document.body.scrollHeight }); + } + }; + + const regenerateResponse = async () => { + console.log('regenerateResponse'); + + if (messages.length != 0 && messages.at(-1).done == true) { + messages.splice(messages.length - 1, 1); + messages = messages; + + let lastUserMessage = messages.at(-1); + + let responseMessage = { + role: 'assistant', + content: '' + }; + + messages = [...messages, responseMessage]; + window.scrollTo({ top: document.body.scrollHeight }); + + const res = await fetch(`${ENDPOINT}/api/generate`, { + method: 'POST', + headers: { + 'Content-Type': 'text/event-stream' + }, + body: JSON.stringify({ + model: selectedModel, + prompt: lastUserMessage.content, + context: + messages.length > 3 && messages.at(-3).context != undefined + ? messages.at(-3).context + : undefined + }) + }); + + const reader = res.body + .pipeThrough(new TextDecoderStream()) + .pipeThrough(splitStream('\n')) + .getReader(); + + while (true) { + const { value, done } = await reader.read(); + if (done) break; + + try { + let lines = value.split('\n'); + + for (const line of lines) { + if (line !== '') { + console.log(line); + let data = JSON.parse(line); + if (data.done == false) { + if (responseMessage.content == '' && data.response == '\n') { + continue; + } else { + responseMessage.content += data.response; + messages = messages; + } + } else { + responseMessage.done = true; + responseMessage.context = data.context; + messages = messages; + } + } + } + } catch (error) { + console.log(error); + } + window.scrollTo({ top: document.body.scrollHeight }); + } + + window.scrollTo({ top: document.body.scrollHeight }); + } + + console.log(messages); + };
@@ -171,7 +252,7 @@ id="models" class="outline-none border border-gray-600 bg-gray-700 text-gray-200 text-sm rounded-lg block w-full p-2.5 placeholder-gray-400" bind:value={selectedModel} - disabled={Object.keys(chatHistory).length != 0} + disabled={messages.length != 0} > @@ -183,8 +264,8 @@
-
- {#if Object.keys(chatHistory).length == 0} +
+ {#if messages.length == 0}
@@ -198,18 +279,18 @@
{:else} - {#each Object.keys(chatHistory) as messageIdx} -
+ {#each messages as message, messageIdx} +
- {#if chatHistory[messageIdx].role != 'user' && chatHistory[messageIdx].content == ''} + {#if message.role != 'user' && message.content == ''}
@@ -231,18 +312,18 @@
{:else}
- {@html marked.parse(chatHistory[messageIdx].content)} + {@html marked.parse(message.content)}
{/if}
- {#if chatHistory[messageIdx].role != 'user' && chatHistory[messageIdx].done} + {#if message.role != 'user' && message.done} +
+ {/if}