@d34dman/flowdrop 0.0.32 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/playground/ChatPanel.svelte +5 -1
- package/dist/components/playground/ChatPanel.svelte.d.ts +2 -0
- package/dist/components/playground/MessageBubble.svelte +177 -28
- package/dist/components/playground/MessageBubble.svelte.d.ts +2 -0
- package/dist/components/playground/Playground.svelte +14 -8
- package/dist/services/playgroundService.js +5 -2
- package/dist/types/playground.d.ts +2 -0
- package/package.json +1 -1
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
onStopExecution?: () => void;
|
|
36
36
|
/** Whether to show log messages inline (false = hide them) */
|
|
37
37
|
showLogsInline?: boolean;
|
|
38
|
+
/** Whether to enable markdown rendering in messages */
|
|
39
|
+
enableMarkdown?: boolean;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
let {
|
|
@@ -43,7 +45,8 @@
|
|
|
43
45
|
placeholder = 'Type your message...',
|
|
44
46
|
onSendMessage,
|
|
45
47
|
onStopExecution,
|
|
46
|
-
showLogsInline = false
|
|
48
|
+
showLogsInline = false,
|
|
49
|
+
enableMarkdown = true
|
|
47
50
|
}: Props = $props();
|
|
48
51
|
|
|
49
52
|
/** Input field value */
|
|
@@ -206,6 +209,7 @@
|
|
|
206
209
|
{message}
|
|
207
210
|
showTimestamp={showTimestamps}
|
|
208
211
|
isLast={index === displayMessages.length - 1}
|
|
212
|
+
{enableMarkdown}
|
|
209
213
|
/>
|
|
210
214
|
{/each}
|
|
211
215
|
|
|
@@ -14,6 +14,8 @@ interface Props {
|
|
|
14
14
|
onStopExecution?: () => void;
|
|
15
15
|
/** Whether to show log messages inline (false = hide them) */
|
|
16
16
|
showLogsInline?: boolean;
|
|
17
|
+
/** Whether to enable markdown rendering in messages */
|
|
18
|
+
enableMarkdown?: boolean;
|
|
17
19
|
}
|
|
18
20
|
declare const ChatPanel: import("svelte").Component<Props, {}, "">;
|
|
19
21
|
type ChatPanel = ReturnType<typeof ChatPanel>;
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
Renders individual messages in the playground chat interface.
|
|
5
5
|
Supports different message roles with distinct styling.
|
|
6
|
+
Supports markdown rendering for message content.
|
|
6
7
|
Styled with BEM syntax.
|
|
7
8
|
-->
|
|
8
9
|
|
|
9
10
|
<script lang="ts">
|
|
10
11
|
import Icon from '@iconify/svelte';
|
|
12
|
+
import { marked } from 'marked';
|
|
11
13
|
import type { PlaygroundMessage, PlaygroundMessageRole } from '../../types/playground.js';
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -20,9 +22,20 @@
|
|
|
20
22
|
showTimestamp?: boolean;
|
|
21
23
|
/** Whether this is the last message (affects styling) */
|
|
22
24
|
isLast?: boolean;
|
|
25
|
+
/** Whether to render markdown content */
|
|
26
|
+
enableMarkdown?: boolean;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
let { message, showTimestamp = true, isLast = false }: Props = $props();
|
|
29
|
+
let { message, showTimestamp = true, isLast = false, enableMarkdown = true }: Props = $props();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Render content as markdown or plain text
|
|
33
|
+
*/
|
|
34
|
+
const renderedContent = $derived(
|
|
35
|
+
enableMarkdown && message.role !== 'log'
|
|
36
|
+
? marked.parse(message.content || '')
|
|
37
|
+
: message.content
|
|
38
|
+
);
|
|
26
39
|
|
|
27
40
|
/**
|
|
28
41
|
* Get the icon for the message role
|
|
@@ -144,7 +157,13 @@
|
|
|
144
157
|
|
|
145
158
|
<!-- Message Text -->
|
|
146
159
|
<div class="message-bubble__text">
|
|
147
|
-
{message.
|
|
160
|
+
{#if enableMarkdown && message.role !== 'log'}
|
|
161
|
+
<!-- Markdown content - marked.js sanitizes content by default -->
|
|
162
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
163
|
+
{@html renderedContent}
|
|
164
|
+
{:else}
|
|
165
|
+
{message.content}
|
|
166
|
+
{/if}
|
|
148
167
|
</div>
|
|
149
168
|
|
|
150
169
|
<!-- Metadata Footer -->
|
|
@@ -188,32 +207,33 @@
|
|
|
188
207
|
}
|
|
189
208
|
}
|
|
190
209
|
|
|
191
|
-
/* Role-specific styling */
|
|
210
|
+
/* Role-specific styling - Neutral theme */
|
|
192
211
|
.message-bubble--user {
|
|
193
|
-
background:
|
|
194
|
-
|
|
212
|
+
background-color: #f1f5f9;
|
|
213
|
+
border: 1px solid #e2e8f0;
|
|
214
|
+
color: #1e293b;
|
|
195
215
|
margin-left: 2rem;
|
|
196
216
|
flex-direction: row-reverse;
|
|
197
217
|
}
|
|
198
218
|
|
|
199
219
|
.message-bubble--assistant {
|
|
200
|
-
background-color: #
|
|
201
|
-
border: 1px solid #
|
|
202
|
-
color: #
|
|
220
|
+
background-color: #ffffff;
|
|
221
|
+
border: 1px solid #e5e7eb;
|
|
222
|
+
color: #1f2937;
|
|
203
223
|
margin-right: 2rem;
|
|
204
224
|
}
|
|
205
225
|
|
|
206
226
|
.message-bubble--system {
|
|
207
|
-
background-color: #
|
|
208
|
-
border: 1px solid #
|
|
209
|
-
color: #
|
|
227
|
+
background-color: #f9fafb;
|
|
228
|
+
border: 1px solid #e5e7eb;
|
|
229
|
+
color: #6b7280;
|
|
210
230
|
margin: 0 1rem;
|
|
211
231
|
font-size: 0.875rem;
|
|
212
232
|
}
|
|
213
233
|
|
|
214
234
|
.message-bubble--log {
|
|
215
|
-
background-color: #
|
|
216
|
-
border: 1px solid #
|
|
235
|
+
background-color: #f8fafc;
|
|
236
|
+
border: 1px solid #e2e8f0;
|
|
217
237
|
color: #475569;
|
|
218
238
|
margin: 0 1rem;
|
|
219
239
|
font-size: 0.8125rem;
|
|
@@ -249,18 +269,18 @@
|
|
|
249
269
|
}
|
|
250
270
|
|
|
251
271
|
.message-bubble--user .message-bubble__avatar {
|
|
252
|
-
background-color:
|
|
253
|
-
color: #
|
|
272
|
+
background-color: #e2e8f0;
|
|
273
|
+
color: #475569;
|
|
254
274
|
}
|
|
255
275
|
|
|
256
276
|
.message-bubble--assistant .message-bubble__avatar {
|
|
257
|
-
background-color: #
|
|
258
|
-
color: #
|
|
277
|
+
background-color: #e5e7eb;
|
|
278
|
+
color: #374151;
|
|
259
279
|
}
|
|
260
280
|
|
|
261
281
|
.message-bubble--system .message-bubble__avatar {
|
|
262
|
-
background-color: #
|
|
263
|
-
color: #
|
|
282
|
+
background-color: #f3f4f6;
|
|
283
|
+
color: #6b7280;
|
|
264
284
|
}
|
|
265
285
|
|
|
266
286
|
.message-bubble--log .message-bubble__avatar {
|
|
@@ -292,14 +312,15 @@
|
|
|
292
312
|
.message-bubble__role {
|
|
293
313
|
font-weight: 600;
|
|
294
314
|
font-size: 0.8125rem;
|
|
315
|
+
color: #374151;
|
|
295
316
|
}
|
|
296
317
|
|
|
297
318
|
.message-bubble--user .message-bubble__role {
|
|
298
|
-
color:
|
|
319
|
+
color: #475569;
|
|
299
320
|
}
|
|
300
321
|
|
|
301
322
|
.message-bubble--assistant .message-bubble__role {
|
|
302
|
-
color: #
|
|
323
|
+
color: #374151;
|
|
303
324
|
}
|
|
304
325
|
|
|
305
326
|
.message-bubble--log .message-bubble__role {
|
|
@@ -319,8 +340,8 @@
|
|
|
319
340
|
}
|
|
320
341
|
|
|
321
342
|
.message-bubble__log-level--info {
|
|
322
|
-
background-color: #
|
|
323
|
-
color: #
|
|
343
|
+
background-color: #e0f2fe;
|
|
344
|
+
color: #0369a1;
|
|
324
345
|
}
|
|
325
346
|
|
|
326
347
|
.message-bubble__log-level--warning {
|
|
@@ -340,24 +361,152 @@
|
|
|
340
361
|
|
|
341
362
|
.message-bubble__timestamp {
|
|
342
363
|
font-size: 0.6875rem;
|
|
343
|
-
|
|
364
|
+
color: #9ca3af;
|
|
344
365
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
345
366
|
}
|
|
346
367
|
|
|
347
368
|
.message-bubble--user .message-bubble__timestamp {
|
|
348
|
-
color:
|
|
369
|
+
color: #9ca3af;
|
|
349
370
|
}
|
|
350
371
|
|
|
351
372
|
/* Message text */
|
|
352
373
|
.message-bubble__text {
|
|
353
|
-
line-height: 1.
|
|
354
|
-
white-space: pre-wrap;
|
|
374
|
+
line-height: 1.6;
|
|
355
375
|
word-break: break-word;
|
|
356
376
|
}
|
|
357
377
|
|
|
358
378
|
.message-bubble--log .message-bubble__text {
|
|
359
379
|
font-size: 0.8125rem;
|
|
360
380
|
line-height: 1.4;
|
|
381
|
+
white-space: pre-wrap;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/* Markdown styling for message content */
|
|
385
|
+
.message-bubble__text :global(p) {
|
|
386
|
+
margin: 0 0 0.75rem 0;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.message-bubble__text :global(p:last-child) {
|
|
390
|
+
margin-bottom: 0;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.message-bubble__text :global(h1),
|
|
394
|
+
.message-bubble__text :global(h2),
|
|
395
|
+
.message-bubble__text :global(h3),
|
|
396
|
+
.message-bubble__text :global(h4),
|
|
397
|
+
.message-bubble__text :global(h5),
|
|
398
|
+
.message-bubble__text :global(h6) {
|
|
399
|
+
margin: 1rem 0 0.5rem 0;
|
|
400
|
+
font-weight: 600;
|
|
401
|
+
line-height: 1.3;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.message-bubble__text :global(h1:first-child),
|
|
405
|
+
.message-bubble__text :global(h2:first-child),
|
|
406
|
+
.message-bubble__text :global(h3:first-child),
|
|
407
|
+
.message-bubble__text :global(h4:first-child),
|
|
408
|
+
.message-bubble__text :global(h5:first-child),
|
|
409
|
+
.message-bubble__text :global(h6:first-child) {
|
|
410
|
+
margin-top: 0;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.message-bubble__text :global(h1) {
|
|
414
|
+
font-size: 1.25rem;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.message-bubble__text :global(h2) {
|
|
418
|
+
font-size: 1.125rem;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.message-bubble__text :global(h3) {
|
|
422
|
+
font-size: 1rem;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.message-bubble__text :global(ul),
|
|
426
|
+
.message-bubble__text :global(ol) {
|
|
427
|
+
margin: 0.5rem 0;
|
|
428
|
+
padding-left: 1.5rem;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.message-bubble__text :global(li) {
|
|
432
|
+
margin: 0.25rem 0;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.message-bubble__text :global(code) {
|
|
436
|
+
background-color: rgba(0, 0, 0, 0.06);
|
|
437
|
+
padding: 0.125rem 0.375rem;
|
|
438
|
+
border-radius: 0.25rem;
|
|
439
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
440
|
+
font-size: 0.875em;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.message-bubble__text :global(pre) {
|
|
444
|
+
background-color: #1e293b;
|
|
445
|
+
color: #e2e8f0;
|
|
446
|
+
padding: 0.75rem 1rem;
|
|
447
|
+
border-radius: 0.5rem;
|
|
448
|
+
overflow-x: auto;
|
|
449
|
+
margin: 0.75rem 0;
|
|
450
|
+
font-size: 0.8125rem;
|
|
451
|
+
line-height: 1.5;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.message-bubble__text :global(pre code) {
|
|
455
|
+
background-color: transparent;
|
|
456
|
+
padding: 0;
|
|
457
|
+
border-radius: 0;
|
|
458
|
+
color: inherit;
|
|
459
|
+
font-size: inherit;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.message-bubble__text :global(blockquote) {
|
|
463
|
+
border-left: 3px solid #d1d5db;
|
|
464
|
+
padding-left: 1rem;
|
|
465
|
+
margin: 0.75rem 0;
|
|
466
|
+
color: #6b7280;
|
|
467
|
+
font-style: italic;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.message-bubble__text :global(a) {
|
|
471
|
+
color: #2563eb;
|
|
472
|
+
text-decoration: none;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.message-bubble__text :global(a:hover) {
|
|
476
|
+
text-decoration: underline;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.message-bubble__text :global(hr) {
|
|
480
|
+
border: none;
|
|
481
|
+
border-top: 1px solid #e5e7eb;
|
|
482
|
+
margin: 1rem 0;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.message-bubble__text :global(table) {
|
|
486
|
+
border-collapse: collapse;
|
|
487
|
+
width: 100%;
|
|
488
|
+
margin: 0.75rem 0;
|
|
489
|
+
font-size: 0.875rem;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.message-bubble__text :global(th),
|
|
493
|
+
.message-bubble__text :global(td) {
|
|
494
|
+
border: 1px solid #e5e7eb;
|
|
495
|
+
padding: 0.5rem 0.75rem;
|
|
496
|
+
text-align: left;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.message-bubble__text :global(th) {
|
|
500
|
+
background-color: #f9fafb;
|
|
501
|
+
font-weight: 600;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.message-bubble__text :global(strong) {
|
|
505
|
+
font-weight: 600;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.message-bubble__text :global(em) {
|
|
509
|
+
font-style: italic;
|
|
361
510
|
}
|
|
362
511
|
|
|
363
512
|
/* Footer */
|
|
@@ -367,7 +516,7 @@
|
|
|
367
516
|
gap: 0.75rem;
|
|
368
517
|
margin-top: 0.5rem;
|
|
369
518
|
font-size: 0.6875rem;
|
|
370
|
-
|
|
519
|
+
color: #9ca3af;
|
|
371
520
|
}
|
|
372
521
|
|
|
373
522
|
.message-bubble--user .message-bubble__footer {
|
|
@@ -9,6 +9,8 @@ interface Props {
|
|
|
9
9
|
showTimestamp?: boolean;
|
|
10
10
|
/** Whether this is the last message (affects styling) */
|
|
11
11
|
isLast?: boolean;
|
|
12
|
+
/** Whether to render markdown content */
|
|
13
|
+
enableMarkdown?: boolean;
|
|
12
14
|
}
|
|
13
15
|
declare const MessageBubble: import("svelte").Component<Props, {}, "">;
|
|
14
16
|
type MessageBubble = ReturnType<typeof MessageBubble>;
|
|
@@ -335,15 +335,20 @@
|
|
|
335
335
|
playgroundActions.addMessages(response.data);
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
338
|
+
// Update session status
|
|
339
|
+
if (response.sessionStatus) {
|
|
340
|
+
playgroundActions.updateSessionStatus(response.sessionStatus);
|
|
341
|
+
|
|
342
|
+
// Stop executing if idle, completed, or failed
|
|
343
|
+
// "idle" means no processing is happening (execution finished)
|
|
344
|
+
if (
|
|
345
|
+
response.sessionStatus === 'idle' ||
|
|
346
|
+
response.sessionStatus === 'completed' ||
|
|
347
|
+
response.sessionStatus === 'failed'
|
|
348
|
+
) {
|
|
349
|
+
playgroundActions.setExecuting(false);
|
|
346
350
|
}
|
|
351
|
+
}
|
|
347
352
|
},
|
|
348
353
|
pollingInterval
|
|
349
354
|
);
|
|
@@ -513,6 +518,7 @@
|
|
|
513
518
|
showTimestamps={config.showTimestamps ?? true}
|
|
514
519
|
autoScroll={config.autoScroll ?? true}
|
|
515
520
|
showLogsInline={config.logDisplayMode === 'inline'}
|
|
521
|
+
enableMarkdown={config.enableMarkdown ?? true}
|
|
516
522
|
onSendMessage={handleSendMessage}
|
|
517
523
|
onStopExecution={handleStopExecution}
|
|
518
524
|
/>
|
|
@@ -263,8 +263,11 @@ export class PlaygroundService {
|
|
|
263
263
|
this.currentBackoff = interval;
|
|
264
264
|
// Call the callback with new messages
|
|
265
265
|
callback(response);
|
|
266
|
-
// Stop polling if session is completed or failed
|
|
267
|
-
|
|
266
|
+
// Stop polling if session is idle, completed, or failed
|
|
267
|
+
// "idle" means no processing is happening (execution finished)
|
|
268
|
+
if (response.sessionStatus === 'idle' ||
|
|
269
|
+
response.sessionStatus === 'completed' ||
|
|
270
|
+
response.sessionStatus === 'failed') {
|
|
268
271
|
this.stopPolling();
|
|
269
272
|
return;
|
|
270
273
|
}
|
|
@@ -178,6 +178,8 @@ export interface PlaygroundConfig {
|
|
|
178
178
|
showTimestamps?: boolean;
|
|
179
179
|
/** Show log messages inline or in collapsible section (default: "collapsible") */
|
|
180
180
|
logDisplayMode?: 'inline' | 'collapsible';
|
|
181
|
+
/** Enable markdown rendering in messages (default: true) */
|
|
182
|
+
enableMarkdown?: boolean;
|
|
181
183
|
}
|
|
182
184
|
/**
|
|
183
185
|
* Display mode for the Playground component
|