Thomas G. Lopes
commited on
Commit
·
f9963a5
1
Parent(s):
f9620c9
null checks
Browse files- .prettierignore +2 -0
- src/lib/components/inference-playground/checkpoints-menu.svelte +2 -2
- src/lib/components/inference-playground/code-snippets.svelte +0 -1
- src/lib/components/inference-playground/conversation.svelte +5 -5
- src/lib/components/inference-playground/message.svelte +1 -1
- src/lib/state/conversations.svelte.ts +7 -4
- src/lib/utils/business.svelte.ts +1 -1
.prettierignore
CHANGED
@@ -18,3 +18,5 @@ pnpm-lock.yaml
|
|
18 |
yarn.lock
|
19 |
|
20 |
context_length.json
|
|
|
|
|
|
18 |
yarn.lock
|
19 |
|
20 |
context_length.json
|
21 |
+
|
22 |
+
.claude
|
src/lib/components/inference-playground/checkpoints-menu.svelte
CHANGED
@@ -93,7 +93,7 @@
|
|
93 |
{/if}
|
94 |
{#each conversations as { messages }, i}
|
95 |
<span class={["text-gray-800 dark:text-gray-200"]}>
|
96 |
-
{messages
|
97 |
</span>
|
98 |
{#if multiple && i === 0}
|
99 |
<span class="text-gray-500">|</span>
|
@@ -139,7 +139,7 @@
|
|
139 |
{...tooltip.arrow}
|
140 |
></div>
|
141 |
{#each conversations as conversation, i}
|
142 |
-
{@const msgs = conversation.messages}
|
143 |
{@const sliced = msgs.slice(0, 4)}
|
144 |
<div
|
145 |
class={[
|
|
|
93 |
{/if}
|
94 |
{#each conversations as { messages }, i}
|
95 |
<span class={["text-gray-800 dark:text-gray-200"]}>
|
96 |
+
{messages?.length || 0} message{(messages?.length || 0) === 1 ? "" : "s"}
|
97 |
</span>
|
98 |
{#if multiple && i === 0}
|
99 |
<span class="text-gray-500">|</span>
|
|
|
139 |
{...tooltip.arrow}
|
140 |
></div>
|
141 |
{#each conversations as conversation, i}
|
142 |
+
{@const msgs = conversation.messages || []}
|
143 |
{@const sliced = msgs.slice(0, 4)}
|
144 |
<div
|
145 |
class={[
|
src/lib/components/inference-playground/code-snippets.svelte
CHANGED
@@ -112,7 +112,6 @@
|
|
112 |
python: getSnippet({ lang: "python", tokenStr, conversation }),
|
113 |
http: getSnippet({ lang: "sh", tokenStr, conversation }),
|
114 |
} as Record<Language, GetInferenceSnippetReturn>);
|
115 |
-
$inspect(snippetsByLang);
|
116 |
|
117 |
const selectedSnippet = $derived(snippetsByLang[lang][selectedSnippetIdxByLang[lang]]);
|
118 |
|
|
|
112 |
python: getSnippet({ lang: "python", tokenStr, conversation }),
|
113 |
http: getSnippet({ lang: "sh", tokenStr, conversation }),
|
114 |
} as Record<Language, GetInferenceSnippetReturn>);
|
|
|
115 |
|
116 |
const selectedSnippet = $derived(snippetsByLang[lang][selectedSnippetIdxByLang[lang]]);
|
117 |
|
src/lib/components/inference-playground/conversation.svelte
CHANGED
@@ -22,7 +22,7 @@
|
|
22 |
const atBottom = $derived(scrollState.arrived.bottom);
|
23 |
|
24 |
watch(
|
25 |
-
() => conversation.data.messages
|
26 |
() => {
|
27 |
const shouldScroll = atBottom && !scrollState.isScrolling;
|
28 |
if (!shouldScroll) return;
|
@@ -37,7 +37,7 @@
|
|
37 |
);
|
38 |
|
39 |
function addMessage() {
|
40 |
-
const msgs = conversation.data.messages
|
41 |
conversation.update({
|
42 |
...conversation.data,
|
43 |
messages: [
|
@@ -52,7 +52,7 @@
|
|
52 |
|
53 |
async function regenMessage(idx: number) {
|
54 |
// TODO: migrate to new logic
|
55 |
-
const msg = conversation.data.messages[idx];
|
56 |
if (!msg) return;
|
57 |
if (msg.role === "user") {
|
58 |
await conversation.deleteMessages(idx + 1);
|
@@ -71,12 +71,12 @@
|
|
71 |
bind:this={messageContainer}
|
72 |
>
|
73 |
{#if !viewCode}
|
74 |
-
{#each conversation.data.messages as message, index}
|
75 |
<Message
|
76 |
{message}
|
77 |
{index}
|
78 |
{conversation}
|
79 |
-
autofocus={index === conversation.data.messages
|
80 |
onDelete={() => conversation.deleteMessage(index)}
|
81 |
onRegen={() => regenMessage(index)}
|
82 |
/>
|
|
|
22 |
const atBottom = $derived(scrollState.arrived.bottom);
|
23 |
|
24 |
watch(
|
25 |
+
() => conversation.data.messages?.at(-1)?.content,
|
26 |
() => {
|
27 |
const shouldScroll = atBottom && !scrollState.isScrolling;
|
28 |
if (!shouldScroll) return;
|
|
|
37 |
);
|
38 |
|
39 |
function addMessage() {
|
40 |
+
const msgs = conversation.data.messages?.slice() || [];
|
41 |
conversation.update({
|
42 |
...conversation.data,
|
43 |
messages: [
|
|
|
52 |
|
53 |
async function regenMessage(idx: number) {
|
54 |
// TODO: migrate to new logic
|
55 |
+
const msg = conversation.data.messages?.[idx];
|
56 |
if (!msg) return;
|
57 |
if (msg.role === "user") {
|
58 |
await conversation.deleteMessages(idx + 1);
|
|
|
71 |
bind:this={messageContainer}
|
72 |
>
|
73 |
{#if !viewCode}
|
74 |
+
{#each conversation.data.messages || [] as message, index}
|
75 |
<Message
|
76 |
{message}
|
77 |
{index}
|
78 |
{conversation}
|
79 |
+
autofocus={index === (conversation.data.messages?.length || 0) - 1}
|
80 |
onDelete={() => conversation.deleteMessage(index)}
|
81 |
onRegen={() => regenMessage(index)}
|
82 |
/>
|
src/lib/components/inference-playground/message.svelte
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
};
|
29 |
|
30 |
const { index, conversation, message, autofocus, onDelete, onRegen }: Props = $props();
|
31 |
-
const isLast = $derived(index === conversation.data.messages
|
32 |
|
33 |
const autosized = new TextareaAutosize();
|
34 |
const shouldStick = $derived(autosized.textareaHeight > 92);
|
|
|
28 |
};
|
29 |
|
30 |
const { index, conversation, message, autofocus, onDelete, onRegen }: Props = $props();
|
31 |
+
const isLast = $derived(index === (conversation.data.messages?.length || 0) - 1);
|
32 |
|
33 |
const autosized = new TextareaAutosize();
|
34 |
const shouldStick = $derived(autosized.textareaHeight > 92);
|
src/lib/state/conversations.svelte.ts
CHANGED
@@ -127,12 +127,13 @@ export class ConversationClass {
|
|
127 |
addMessage = async (message: ConversationMessage) => {
|
128 |
this.update({
|
129 |
...this.data,
|
130 |
-
messages: [...this.data.messages, snapshot(message)],
|
131 |
});
|
132 |
};
|
133 |
|
134 |
updateMessage = async (args: { index: number; message: Partial<ConversationMessage> }) => {
|
135 |
-
|
|
|
136 |
|
137 |
if (!prev) return;
|
138 |
|
@@ -147,6 +148,7 @@ export class ConversationClass {
|
|
147 |
};
|
148 |
|
149 |
deleteMessage = async (idx: number) => {
|
|
|
150 |
const imgKeys = this.data.messages.flatMap(m => m.images).filter(isString);
|
151 |
await Promise.all([
|
152 |
...imgKeys.map(k => images.delete(k)),
|
@@ -158,6 +160,7 @@ export class ConversationClass {
|
|
158 |
};
|
159 |
|
160 |
deleteMessages = async (from: number) => {
|
|
|
161 |
const sliced = this.data.messages.slice(0, from);
|
162 |
const notSliced = this.data.messages.slice(from);
|
163 |
|
@@ -179,7 +182,7 @@ export class ConversationClass {
|
|
179 |
if (this.data.streaming) {
|
180 |
let addedMessage = false;
|
181 |
const streamingMessage = { role: "assistant", content: "" };
|
182 |
-
const index = this.data.messages
|
183 |
|
184 |
await handleStreamingResponse(
|
185 |
this,
|
@@ -368,7 +371,7 @@ class Conversations {
|
|
368 |
|
369 |
for (let idx = 0; idx < conversations.length; idx++) {
|
370 |
const conversation = conversations[idx];
|
371 |
-
if (!conversation || conversation.data.messages
|
372 |
|
373 |
let prefix = "";
|
374 |
if (this.active.length === 2) {
|
|
|
127 |
addMessage = async (message: ConversationMessage) => {
|
128 |
this.update({
|
129 |
...this.data,
|
130 |
+
messages: [...(this.data.messages || []), snapshot(message)],
|
131 |
});
|
132 |
};
|
133 |
|
134 |
updateMessage = async (args: { index: number; message: Partial<ConversationMessage> }) => {
|
135 |
+
if (!this.data.messages) return;
|
136 |
+
const prev = await poll(() => this.data.messages?.[args.index], { interval: 10, maxAttempts: 200 });
|
137 |
|
138 |
if (!prev) return;
|
139 |
|
|
|
148 |
};
|
149 |
|
150 |
deleteMessage = async (idx: number) => {
|
151 |
+
if (!this.data.messages) return;
|
152 |
const imgKeys = this.data.messages.flatMap(m => m.images).filter(isString);
|
153 |
await Promise.all([
|
154 |
...imgKeys.map(k => images.delete(k)),
|
|
|
160 |
};
|
161 |
|
162 |
deleteMessages = async (from: number) => {
|
163 |
+
if (!this.data.messages) return;
|
164 |
const sliced = this.data.messages.slice(0, from);
|
165 |
const notSliced = this.data.messages.slice(from);
|
166 |
|
|
|
182 |
if (this.data.streaming) {
|
183 |
let addedMessage = false;
|
184 |
const streamingMessage = { role: "assistant", content: "" };
|
185 |
+
const index = this.data.messages?.length || 0;
|
186 |
|
187 |
await handleStreamingResponse(
|
188 |
this,
|
|
|
371 |
|
372 |
for (let idx = 0; idx < conversations.length; idx++) {
|
373 |
const conversation = conversations[idx];
|
374 |
+
if (!conversation || conversation.data.messages?.at(-1)?.role !== "assistant") continue;
|
375 |
|
376 |
let prefix = "";
|
377 |
if (this.active.length === 2) {
|
src/lib/utils/business.svelte.ts
CHANGED
@@ -128,7 +128,7 @@ async function getCompletionMetadata(
|
|
128 |
|
129 |
const messages: ConversationMessage[] = [
|
130 |
...(isSystemPromptSupported(model) && systemMessage?.length ? [{ role: "system", content: systemMessage }] : []),
|
131 |
-
...data.messages,
|
132 |
];
|
133 |
const parsed = await Promise.all(messages.map(parseMessage));
|
134 |
|
|
|
128 |
|
129 |
const messages: ConversationMessage[] = [
|
130 |
...(isSystemPromptSupported(model) && systemMessage?.length ? [{ role: "system", content: systemMessage }] : []),
|
131 |
+
...(data.messages || []),
|
132 |
];
|
133 |
const parsed = await Promise.all(messages.map(parseMessage));
|
134 |
|