File size: 4,949 Bytes
ef5513c
793c54c
ef5513c
16c33b0
a3ae6ee
62db40f
793c54c
 
 
 
 
 
 
669277f
793c54c
 
 
ef5513c
a3ae6ee
ef5513c
 
f61a0be
 
 
 
 
 
ef5513c
 
 
 
 
793c54c
 
 
 
 
82ab608
ef5513c
62db40f
82ab608
ef5513c
 
 
82ab608
793c54c
 
 
 
 
 
ef5513c
 
 
61504f4
ef5513c
82ab608
 
 
 
 
 
 
793c54c
ef5513c
 
 
 
793c54c
ef5513c
 
 
 
 
62db40f
ef5513c
62db40f
 
 
 
ef5513c
 
 
 
 
663005a
 
 
a3ae6ee
663005a
a3ae6ee
1dc44c8
663005a
793c54c
663005a
 
 
0f32539
 
1dc44c8
663005a
 
 
 
1dc44c8
0f32539
 
 
 
663005a
 
 
 
ec8d856
 
663005a
 
 
 
ec8d856
 
0f32539
1a39133
ec8d856
f61a0be
ec8d856
 
 
 
bd8c7a0
ec8d856
663005a
ec8d856
b4899ca
ec8d856
663005a
7e19a85
ec8d856
ef5513c
663005a
ec8d856
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b4899ca
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
<script lang="ts">
	import { afterUpdate } from 'svelte';
	import { fetchEventSource } from '@microsoft/fetch-event-source';
	import ChatBox from '$lib/chat/ChatBox.svelte';
	import ChatIntroduction from '$lib/chat/ChatIntroduction.svelte';
	import type { Message, StreamResponse } from '$lib/Types';
	import {
		PUBLIC_ASSISTANT_MESSAGE_TOKEN,
		PUBLIC_ENDPOINT,
		PUBLIC_HF_TOKEN,
		PUBLIC_SEP_TOKEN,
		PUBLIC_USER_MESSAGE_TOKEN
	} from '$env/static/public';

	const userToken = PUBLIC_USER_MESSAGE_TOKEN || '<|prompter|>';
	const assistantToken = PUBLIC_ASSISTANT_MESSAGE_TOKEN || '<|assistant|>';
	const sepToken = PUBLIC_SEP_TOKEN || '<|endoftext|>';

	let messages: Message[] = [];
	let message = '';

	let messagesContainer: HTMLElement;

	afterUpdate(() => {
		messagesContainer.scrollTo(0, messagesContainer.scrollHeight);
	});

	function onWrite() {
		messages = [...messages, { from: 'user', content: message }];
		message = '';
		const inputs =
			messages
				.map(
					(m) =>
						(m.from === 'user' ? userToken + m.content : assistantToken + m.content) +
						(m.content.endsWith(sepToken) ? '' : sepToken)
				)
				.join('') + assistantToken;

		console.log(inputs);
		fetchEventSource(PUBLIC_ENDPOINT, {
			method: 'POST',
			headers: {
				Accept: 'text/event-stream',
				'Content-Type': 'application/json',
				'user-agent': 'chat-ui/0.0.1',
				...(PUBLIC_HF_TOKEN
					? {
							authorization: `Bearer ${PUBLIC_HF_TOKEN}`
					  }
					: {})
			},
			body: JSON.stringify({
				inputs: inputs,
				stream: true,
				parameters: {
					do_sample: false,
					max_new_tokens: 500,
					return_full_text: false,
					stop: [],
					truncate: 1000,
					typical_p: 0.2,
					watermark: false,
					details: true
				}
			}),
			async onopen(response) {
				if (response.ok && response.headers.get('content-type') === 'text/event-stream') {
					messages = [...messages, { from: 'bot', content: '' }];
				} else {
					console.error('error opening the SSE endpoint');
				}
			},
			onmessage(msg) {
				const data = JSON.parse(msg.data) as StreamResponse;
				// console.log(data);
				if (!data.token.special) {
					messages.at(-1)!.content += data.token.text;
					messages = messages;
				}
			}
		});
	}
</script>

<div
	class="grid h-screen w-screen md:grid-cols-[280px,1fr] overflow-hidden text-smd dark:text-gray-300"
>
	<nav
		class="max-md:hidden grid grid-rows-[auto,1fr,auto] grid-cols-1 max-h-screen bg-gradient-to-l from-gray-50 dark:from-gray-800/30"
	>
		<div class="flex-none sticky top-0 relative p-3 flex flex-col">
			<button
				on:click={() => location.reload()}
				class="border px-12 py-2.5 rounded-lg border shadow bg-white dark:bg-gray-700 dark:border-gray-600"
				>New Chat</button
			>
		</div>
		<div class="flex flex-col overflow-y-auto p-3 -mt-3 gap-2">
			{#each Array(5) as _}
				<a
					href="/"
					class="truncate py-3 px-3 rounded-lg flex-none text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700"
				>
					Amet consectetur adipisicing elit. Eos dolorum nihil alias.
				</a>
			{/each}
		</div>
		<div class="flex flex-col p-3 gap-2">
			<a
				href="/"
				class="truncate py-3 px-3 rounded-lg flex-none text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700"
			>
				Appearance
			</a>
			<a
				href="/"
				class="truncate py-3 px-3 rounded-lg flex-none text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700"
			>
				Settings
			</a>
		</div>
	</nav>
	<div class="relative h-screen">
		<div class="overflow-y-auto h-full" bind:this={messagesContainer}>
			<div class="max-w-3xl xl:max-w-4xl mx-auto px-5 pt-6 flex flex-col gap-8 h-full">
				{#each messages as message}
					<ChatBox {message} />
				{:else}
					<ChatIntroduction />
				{/each}
				<div class="h-32 flex-none" />
			</div>
		</div>
		<div
			class="flex items-center bg-gradient-to-t from-white dark:from-gray-900 to-transparent justify-center absolute inset-x-0 max-w-3xl xl:max-w-4xl mx-auto px-5 bottom-0 h-32 w-full"
		>
			<form
				on:submit={onWrite}
				class="shadow-alternate relative flex items-center rounded-xl flex-1 max-w-4xl border bg-gray-100 dark:bg-gray-700 dark:border-gray-600"
			>
				<svg
					class="absolute left-3 text-gray-300 top-1/2 transform -translate-y-1/2 pointer-events-none"
					xmlns="http://www.w3.org/2000/svg"
					xmlns:xlink="http://www.w3.org/1999/xlink"
					aria-hidden="true"
					focusable="false"
					role="img"
					width="1em"
					height="1em"
					preserveAspectRatio="xMidYMid meet"
					viewBox="0 0 32 32"
					><path
						d="M30 28.59L22.45 21A11 11 0 1 0 21 22.45L28.59 30zM5 14a9 9 0 1 1 9 9a9 9 0 0 1-9-9z"
						fill="currentColor"
					/></svg
				>
				<input
					class="flex-1 border-none bg-transparent px-1 py-3 pr-3 pl-10 outline-none"
					bind:value={message}
					on:submit={onWrite}
					placeholder="Ask anything"
					autofocus
				/>
			</form>
		</div>
	</div>
</div>