@flowdrop/flowdrop 1.8.0 → 1.9.0

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.
@@ -160,16 +160,31 @@
160
160
  <span class="system-notice__timestamp">{formatTimestamp(message.timestamp)}</span>
161
161
  {/if}
162
162
  </div>
163
+ {:else if message.role === 'log'}
164
+ <!-- Compact log row: terminal-style entry, visually distinct from chat bubbles -->
165
+ <div
166
+ class="log-row"
167
+ class:log-row--error={message.metadata?.level === 'error'}
168
+ class:log-row--warning={message.metadata?.level === 'warning'}
169
+ class:log-row--debug={message.metadata?.level === 'debug'}
170
+ >
171
+ <div class="log-row__level">
172
+ <Icon icon={getLogLevelIcon()} />
173
+ </div>
174
+ <div class="log-row__body">
175
+ <span class="log-row__node">{message.metadata?.nodeLabel ?? message.nodeId ?? 'log'}</span>
176
+ <span class="log-row__text">{message.content}</span>
177
+ </div>
178
+ {#if showTimestamp}
179
+ <span class="log-row__timestamp">{formatTimestamp(message.timestamp)}</span>
180
+ {/if}
181
+ </div>
163
182
  {:else}
164
183
  <div
165
184
  class="message-bubble"
166
185
  class:message-bubble--user={message.role === 'user'}
167
186
  class:message-bubble--assistant={message.role === 'assistant'}
168
187
  class:message-bubble--system={message.role === 'system'}
169
- class:message-bubble--log={message.role === 'log'}
170
- class:message-bubble--log-error={message.role === 'log' && message.metadata?.level === 'error'}
171
- class:message-bubble--log-warning={message.role === 'log' &&
172
- message.metadata?.level === 'warning'}
173
188
  class:message-bubble--last={isLast}
174
189
  >
175
190
  <!-- Avatar / Icon -->
@@ -182,14 +197,6 @@
182
197
  <!-- Header -->
183
198
  <div class="message-bubble__header">
184
199
  <span class="message-bubble__role">{getRoleLabel(message.role, message.metadata)}</span>
185
- {#if message.role === 'log' && message.metadata?.level}
186
- <span
187
- class="message-bubble__log-level message-bubble__log-level--{message.metadata.level}"
188
- >
189
- <Icon icon={getLogLevelIcon()} />
190
- {message.metadata.level.toUpperCase()}
191
- </span>
192
- {/if}
193
200
  {#if showTimestamp}
194
201
  <span class="message-bubble__timestamp">{formatTimestamp(message.timestamp)}</span>
195
202
  {/if}
@@ -197,7 +204,7 @@
197
204
 
198
205
  <!-- Message Text -->
199
206
  <div class="message-bubble__text">
200
- {#if enableMarkdown && message.role !== 'log'}
207
+ {#if enableMarkdown}
201
208
  <!-- Markdown content - sanitized with DOMPurify to prevent XSS -->
202
209
  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
203
210
  {@html renderedContent}
@@ -214,8 +221,8 @@
214
221
  class="message-bubble__node"
215
222
  title={m().playground.messageTooltips.nodeId({ id: message.nodeId })}
216
223
  >
217
- <Icon icon="mdi:graph" />
218
- {message.metadata?.nodeLabel ?? message.nodeId}
224
+ <Icon icon="mdi:vector-square" />
225
+ via {message.metadata?.nodeLabel ?? message.nodeId}
219
226
  </span>
220
227
  {/if}
221
228
  {#if message.metadata?.duration !== undefined}
@@ -234,19 +241,22 @@
234
241
  {/if}
235
242
 
236
243
  <style>
244
+ /* ============================================================
245
+ Bubble container — layout only, no background
246
+ ============================================================ */
237
247
  .message-bubble {
238
248
  display: flex;
239
- gap: var(--fd-space-md);
240
- padding: var(--fd-space-md) var(--fd-space-xl);
241
- margin-bottom: var(--fd-space-xs);
242
- border-radius: var(--fd-radius-xl);
243
- animation: fadeIn 0.2s ease-out;
249
+ gap: var(--fd-space-sm);
250
+ padding: 2px var(--fd-space-xl);
251
+ margin-bottom: 2px;
252
+ align-items: flex-end;
253
+ animation: fadeIn 0.18s ease-out;
244
254
  }
245
255
 
246
256
  @keyframes fadeIn {
247
257
  from {
248
258
  opacity: 0;
249
- transform: translateY(8px);
259
+ transform: translateY(6px);
250
260
  }
251
261
  to {
252
262
  opacity: 1;
@@ -254,75 +264,37 @@
254
264
  }
255
265
  }
256
266
 
257
- /* Role-specific styling - Neutral theme */
258
267
  .message-bubble--user {
259
- background-color: var(--fd-muted);
260
- border: 1px solid var(--fd-border);
261
- color: var(--fd-foreground);
262
- margin-left: var(--fd-space-4xl);
263
268
  flex-direction: row-reverse;
264
269
  }
265
270
 
266
- .message-bubble--assistant {
267
- background-color: var(--fd-card);
268
- border: 1px solid var(--fd-border);
269
- color: var(--fd-card-foreground);
270
- margin-right: var(--fd-space-4xl);
271
- }
272
-
273
- .message-bubble--system {
274
- background-color: var(--fd-muted);
275
- border: 1px solid var(--fd-border);
276
- color: var(--fd-muted-foreground);
277
- margin: 0 var(--fd-space-xl);
278
- font-size: var(--fd-text-sm);
279
- }
280
-
281
- .message-bubble--log {
282
- background-color: var(--fd-muted);
283
- border: 1px solid var(--fd-border);
284
- color: var(--fd-muted-foreground);
285
- margin: 0 var(--fd-space-xl);
286
- font-size: var(--fd-text-sm);
287
- font-family: var(--fd-font-mono);
288
- }
289
-
290
- .message-bubble--log-error {
291
- background-color: var(--fd-error-muted);
292
- border-color: var(--fd-error);
293
- color: var(--fd-error);
294
- }
295
-
296
- .message-bubble--log-warning {
297
- background-color: var(--fd-warning-muted);
298
- border-color: var(--fd-warning);
299
- color: var(--fd-warning);
300
- }
301
-
302
271
  .message-bubble--last {
303
272
  margin-bottom: var(--fd-space-xl);
304
273
  }
305
274
 
306
- /* Avatar */
275
+ /* ============================================================
276
+ Avatar — smaller, aligned to bubble bottom
277
+ ============================================================ */
307
278
  .message-bubble__avatar {
308
279
  flex-shrink: 0;
309
- width: var(--fd-space-4xl);
310
- height: var(--fd-space-4xl);
280
+ width: 1.875rem;
281
+ height: 1.875rem;
311
282
  display: flex;
312
283
  align-items: center;
313
284
  justify-content: center;
314
285
  border-radius: var(--fd-radius-full);
315
- font-size: var(--fd-text-lg);
286
+ font-size: 1rem;
316
287
  }
317
288
 
318
289
  .message-bubble--user .message-bubble__avatar {
319
- background-color: var(--fd-secondary);
320
- color: var(--fd-secondary-foreground);
290
+ background-color: var(--fd-primary);
291
+ color: var(--fd-primary-foreground);
321
292
  }
322
293
 
323
294
  .message-bubble--assistant .message-bubble__avatar {
324
295
  background-color: var(--fd-secondary);
325
296
  color: var(--fd-secondary-foreground);
297
+ border: 1px solid var(--fd-border);
326
298
  }
327
299
 
328
300
  .message-bubble--system .message-bubble__avatar {
@@ -330,21 +302,41 @@
330
302
  color: var(--fd-muted-foreground);
331
303
  }
332
304
 
333
- .message-bubble--log .message-bubble__avatar {
334
- background-color: var(--fd-secondary);
335
- color: var(--fd-muted-foreground);
336
- width: var(--fd-space-3xl);
337
- height: var(--fd-space-3xl);
338
- font-size: var(--fd-text-sm);
339
- }
340
-
341
- /* Content */
305
+ /* ============================================================
306
+ Content — the actual visible bubble
307
+ ============================================================ */
342
308
  .message-bubble__content {
343
- flex: 1;
344
309
  min-width: 0;
310
+ max-width: 78%;
311
+ padding: var(--fd-space-sm) var(--fd-space-md);
312
+ border-radius: var(--fd-radius-2xl);
313
+ }
314
+
315
+ .message-bubble--user .message-bubble__content {
316
+ background-color: var(--fd-primary);
317
+ color: var(--fd-primary-foreground);
318
+ border-bottom-right-radius: var(--fd-radius-sm);
319
+ }
320
+
321
+ .message-bubble--assistant .message-bubble__content {
322
+ background-color: var(--fd-card);
323
+ border: 1px solid var(--fd-border);
324
+ color: var(--fd-card-foreground);
325
+ box-shadow: 0 1px 3px 0 oklch(0% 0 0 / 0.06), 0 1px 2px -1px oklch(0% 0 0 / 0.04);
326
+ border-bottom-left-radius: var(--fd-radius-sm);
345
327
  }
346
328
 
347
- /* Header */
329
+ .message-bubble--system .message-bubble__content {
330
+ background-color: var(--fd-muted);
331
+ border: 1px solid var(--fd-border);
332
+ color: var(--fd-muted-foreground);
333
+ font-size: var(--fd-text-sm);
334
+ max-width: 88%;
335
+ }
336
+
337
+ /* ============================================================
338
+ Header — role label + timestamp
339
+ ============================================================ */
348
340
  .message-bubble__header {
349
341
  display: flex;
350
342
  align-items: center;
@@ -358,77 +350,47 @@
358
350
 
359
351
  .message-bubble__role {
360
352
  font-weight: 600;
361
- font-size: var(--fd-text-sm);
362
- color: var(--fd-foreground);
363
- }
364
-
365
- .message-bubble--user .message-bubble__role {
366
- color: var(--fd-foreground);
367
- }
368
-
369
- .message-bubble--assistant .message-bubble__role {
370
- color: var(--fd-foreground);
371
- }
372
-
373
- .message-bubble--log .message-bubble__role {
374
- font-weight: 500;
375
- }
376
-
377
- .message-bubble__log-level {
378
- display: flex;
379
- align-items: center;
380
- gap: var(--fd-space-3xs);
381
353
  font-size: var(--fd-text-xs);
382
- font-weight: 600;
383
- padding: 0.125rem var(--fd-space-3xs);
384
- border-radius: var(--fd-radius-sm);
385
354
  text-transform: uppercase;
386
355
  letter-spacing: 0.05em;
387
356
  }
388
357
 
389
- .message-bubble__log-level--info {
390
- background-color: var(--fd-info-muted);
391
- color: var(--fd-info);
392
- }
393
-
394
- .message-bubble__log-level--warning {
395
- background-color: var(--fd-warning-muted);
396
- color: var(--fd-warning);
358
+ .message-bubble--user .message-bubble__role {
359
+ color: var(--fd-primary-foreground);
360
+ opacity: 0.75;
397
361
  }
398
362
 
399
- .message-bubble__log-level--error {
400
- background-color: var(--fd-error-muted);
401
- color: var(--fd-error);
363
+ .message-bubble--assistant .message-bubble__role {
364
+ color: var(--fd-muted-foreground);
402
365
  }
403
366
 
404
- .message-bubble__log-level--debug {
405
- background-color: var(--fd-accent-muted);
406
- color: var(--fd-accent);
367
+ .message-bubble--system .message-bubble__role {
368
+ color: var(--fd-muted-foreground);
407
369
  }
408
370
 
409
371
  .message-bubble__timestamp {
410
- font-size: var(--fd-text-xs);
411
- color: var(--fd-muted-foreground);
372
+ font-size: 0.6875rem;
412
373
  font-family: var(--fd-font-mono);
374
+ opacity: 0.55;
413
375
  }
414
376
 
415
377
  .message-bubble--user .message-bubble__timestamp {
378
+ color: var(--fd-primary-foreground);
379
+ }
380
+
381
+ .message-bubble--assistant .message-bubble__timestamp {
416
382
  color: var(--fd-muted-foreground);
417
383
  }
418
384
 
419
- /* Message text */
385
+ /* ============================================================
386
+ Message text
387
+ ============================================================ */
420
388
  .message-bubble__text {
421
389
  line-height: var(--fd-leading-relaxed);
422
390
  word-break: break-word;
423
391
  }
424
392
 
425
- .message-bubble--log .message-bubble__text {
426
- font-size: var(--fd-text-sm);
427
- line-height: var(--fd-leading-tight);
428
- white-space: pre-wrap;
429
- }
430
-
431
- /* Markdown styling for message content */
393
+ /* Markdown — shared */
432
394
  .message-bubble__text :global(p) {
433
395
  margin: 0 0 var(--fd-space-md) 0;
434
396
  }
@@ -457,17 +419,9 @@
457
419
  margin-top: 0;
458
420
  }
459
421
 
460
- .message-bubble__text :global(h1) {
461
- font-size: var(--fd-text-xl);
462
- }
463
-
464
- .message-bubble__text :global(h2) {
465
- font-size: var(--fd-text-lg);
466
- }
467
-
468
- .message-bubble__text :global(h3) {
469
- font-size: var(--fd-text-base);
470
- }
422
+ .message-bubble__text :global(h1) { font-size: var(--fd-text-xl); }
423
+ .message-bubble__text :global(h2) { font-size: var(--fd-text-lg); }
424
+ .message-bubble__text :global(h3) { font-size: var(--fd-text-base); }
471
425
 
472
426
  .message-bubble__text :global(ul),
473
427
  .message-bubble__text :global(ol) {
@@ -548,26 +502,51 @@
548
502
  font-weight: 600;
549
503
  }
550
504
 
551
- .message-bubble__text :global(strong) {
552
- font-weight: 600;
505
+ .message-bubble__text :global(strong) { font-weight: 600; }
506
+ .message-bubble__text :global(em) { font-style: italic; }
507
+
508
+ /* Markdown overrides for primary-bg (user) bubbles */
509
+ .message-bubble--user .message-bubble__text :global(code) {
510
+ background-color: color-mix(in srgb, var(--fd-primary-foreground) 18%, transparent);
511
+ color: var(--fd-primary-foreground);
553
512
  }
554
513
 
555
- .message-bubble__text :global(em) {
556
- font-style: italic;
514
+ .message-bubble--user .message-bubble__text :global(pre) {
515
+ background-color: rgb(0 0 0 / 0.25);
516
+ color: var(--fd-primary-foreground);
557
517
  }
558
518
 
559
- /* Footer */
519
+ .message-bubble--user .message-bubble__text :global(a) {
520
+ color: var(--fd-primary-foreground);
521
+ text-decoration: underline;
522
+ opacity: 0.85;
523
+ }
524
+
525
+ .message-bubble--user .message-bubble__text :global(blockquote) {
526
+ border-left-color: color-mix(in srgb, var(--fd-primary-foreground) 40%, transparent);
527
+ color: var(--fd-primary-foreground);
528
+ opacity: 0.8;
529
+ }
530
+
531
+ /* ============================================================
532
+ Footer — node / duration metadata
533
+ ============================================================ */
560
534
  .message-bubble__footer {
561
535
  display: flex;
562
536
  align-items: center;
563
537
  gap: var(--fd-space-md);
564
538
  margin-top: var(--fd-space-xs);
539
+ padding-top: var(--fd-space-3xs);
540
+ border-top: 1px solid var(--fd-border);
565
541
  font-size: var(--fd-text-xs);
566
542
  color: var(--fd-muted-foreground);
567
543
  }
568
544
 
569
545
  .message-bubble--user .message-bubble__footer {
570
546
  justify-content: flex-end;
547
+ border-top-color: color-mix(in srgb, var(--fd-primary-foreground) 20%, transparent);
548
+ color: var(--fd-primary-foreground);
549
+ opacity: 0.75;
571
550
  }
572
551
 
573
552
  .message-bubble__node,
@@ -577,25 +556,114 @@
577
556
  gap: var(--fd-space-3xs);
578
557
  }
579
558
 
580
- /* Responsive */
559
+ /* ============================================================
560
+ Responsive
561
+ ============================================================ */
581
562
  @media (max-width: 640px) {
582
- .message-bubble--user,
583
- .message-bubble--assistant {
584
- margin-left: 0;
585
- margin-right: 0;
563
+ .message-bubble__content {
564
+ max-width: 88%;
586
565
  }
587
566
 
588
567
  .message-bubble__avatar {
589
- width: 1.75rem;
590
- height: 1.75rem;
591
- font-size: var(--fd-text-base);
568
+ width: 1.625rem;
569
+ height: 1.625rem;
570
+ font-size: var(--fd-text-sm);
592
571
  }
593
572
  }
594
573
 
595
574
  /* ========================================
596
- Compact System Notice Styles
597
- Minimal inline display for system messages
598
- ======================================== */
575
+ Log Row Styles
576
+ Compact terminal-style entry, distinct from chat bubbles
577
+ ======================================== */
578
+
579
+ .log-row {
580
+ display: flex;
581
+ align-items: baseline;
582
+ gap: var(--fd-space-sm);
583
+ padding: 0.1875rem var(--fd-space-xl);
584
+ border-left: 2px solid var(--fd-info);
585
+ margin: 1px 0;
586
+ font-family: var(--fd-font-mono);
587
+ font-size: var(--fd-text-xs);
588
+ color: var(--fd-muted-foreground);
589
+ line-height: var(--fd-leading-normal);
590
+ background-color: transparent;
591
+ }
592
+
593
+ .log-row:hover {
594
+ background-color: var(--fd-muted);
595
+ }
596
+
597
+ .log-row--error {
598
+ border-left-color: var(--fd-error);
599
+ color: var(--fd-error);
600
+ }
601
+
602
+ .log-row--warning {
603
+ border-left-color: var(--fd-warning);
604
+ color: var(--fd-warning);
605
+ }
606
+
607
+ .log-row--debug {
608
+ border-left-color: var(--fd-border-strong);
609
+ color: var(--fd-border-strong);
610
+ }
611
+
612
+ .log-row__level {
613
+ flex-shrink: 0;
614
+ display: flex;
615
+ align-items: center;
616
+ font-size: var(--fd-text-sm);
617
+ opacity: 0.7;
618
+ }
619
+
620
+ .log-row--error .log-row__level {
621
+ color: var(--fd-error);
622
+ opacity: 1;
623
+ }
624
+
625
+ .log-row--warning .log-row__level {
626
+ color: var(--fd-warning);
627
+ opacity: 1;
628
+ }
629
+
630
+ .log-row__body {
631
+ flex: 1;
632
+ min-width: 0;
633
+ display: flex;
634
+ align-items: baseline;
635
+ gap: var(--fd-space-sm);
636
+ overflow: hidden;
637
+ }
638
+
639
+ .log-row__node {
640
+ flex-shrink: 0;
641
+ font-weight: 600;
642
+ color: var(--fd-foreground);
643
+ opacity: 0.5;
644
+ font-size: 0.65rem;
645
+ text-transform: uppercase;
646
+ letter-spacing: 0.04em;
647
+ }
648
+
649
+ .log-row__text {
650
+ flex: 1;
651
+ min-width: 0;
652
+ white-space: pre-wrap;
653
+ word-break: break-word;
654
+ }
655
+
656
+ .log-row__timestamp {
657
+ flex-shrink: 0;
658
+ font-size: 0.625rem;
659
+ color: var(--fd-border-strong);
660
+ opacity: 0.8;
661
+ }
662
+
663
+ /* ========================================
664
+ Compact System Notice Styles
665
+ Minimal inline display for system messages
666
+ ======================================== */
599
667
 
600
668
  .system-notice {
601
669
  display: flex;