@flowdrop/flowdrop 1.11.0 → 1.13.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.
- package/dist/api/enhanced-client.d.ts +29 -16
- package/dist/api/enhanced-client.js +0 -14
- package/dist/components/ConfigForm.svelte +1 -0
- package/dist/components/PipelineStatus.svelte +9 -12
- package/dist/components/SchemaForm.svelte +1 -0
- package/dist/components/WorkflowEditor.svelte +3 -0
- package/dist/components/form/FormAutocomplete.svelte +67 -10
- package/dist/components/form/FormField.svelte +21 -0
- package/dist/components/form/FormFieldLight.svelte +1 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +24 -5
- package/dist/components/interrupt/ConfirmationPrompt.svelte +5 -0
- package/dist/components/interrupt/InterruptBubble.svelte +88 -17
- package/dist/components/interrupt/InterruptBubble.svelte.d.ts +11 -0
- package/dist/components/interrupt/ReviewPrompt.svelte +20 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +5 -0
- package/dist/components/nodes/GatewayNode.svelte +2 -6
- package/dist/components/nodes/WorkflowNode.svelte +2 -6
- package/dist/components/playground/ChatBubble.svelte +289 -0
- package/dist/components/playground/ChatBubble.svelte.d.ts +10 -0
- package/dist/components/playground/ChatInput.svelte +359 -0
- package/dist/components/playground/ChatInput.svelte.d.ts +14 -0
- package/dist/components/playground/ChatPanel.svelte +100 -724
- package/dist/components/playground/ChatPanel.svelte.d.ts +9 -26
- package/dist/components/playground/ControlPanel.svelte +496 -0
- package/dist/components/playground/ControlPanel.svelte.d.ts +20 -0
- package/dist/components/playground/ExecutionConsole.svelte +163 -0
- package/dist/components/playground/ExecutionConsole.svelte.d.ts +14 -0
- package/dist/components/playground/HierarchyTrail.svelte +88 -0
- package/dist/components/playground/HierarchyTrail.svelte.d.ts +7 -0
- package/dist/components/playground/LogRow.svelte +178 -0
- package/dist/components/playground/LogRow.svelte.d.ts +8 -0
- package/dist/components/playground/MessageBubble.stories.svelte +89 -0
- package/dist/components/playground/MessageBubble.svelte +25 -737
- package/dist/components/playground/MessageBubble.svelte.d.ts +3 -11
- package/dist/components/playground/MessageCard.svelte +106 -0
- package/dist/components/playground/MessageCard.svelte.d.ts +10 -0
- package/dist/components/playground/MessageMarkdown.svelte +160 -0
- package/dist/components/playground/MessageMarkdown.svelte.d.ts +7 -0
- package/dist/components/playground/MessageNotice.svelte +120 -0
- package/dist/components/playground/MessageNotice.svelte.d.ts +9 -0
- package/dist/components/playground/MessageStream.svelte +367 -0
- package/dist/components/playground/MessageStream.svelte.d.ts +27 -0
- package/dist/components/playground/MessageTagChip.svelte +99 -0
- package/dist/components/playground/MessageTagChip.svelte.d.ts +7 -0
- package/dist/components/playground/MessageTagStrip.svelte +37 -0
- package/dist/components/playground/MessageTagStrip.svelte.d.ts +7 -0
- package/dist/components/playground/PipelineKanbanView.svelte +284 -0
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +11 -0
- package/dist/components/playground/PipelinePanel.svelte +204 -65
- package/dist/components/playground/PipelinePanel.svelte.d.ts +3 -1
- package/dist/components/playground/PipelineTableView.svelte +376 -0
- package/dist/components/playground/PipelineTableView.svelte.d.ts +11 -0
- package/dist/components/playground/Playground.svelte +262 -1200
- package/dist/components/playground/Playground.svelte.d.ts +0 -13
- package/dist/components/playground/PlaygroundStudio.svelte +113 -61
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -1
- package/dist/components/playground/messageDisplay.d.ts +19 -0
- package/dist/components/playground/messageDisplay.js +62 -0
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +22 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +77 -0
- package/dist/form/autocomplete.d.ts +1 -0
- package/dist/form/autocomplete.js +1 -0
- package/dist/form/index.d.ts +17 -0
- package/dist/form/index.js +19 -0
- package/dist/messages/defaults.d.ts +29 -0
- package/dist/messages/defaults.js +30 -0
- package/dist/playground/index.d.ts +6 -1
- package/dist/playground/index.js +6 -0
- package/dist/playground/mount.d.ts +3 -0
- package/dist/playground/mount.js +3 -2
- package/dist/schemas/v1/workflow.schema.json +10 -1
- package/dist/services/categoriesApi.d.ts +2 -1
- package/dist/services/categoriesApi.js +5 -3
- package/dist/services/portConfigApi.d.ts +2 -1
- package/dist/services/portConfigApi.js +5 -3
- package/dist/stores/playgroundStore.svelte.d.ts +6 -0
- package/dist/stores/playgroundStore.svelte.js +21 -1
- package/dist/svelte-app.d.ts +1 -0
- package/dist/svelte-app.js +5 -5
- package/dist/types/index.d.ts +41 -2
- package/dist/types/playground.d.ts +81 -2
- package/dist/types/playground.js +19 -7
- package/dist/utils/nodeStatus.js +15 -5
- package/package.json +6 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
ExecutionConsole Component
|
|
3
|
+
|
|
4
|
+
The running workflow's runtime surface. Renders the message feed via
|
|
5
|
+
MessageStream and surfaces the flow's own UI (interrupts) inline during
|
|
6
|
+
execution. This is *not* a chat — it's the console where the flow speaks
|
|
7
|
+
to the user during a run. User-initiated commands live in ControlPanel.
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
<script lang="ts">
|
|
11
|
+
import Icon from '@iconify/svelte';
|
|
12
|
+
import MessageStream from './MessageStream.svelte';
|
|
13
|
+
import { m } from '../../messages/index.js';
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
showTimestamps?: boolean;
|
|
17
|
+
autoScroll?: boolean;
|
|
18
|
+
enableMarkdown?: boolean;
|
|
19
|
+
/** Whether log messages can appear when the user toggle is on. Defaults to true for the execution console. */
|
|
20
|
+
allowLogs?: boolean;
|
|
21
|
+
compactSystemMessages?: boolean;
|
|
22
|
+
onInterruptResolved?: () => void;
|
|
23
|
+
/** Optional callback that, when provided, shows a "New session" CTA in the welcome state */
|
|
24
|
+
onCreateSession?: () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
showTimestamps = true,
|
|
29
|
+
autoScroll = true,
|
|
30
|
+
enableMarkdown = true,
|
|
31
|
+
allowLogs = true,
|
|
32
|
+
compactSystemMessages = true,
|
|
33
|
+
onInterruptResolved,
|
|
34
|
+
onCreateSession
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
|
|
37
|
+
const ec = $derived(m().playground.executionConsole);
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<section class="execution-console">
|
|
41
|
+
<header class="execution-console__header">
|
|
42
|
+
<Icon icon="mdi:console-line" class="execution-console__icon" />
|
|
43
|
+
<span class="execution-console__title">{ec.header}</span>
|
|
44
|
+
</header>
|
|
45
|
+
|
|
46
|
+
<MessageStream
|
|
47
|
+
{showTimestamps}
|
|
48
|
+
{autoScroll}
|
|
49
|
+
{enableMarkdown}
|
|
50
|
+
{allowLogs}
|
|
51
|
+
{compactSystemMessages}
|
|
52
|
+
{onInterruptResolved}
|
|
53
|
+
welcome={welcomeState}
|
|
54
|
+
emptySession={readyState}
|
|
55
|
+
/>
|
|
56
|
+
</section>
|
|
57
|
+
|
|
58
|
+
{#snippet welcomeState()}
|
|
59
|
+
<div class="execution-console__placeholder">
|
|
60
|
+
<Icon icon="mdi:play-circle-outline" class="execution-console__placeholder-icon" />
|
|
61
|
+
<h2 class="execution-console__placeholder-title">{ec.noExecutionTitle}</h2>
|
|
62
|
+
<p class="execution-console__placeholder-text">{ec.noExecutionText}</p>
|
|
63
|
+
{#if onCreateSession}
|
|
64
|
+
<button type="button" class="execution-console__cta" onclick={onCreateSession}>
|
|
65
|
+
<Icon icon="mdi:plus" />
|
|
66
|
+
{ec.newSession}
|
|
67
|
+
</button>
|
|
68
|
+
{/if}
|
|
69
|
+
</div>
|
|
70
|
+
{/snippet}
|
|
71
|
+
|
|
72
|
+
{#snippet readyState()}
|
|
73
|
+
<div class="execution-console__placeholder">
|
|
74
|
+
<Icon icon="mdi:play-circle-outline" class="execution-console__placeholder-icon" />
|
|
75
|
+
<h2 class="execution-console__placeholder-title">{ec.readyTitle}</h2>
|
|
76
|
+
<p class="execution-console__placeholder-text">{ec.readyText}</p>
|
|
77
|
+
</div>
|
|
78
|
+
{/snippet}
|
|
79
|
+
|
|
80
|
+
<style>
|
|
81
|
+
.execution-console {
|
|
82
|
+
flex: 1;
|
|
83
|
+
min-height: 0;
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
background-color: var(--fd-background);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.execution-console__header {
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
gap: var(--fd-space-xs);
|
|
94
|
+
padding: 0 var(--fd-space-xl);
|
|
95
|
+
height: var(--fd-playground-header-height);
|
|
96
|
+
min-height: var(--fd-playground-header-height);
|
|
97
|
+
border-bottom: 1px solid var(--fd-border);
|
|
98
|
+
flex-shrink: 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
:global(.execution-console__icon) {
|
|
102
|
+
font-size: var(--fd-text-base);
|
|
103
|
+
color: var(--fd-muted-foreground);
|
|
104
|
+
flex-shrink: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.execution-console__title {
|
|
108
|
+
font-size: var(--fd-text-sm);
|
|
109
|
+
font-weight: 600;
|
|
110
|
+
color: var(--fd-foreground);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.execution-console__placeholder {
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
align-items: center;
|
|
117
|
+
justify-content: center;
|
|
118
|
+
height: 100%;
|
|
119
|
+
text-align: center;
|
|
120
|
+
padding: var(--fd-space-4xl);
|
|
121
|
+
color: var(--fd-muted-foreground);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
:global(.execution-console__placeholder-icon) {
|
|
125
|
+
font-size: var(--fd-space-6xl);
|
|
126
|
+
color: var(--fd-border-strong);
|
|
127
|
+
margin-bottom: var(--fd-space-xl);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.execution-console__placeholder-title {
|
|
131
|
+
font-size: var(--fd-text-xl);
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
color: var(--fd-foreground);
|
|
134
|
+
margin: 0 0 var(--fd-space-xs) 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.execution-console__placeholder-text {
|
|
138
|
+
font-size: var(--fd-text-sm);
|
|
139
|
+
color: var(--fd-muted-foreground);
|
|
140
|
+
margin: 0;
|
|
141
|
+
max-width: 360px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.execution-console__cta {
|
|
145
|
+
display: inline-flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
gap: var(--fd-space-xs);
|
|
148
|
+
margin-top: var(--fd-space-2xl);
|
|
149
|
+
padding: var(--fd-space-sm) var(--fd-space-xl);
|
|
150
|
+
border: none;
|
|
151
|
+
border-radius: var(--fd-radius-md);
|
|
152
|
+
background: var(--fd-primary);
|
|
153
|
+
color: var(--fd-primary-foreground);
|
|
154
|
+
font-size: var(--fd-text-base);
|
|
155
|
+
font-weight: 500;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
transition: opacity var(--fd-transition-fast);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.execution-console__cta:hover {
|
|
161
|
+
opacity: 0.9;
|
|
162
|
+
}
|
|
163
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
showTimestamps?: boolean;
|
|
3
|
+
autoScroll?: boolean;
|
|
4
|
+
enableMarkdown?: boolean;
|
|
5
|
+
/** Whether log messages can appear when the user toggle is on. Defaults to true for the execution console. */
|
|
6
|
+
allowLogs?: boolean;
|
|
7
|
+
compactSystemMessages?: boolean;
|
|
8
|
+
onInterruptResolved?: () => void;
|
|
9
|
+
/** Optional callback that, when provided, shows a "New session" CTA in the welcome state */
|
|
10
|
+
onCreateSession?: () => void;
|
|
11
|
+
}
|
|
12
|
+
declare const ExecutionConsole: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type ExecutionConsole = ReturnType<typeof ExecutionConsole>;
|
|
14
|
+
export default ExecutionConsole;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
HierarchyTrail Component
|
|
3
|
+
|
|
4
|
+
Renders a chevron-separated path of MessageHierarchyItem entries. The
|
|
5
|
+
path is a *display*, not a list users navigate, so the SR announcement
|
|
6
|
+
comes entirely from the wrapper's aria-label (built from the labels of
|
|
7
|
+
the items themselves) and the visible chips are hidden from AT to avoid
|
|
8
|
+
the path being announced twice.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import Icon from '@iconify/svelte';
|
|
13
|
+
import type { MessageHierarchyItem } from '../../types/playground.js';
|
|
14
|
+
import { m } from '../../messages/index.js';
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
items: MessageHierarchyItem[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let { items }: Props = $props();
|
|
21
|
+
|
|
22
|
+
const ariaLabel = $derived.by(() => {
|
|
23
|
+
const path = items.map((i) => i.label).join(' / ');
|
|
24
|
+
return m().playground.messageAnnotations.hierarchyOf({ path });
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
{#if items.length > 0}
|
|
29
|
+
<span class="hierarchy-trail" aria-label={ariaLabel}>
|
|
30
|
+
{#each items as item (item.id)}
|
|
31
|
+
<span class="hierarchy-trail__item" aria-hidden="true">
|
|
32
|
+
{#if item.icon}
|
|
33
|
+
<Icon icon={item.icon} class="hierarchy-trail__icon" />
|
|
34
|
+
{/if}
|
|
35
|
+
<span class="hierarchy-trail__label">{item.label}</span>
|
|
36
|
+
</span>
|
|
37
|
+
{/each}
|
|
38
|
+
</span>
|
|
39
|
+
{/if}
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
.hierarchy-trail {
|
|
43
|
+
display: inline-flex;
|
|
44
|
+
flex-wrap: wrap;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: var(--fd-space-3xs);
|
|
47
|
+
font-size: var(--fd-text-2xs);
|
|
48
|
+
color: var(--fd-muted-foreground);
|
|
49
|
+
min-width: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.hierarchy-trail__item {
|
|
53
|
+
display: inline-flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: var(--fd-space-3xs);
|
|
56
|
+
min-width: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Chevron separator between items, drawn as a pseudo-element so it
|
|
60
|
+
doesn't enter the markup (and so it never appears to AT — the items
|
|
61
|
+
are already aria-hidden, but belt-and-braces). U+203A SINGLE
|
|
62
|
+
RIGHT-POINTING ANGLE QUOTATION MARK matches mdi:chevron-right
|
|
63
|
+
closely enough without a second iconify dependency. */
|
|
64
|
+
.hierarchy-trail__item:not(:last-child)::after {
|
|
65
|
+
content: '\203A';
|
|
66
|
+
margin-inline-start: var(--fd-space-3xs);
|
|
67
|
+
opacity: 0.5;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.hierarchy-trail__label {
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
text-overflow: ellipsis;
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
max-width: 8rem;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@media (max-width: 640px) {
|
|
78
|
+
.hierarchy-trail__label {
|
|
79
|
+
max-width: 5rem;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.hierarchy-trail :global(.hierarchy-trail__icon) {
|
|
84
|
+
flex-shrink: 0;
|
|
85
|
+
font-size: 0.875em;
|
|
86
|
+
opacity: 0.7;
|
|
87
|
+
}
|
|
88
|
+
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MessageHierarchyItem } from '../../types/playground.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
items: MessageHierarchyItem[];
|
|
4
|
+
}
|
|
5
|
+
declare const HierarchyTrail: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type HierarchyTrail = ReturnType<typeof HierarchyTrail>;
|
|
7
|
+
export default HierarchyTrail;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
LogRow — dense terminal-style entry for log messages.
|
|
3
|
+
Width-based reshaping is driven by `@container fd-message-stream` rules
|
|
4
|
+
declared in MessageStream.svelte (the file that also sets the container).
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import Icon from '@iconify/svelte';
|
|
9
|
+
import type { PlaygroundMessage } from '../../types/playground.js';
|
|
10
|
+
import HierarchyTrail from './HierarchyTrail.svelte';
|
|
11
|
+
import MessageTagStrip from './MessageTagStrip.svelte';
|
|
12
|
+
import { formatTimestamp, getLogLevelIcon } from './messageDisplay.js';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
message: PlaygroundMessage;
|
|
16
|
+
showTimestamp?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { message, showTimestamp = true }: Props = $props();
|
|
20
|
+
|
|
21
|
+
const level = $derived(message.metadata?.level);
|
|
22
|
+
const hierarchy = $derived(message.hierarchy ?? []);
|
|
23
|
+
const tags = $derived(message.tags ?? []);
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="log-row"
|
|
28
|
+
class:log-row--error={level === 'error'}
|
|
29
|
+
class:log-row--warning={level === 'warning'}
|
|
30
|
+
class:log-row--debug={level === 'debug'}
|
|
31
|
+
aria-label="{level ?? 'info'} log{message.metadata?.nodeLabel
|
|
32
|
+
? ` from ${message.metadata.nodeLabel}`
|
|
33
|
+
: ''}"
|
|
34
|
+
>
|
|
35
|
+
<div class="log-row__level" aria-hidden="true">
|
|
36
|
+
<Icon icon={getLogLevelIcon(level)} />
|
|
37
|
+
</div>
|
|
38
|
+
<div class="log-row__body">
|
|
39
|
+
{#if message.metadata?.source}
|
|
40
|
+
<span class="log-row__source">{message.metadata.source}</span>
|
|
41
|
+
{/if}
|
|
42
|
+
<HierarchyTrail items={hierarchy} />
|
|
43
|
+
{#if message.metadata?.nodeLabel ?? message.nodeId}
|
|
44
|
+
<span class="log-row__node">{message.metadata?.nodeLabel ?? message.nodeId}</span>
|
|
45
|
+
{/if}
|
|
46
|
+
<span class="log-row__text">{message.content}</span>
|
|
47
|
+
</div>
|
|
48
|
+
{#if tags.length > 0}
|
|
49
|
+
<span class="log-row__tags">
|
|
50
|
+
<MessageTagStrip {tags} />
|
|
51
|
+
</span>
|
|
52
|
+
{/if}
|
|
53
|
+
{#if showTimestamp}
|
|
54
|
+
<time
|
|
55
|
+
class="log-row__timestamp"
|
|
56
|
+
datetime={message.timestamp}
|
|
57
|
+
aria-label="sent at {formatTimestamp(message.timestamp)}"
|
|
58
|
+
>{formatTimestamp(message.timestamp)}</time>
|
|
59
|
+
{/if}
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
.log-row {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-wrap: wrap;
|
|
66
|
+
align-items: center;
|
|
67
|
+
gap: var(--fd-space-sm);
|
|
68
|
+
padding: 0.1875rem var(--fd-space-xl);
|
|
69
|
+
border-left: 2px solid var(--fd-info);
|
|
70
|
+
margin: 1px 0;
|
|
71
|
+
font-family: var(--fd-font-mono);
|
|
72
|
+
font-size: var(--fd-text-xs);
|
|
73
|
+
color: var(--fd-muted-foreground);
|
|
74
|
+
line-height: var(--fd-leading-normal);
|
|
75
|
+
background-color: transparent;
|
|
76
|
+
min-width: 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.log-row:hover {
|
|
80
|
+
background-color: var(--fd-muted);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.log-row--error {
|
|
84
|
+
border-left-color: var(--fd-error);
|
|
85
|
+
color: var(--fd-error);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.log-row--warning {
|
|
89
|
+
border-left-color: var(--fd-warning);
|
|
90
|
+
color: var(--fd-warning);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.log-row--debug {
|
|
94
|
+
border-left-color: var(--fd-border-strong);
|
|
95
|
+
color: var(--fd-border-strong);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.log-row__level {
|
|
99
|
+
flex-shrink: 0;
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
font-size: var(--fd-text-sm);
|
|
103
|
+
opacity: 0.7;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.log-row--error .log-row__level,
|
|
107
|
+
.log-row--warning .log-row__level {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.log-row__body {
|
|
112
|
+
flex: 1 1 12rem;
|
|
113
|
+
min-width: 0;
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-wrap: wrap;
|
|
116
|
+
align-items: baseline;
|
|
117
|
+
gap: var(--fd-space-sm);
|
|
118
|
+
overflow: hidden;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.log-row__source {
|
|
122
|
+
flex-shrink: 0;
|
|
123
|
+
font-size: 0.6rem;
|
|
124
|
+
text-transform: uppercase;
|
|
125
|
+
letter-spacing: 0.06em;
|
|
126
|
+
color: var(--fd-muted-foreground);
|
|
127
|
+
opacity: 0.6;
|
|
128
|
+
background-color: var(--fd-muted);
|
|
129
|
+
border: 1px solid var(--fd-border);
|
|
130
|
+
border-radius: var(--fd-radius-sm);
|
|
131
|
+
padding: 0 0.25rem;
|
|
132
|
+
line-height: 1.4;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.log-row__node {
|
|
136
|
+
flex-shrink: 0;
|
|
137
|
+
font-weight: 600;
|
|
138
|
+
color: var(--fd-foreground);
|
|
139
|
+
opacity: 0.5;
|
|
140
|
+
font-size: 0.65rem;
|
|
141
|
+
text-transform: uppercase;
|
|
142
|
+
letter-spacing: 0.04em;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.log-row__text {
|
|
146
|
+
flex: 1;
|
|
147
|
+
min-width: 0;
|
|
148
|
+
white-space: pre-wrap;
|
|
149
|
+
overflow-wrap: anywhere;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.log-row__timestamp {
|
|
153
|
+
flex-shrink: 0;
|
|
154
|
+
font-size: 0.625rem;
|
|
155
|
+
color: var(--fd-border-strong);
|
|
156
|
+
opacity: 0.8;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Wrapper around the tag strip. Owns its grid-area in the @container
|
|
160
|
+
queries (see MessageStream.svelte) without those rules reaching into
|
|
161
|
+
MessageTagStrip's scope. inline-flex so the strip lays out naturally
|
|
162
|
+
in the default wide layout. */
|
|
163
|
+
.log-row__tags {
|
|
164
|
+
display: inline-flex;
|
|
165
|
+
min-width: 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@media (max-width: 640px) {
|
|
169
|
+
.log-row {
|
|
170
|
+
padding: 0.1875rem var(--fd-space-md);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.log-row__source,
|
|
174
|
+
.log-row__node {
|
|
175
|
+
font-size: 0.55rem;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
</style>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PlaygroundMessage } from '../../types/playground.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
message: PlaygroundMessage;
|
|
4
|
+
showTimestamp?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare const LogRow: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type LogRow = ReturnType<typeof LogRow>;
|
|
8
|
+
export default LogRow;
|
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
layout: 'padded'
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
|
+
|
|
14
|
+
const baseHierarchy = [
|
|
15
|
+
{ id: 'demo-foreach-loop', label: 'ForEach Loop', icon: 'mdi:graph' },
|
|
16
|
+
{ id: 'greeter-flow', label: 'Greeter', icon: 'mdi:hand-wave' }
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const sampleTags = [
|
|
20
|
+
{ id: 'run', label: 'Run #3', icon: 'mdi:play-circle', color: 'info', variant: 'subtle' },
|
|
21
|
+
{ id: 'iteration', label: 'iter 1/5', color: 'muted', variant: 'subtle' }
|
|
22
|
+
];
|
|
13
23
|
</script>
|
|
14
24
|
|
|
15
25
|
<Story
|
|
@@ -60,3 +70,82 @@
|
|
|
60
70
|
}
|
|
61
71
|
}}
|
|
62
72
|
/>
|
|
73
|
+
|
|
74
|
+
<Story
|
|
75
|
+
name="With Tags"
|
|
76
|
+
args={{
|
|
77
|
+
message: {
|
|
78
|
+
id: 'msg-5',
|
|
79
|
+
role: 'assistant',
|
|
80
|
+
content: 'Iteration complete.',
|
|
81
|
+
timestamp: new Date().toISOString(),
|
|
82
|
+
tags: sampleTags
|
|
83
|
+
}
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
86
|
+
|
|
87
|
+
<Story
|
|
88
|
+
name="Tag Colors (each variant)"
|
|
89
|
+
args={{
|
|
90
|
+
message: {
|
|
91
|
+
id: 'msg-6',
|
|
92
|
+
role: 'log',
|
|
93
|
+
content: 'Showcasing semantic colors and visual variants',
|
|
94
|
+
timestamp: new Date().toISOString(),
|
|
95
|
+
tags: [
|
|
96
|
+
{ id: 't-1', label: 'subtle.muted', color: 'muted', variant: 'subtle' },
|
|
97
|
+
{ id: 't-2', label: 'subtle.success', color: 'success', variant: 'subtle' },
|
|
98
|
+
{ id: 't-3', label: 'subtle.warning', color: 'warning', variant: 'subtle' },
|
|
99
|
+
{ id: 't-4', label: 'subtle.error', color: 'error', variant: 'subtle' },
|
|
100
|
+
{ id: 't-5', label: 'outline.primary', color: 'primary', variant: 'outline' },
|
|
101
|
+
{ id: 't-6', label: 'solid.info', color: 'info', variant: 'solid' }
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
|
|
107
|
+
<Story
|
|
108
|
+
name="With Hierarchy"
|
|
109
|
+
args={{
|
|
110
|
+
message: {
|
|
111
|
+
id: 'msg-7',
|
|
112
|
+
role: 'log',
|
|
113
|
+
content: 'greeter said hi to Apple',
|
|
114
|
+
timestamp: new Date().toISOString(),
|
|
115
|
+
hierarchy: baseHierarchy,
|
|
116
|
+
tags: [{ id: 'iter', label: 'iter 1/5', color: 'muted', variant: 'subtle' }]
|
|
117
|
+
}
|
|
118
|
+
}}
|
|
119
|
+
/>
|
|
120
|
+
|
|
121
|
+
<Story
|
|
122
|
+
name="Card Display"
|
|
123
|
+
args={{
|
|
124
|
+
message: {
|
|
125
|
+
id: 'msg-8',
|
|
126
|
+
role: 'log',
|
|
127
|
+
content:
|
|
128
|
+
'Greeter aborted because Cherry never reached the queue. The upstream loader returned a timeout after retrying twice — check the JSON Loader configuration for `retries` and `backoffMs`.',
|
|
129
|
+
timestamp: new Date().toISOString(),
|
|
130
|
+
display: 'card',
|
|
131
|
+
hierarchy: baseHierarchy,
|
|
132
|
+
tags: [
|
|
133
|
+
{ id: 'iter', label: 'iter 3/5', color: 'muted', variant: 'subtle' },
|
|
134
|
+
{ id: 'status', label: 'aborted', color: 'warning', variant: 'solid' }
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
<Story
|
|
141
|
+
name="Server-driven display override (log as bubble)"
|
|
142
|
+
args={{
|
|
143
|
+
message: {
|
|
144
|
+
id: 'msg-9',
|
|
145
|
+
role: 'log',
|
|
146
|
+
content: 'This log message is rendered as a bubble because the server set display=bubble',
|
|
147
|
+
timestamp: new Date().toISOString(),
|
|
148
|
+
display: 'bubble'
|
|
149
|
+
}
|
|
150
|
+
}}
|
|
151
|
+
/>
|