@d34dman/flowdrop 0.0.30 → 0.0.32

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.
Files changed (53) hide show
  1. package/dist/components/App.svelte +54 -6
  2. package/dist/components/NodeSidebar.svelte +1 -1
  3. package/dist/components/SchemaForm.svelte +14 -14
  4. package/dist/components/SchemaForm.svelte.d.ts +1 -1
  5. package/dist/components/form/FormFieldLight.svelte +66 -66
  6. package/dist/components/form/FormFieldLight.svelte.d.ts +1 -1
  7. package/dist/components/form/types.d.ts +1 -1
  8. package/dist/components/playground/ChatPanel.svelte +523 -0
  9. package/dist/components/playground/ChatPanel.svelte.d.ts +20 -0
  10. package/dist/components/playground/ExecutionLogs.svelte +486 -0
  11. package/dist/components/playground/ExecutionLogs.svelte.d.ts +14 -0
  12. package/dist/components/playground/InputCollector.svelte +444 -0
  13. package/dist/components/playground/InputCollector.svelte.d.ts +16 -0
  14. package/dist/components/playground/MessageBubble.svelte +398 -0
  15. package/dist/components/playground/MessageBubble.svelte.d.ts +15 -0
  16. package/dist/components/playground/Playground.svelte +861 -0
  17. package/dist/components/playground/Playground.svelte.d.ts +25 -0
  18. package/dist/components/playground/PlaygroundModal.svelte +220 -0
  19. package/dist/components/playground/PlaygroundModal.svelte.d.ts +25 -0
  20. package/dist/components/playground/SessionManager.svelte +537 -0
  21. package/dist/components/playground/SessionManager.svelte.d.ts +20 -0
  22. package/dist/config/endpoints.d.ts +16 -0
  23. package/dist/config/endpoints.js +9 -0
  24. package/dist/core/index.d.ts +25 -23
  25. package/dist/core/index.js +13 -12
  26. package/dist/display/index.d.ts +2 -2
  27. package/dist/display/index.js +2 -2
  28. package/dist/editor/index.d.ts +58 -49
  29. package/dist/editor/index.js +53 -42
  30. package/dist/form/code.d.ts +4 -4
  31. package/dist/form/code.js +11 -11
  32. package/dist/form/fieldRegistry.d.ts +2 -2
  33. package/dist/form/fieldRegistry.js +8 -10
  34. package/dist/form/full.d.ts +5 -5
  35. package/dist/form/full.js +7 -7
  36. package/dist/form/index.d.ts +16 -16
  37. package/dist/form/index.js +14 -14
  38. package/dist/form/markdown.d.ts +3 -3
  39. package/dist/form/markdown.js +6 -6
  40. package/dist/index.d.ts +6 -4
  41. package/dist/index.js +9 -4
  42. package/dist/playground/index.d.ts +125 -0
  43. package/dist/playground/index.js +147 -0
  44. package/dist/playground/mount.d.ts +184 -0
  45. package/dist/playground/mount.js +209 -0
  46. package/dist/services/playgroundService.d.ts +129 -0
  47. package/dist/services/playgroundService.js +317 -0
  48. package/dist/stores/playgroundStore.d.ts +199 -0
  49. package/dist/stores/playgroundStore.js +350 -0
  50. package/dist/types/playground.d.ts +230 -0
  51. package/dist/types/playground.js +28 -0
  52. package/dist/utils/colors.js +4 -4
  53. package/package.json +6 -1
@@ -0,0 +1,523 @@
1
+ <!--
2
+ ChatPanel Component
3
+
4
+ Clean conversational chat interface for the playground.
5
+ Displays messages with chat bubbles and includes a simple input area.
6
+ Styled with BEM syntax for a Langflow-like appearance.
7
+ -->
8
+
9
+ <script lang="ts">
10
+ import Icon from '@iconify/svelte';
11
+ import { tick } from 'svelte';
12
+ import MessageBubble from './MessageBubble.svelte';
13
+ import type { PlaygroundMessage } from '../../types/playground.js';
14
+ import {
15
+ messages,
16
+ chatMessages,
17
+ isExecuting,
18
+ sessionStatus,
19
+ currentSession
20
+ } from '../../stores/playgroundStore.js';
21
+
22
+ /**
23
+ * Component props
24
+ */
25
+ interface Props {
26
+ /** Whether to show timestamps on messages */
27
+ showTimestamps?: boolean;
28
+ /** Whether to auto-scroll to bottom on new messages */
29
+ autoScroll?: boolean;
30
+ /** Placeholder text for the input */
31
+ placeholder?: string;
32
+ /** Callback when user sends a message */
33
+ onSendMessage?: (content: string) => void;
34
+ /** Callback when user requests to stop execution */
35
+ onStopExecution?: () => void;
36
+ /** Whether to show log messages inline (false = hide them) */
37
+ showLogsInline?: boolean;
38
+ }
39
+
40
+ let {
41
+ showTimestamps = true,
42
+ autoScroll = true,
43
+ placeholder = 'Type your message...',
44
+ onSendMessage,
45
+ onStopExecution,
46
+ showLogsInline = false
47
+ }: Props = $props();
48
+
49
+ /** Input field value */
50
+ let inputValue = $state('');
51
+
52
+ /** Reference to the messages container for scrolling */
53
+ let messagesContainer = $state<HTMLDivElement>();
54
+
55
+ /** Reference to the input field */
56
+ let inputField = $state<HTMLTextAreaElement>();
57
+
58
+ /**
59
+ * Filter messages based on showLogsInline setting
60
+ */
61
+ const displayMessages = $derived(showLogsInline ? $messages : $chatMessages);
62
+
63
+ /**
64
+ * Check if we should show the welcome state
65
+ */
66
+ const showWelcome = $derived(!$currentSession && displayMessages.length === 0);
67
+
68
+ /**
69
+ * Check if we should show the empty chat state (session exists but no messages)
70
+ */
71
+ const showEmptyChat = $derived($currentSession && displayMessages.length === 0);
72
+
73
+ /**
74
+ * Handle sending a message
75
+ */
76
+ function handleSend(): void {
77
+ const trimmedValue = inputValue.trim();
78
+ if (!trimmedValue || $isExecuting) {
79
+ return;
80
+ }
81
+
82
+ onSendMessage?.(trimmedValue);
83
+ inputValue = '';
84
+
85
+ // Reset textarea height
86
+ if (inputField) {
87
+ inputField.style.height = 'auto';
88
+ }
89
+
90
+ // Re-focus the input
91
+ tick().then(() => {
92
+ inputField?.focus();
93
+ });
94
+ }
95
+
96
+ /**
97
+ * Handle keyboard events in the input
98
+ */
99
+ function handleKeydown(event: KeyboardEvent): void {
100
+ if (event.key === 'Enter' && !event.shiftKey) {
101
+ event.preventDefault();
102
+ handleSend();
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Handle stop execution
108
+ */
109
+ function handleStop(): void {
110
+ onStopExecution?.();
111
+ }
112
+
113
+ /**
114
+ * Auto-scroll to bottom when messages change
115
+ */
116
+ $effect(() => {
117
+ if (autoScroll && messagesContainer && displayMessages.length > 0) {
118
+ tick().then(() => {
119
+ if (messagesContainer) {
120
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
121
+ }
122
+ });
123
+ }
124
+ });
125
+
126
+ /**
127
+ * Auto-resize textarea based on content
128
+ */
129
+ function handleInput(): void {
130
+ if (inputField) {
131
+ inputField.style.height = 'auto';
132
+ inputField.style.height = `${Math.min(inputField.scrollHeight, 120)}px`;
133
+ }
134
+ }
135
+ </script>
136
+
137
+ <div class="chat-panel">
138
+ <!-- Messages Container -->
139
+ <div class="chat-panel__messages" bind:this={messagesContainer}>
140
+ {#if showWelcome}
141
+ <!-- Welcome State (no session) -->
142
+ <div class="chat-panel__welcome">
143
+ <div class="chat-panel__welcome-icon">
144
+ <svg
145
+ width="48"
146
+ height="48"
147
+ viewBox="0 0 48 48"
148
+ fill="none"
149
+ xmlns="http://www.w3.org/2000/svg"
150
+ >
151
+ <path
152
+ d="M8 16L24 8L40 16V32L24 40L8 32V16Z"
153
+ stroke="currentColor"
154
+ stroke-width="2"
155
+ stroke-linejoin="round"
156
+ />
157
+ <path
158
+ d="M8 16L24 24L40 16"
159
+ stroke="currentColor"
160
+ stroke-width="2"
161
+ stroke-linejoin="round"
162
+ />
163
+ <path d="M24 24V40" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
164
+ <path d="M16 12L32 20" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
165
+ <path d="M16 36L32 28" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
166
+ </svg>
167
+ </div>
168
+ <h2 class="chat-panel__welcome-title">New chat</h2>
169
+ <p class="chat-panel__welcome-text">Test your flow with a chat prompt</p>
170
+ </div>
171
+ {:else if showEmptyChat}
172
+ <!-- Empty Chat State (session exists but no messages) -->
173
+ <div class="chat-panel__welcome">
174
+ <div class="chat-panel__welcome-icon">
175
+ <svg
176
+ width="48"
177
+ height="48"
178
+ viewBox="0 0 48 48"
179
+ fill="none"
180
+ xmlns="http://www.w3.org/2000/svg"
181
+ >
182
+ <path
183
+ d="M8 16L24 8L40 16V32L24 40L8 32V16Z"
184
+ stroke="currentColor"
185
+ stroke-width="2"
186
+ stroke-linejoin="round"
187
+ />
188
+ <path
189
+ d="M8 16L24 24L40 16"
190
+ stroke="currentColor"
191
+ stroke-width="2"
192
+ stroke-linejoin="round"
193
+ />
194
+ <path d="M24 24V40" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
195
+ <path d="M16 12L32 20" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
196
+ <path d="M16 36L32 28" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
197
+ </svg>
198
+ </div>
199
+ <h2 class="chat-panel__welcome-title">New chat</h2>
200
+ <p class="chat-panel__welcome-text">Test your flow with a chat prompt</p>
201
+ </div>
202
+ {:else}
203
+ <!-- Messages -->
204
+ {#each displayMessages as message, index (message.id)}
205
+ <MessageBubble
206
+ {message}
207
+ showTimestamp={showTimestamps}
208
+ isLast={index === displayMessages.length - 1}
209
+ />
210
+ {/each}
211
+
212
+ {#if $isExecuting}
213
+ <div class="chat-panel__typing">
214
+ <div class="chat-panel__typing-indicator">
215
+ <span></span>
216
+ <span></span>
217
+ <span></span>
218
+ </div>
219
+ <span class="chat-panel__typing-text">Processing...</span>
220
+ </div>
221
+ {/if}
222
+ {/if}
223
+ </div>
224
+
225
+ <!-- Input Area -->
226
+ <div class="chat-panel__input-area">
227
+ <div class="chat-panel__input-container">
228
+ <div class="chat-panel__input-wrapper">
229
+ <textarea
230
+ bind:this={inputField}
231
+ bind:value={inputValue}
232
+ class="chat-panel__input"
233
+ {placeholder}
234
+ rows="1"
235
+ disabled={$isExecuting}
236
+ onkeydown={handleKeydown}
237
+ oninput={handleInput}
238
+ ></textarea>
239
+
240
+ <!-- Attachment button placeholder -->
241
+ <button type="button" class="chat-panel__attachment-btn" title="Attach file" disabled>
242
+ <Icon icon="mdi:image-outline" />
243
+ </button>
244
+ </div>
245
+
246
+ {#if $sessionStatus === 'running' || $isExecuting}
247
+ <button
248
+ type="button"
249
+ class="chat-panel__stop-btn"
250
+ onclick={handleStop}
251
+ title="Stop execution"
252
+ >
253
+ <Icon icon="mdi:stop" />
254
+ Stop
255
+ </button>
256
+ {:else}
257
+ <button
258
+ type="button"
259
+ class="chat-panel__send-btn"
260
+ onclick={handleSend}
261
+ disabled={!inputValue.trim()}
262
+ title="Send message"
263
+ >
264
+ Send
265
+ </button>
266
+ {/if}
267
+ </div>
268
+ </div>
269
+ </div>
270
+
271
+ <style>
272
+ .chat-panel {
273
+ display: flex;
274
+ flex-direction: column;
275
+ height: 100%;
276
+ background-color: #ffffff;
277
+ }
278
+
279
+ /* Messages Container */
280
+ .chat-panel__messages {
281
+ flex: 1;
282
+ overflow-y: auto;
283
+ padding: 1.5rem;
284
+ scroll-behavior: smooth;
285
+ }
286
+
287
+ /* Welcome State */
288
+ .chat-panel__welcome {
289
+ display: flex;
290
+ flex-direction: column;
291
+ align-items: center;
292
+ justify-content: center;
293
+ height: 100%;
294
+ text-align: center;
295
+ padding: 2rem;
296
+ }
297
+
298
+ .chat-panel__welcome-icon {
299
+ display: flex;
300
+ align-items: center;
301
+ justify-content: center;
302
+ width: 80px;
303
+ height: 80px;
304
+ margin-bottom: 1.5rem;
305
+ color: #1f2937;
306
+ }
307
+
308
+ .chat-panel__welcome-icon svg {
309
+ width: 100%;
310
+ height: 100%;
311
+ }
312
+
313
+ .chat-panel__welcome-title {
314
+ font-size: 1.5rem;
315
+ font-weight: 600;
316
+ color: #1f2937;
317
+ margin: 0 0 0.5rem 0;
318
+ }
319
+
320
+ .chat-panel__welcome-text {
321
+ font-size: 1rem;
322
+ color: #6b7280;
323
+ margin: 0;
324
+ }
325
+
326
+ /* Typing Indicator */
327
+ .chat-panel__typing {
328
+ display: flex;
329
+ align-items: center;
330
+ gap: 0.5rem;
331
+ padding: 0.75rem 1rem;
332
+ margin-top: 0.5rem;
333
+ background-color: #f3f4f6;
334
+ border-radius: 1rem;
335
+ width: fit-content;
336
+ }
337
+
338
+ .chat-panel__typing-indicator {
339
+ display: flex;
340
+ gap: 0.25rem;
341
+ }
342
+
343
+ .chat-panel__typing-indicator span {
344
+ width: 0.375rem;
345
+ height: 0.375rem;
346
+ background-color: #9ca3af;
347
+ border-radius: 50%;
348
+ animation: bounce 1.4s ease-in-out infinite;
349
+ }
350
+
351
+ .chat-panel__typing-indicator span:nth-child(1) {
352
+ animation-delay: 0s;
353
+ }
354
+
355
+ .chat-panel__typing-indicator span:nth-child(2) {
356
+ animation-delay: 0.2s;
357
+ }
358
+
359
+ .chat-panel__typing-indicator span:nth-child(3) {
360
+ animation-delay: 0.4s;
361
+ }
362
+
363
+ @keyframes bounce {
364
+ 0%,
365
+ 60%,
366
+ 100% {
367
+ transform: translateY(0);
368
+ }
369
+ 30% {
370
+ transform: translateY(-0.25rem);
371
+ }
372
+ }
373
+
374
+ .chat-panel__typing-text {
375
+ font-size: 0.8125rem;
376
+ color: #6b7280;
377
+ }
378
+
379
+ /* Input Area */
380
+ .chat-panel__input-area {
381
+ padding: 1rem 1.5rem 1.5rem;
382
+ background-color: #ffffff;
383
+ }
384
+
385
+ .chat-panel__input-container {
386
+ display: flex;
387
+ align-items: flex-end;
388
+ gap: 0.75rem;
389
+ max-width: 800px;
390
+ margin: 0 auto;
391
+ }
392
+
393
+ .chat-panel__input-wrapper {
394
+ flex: 1;
395
+ display: flex;
396
+ align-items: flex-end;
397
+ background-color: #ffffff;
398
+ border: 1px solid #e5e7eb;
399
+ border-radius: 0.75rem;
400
+ padding: 0.625rem 0.75rem;
401
+ transition:
402
+ border-color 0.15s ease,
403
+ box-shadow 0.15s ease;
404
+ }
405
+
406
+ .chat-panel__input-wrapper:focus-within {
407
+ border-color: #6366f1;
408
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
409
+ }
410
+
411
+ .chat-panel__input {
412
+ flex: 1;
413
+ border: none;
414
+ outline: none;
415
+ resize: none;
416
+ font-family: inherit;
417
+ font-size: 0.9375rem;
418
+ line-height: 1.5;
419
+ max-height: 120px;
420
+ background: transparent;
421
+ color: #1f2937;
422
+ }
423
+
424
+ .chat-panel__input::placeholder {
425
+ color: #9ca3af;
426
+ }
427
+
428
+ .chat-panel__input:disabled {
429
+ cursor: not-allowed;
430
+ opacity: 0.6;
431
+ }
432
+
433
+ .chat-panel__attachment-btn {
434
+ display: flex;
435
+ align-items: center;
436
+ justify-content: center;
437
+ width: 2rem;
438
+ height: 2rem;
439
+ border: none;
440
+ border-radius: 0.375rem;
441
+ background: transparent;
442
+ color: #9ca3af;
443
+ cursor: pointer;
444
+ transition: all 0.15s ease;
445
+ flex-shrink: 0;
446
+ }
447
+
448
+ .chat-panel__attachment-btn:hover:not(:disabled) {
449
+ color: #6b7280;
450
+ background-color: #f3f4f6;
451
+ }
452
+
453
+ .chat-panel__attachment-btn:disabled {
454
+ opacity: 0.5;
455
+ cursor: not-allowed;
456
+ }
457
+
458
+ .chat-panel__send-btn {
459
+ display: flex;
460
+ align-items: center;
461
+ justify-content: center;
462
+ padding: 0.625rem 1.25rem;
463
+ border: none;
464
+ border-radius: 0.5rem;
465
+ background-color: #1f2937;
466
+ color: #ffffff;
467
+ font-size: 0.875rem;
468
+ font-weight: 500;
469
+ cursor: pointer;
470
+ transition: all 0.15s ease;
471
+ flex-shrink: 0;
472
+ }
473
+
474
+ .chat-panel__send-btn:hover:not(:disabled) {
475
+ background-color: #374151;
476
+ }
477
+
478
+ .chat-panel__send-btn:disabled {
479
+ background-color: #e5e7eb;
480
+ color: #9ca3af;
481
+ cursor: not-allowed;
482
+ }
483
+
484
+ .chat-panel__stop-btn {
485
+ display: flex;
486
+ align-items: center;
487
+ gap: 0.375rem;
488
+ padding: 0.625rem 1rem;
489
+ border: none;
490
+ border-radius: 0.5rem;
491
+ background-color: #ef4444;
492
+ color: #ffffff;
493
+ font-size: 0.875rem;
494
+ font-weight: 500;
495
+ cursor: pointer;
496
+ transition: background-color 0.15s ease;
497
+ flex-shrink: 0;
498
+ }
499
+
500
+ .chat-panel__stop-btn:hover {
501
+ background-color: #dc2626;
502
+ }
503
+
504
+ /* Responsive */
505
+ @media (max-width: 640px) {
506
+ .chat-panel__messages {
507
+ padding: 1rem;
508
+ }
509
+
510
+ .chat-panel__input-area {
511
+ padding: 0.75rem 1rem 1rem;
512
+ }
513
+
514
+ .chat-panel__input-container {
515
+ gap: 0.5rem;
516
+ }
517
+
518
+ .chat-panel__send-btn,
519
+ .chat-panel__stop-btn {
520
+ padding: 0.5rem 1rem;
521
+ }
522
+ }
523
+ </style>
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Component props
3
+ */
4
+ interface Props {
5
+ /** Whether to show timestamps on messages */
6
+ showTimestamps?: boolean;
7
+ /** Whether to auto-scroll to bottom on new messages */
8
+ autoScroll?: boolean;
9
+ /** Placeholder text for the input */
10
+ placeholder?: string;
11
+ /** Callback when user sends a message */
12
+ onSendMessage?: (content: string) => void;
13
+ /** Callback when user requests to stop execution */
14
+ onStopExecution?: () => void;
15
+ /** Whether to show log messages inline (false = hide them) */
16
+ showLogsInline?: boolean;
17
+ }
18
+ declare const ChatPanel: import("svelte").Component<Props, {}, "">;
19
+ type ChatPanel = ReturnType<typeof ChatPanel>;
20
+ export default ChatPanel;