Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Thomas G. Lopes
commited on
Commit
·
7c08d14
1
Parent(s):
96cfab0
add markdown parsing
Browse files- package.json +2 -0
- pnpm-lock.yaml +45 -0
- src/app.css +1 -0
- src/lib/components/inference-playground/generation-config.svelte +12 -0
- src/lib/components/inference-playground/message-textarea.svelte +2 -2
- src/lib/components/inference-playground/message.svelte +40 -22
- src/lib/spells/textarea-autosize.svelte.ts +1 -1
- src/lib/state/conversations.svelte.ts +4 -0
package.json
CHANGED
@@ -74,8 +74,10 @@
|
|
74 |
},
|
75 |
"type": "module",
|
76 |
"dependencies": {
|
|
|
77 |
"dequal": "^2.0.3",
|
78 |
"eslint-plugin-svelte": "^3.11.0",
|
|
|
79 |
"remult": "^3.0.2",
|
80 |
"typia": "^8.0.0"
|
81 |
},
|
|
|
74 |
},
|
75 |
"type": "module",
|
76 |
"dependencies": {
|
77 |
+
"@tailwindcss/typography": "^0.5.16",
|
78 |
"dequal": "^2.0.3",
|
79 |
"eslint-plugin-svelte": "^3.11.0",
|
80 |
+
"marked": "^16.1.2",
|
81 |
"remult": "^3.0.2",
|
82 |
"typia": "^8.0.0"
|
83 |
},
|
pnpm-lock.yaml
CHANGED
@@ -8,12 +8,18 @@ importers:
|
|
8 |
|
9 |
.:
|
10 |
dependencies:
|
|
|
|
|
|
|
11 |
dequal:
|
12 |
specifier: ^2.0.3
|
13 |
version: 2.0.3
|
14 |
eslint-plugin-svelte:
|
15 |
specifier: ^3.11.0
|
16 |
version: 3.11.0([email protected]([email protected]))([email protected])
|
|
|
|
|
|
|
17 |
remult:
|
18 |
specifier: ^3.0.2
|
19 |
version: 3.0.2
|
@@ -1128,6 +1134,11 @@ packages:
|
|
1128 |
'@tailwindcss/[email protected]':
|
1129 |
resolution: {integrity: sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==}
|
1130 |
|
|
|
|
|
|
|
|
|
|
|
1131 |
'@testing-library/[email protected]':
|
1132 |
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
1133 |
engines: {node: '>=18'}
|
@@ -2207,6 +2218,12 @@ packages:
|
|
2207 |
resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
|
2208 |
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
2209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
2210 | |
2211 |
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
2212 |
|
@@ -2233,6 +2250,11 @@ packages:
|
|
2233 | |
2234 |
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
2235 |
|
|
|
|
|
|
|
|
|
|
|
2236 | |
2237 |
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
2238 |
engines: {node: '>=10'}
|
@@ -2518,6 +2540,10 @@ packages:
|
|
2518 |
peerDependencies:
|
2519 |
postcss: ^8.4.29
|
2520 |
|
|
|
|
|
|
|
|
|
2521 | |
2522 |
resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==}
|
2523 |
engines: {node: '>=4'}
|
@@ -4045,6 +4071,14 @@ snapshots:
|
|
4045 |
postcss: 8.5.3
|
4046 |
tailwindcss: 4.0.9
|
4047 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4048 |
'@testing-library/[email protected]':
|
4049 |
dependencies:
|
4050 |
'@babel/code-frame': 7.27.1
|
@@ -5168,6 +5202,10 @@ snapshots:
|
|
5168 |
dependencies:
|
5169 |
p-locate: 6.0.0
|
5170 |
|
|
|
|
|
|
|
|
|
5171 | |
5172 |
|
5173 | |
@@ -5189,6 +5227,8 @@ snapshots:
|
|
5189 |
dependencies:
|
5190 |
'@jridgewell/sourcemap-codec': 1.5.0
|
5191 |
|
|
|
|
|
5192 | |
5193 |
dependencies:
|
5194 |
escape-string-regexp: 4.0.0
|
@@ -5456,6 +5496,11 @@ snapshots:
|
|
5456 |
dependencies:
|
5457 |
postcss: 8.5.3
|
5458 |
|
|
|
|
|
|
|
|
|
|
|
5459 | |
5460 |
dependencies:
|
5461 |
cssesc: 3.0.0
|
|
|
8 |
|
9 |
.:
|
10 |
dependencies:
|
11 |
+
'@tailwindcss/typography':
|
12 |
+
specifier: ^0.5.16
|
13 |
+
version: 0.5.16([email protected])
|
14 |
dequal:
|
15 |
specifier: ^2.0.3
|
16 |
version: 2.0.3
|
17 |
eslint-plugin-svelte:
|
18 |
specifier: ^3.11.0
|
19 |
version: 3.11.0([email protected]([email protected]))([email protected])
|
20 |
+
marked:
|
21 |
+
specifier: ^16.1.2
|
22 |
+
version: 16.1.2
|
23 |
remult:
|
24 |
specifier: ^3.0.2
|
25 |
version: 3.0.2
|
|
|
1134 |
'@tailwindcss/[email protected]':
|
1135 |
resolution: {integrity: sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==}
|
1136 |
|
1137 |
+
'@tailwindcss/[email protected]':
|
1138 |
+
resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==}
|
1139 |
+
peerDependencies:
|
1140 |
+
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
|
1141 |
+
|
1142 |
'@testing-library/[email protected]':
|
1143 |
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
|
1144 |
engines: {node: '>=18'}
|
|
|
2218 |
resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
|
2219 |
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
2220 |
|
2221 | |
2222 |
+
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
|
2223 |
+
|
2224 | |
2225 |
+
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
|
2226 |
+
|
2227 | |
2228 |
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
2229 |
|
|
|
2250 | |
2251 |
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
2252 |
|
2253 | |
2254 |
+
resolution: {integrity: sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ==}
|
2255 |
+
engines: {node: '>= 20'}
|
2256 |
+
hasBin: true
|
2257 |
+
|
2258 | |
2259 |
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
2260 |
engines: {node: '>=10'}
|
|
|
2540 |
peerDependencies:
|
2541 |
postcss: ^8.4.29
|
2542 |
|
2543 | |
2544 |
+
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
|
2545 |
+
engines: {node: '>=4'}
|
2546 |
+
|
2547 | |
2548 |
resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==}
|
2549 |
engines: {node: '>=4'}
|
|
|
4071 |
postcss: 8.5.3
|
4072 |
tailwindcss: 4.0.9
|
4073 |
|
4074 |
+
'@tailwindcss/[email protected]([email protected])':
|
4075 |
+
dependencies:
|
4076 |
+
lodash.castarray: 4.4.0
|
4077 |
+
lodash.isplainobject: 4.0.6
|
4078 |
+
lodash.merge: 4.6.2
|
4079 |
+
postcss-selector-parser: 6.0.10
|
4080 |
+
tailwindcss: 4.0.9
|
4081 |
+
|
4082 |
'@testing-library/[email protected]':
|
4083 |
dependencies:
|
4084 |
'@babel/code-frame': 7.27.1
|
|
|
5202 |
dependencies:
|
5203 |
p-locate: 6.0.0
|
5204 |
|
5205 |
+
[email protected]: {}
|
5206 |
+
|
5207 |
+
[email protected]: {}
|
5208 |
+
|
5209 | |
5210 |
|
5211 | |
|
|
5227 |
dependencies:
|
5228 |
'@jridgewell/sourcemap-codec': 1.5.0
|
5229 |
|
5230 |
+
[email protected]: {}
|
5231 |
+
|
5232 | |
5233 |
dependencies:
|
5234 |
escape-string-regexp: 4.0.0
|
|
|
5496 |
dependencies:
|
5497 |
postcss: 8.5.3
|
5498 |
|
5499 | |
5500 |
+
dependencies:
|
5501 |
+
cssesc: 3.0.0
|
5502 |
+
util-deprecate: 1.0.2
|
5503 |
+
|
5504 | |
5505 |
dependencies:
|
5506 |
cssesc: 3.0.0
|
src/app.css
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
@import "tailwindcss";
|
3 |
|
4 |
@plugin '@tailwindcss/container-queries';
|
|
|
5 |
|
6 |
@custom-variant dark (&:where(.dark, .dark *));
|
7 |
|
|
|
2 |
@import "tailwindcss";
|
3 |
|
4 |
@plugin '@tailwindcss/container-queries';
|
5 |
+
@plugin '@tailwindcss/typography';
|
6 |
|
7 |
@custom-variant dark (&:where(.dark, .dark *));
|
8 |
|
src/lib/components/inference-playground/generation-config.svelte
CHANGED
@@ -137,6 +137,18 @@
|
|
137 |
</span>
|
138 |
<button class="btn-mini ml-auto" type="button" onclick={openExtraParamsModal}>edit</button>
|
139 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
</div>
|
141 |
|
142 |
<StructuredOutputModal {conversation} />
|
|
|
137 |
</span>
|
138 |
<button class="btn-mini ml-auto" type="button" onclick={openExtraParamsModal}>edit</button>
|
139 |
</div>
|
140 |
+
|
141 |
+
<label class="mt-2 flex cursor-pointer items-center justify-between">
|
142 |
+
<input
|
143 |
+
type="checkbox"
|
144 |
+
bind:checked={() => conversation.data.parseMarkdown, v => conversation.update({ parseMarkdown: v })}
|
145 |
+
class="peer sr-only"
|
146 |
+
/>
|
147 |
+
<span class="text-sm font-medium text-gray-900 dark:text-gray-300">Parse Markdown</span>
|
148 |
+
<div
|
149 |
+
class="peer relative h-5 w-9 rounded-full bg-gray-200 peer-checked:bg-black peer-focus:outline-hidden after:absolute after:start-[2px] after:top-[2px] after:h-4 after:w-4 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full peer-checked:after:border-white dark:border-gray-600 dark:bg-gray-700 dark:peer-checked:bg-blue-600"
|
150 |
+
></div>
|
151 |
+
</label>
|
152 |
</div>
|
153 |
|
154 |
<StructuredOutputModal {conversation} />
|
src/lib/components/inference-playground/message-textarea.svelte
CHANGED
@@ -5,14 +5,14 @@
|
|
5 |
import { images } from "$lib/state/images.svelte";
|
6 |
import type { ConversationMessage } from "$lib/types.js";
|
7 |
import { fileToDataURL } from "$lib/utils/file.js";
|
|
|
8 |
import { cmdOrCtrl } from "$lib/utils/platform.js";
|
9 |
import { FileUpload } from "melt/builders";
|
|
|
10 |
import IconImage from "~icons/carbon/image-reference";
|
11 |
import IconMaximize from "~icons/carbon/maximize";
|
12 |
import Tooltip from "../tooltip.svelte";
|
13 |
import { previewImage } from "./img-preview.svelte";
|
14 |
-
import { omit } from "$lib/utils/object.svelte";
|
15 |
-
import { fade } from "svelte/transition";
|
16 |
|
17 |
const multiple = $derived(conversations.active.length > 1);
|
18 |
const loading = $derived(conversations.generating);
|
|
|
5 |
import { images } from "$lib/state/images.svelte";
|
6 |
import type { ConversationMessage } from "$lib/types.js";
|
7 |
import { fileToDataURL } from "$lib/utils/file.js";
|
8 |
+
import { omit } from "$lib/utils/object.svelte";
|
9 |
import { cmdOrCtrl } from "$lib/utils/platform.js";
|
10 |
import { FileUpload } from "melt/builders";
|
11 |
+
import { fade } from "svelte/transition";
|
12 |
import IconImage from "~icons/carbon/image-reference";
|
13 |
import IconMaximize from "~icons/carbon/maximize";
|
14 |
import Tooltip from "../tooltip.svelte";
|
15 |
import { previewImage } from "./img-preview.svelte";
|
|
|
|
|
16 |
|
17 |
const multiple = $derived(conversations.active.length > 1);
|
18 |
const loading = $derived(conversations.generating);
|
src/lib/components/inference-playground/message.svelte
CHANGED
@@ -16,6 +16,7 @@
|
|
16 |
import IconCustom from "../icon-custom.svelte";
|
17 |
import LocalToasts from "../local-toasts.svelte";
|
18 |
import { previewImage } from "./img-preview.svelte";
|
|
|
19 |
|
20 |
type Props = {
|
21 |
conversation: ConversationClass;
|
@@ -59,6 +60,13 @@
|
|
59 |
if (message?.role === "assistant") return "Regenerate";
|
60 |
return isLast ? "Generate from here" : "Regenerate from here";
|
61 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
</script>
|
63 |
|
64 |
<div
|
@@ -88,28 +96,38 @@
|
|
88 |
{message?.role}
|
89 |
</div>
|
90 |
<div class="flex w-full gap-4">
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
<!-- Sticky wrapper for action buttons -->
|
115 |
<div class={["top-8 z-10 self-start", shouldStick && "sticky"]}>
|
|
|
16 |
import IconCustom from "../icon-custom.svelte";
|
17 |
import LocalToasts from "../local-toasts.svelte";
|
18 |
import { previewImage } from "./img-preview.svelte";
|
19 |
+
import { marked } from "marked";
|
20 |
|
21 |
type Props = {
|
22 |
conversation: ConversationClass;
|
|
|
60 |
if (message?.role === "assistant") return "Regenerate";
|
61 |
return isLast ? "Generate from here" : "Regenerate from here";
|
62 |
});
|
63 |
+
|
64 |
+
const parsedContent = $derived.by(() => {
|
65 |
+
if (!conversation.data.parseMarkdown || !message?.content) {
|
66 |
+
return message?.content ?? "";
|
67 |
+
}
|
68 |
+
return marked(message.content);
|
69 |
+
});
|
70 |
</script>
|
71 |
|
72 |
<div
|
|
|
96 |
{message?.role}
|
97 |
</div>
|
98 |
<div class="flex w-full gap-4">
|
99 |
+
{#if conversation.data.parseMarkdown && message?.role === "assistant"}
|
100 |
+
<div
|
101 |
+
class="prose prose-sm dark:prose-invert max-w-none grow rounded-lg bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:bg-white @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900"
|
102 |
+
data-message
|
103 |
+
data-test-id={TEST_IDS.message}
|
104 |
+
>
|
105 |
+
{@html parsedContent}
|
106 |
+
</div>
|
107 |
+
{:else}
|
108 |
+
<textarea
|
109 |
+
value={message?.content}
|
110 |
+
onchange={e => {
|
111 |
+
const el = e.target as HTMLTextAreaElement;
|
112 |
+
const content = el?.value;
|
113 |
+
if (!message || !content) return;
|
114 |
+
conversation.updateMessage({ index, message: { ...message, content } });
|
115 |
+
}}
|
116 |
+
onkeydown={e => {
|
117 |
+
if ((e.ctrlKey || e.metaKey) && e.key === "g") {
|
118 |
+
e.preventDefault();
|
119 |
+
e.stopPropagation();
|
120 |
+
onRegen?.();
|
121 |
+
}
|
122 |
+
}}
|
123 |
+
placeholder="Enter {message?.role} message"
|
124 |
+
class="grow resize-none overflow-hidden rounded-lg bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:bg-white focus:bg-white focus:ring-3 @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900 dark:focus:bg-gray-900"
|
125 |
+
rows="1"
|
126 |
+
data-message
|
127 |
+
data-test-id={TEST_IDS.message}
|
128 |
+
{@attach autosized.attachment}
|
129 |
+
></textarea>
|
130 |
+
{/if}
|
131 |
|
132 |
<!-- Sticky wrapper for action buttons -->
|
133 |
<div class={["top-8 z-10 self-start", shouldStick && "sticky"]}>
|
src/lib/spells/textarea-autosize.svelte.ts
CHANGED
@@ -150,7 +150,7 @@ export class TextareaAutosize {
|
|
150 |
}
|
151 |
|
152 |
// Only update if height actually changed
|
153 |
-
if (this.textareaHeight !== newHeight) {
|
154 |
this.textareaHeight = newHeight;
|
155 |
this.element.style[this.styleProp] = `${newHeight}px`;
|
156 |
}
|
|
|
150 |
}
|
151 |
|
152 |
// Only update if height actually changed
|
153 |
+
if (this.textareaHeight !== newHeight || !this.element.style[this.styleProp]) {
|
154 |
this.textareaHeight = newHeight;
|
155 |
this.element.style[this.styleProp] = `${newHeight}px`;
|
156 |
}
|
src/lib/state/conversations.svelte.ts
CHANGED
@@ -38,6 +38,9 @@ export class ConversationEntity {
|
|
38 |
schema?: string;
|
39 |
};
|
40 |
|
|
|
|
|
|
|
41 |
@Fields.json()
|
42 |
messages?: ConversationMessage[];
|
43 |
|
@@ -82,6 +85,7 @@ function getDefaultConversation(projectId: string) {
|
|
82 |
config: { ...defaultGenerationConfig },
|
83 |
messages: [],
|
84 |
streaming: true,
|
|
|
85 |
createdAt: new Date(),
|
86 |
} satisfies Partial<ConversationEntityMembers>;
|
87 |
}
|
|
|
38 |
schema?: string;
|
39 |
};
|
40 |
|
41 |
+
@Fields.boolean()
|
42 |
+
parseMarkdown = false;
|
43 |
+
|
44 |
@Fields.json()
|
45 |
messages?: ConversationMessage[];
|
46 |
|
|
|
85 |
config: { ...defaultGenerationConfig },
|
86 |
messages: [],
|
87 |
streaming: true,
|
88 |
+
parseMarkdown: false,
|
89 |
createdAt: new Date(),
|
90 |
} satisfies Partial<ConversationEntityMembers>;
|
91 |
}
|