@d34dman/flowdrop 0.0.37 → 0.0.39
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/LICENSE +21 -0
- package/dist/components/NodeSidebar.svelte +1 -0
- package/dist/components/form/FormCodeEditor.svelte +6 -1
- package/dist/components/interrupt/ChoicePrompt.svelte +389 -0
- package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +21 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte +280 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/FormPrompt.svelte +223 -0
- package/dist/components/interrupt/FormPrompt.svelte.d.ts +21 -0
- package/dist/components/interrupt/InterruptBubble.svelte +621 -0
- package/dist/components/interrupt/InterruptBubble.svelte.d.ts +16 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +333 -0
- package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +21 -0
- package/dist/components/interrupt/index.d.ts +13 -0
- package/dist/components/interrupt/index.js +15 -0
- package/dist/components/nodes/GatewayNode.svelte +1 -3
- package/dist/components/nodes/IdeaNode.svelte +30 -35
- package/dist/components/nodes/IdeaNode.svelte.d.ts +1 -1
- package/dist/components/nodes/SimpleNode.svelte +1 -3
- package/dist/components/nodes/TerminalNode.svelte +1 -3
- package/dist/components/nodes/ToolNode.svelte +2 -2
- package/dist/components/nodes/WorkflowNode.svelte +1 -3
- package/dist/components/playground/ChatPanel.svelte +144 -7
- package/dist/components/playground/ChatPanel.svelte.d.ts +2 -0
- package/dist/components/playground/MessageBubble.svelte +1 -3
- package/dist/components/playground/Playground.svelte +50 -5
- package/dist/components/playground/PlaygroundModal.svelte +8 -7
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -3
- package/dist/config/endpoints.d.ts +12 -0
- package/dist/config/endpoints.js +7 -0
- package/dist/playground/index.d.ts +5 -0
- package/dist/playground/index.js +21 -0
- package/dist/playground/mount.d.ts +3 -3
- package/dist/playground/mount.js +30 -22
- package/dist/services/interruptService.d.ts +133 -0
- package/dist/services/interruptService.js +279 -0
- package/dist/stores/interruptStore.d.ts +200 -0
- package/dist/stores/interruptStore.js +424 -0
- package/dist/stores/playgroundStore.d.ts +11 -1
- package/dist/stores/playgroundStore.js +34 -0
- package/dist/styles/base.css +89 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/interrupt.d.ts +305 -0
- package/dist/types/interrupt.js +126 -0
- package/dist/types/interruptState.d.ts +211 -0
- package/dist/types/interruptState.js +308 -0
- package/dist/utils/colors.js +1 -0
- package/dist/utils/connections.js +2 -2
- package/dist/utils/icons.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interrupt State Machine
|
|
3
|
+
*
|
|
4
|
+
* Lightweight state machine pattern for interrupt handling.
|
|
5
|
+
* Ensures valid state transitions and prevents deadlocks.
|
|
6
|
+
*
|
|
7
|
+
* State Diagram:
|
|
8
|
+
* ```
|
|
9
|
+
* ┌─────────────┐
|
|
10
|
+
* │ idle │
|
|
11
|
+
* └──────┬──────┘
|
|
12
|
+
* │
|
|
13
|
+
* ┌──────────────┼──────────────┐
|
|
14
|
+
* │ submit │ cancel │
|
|
15
|
+
* ▼ │ ▼
|
|
16
|
+
* ┌─────────────┐ │ ┌─────────────┐
|
|
17
|
+
* │ submitting │ │ │ cancelled │
|
|
18
|
+
* └──────┬──────┘ │ └─────────────┘
|
|
19
|
+
* │ │
|
|
20
|
+
* ┌──────┴──────┐ │
|
|
21
|
+
* │ │ │
|
|
22
|
+
* ▼ success ▼ fail │
|
|
23
|
+
* ┌─────────┐ ┌─────────┐ │
|
|
24
|
+
* │resolved │ │ error │──┘ cancel
|
|
25
|
+
* └─────────┘ └────┬────┘
|
|
26
|
+
* │ retry
|
|
27
|
+
* ▼
|
|
28
|
+
* ┌─────────────┐
|
|
29
|
+
* │ submitting │
|
|
30
|
+
* └─────────────┘
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @module types/interruptState
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Initial idle state
|
|
37
|
+
*/
|
|
38
|
+
export const initialState = { status: 'idle' };
|
|
39
|
+
/**
|
|
40
|
+
* Transition function for the interrupt state machine
|
|
41
|
+
*
|
|
42
|
+
* @param state - Current state
|
|
43
|
+
* @param action - Action to apply
|
|
44
|
+
* @returns New state after transition
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* let state = initialState;
|
|
49
|
+
*
|
|
50
|
+
* // User submits
|
|
51
|
+
* const result1 = transition(state, { type: "SUBMIT", value: true });
|
|
52
|
+
* if (result1.valid) state = result1.state;
|
|
53
|
+
*
|
|
54
|
+
* // API succeeds
|
|
55
|
+
* const result2 = transition(state, { type: "SUCCESS" });
|
|
56
|
+
* if (result2.valid) state = result2.state;
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function transition(state, action) {
|
|
60
|
+
switch (state.status) {
|
|
61
|
+
case 'idle':
|
|
62
|
+
return transitionFromIdle(state, action);
|
|
63
|
+
case 'submitting':
|
|
64
|
+
return transitionFromSubmitting(state, action);
|
|
65
|
+
case 'error':
|
|
66
|
+
return transitionFromError(state, action);
|
|
67
|
+
case 'resolved':
|
|
68
|
+
return transitionFromResolved(state, action);
|
|
69
|
+
case 'cancelled':
|
|
70
|
+
return transitionFromCancelled(state, action);
|
|
71
|
+
default:
|
|
72
|
+
return {
|
|
73
|
+
state,
|
|
74
|
+
valid: false,
|
|
75
|
+
error: `Unknown state: ${state.status}`
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Transitions from idle state
|
|
81
|
+
*/
|
|
82
|
+
function transitionFromIdle(_state, action) {
|
|
83
|
+
switch (action.type) {
|
|
84
|
+
case 'SUBMIT':
|
|
85
|
+
return {
|
|
86
|
+
state: {
|
|
87
|
+
status: 'submitting',
|
|
88
|
+
pendingValue: action.value,
|
|
89
|
+
isCancelAction: false
|
|
90
|
+
},
|
|
91
|
+
valid: true
|
|
92
|
+
};
|
|
93
|
+
case 'CANCEL':
|
|
94
|
+
return {
|
|
95
|
+
state: {
|
|
96
|
+
status: 'submitting',
|
|
97
|
+
pendingValue: undefined,
|
|
98
|
+
isCancelAction: true
|
|
99
|
+
},
|
|
100
|
+
valid: true
|
|
101
|
+
};
|
|
102
|
+
case 'RESET':
|
|
103
|
+
return { state: initialState, valid: true };
|
|
104
|
+
default:
|
|
105
|
+
return {
|
|
106
|
+
state: _state,
|
|
107
|
+
valid: false,
|
|
108
|
+
error: `Cannot ${action.type} from idle state`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Transitions from submitting state
|
|
114
|
+
*/
|
|
115
|
+
function transitionFromSubmitting(state, action) {
|
|
116
|
+
switch (action.type) {
|
|
117
|
+
case 'SUCCESS':
|
|
118
|
+
if (state.isCancelAction) {
|
|
119
|
+
return {
|
|
120
|
+
state: {
|
|
121
|
+
status: 'cancelled',
|
|
122
|
+
cancelledAt: new Date().toISOString()
|
|
123
|
+
},
|
|
124
|
+
valid: true
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
state: {
|
|
129
|
+
status: 'resolved',
|
|
130
|
+
value: state.pendingValue,
|
|
131
|
+
resolvedAt: new Date().toISOString()
|
|
132
|
+
},
|
|
133
|
+
valid: true
|
|
134
|
+
};
|
|
135
|
+
case 'FAILURE':
|
|
136
|
+
return {
|
|
137
|
+
state: {
|
|
138
|
+
status: 'error',
|
|
139
|
+
error: action.error,
|
|
140
|
+
failedValue: state.pendingValue,
|
|
141
|
+
wasCancelAction: state.isCancelAction
|
|
142
|
+
},
|
|
143
|
+
valid: true
|
|
144
|
+
};
|
|
145
|
+
case 'RESET':
|
|
146
|
+
return { state: initialState, valid: true };
|
|
147
|
+
// Prevent double-submit
|
|
148
|
+
case 'SUBMIT':
|
|
149
|
+
case 'CANCEL':
|
|
150
|
+
return {
|
|
151
|
+
state,
|
|
152
|
+
valid: false,
|
|
153
|
+
error: 'Cannot submit/cancel while already submitting'
|
|
154
|
+
};
|
|
155
|
+
default:
|
|
156
|
+
return {
|
|
157
|
+
state,
|
|
158
|
+
valid: false,
|
|
159
|
+
error: `Cannot ${action.type} from submitting state`
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Transitions from error state
|
|
165
|
+
*/
|
|
166
|
+
function transitionFromError(state, action) {
|
|
167
|
+
switch (action.type) {
|
|
168
|
+
case 'RETRY':
|
|
169
|
+
return {
|
|
170
|
+
state: {
|
|
171
|
+
status: 'submitting',
|
|
172
|
+
pendingValue: state.failedValue,
|
|
173
|
+
isCancelAction: state.wasCancelAction
|
|
174
|
+
},
|
|
175
|
+
valid: true
|
|
176
|
+
};
|
|
177
|
+
case 'SUBMIT':
|
|
178
|
+
// Allow resubmitting with new value
|
|
179
|
+
return {
|
|
180
|
+
state: {
|
|
181
|
+
status: 'submitting',
|
|
182
|
+
pendingValue: action.value,
|
|
183
|
+
isCancelAction: false
|
|
184
|
+
},
|
|
185
|
+
valid: true
|
|
186
|
+
};
|
|
187
|
+
case 'CANCEL':
|
|
188
|
+
return {
|
|
189
|
+
state: {
|
|
190
|
+
status: 'submitting',
|
|
191
|
+
pendingValue: undefined,
|
|
192
|
+
isCancelAction: true
|
|
193
|
+
},
|
|
194
|
+
valid: true
|
|
195
|
+
};
|
|
196
|
+
case 'RESET':
|
|
197
|
+
return { state: initialState, valid: true };
|
|
198
|
+
default:
|
|
199
|
+
return {
|
|
200
|
+
state,
|
|
201
|
+
valid: false,
|
|
202
|
+
error: `Cannot ${action.type} from error state`
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Transitions from resolved state (terminal - only reset allowed)
|
|
208
|
+
*/
|
|
209
|
+
function transitionFromResolved(state, action) {
|
|
210
|
+
if (action.type === 'RESET') {
|
|
211
|
+
return { state: initialState, valid: true };
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
state,
|
|
215
|
+
valid: false,
|
|
216
|
+
error: `Cannot ${action.type} from resolved state - interrupt already completed`
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Transitions from cancelled state (terminal - only reset allowed)
|
|
221
|
+
*/
|
|
222
|
+
function transitionFromCancelled(state, action) {
|
|
223
|
+
if (action.type === 'RESET') {
|
|
224
|
+
return { state: initialState, valid: true };
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
state,
|
|
228
|
+
valid: false,
|
|
229
|
+
error: `Cannot ${action.type} from cancelled state - interrupt already cancelled`
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
// =========================================================================
|
|
233
|
+
// Helper Functions
|
|
234
|
+
// =========================================================================
|
|
235
|
+
/**
|
|
236
|
+
* Check if the interrupt is in a terminal state (resolved or cancelled)
|
|
237
|
+
*
|
|
238
|
+
* @param state - The interrupt state
|
|
239
|
+
* @returns True if the interrupt is finished
|
|
240
|
+
*/
|
|
241
|
+
export function isTerminalState(state) {
|
|
242
|
+
return state.status === 'resolved' || state.status === 'cancelled';
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Check if the interrupt is currently submitting
|
|
246
|
+
*
|
|
247
|
+
* @param state - The interrupt state
|
|
248
|
+
* @returns True if submitting
|
|
249
|
+
*/
|
|
250
|
+
export function isSubmitting(state) {
|
|
251
|
+
return state.status === 'submitting';
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Check if the interrupt has an error
|
|
255
|
+
*
|
|
256
|
+
* @param state - The interrupt state
|
|
257
|
+
* @returns True if in error state
|
|
258
|
+
*/
|
|
259
|
+
export function hasError(state) {
|
|
260
|
+
return state.status === 'error';
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Check if the interrupt can accept user input
|
|
264
|
+
*
|
|
265
|
+
* @param state - The interrupt state
|
|
266
|
+
* @returns True if idle or error (can submit)
|
|
267
|
+
*/
|
|
268
|
+
export function canSubmit(state) {
|
|
269
|
+
return state.status === 'idle' || state.status === 'error';
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get the error message if in error state
|
|
273
|
+
*
|
|
274
|
+
* @param state - The interrupt state
|
|
275
|
+
* @returns Error message or undefined
|
|
276
|
+
*/
|
|
277
|
+
export function getErrorMessage(state) {
|
|
278
|
+
return state.status === 'error' ? state.error : undefined;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get the resolved value if in resolved state
|
|
282
|
+
*
|
|
283
|
+
* @param state - The interrupt state
|
|
284
|
+
* @returns Resolved value or undefined
|
|
285
|
+
*/
|
|
286
|
+
export function getResolvedValue(state) {
|
|
287
|
+
return state.status === 'resolved' ? state.value : undefined;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Map InterruptState status to legacy InterruptStatus for backward compatibility
|
|
291
|
+
*
|
|
292
|
+
* @param state - The interrupt state
|
|
293
|
+
* @returns Legacy status string
|
|
294
|
+
*/
|
|
295
|
+
export function toLegacyStatus(state) {
|
|
296
|
+
switch (state.status) {
|
|
297
|
+
case 'idle':
|
|
298
|
+
case 'submitting':
|
|
299
|
+
case 'error':
|
|
300
|
+
return 'pending';
|
|
301
|
+
case 'resolved':
|
|
302
|
+
return 'resolved';
|
|
303
|
+
case 'cancelled':
|
|
304
|
+
return 'cancelled';
|
|
305
|
+
default:
|
|
306
|
+
return 'pending';
|
|
307
|
+
}
|
|
308
|
+
}
|
package/dist/utils/colors.js
CHANGED
|
@@ -8,6 +8,7 @@ import { getPortCompatibilityChecker } from './connections.js';
|
|
|
8
8
|
* Category color mapping to reference tokens (CSS variables)
|
|
9
9
|
*/
|
|
10
10
|
export const CATEGORY_COLOR_TOKENS = {
|
|
11
|
+
triggers: 'var(--color-ref-cyan-500)',
|
|
11
12
|
inputs: 'var(--color-ref-emerald-500)',
|
|
12
13
|
outputs: 'var(--color-ref-blue-600)',
|
|
13
14
|
prompts: 'var(--color-ref-amber-500)',
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Loopback port name constant
|
|
6
6
|
* This is the standard input port name used for loop iteration triggers
|
|
7
7
|
*/
|
|
8
|
-
const LOOPBACK_PORT_NAME =
|
|
8
|
+
const LOOPBACK_PORT_NAME = 'loop_back';
|
|
9
9
|
/**
|
|
10
10
|
* Determines if an edge is a loopback edge.
|
|
11
11
|
* Loopback edges target the special `loop_back` input port on ForEach nodes.
|
|
@@ -21,7 +21,7 @@ const LOOPBACK_PORT_NAME = "loop_back";
|
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export function isLoopbackEdge(edge) {
|
|
24
|
-
const targetHandle = edge.targetHandle ??
|
|
24
|
+
const targetHandle = edge.targetHandle ?? '';
|
|
25
25
|
return targetHandle.includes(`-input-${LOOPBACK_PORT_NAME}`);
|
|
26
26
|
}
|
|
27
27
|
/**
|
package/dist/utils/icons.js
CHANGED
|
@@ -80,6 +80,7 @@ export const DEFAULT_ICONS = {
|
|
|
80
80
|
* Category-specific icons matching Langflow's visual style
|
|
81
81
|
*/
|
|
82
82
|
export const CATEGORY_ICONS = {
|
|
83
|
+
triggers: 'mdi:lightning-bolt',
|
|
83
84
|
inputs: 'mdi:arrow-down-circle',
|
|
84
85
|
outputs: 'mdi:arrow-up-circle',
|
|
85
86
|
prompts: 'mdi:message-text',
|