@d34dman/flowdrop 0.0.36 → 0.0.38

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 (49) hide show
  1. package/dist/components/NodeSidebar.svelte +1 -0
  2. package/dist/components/form/FormCodeEditor.svelte +6 -1
  3. package/dist/components/interrupt/ChoicePrompt.svelte +389 -0
  4. package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +21 -0
  5. package/dist/components/interrupt/ConfirmationPrompt.svelte +280 -0
  6. package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +23 -0
  7. package/dist/components/interrupt/FormPrompt.svelte +223 -0
  8. package/dist/components/interrupt/FormPrompt.svelte.d.ts +21 -0
  9. package/dist/components/interrupt/InterruptBubble.svelte +621 -0
  10. package/dist/components/interrupt/InterruptBubble.svelte.d.ts +16 -0
  11. package/dist/components/interrupt/TextInputPrompt.svelte +333 -0
  12. package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +21 -0
  13. package/dist/components/interrupt/index.d.ts +13 -0
  14. package/dist/components/interrupt/index.js +15 -0
  15. package/dist/components/nodes/GatewayNode.svelte +21 -5
  16. package/dist/components/nodes/IdeaNode.svelte +48 -43
  17. package/dist/components/nodes/IdeaNode.svelte.d.ts +1 -1
  18. package/dist/components/nodes/SimpleNode.svelte +1 -3
  19. package/dist/components/nodes/TerminalNode.svelte +52 -11
  20. package/dist/components/nodes/ToolNode.svelte +22 -7
  21. package/dist/components/nodes/WorkflowNode.svelte +1 -3
  22. package/dist/components/playground/ChatPanel.svelte +131 -7
  23. package/dist/components/playground/ChatPanel.svelte.d.ts +2 -0
  24. package/dist/components/playground/MessageBubble.svelte +1 -3
  25. package/dist/components/playground/Playground.svelte +50 -5
  26. package/dist/components/playground/PlaygroundModal.svelte +8 -7
  27. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -3
  28. package/dist/config/endpoints.d.ts +12 -0
  29. package/dist/config/endpoints.js +7 -0
  30. package/dist/playground/index.d.ts +5 -0
  31. package/dist/playground/index.js +21 -0
  32. package/dist/playground/mount.d.ts +3 -3
  33. package/dist/playground/mount.js +30 -22
  34. package/dist/services/interruptService.d.ts +133 -0
  35. package/dist/services/interruptService.js +279 -0
  36. package/dist/stores/interruptStore.d.ts +200 -0
  37. package/dist/stores/interruptStore.js +424 -0
  38. package/dist/stores/playgroundStore.d.ts +11 -1
  39. package/dist/stores/playgroundStore.js +34 -0
  40. package/dist/styles/base.css +89 -0
  41. package/dist/types/index.d.ts +1 -1
  42. package/dist/types/interrupt.d.ts +303 -0
  43. package/dist/types/interrupt.js +125 -0
  44. package/dist/types/interruptState.d.ts +211 -0
  45. package/dist/types/interruptState.js +308 -0
  46. package/dist/utils/colors.js +1 -0
  47. package/dist/utils/connections.js +2 -2
  48. package/dist/utils/icons.js +1 -0
  49. package/package.json +1 -1
@@ -1180,6 +1180,95 @@
1180
1180
  --flowdrop-text-color-primary: var(--color-ref-gray-900);
1181
1181
  --flowdrop-text-color-secondary: var(--color-ref-gray-600);
1182
1182
 
1183
+ /* =========================================================================
1184
+ Interrupt Component Tokens
1185
+ ========================================================================= */
1186
+
1187
+ /* Interrupt state: Pending (awaiting user response) */
1188
+ --flowdrop-interrupt-pending-bg: linear-gradient(
1189
+ 135deg,
1190
+ var(--color-ref-amber-100) 0%,
1191
+ var(--color-ref-amber-200) 100%
1192
+ );
1193
+ --flowdrop-interrupt-pending-border: var(--color-ref-amber-500);
1194
+ --flowdrop-interrupt-pending-shadow: rgba(245, 158, 11, 0.15);
1195
+ --flowdrop-interrupt-pending-avatar: var(--color-ref-amber-500);
1196
+ --flowdrop-interrupt-pending-text: var(--color-ref-amber-800);
1197
+ --flowdrop-interrupt-pending-text-light: var(--color-ref-amber-700);
1198
+
1199
+ /* Interrupt state: Completed (response received - neutral) */
1200
+ --flowdrop-interrupt-completed-bg: linear-gradient(
1201
+ 135deg,
1202
+ var(--color-ref-blue-50) 0%,
1203
+ var(--color-ref-blue-100) 100%
1204
+ );
1205
+ --flowdrop-interrupt-completed-border: var(--color-ref-blue-500);
1206
+ --flowdrop-interrupt-completed-shadow: rgba(59, 130, 246, 0.15);
1207
+ --flowdrop-interrupt-completed-avatar: var(--color-ref-blue-500);
1208
+ --flowdrop-interrupt-completed-text: var(--color-ref-blue-800);
1209
+ --flowdrop-interrupt-completed-text-light: var(--color-ref-blue-600);
1210
+
1211
+ /* Interrupt state: Cancelled (dismissed without responding) */
1212
+ --flowdrop-interrupt-cancelled-bg: linear-gradient(
1213
+ 135deg,
1214
+ var(--color-ref-gray-100) 0%,
1215
+ var(--color-ref-gray-200) 100%
1216
+ );
1217
+ --flowdrop-interrupt-cancelled-border: var(--color-ref-gray-400);
1218
+ --flowdrop-interrupt-cancelled-shadow: rgba(107, 114, 128, 0.15);
1219
+ --flowdrop-interrupt-cancelled-avatar: var(--color-ref-gray-500);
1220
+ --flowdrop-interrupt-cancelled-text: var(--color-ref-gray-600);
1221
+ --flowdrop-interrupt-cancelled-text-light: var(--color-ref-gray-500);
1222
+
1223
+ /* Interrupt state: Error */
1224
+ --flowdrop-interrupt-error-bg: linear-gradient(
1225
+ 135deg,
1226
+ var(--color-ref-red-50) 0%,
1227
+ var(--color-ref-red-100) 100%
1228
+ );
1229
+ --flowdrop-interrupt-error-border: var(--color-ref-red-500);
1230
+ --flowdrop-interrupt-error-shadow: rgba(239, 68, 68, 0.15);
1231
+ --flowdrop-interrupt-error-avatar: var(--color-ref-red-500);
1232
+ --flowdrop-interrupt-error-text: var(--color-ref-red-700);
1233
+ --flowdrop-interrupt-error-text-light: var(--color-ref-red-600);
1234
+
1235
+ /* Interrupt prompt inner styling */
1236
+ --flowdrop-interrupt-prompt-bg: rgba(255, 255, 255, 0.85);
1237
+ --flowdrop-interrupt-prompt-border-pending: rgba(245, 158, 11, 0.2);
1238
+ --flowdrop-interrupt-prompt-border-completed: rgba(59, 130, 246, 0.2);
1239
+ --flowdrop-interrupt-prompt-border-cancelled: rgba(107, 114, 128, 0.2);
1240
+ --flowdrop-interrupt-prompt-border-error: rgba(239, 68, 68, 0.2);
1241
+
1242
+ /* Interrupt button tokens */
1243
+ --flowdrop-interrupt-btn-primary-bg: linear-gradient(
1244
+ 135deg,
1245
+ var(--color-ref-blue-500) 0%,
1246
+ var(--color-ref-blue-600) 100%
1247
+ );
1248
+ --flowdrop-interrupt-btn-primary-bg-hover: linear-gradient(
1249
+ 135deg,
1250
+ var(--color-ref-blue-600) 0%,
1251
+ var(--color-ref-blue-700) 100%
1252
+ );
1253
+ --flowdrop-interrupt-btn-primary-shadow: rgba(59, 130, 246, 0.3);
1254
+ --flowdrop-interrupt-btn-secondary-bg: var(--color-ref-gray-100);
1255
+ --flowdrop-interrupt-btn-secondary-border: var(--color-ref-gray-300);
1256
+ --flowdrop-interrupt-btn-secondary-text: var(--color-ref-gray-700);
1257
+
1258
+ /* Interrupt selection tokens (for confirmation/choice) */
1259
+ --flowdrop-interrupt-selected-confirm-bg: var(--flowdrop-interrupt-btn-primary-bg);
1260
+ --flowdrop-interrupt-selected-confirm-border: var(--color-ref-blue-700);
1261
+ --flowdrop-interrupt-selected-confirm-glow: rgba(59, 130, 246, 0.3);
1262
+ --flowdrop-interrupt-selected-decline-bg: var(--color-ref-red-50);
1263
+ --flowdrop-interrupt-selected-decline-border: var(--color-ref-red-400);
1264
+ --flowdrop-interrupt-selected-decline-text: var(--color-ref-red-600);
1265
+ --flowdrop-interrupt-selected-decline-glow: rgba(248, 113, 113, 0.2);
1266
+ --flowdrop-interrupt-not-selected-opacity: 0.4;
1267
+
1268
+ /* Interrupt badge tokens */
1269
+ --flowdrop-interrupt-badge-completed-bg: var(--color-ref-blue-50);
1270
+ --flowdrop-interrupt-badge-completed-text: var(--color-ref-blue-600);
1271
+
1183
1272
  /* NotesNode component variables */
1184
1273
  --notes-node-width: 500px;
1185
1274
  --notes-node-min-width: 250px;
@@ -8,7 +8,7 @@ import type { EndpointConfig } from '../config/endpoints.js';
8
8
  * Node category types for organizing nodes in the sidebar
9
9
  * Based on actual API response categories
10
10
  */
11
- export type NodeCategory = 'inputs' | 'outputs' | 'prompts' | 'models' | 'processing' | 'logic' | 'data' | 'tools' | 'helpers' | 'vector stores' | 'embeddings' | 'memories' | 'agents' | 'ai' | 'bundles';
11
+ export type NodeCategory = 'triggers' | 'inputs' | 'outputs' | 'prompts' | 'models' | 'processing' | 'logic' | 'data' | 'tools' | 'helpers' | 'vector stores' | 'embeddings' | 'memories' | 'agents' | 'ai' | 'bundles';
12
12
  /**
13
13
  * Port data type configuration
14
14
  */
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Interrupt Types for Human-in-the-Loop (HITL) Support
3
+ *
4
+ * TypeScript types for workflow interrupts that pause execution
5
+ * and request user input before continuing.
6
+ *
7
+ * @module types/interrupt
8
+ */
9
+ import type { ConfigSchema } from './index.js';
10
+ export type { InterruptState, IdleState, SubmittingState, ResolvedState, CancelledState, ErrorState, InterruptAction, SubmitAction, CancelAction, SuccessAction, FailureAction, RetryAction, ResetAction, TransitionResult } from './interruptState.js';
11
+ export { initialState, transition, isTerminalState, isSubmitting, hasError, canSubmit, getErrorMessage, getResolvedValue, toLegacyStatus } from './interruptState.js';
12
+ /**
13
+ * Types of interrupts supported by the system
14
+ *
15
+ * - `confirmation`: Simple Yes/No prompt
16
+ * - `choice`: Single or multiple option selection
17
+ * - `text`: Free-form text input
18
+ * - `form`: JSON Schema-based form
19
+ */
20
+ export type InterruptType = 'confirmation' | 'choice' | 'text' | 'form';
21
+ /**
22
+ * Status of an interrupt request
23
+ *
24
+ * - `pending`: Awaiting user response
25
+ * - `resolved`: User has provided a response
26
+ * - `cancelled`: User or system cancelled the interrupt
27
+ * - `expired`: Interrupt timed out without response
28
+ */
29
+ export type InterruptStatus = 'pending' | 'resolved' | 'cancelled' | 'expired';
30
+ /**
31
+ * Choice option for choice-type interrupts
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const option: InterruptChoice = {
36
+ * value: "high",
37
+ * label: "High Priority",
38
+ * description: "Process immediately"
39
+ * };
40
+ * ```
41
+ */
42
+ export interface InterruptChoice {
43
+ /** Unique value identifier for this option */
44
+ value: string;
45
+ /** Display label for the option */
46
+ label: string;
47
+ /** Optional description providing more context */
48
+ description?: string;
49
+ }
50
+ /**
51
+ * Configuration for confirmation-type interrupts
52
+ */
53
+ export interface ConfirmationConfig {
54
+ /** The confirmation message/question to display */
55
+ message: string;
56
+ /** Label for the confirm/yes button */
57
+ confirmLabel?: string;
58
+ /** Label for the cancel/no button */
59
+ cancelLabel?: string;
60
+ }
61
+ /**
62
+ * Configuration for choice-type interrupts
63
+ */
64
+ export interface ChoiceConfig {
65
+ /** The prompt message to display */
66
+ message: string;
67
+ /** Available options to choose from */
68
+ options: InterruptChoice[];
69
+ /** Whether multiple selections are allowed */
70
+ multiple?: boolean;
71
+ /** Minimum number of selections required (for multiple mode) */
72
+ minSelections?: number;
73
+ /** Maximum number of selections allowed (for multiple mode) */
74
+ maxSelections?: number;
75
+ }
76
+ /**
77
+ * Configuration for text-type interrupts
78
+ */
79
+ export interface TextConfig {
80
+ /** The prompt message to display */
81
+ message: string;
82
+ /** Placeholder text for the input field */
83
+ placeholder?: string;
84
+ /** Whether to show a multiline text area */
85
+ multiline?: boolean;
86
+ /** Minimum text length required */
87
+ minLength?: number;
88
+ /** Maximum text length allowed */
89
+ maxLength?: number;
90
+ /** Default value to pre-fill */
91
+ defaultValue?: string;
92
+ }
93
+ /**
94
+ * Configuration for form-type interrupts
95
+ */
96
+ export interface FormConfig {
97
+ /** The prompt message to display */
98
+ message: string;
99
+ /** JSON Schema defining the form fields */
100
+ schema: ConfigSchema;
101
+ /** Default values for form fields */
102
+ defaultValues?: Record<string, unknown>;
103
+ }
104
+ /**
105
+ * Union type for interrupt-specific configuration
106
+ */
107
+ export type InterruptConfig = ConfirmationConfig | ChoiceConfig | TextConfig | FormConfig;
108
+ /**
109
+ * Core interrupt data structure
110
+ *
111
+ * Represents a pending or resolved interrupt request from the workflow.
112
+ * Includes a state machine for tracking the interaction state.
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * const interrupt: Interrupt = {
117
+ * id: "int-123",
118
+ * type: "confirmation",
119
+ * status: "pending",
120
+ * message: "Send email to John?",
121
+ * nodeId: "node-456",
122
+ * executionId: "exec-789",
123
+ * sessionId: "sess-abc",
124
+ * createdAt: "2024-01-20T10:00:00Z",
125
+ * allowCancel: true,
126
+ * config: {
127
+ * message: "Send email to John?",
128
+ * confirmLabel: "Send",
129
+ * cancelLabel: "Don't Send"
130
+ * },
131
+ * state: { status: "idle" }
132
+ * };
133
+ * ```
134
+ */
135
+ export interface Interrupt {
136
+ /** Unique identifier for the interrupt */
137
+ id: string;
138
+ /** Type of interrupt (confirmation, choice, text, form) */
139
+ type: InterruptType;
140
+ /**
141
+ * Current status of the interrupt (legacy field)
142
+ * @deprecated Use `state` for more detailed status tracking
143
+ */
144
+ status: InterruptStatus;
145
+ /** Primary message/prompt to display */
146
+ message: string;
147
+ /** ID of the node that triggered the interrupt */
148
+ nodeId?: string;
149
+ /** ID of the workflow execution */
150
+ executionId?: string;
151
+ /** ID of the playground session (if applicable) */
152
+ sessionId?: string;
153
+ /** ID of the pipeline (if applicable) */
154
+ pipelineId?: string;
155
+ /** ID of the associated message in the chat flow */
156
+ messageId?: string;
157
+ /** Timestamp when the interrupt was created (ISO 8601) */
158
+ createdAt: string;
159
+ /** Timestamp when the interrupt was resolved (ISO 8601) */
160
+ resolvedAt?: string;
161
+ /** Timestamp when the interrupt expires (ISO 8601) */
162
+ expiresAt?: string;
163
+ /** Whether the user can cancel/dismiss this interrupt */
164
+ allowCancel: boolean;
165
+ /** Type-specific configuration */
166
+ config: InterruptConfig;
167
+ /** The user's response value (when resolved) */
168
+ responseValue?: unknown;
169
+ /** Additional metadata from the backend */
170
+ metadata?: Record<string, unknown>;
171
+ }
172
+ /**
173
+ * Payload for resolving an interrupt
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * // Confirmation response
178
+ * const resolution: InterruptResolution = {
179
+ * value: true // or false
180
+ * };
181
+ *
182
+ * // Choice response (single)
183
+ * const resolution: InterruptResolution = {
184
+ * value: "option_a"
185
+ * };
186
+ *
187
+ * // Choice response (multiple)
188
+ * const resolution: InterruptResolution = {
189
+ * value: ["option_a", "option_b"]
190
+ * };
191
+ *
192
+ * // Text response
193
+ * const resolution: InterruptResolution = {
194
+ * value: "User entered text"
195
+ * };
196
+ *
197
+ * // Form response
198
+ * const resolution: InterruptResolution = {
199
+ * value: { name: "John", email: "john@example.com" }
200
+ * };
201
+ * ```
202
+ */
203
+ export interface InterruptResolution {
204
+ /** The user's response value */
205
+ value: unknown;
206
+ }
207
+ /**
208
+ * API response for interrupt operations
209
+ */
210
+ export interface InterruptApiResponse<T = Interrupt> {
211
+ /** Whether the request was successful */
212
+ success: boolean;
213
+ /** Response data */
214
+ data?: T;
215
+ /** Error message if unsuccessful */
216
+ error?: string;
217
+ /** Human-readable message */
218
+ message?: string;
219
+ }
220
+ /**
221
+ * Response type for listing interrupts
222
+ */
223
+ export type InterruptListResponse = InterruptApiResponse<Interrupt[]>;
224
+ /**
225
+ * Response type for single interrupt operations
226
+ */
227
+ export type InterruptResponse = InterruptApiResponse<Interrupt>;
228
+ /**
229
+ * Message metadata structure for interrupt detection
230
+ *
231
+ * When a message contains this metadata type, it indicates
232
+ * an interrupt request that should be rendered inline.
233
+ */
234
+ export interface InterruptMessageMetadata {
235
+ /** Indicates this is an interrupt request */
236
+ type: 'interrupt_request';
237
+ /** The interrupt ID */
238
+ interrupt_id: string;
239
+ /** Type of interrupt */
240
+ interrupt_type: InterruptType;
241
+ /** JSON Schema for form-type interrupts */
242
+ schema?: ConfigSchema;
243
+ /** Options for choice-type interrupts */
244
+ options?: InterruptChoice[];
245
+ /** Default value for pre-filling */
246
+ default_value?: unknown;
247
+ /** Node ID that triggered the interrupt */
248
+ node_id?: string;
249
+ /** Execution ID */
250
+ execution_id?: string;
251
+ /** Whether cancel is allowed */
252
+ allow_cancel?: boolean;
253
+ /** Labels for confirmation type */
254
+ confirm_label?: string;
255
+ cancel_label?: string;
256
+ /** Text input configuration */
257
+ placeholder?: string;
258
+ multiline?: boolean;
259
+ min_length?: number;
260
+ max_length?: number;
261
+ /** Choice configuration */
262
+ multiple?: boolean;
263
+ min_selections?: number;
264
+ max_selections?: number;
265
+ }
266
+ /**
267
+ * Type guard to check if message metadata indicates an interrupt
268
+ *
269
+ * @param metadata - Message metadata to check
270
+ * @returns True if the metadata indicates an interrupt request
271
+ */
272
+ export declare function isInterruptMetadata(metadata: Record<string, unknown> | undefined): boolean;
273
+ /**
274
+ * Safely extract interrupt metadata from a generic record
275
+ *
276
+ * @param metadata - The metadata record to extract from
277
+ * @returns The interrupt metadata if valid, or null
278
+ */
279
+ export declare function extractInterruptMetadata(metadata: Record<string, unknown> | undefined): InterruptMessageMetadata | null;
280
+ /**
281
+ * Convert interrupt message metadata to a full Interrupt object
282
+ *
283
+ * @param metadata - The interrupt message metadata
284
+ * @param messageId - The ID of the message containing the interrupt
285
+ * @param content - The message content (used as the interrupt message)
286
+ * @returns A fully populated Interrupt object
287
+ */
288
+ export declare function metadataToInterrupt(metadata: InterruptMessageMetadata, messageId: string, content: string): Interrupt;
289
+ /**
290
+ * Configuration options for interrupt polling
291
+ */
292
+ export interface InterruptPollingConfig {
293
+ /** Whether to enable dedicated interrupt polling */
294
+ enabled: boolean;
295
+ /** Polling interval in milliseconds */
296
+ interval?: number;
297
+ /** Maximum polling backoff interval in milliseconds */
298
+ maxBackoff?: number;
299
+ }
300
+ /**
301
+ * Default interrupt polling configuration
302
+ */
303
+ export declare const defaultInterruptPollingConfig: InterruptPollingConfig;
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Interrupt Types for Human-in-the-Loop (HITL) Support
3
+ *
4
+ * TypeScript types for workflow interrupts that pause execution
5
+ * and request user input before continuing.
6
+ *
7
+ * @module types/interrupt
8
+ */
9
+ export { initialState, transition, isTerminalState, isSubmitting, hasError, canSubmit, getErrorMessage, getResolvedValue, toLegacyStatus } from './interruptState.js';
10
+ /**
11
+ * Type guard to check if message metadata indicates an interrupt
12
+ *
13
+ * @param metadata - Message metadata to check
14
+ * @returns True if the metadata indicates an interrupt request
15
+ */
16
+ export function isInterruptMetadata(metadata) {
17
+ return (metadata !== undefined &&
18
+ metadata.type === 'interrupt_request' &&
19
+ typeof metadata.interrupt_id === 'string');
20
+ }
21
+ /**
22
+ * Safely extract interrupt metadata from a generic record
23
+ *
24
+ * @param metadata - The metadata record to extract from
25
+ * @returns The interrupt metadata if valid, or null
26
+ */
27
+ export function extractInterruptMetadata(metadata) {
28
+ if (!isInterruptMetadata(metadata)) {
29
+ return null;
30
+ }
31
+ // Manually construct the typed object from the validated metadata
32
+ return {
33
+ type: 'interrupt_request',
34
+ interrupt_id: metadata.interrupt_id,
35
+ interrupt_type: metadata.interrupt_type,
36
+ schema: metadata.schema,
37
+ options: metadata.options,
38
+ default_value: metadata.default_value,
39
+ node_id: metadata.node_id,
40
+ execution_id: metadata.execution_id,
41
+ allow_cancel: metadata.allow_cancel,
42
+ confirm_label: metadata.confirm_label,
43
+ cancel_label: metadata.cancel_label,
44
+ placeholder: metadata.placeholder,
45
+ multiline: metadata.multiline,
46
+ min_length: metadata.min_length,
47
+ max_length: metadata.max_length,
48
+ multiple: metadata.multiple,
49
+ min_selections: metadata.min_selections,
50
+ max_selections: metadata.max_selections
51
+ };
52
+ }
53
+ /**
54
+ * Convert interrupt message metadata to a full Interrupt object
55
+ *
56
+ * @param metadata - The interrupt message metadata
57
+ * @param messageId - The ID of the message containing the interrupt
58
+ * @param content - The message content (used as the interrupt message)
59
+ * @returns A fully populated Interrupt object
60
+ */
61
+ export function metadataToInterrupt(metadata, messageId, content) {
62
+ const baseInterrupt = {
63
+ id: metadata.interrupt_id,
64
+ type: metadata.interrupt_type,
65
+ status: 'pending',
66
+ message: content,
67
+ nodeId: metadata.node_id,
68
+ executionId: metadata.execution_id,
69
+ messageId,
70
+ createdAt: new Date().toISOString(),
71
+ allowCancel: metadata.allow_cancel ?? true,
72
+ config: buildInterruptConfig(metadata, content)
73
+ };
74
+ return baseInterrupt;
75
+ }
76
+ /**
77
+ * Build the type-specific config from message metadata
78
+ *
79
+ * @param metadata - The interrupt message metadata
80
+ * @param message - The interrupt message content
81
+ * @returns Type-specific interrupt configuration
82
+ */
83
+ function buildInterruptConfig(metadata, message) {
84
+ switch (metadata.interrupt_type) {
85
+ case 'confirmation':
86
+ return {
87
+ message,
88
+ confirmLabel: metadata.confirm_label ?? 'Yes',
89
+ cancelLabel: metadata.cancel_label ?? 'No'
90
+ };
91
+ case 'choice':
92
+ return {
93
+ message,
94
+ options: metadata.options ?? [],
95
+ multiple: metadata.multiple ?? false,
96
+ minSelections: metadata.min_selections,
97
+ maxSelections: metadata.max_selections
98
+ };
99
+ case 'text':
100
+ return {
101
+ message,
102
+ placeholder: metadata.placeholder,
103
+ multiline: metadata.multiline ?? false,
104
+ minLength: metadata.min_length,
105
+ maxLength: metadata.max_length,
106
+ defaultValue: metadata.default_value
107
+ };
108
+ case 'form':
109
+ return {
110
+ message,
111
+ schema: metadata.schema ?? { type: 'object', properties: {} },
112
+ defaultValues: metadata.default_value
113
+ };
114
+ default:
115
+ return { message };
116
+ }
117
+ }
118
+ /**
119
+ * Default interrupt polling configuration
120
+ */
121
+ export const defaultInterruptPollingConfig = {
122
+ enabled: false,
123
+ interval: 2000,
124
+ maxBackoff: 10000
125
+ };