basic llm request stream
This commit is contained in:
1 parent
f74e4d1043
commit
a92cc76a9a
66 files changed
+1496
-158
No files matched your search
@@ -1,8 +1,35 @@
|
||||
<div class="container">
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores, reiciendis quo. Quos animi nisi modi cumque hic illo doloremque totam! Distinctio molestias sint magnam illum nostrum eos, fugit aliquid consequuntur?
|
||||
<script lang="ts">
|
||||
import {autofocus} from "$lib/ui/autofocus"
|
||||
import {chatApi} from "$lib/api/endpoints/chat"
|
||||
import type {Chat} from "$lib/types/api"
|
||||
import type { PageProps } from './$types';
|
||||
import { goto } from "$app/navigation";
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
let chat = $state({} as Chat)
|
||||
let prompt = $state("")
|
||||
|
||||
const handleOnSubmit = async () => {
|
||||
chatApi.createChat(data.spaceId, chat)
|
||||
.then((result)=>{
|
||||
goto(`/${data.spaceId}/${result.id}`, {state: {prompt: prompt }})
|
||||
}).catch((err)=>console.log(err))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="h-full w-full flex items-center public">
|
||||
<div class="container">
|
||||
<form class="request flex w-full" onsubmit={handleOnSubmit}>
|
||||
<input
|
||||
class="chatinput w-full flex-1 focus:outline-hidden focus:shadow-none focus:ring-0"
|
||||
type="text"
|
||||
placeholder="Demande ce que tu veux"
|
||||
bind:value={prompt}
|
||||
use:autofocus
|
||||
/>
|
||||
<button class="chatbutton">Go</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,3 +1,8 @@
|
||||
export function load() {
|
||||
return { title: 'Conversation' };
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export const load: PageLoad = ({params}) => {
|
||||
return {
|
||||
title: 'Nouvelle conversation',
|
||||
spaceId : params.space,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<script lang="ts">
|
||||
import {autofocus} from "$lib/ui/autofocus"
|
||||
import { onMount } from "svelte"
|
||||
import {page} from "$app/state"
|
||||
import {chatApi} from "$lib/api/endpoints/chat"
|
||||
import type { PageProps } from './$types';
|
||||
import type { Message, Chunk } from "$lib/types/api"
|
||||
import SvelteMarkdown from '@humanspeak/svelte-markdown'
|
||||
|
||||
let prompt = $state("")
|
||||
let { data }: PageProps = $props();
|
||||
let messages = $state([] as Message[])
|
||||
|
||||
onMount(async ()=>{
|
||||
if (page.state.prompt) {
|
||||
console.log(page.state.prompt)
|
||||
await sendRequest(page.state.prompt)
|
||||
}
|
||||
})
|
||||
|
||||
let historyDiv: HTMLDivElement;
|
||||
$effect(() => {
|
||||
if (historyDiv) {
|
||||
console.log("effect")
|
||||
historyDiv.scrollTop = historyDiv.scrollHeight;
|
||||
}
|
||||
});
|
||||
|
||||
const sendRequest = async(theprompt) => {
|
||||
prompt = ""
|
||||
let lastrole=""
|
||||
for await (const chunk of chatApi.createChatMessage(data.spaceId, data.chatId, { prompt: theprompt })) {
|
||||
if (chunk.role!=lastrole) {
|
||||
const currentDate = new Date()
|
||||
messages.push({
|
||||
id: currentDate.getTime(),
|
||||
role: chunk.role,
|
||||
content: chunk.content,
|
||||
})
|
||||
lastrole=chunk.role
|
||||
} else {
|
||||
messages[messages.length-1].content += chunk.content
|
||||
}
|
||||
historyDiv.scrollTop = historyDiv.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
const handleOnSubmit = async ()=>{
|
||||
await sendRequest(prompt)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="h-full w-full flex flex-col">
|
||||
<div id="history" class="flex-1 container overflow-auto" bind:this={historyDiv}>
|
||||
{#each messages as message (message.id)}
|
||||
<div class={["message", "rounded", message.role]}>
|
||||
<div class="message-content">
|
||||
<SvelteMarkdown source={message.content} />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div id="prompt" class="container">
|
||||
<form class="request flex w-full" onsubmit={handleOnSubmit}>
|
||||
<input
|
||||
class="chatinput w-full flex-1 focus:outline-hidden focus:shadow-none focus:ring-0"
|
||||
type="text"
|
||||
placeholder="..."
|
||||
bind:value={prompt}
|
||||
use:autofocus
|
||||
/>
|
||||
<button class="chatbutton">Go</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export const load: PageLoad = ({params}) => {
|
||||
return {
|
||||
title: 'Nouvelle conversation',
|
||||
spaceId: params.space,
|
||||
chatId: params.conversation,
|
||||
};
|
||||
}
|
||||
@@ -100,7 +100,6 @@
|
||||
let updSpace = space
|
||||
updSpace.defaultAgentId = agentId
|
||||
teamApi.updateSpace(updSpace.id, updSpace).then((newdata)=>{
|
||||
console.log(newdata)
|
||||
spaceState.spaces.map((s)=>s.id===spaceState.current?newdata:s)
|
||||
space=newdata
|
||||
}).catch((err)=>{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { auth, setToken } from '$lib/state/auth.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { authApi } from "$lib/api/endpoints/auth"
|
||||
import { validateEmail } from "$lib/utilities/validators"
|
||||
|
||||
type Credentials = {
|
||||
email: string
|
||||
@@ -17,7 +18,7 @@
|
||||
})
|
||||
|
||||
const formSubmitEmail = () => {
|
||||
credentials.validemail = true
|
||||
credentials.validemail = validateEmail(credentials.email)
|
||||
}
|
||||
|
||||
const formSubmitPass = (e: Event) => {
|
||||
@@ -43,16 +44,16 @@
|
||||
<form onsubmit={formSubmitEmail}>
|
||||
<div class="flex">
|
||||
<label for="email" class="block mb-2 flex-1">Email</label>
|
||||
<a href="/recover-password" class="text-xs">Mot de passe oublié ?</a>
|
||||
<a href="/recover-password" class="text-xs ">Mot de passe oublié ?</a>
|
||||
</div>
|
||||
<div class="flex flex-row">
|
||||
<input
|
||||
type="text"
|
||||
bind:value={credentials.email}
|
||||
class="textinput mr-1"
|
||||
class="textinput mr-1 flex-1"
|
||||
autofocus
|
||||
/>
|
||||
<button class="bt" title="page suivante">
|
||||
<button class="bt small" title="page suivante">
|
||||
<i class="icon-right-big"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -72,10 +73,10 @@
|
||||
<input
|
||||
type="password"
|
||||
bind:value={credentials.password}
|
||||
class="textinput mr-1"
|
||||
class="textinput mr-1 flex-1"
|
||||
autofocus
|
||||
/>
|
||||
<button class="bt">
|
||||
<button class="bt small">
|
||||
Entrer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ body {
|
||||
@apply h-full bg-stone-100 text-stone-950 dark:bg-stone-950 dark:text-stone-100;
|
||||
}
|
||||
|
||||
.formelement > label {
|
||||
label {
|
||||
@apply text-xs text-stone-600 uppercase dark:text-stone-400;
|
||||
}
|
||||
hr {
|
||||
@@ -30,9 +30,9 @@ h2 {
|
||||
}
|
||||
.bt {
|
||||
appearance: button;
|
||||
@apply min-w-40 cursor-pointer rounded bg-stone-300 px-4 py-1 transition-all duration-300 hover:bg-stone-200 dark:bg-stone-800 dark:hover:bg-stone-700;
|
||||
@apply min-w-40 cursor-pointer rounded bg-stone-300 px-4 py-1 transition-all duration-300 hover:bg-stone-400 dark:bg-stone-800 dark:hover:bg-stone-700;
|
||||
&.small {
|
||||
@apply min-w-0 px-2 py-1;
|
||||
@apply min-w-2 px-2 py-1;
|
||||
}
|
||||
&.changed,
|
||||
&.saving {
|
||||
@@ -62,10 +62,12 @@ h2 {
|
||||
.public h1 {
|
||||
@apply mb-4 text-3xl font-bold;
|
||||
}
|
||||
.profile a,
|
||||
.public a {
|
||||
.profile a {
|
||||
@apply bg-sky-300 dark:bg-sky-700;
|
||||
}
|
||||
.public a {
|
||||
@apply text-sky-500 dark:text-sky-500;
|
||||
}
|
||||
|
||||
#outer {
|
||||
@apply flex h-full flex-row;
|
||||
@@ -113,10 +115,18 @@ h2 {
|
||||
}
|
||||
}
|
||||
|
||||
.chatinput {
|
||||
@apply w-full rounded-l-xl border-stone-300 bg-stone-50 p-2 text-stone-900 dark:border-stone-700 dark:bg-stone-900 dark:text-stone-100;
|
||||
}
|
||||
|
||||
.chatbutton {
|
||||
@apply min-w-12 cursor-pointer rounded-r-xl bg-stone-300 px-2 py-1 transition-all duration-300 hover:bg-stone-400 dark:bg-stone-700 dark:hover:bg-stone-600;
|
||||
}
|
||||
|
||||
/* form */
|
||||
|
||||
.formgroup {
|
||||
@apply rounded border border-stone-300 bg-stone-100 p-2 text-sm dark:border-stone-700 dark:bg-stone-900;
|
||||
@apply rounded border border-stone-300 bg-stone-200 p-2 text-sm dark:border-stone-700 dark:bg-stone-900;
|
||||
}
|
||||
|
||||
.formelement {
|
||||
@@ -124,11 +134,11 @@ h2 {
|
||||
}
|
||||
|
||||
.textinput {
|
||||
@apply h-8 w-full rounded border-stone-700 bg-stone-50 px-2 py-1 text-sm text-stone-900 dark:bg-stone-950 dark:text-stone-100;
|
||||
@apply h-8 w-full rounded border-stone-300 bg-stone-50 px-2 py-1 text-sm text-stone-900 dark:border-stone-700 dark:bg-stone-950 dark:text-stone-100;
|
||||
}
|
||||
|
||||
.areainput {
|
||||
@apply w-full rounded border-stone-700 bg-stone-50 px-2 py-1 text-sm text-stone-900 dark:bg-stone-950 dark:text-stone-100;
|
||||
@apply w-full rounded border-stone-300 bg-stone-50 px-2 py-1 text-sm text-stone-900 dark:bg-stone-950 dark:text-stone-100;
|
||||
}
|
||||
|
||||
/* svelte select */
|
||||
@@ -261,3 +271,31 @@ h2 {
|
||||
.list-item {
|
||||
@apply list-none;
|
||||
}
|
||||
|
||||
/* chat */
|
||||
|
||||
.message {
|
||||
@apply m-2 rounded p-2;
|
||||
|
||||
&.user {
|
||||
@apply bg-sky-500 dark:text-white;
|
||||
}
|
||||
|
||||
&.assistant {
|
||||
&.reasoning {
|
||||
@apply text-white/50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-content {
|
||||
@apply text-sm;
|
||||
}
|
||||
|
||||
.message-content p {
|
||||
@apply my-2;
|
||||
}
|
||||
|
||||
.message-content pre {
|
||||
@apply my-2 whitespace-pre dark:bg-stone-700;
|
||||
}
|
||||
Reference in new issue
Block a user