@d34dman/flowdrop 0.0.56 → 0.0.57

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 (43) hide show
  1. package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +92 -0
  2. package/dist/adapters/agentspec/AgentSpecAdapter.js +658 -0
  3. package/dist/adapters/agentspec/agentAdapter.d.ts +59 -0
  4. package/dist/adapters/agentspec/agentAdapter.js +91 -0
  5. package/dist/adapters/agentspec/autoLayout.d.ts +34 -0
  6. package/dist/adapters/agentspec/autoLayout.js +127 -0
  7. package/dist/adapters/agentspec/index.d.ts +35 -0
  8. package/dist/adapters/agentspec/index.js +37 -0
  9. package/dist/adapters/agentspec/nodeTypeRegistry.d.ts +62 -0
  10. package/dist/adapters/agentspec/nodeTypeRegistry.js +589 -0
  11. package/dist/adapters/agentspec/validator.d.ts +34 -0
  12. package/dist/adapters/agentspec/validator.js +169 -0
  13. package/dist/components/ConfigForm.svelte +46 -12
  14. package/dist/components/ConfigForm.svelte.d.ts +8 -0
  15. package/dist/components/SchemaForm.svelte +34 -12
  16. package/dist/components/SchemaForm.svelte.d.ts +8 -0
  17. package/dist/components/form/FormFieldset.svelte +142 -0
  18. package/dist/components/form/FormFieldset.svelte.d.ts +11 -0
  19. package/dist/components/form/FormUISchemaRenderer.svelte +140 -0
  20. package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +32 -0
  21. package/dist/components/form/index.d.ts +2 -0
  22. package/dist/components/form/index.js +3 -0
  23. package/dist/config/agentSpecEndpoints.d.ts +70 -0
  24. package/dist/config/agentSpecEndpoints.js +65 -0
  25. package/dist/config/endpoints.d.ts +6 -0
  26. package/dist/core/index.d.ts +17 -1
  27. package/dist/core/index.js +17 -0
  28. package/dist/form/index.d.ts +2 -0
  29. package/dist/form/index.js +3 -0
  30. package/dist/helpers/workflowEditorHelper.d.ts +24 -0
  31. package/dist/helpers/workflowEditorHelper.js +55 -0
  32. package/dist/services/agentSpecExecutionService.d.ts +106 -0
  33. package/dist/services/agentSpecExecutionService.js +333 -0
  34. package/dist/types/agentspec.d.ts +318 -0
  35. package/dist/types/agentspec.js +48 -0
  36. package/dist/types/events.d.ts +28 -1
  37. package/dist/types/index.d.ts +13 -0
  38. package/dist/types/index.js +1 -0
  39. package/dist/types/uischema.d.ts +144 -0
  40. package/dist/types/uischema.js +51 -0
  41. package/dist/utils/uischema.d.ts +52 -0
  42. package/dist/utils/uischema.js +88 -0
  43. package/package.json +1 -1
@@ -0,0 +1,589 @@
1
+ /**
2
+ * Agent Spec Node Type Registry
3
+ *
4
+ * Maps Agent Spec component types to FlowDrop NodeMetadata definitions.
5
+ * Each Agent Spec node type gets a full NodeMetadata with visual type,
6
+ * category, default ports, config schema, and icon.
7
+ */
8
+ /** Namespace prefix for Agent Spec node type IDs */
9
+ const AGENTSPEC_NS = 'agentspec';
10
+ /** Standard trigger input port shared by most nodes */
11
+ const TRIGGER_INPUT = {
12
+ id: 'trigger',
13
+ name: 'Trigger',
14
+ type: 'input',
15
+ dataType: 'trigger',
16
+ required: false,
17
+ description: 'Control flow input'
18
+ };
19
+ /** Standard trigger output port shared by most nodes */
20
+ const TRIGGER_OUTPUT = {
21
+ id: 'trigger',
22
+ name: 'Trigger',
23
+ type: 'output',
24
+ dataType: 'trigger',
25
+ required: false,
26
+ description: 'Control flow output'
27
+ };
28
+ /**
29
+ * Build the full registry of Agent Spec node types.
30
+ */
31
+ function buildRegistry() {
32
+ const registry = new Map();
33
+ // ========================================================================
34
+ // StartNode — Graph entry point
35
+ // ========================================================================
36
+ registry.set('start_node', {
37
+ componentType: 'start_node',
38
+ metadata: {
39
+ id: `${AGENTSPEC_NS}.start_node`,
40
+ name: 'Start',
41
+ type: 'terminal',
42
+ description: 'Flow entry point. Defines the initial inputs for the flow.',
43
+ category: 'triggers',
44
+ version: '1.0.0',
45
+ icon: 'mdi:play-circle',
46
+ color: '#22c55e',
47
+ badge: 'START',
48
+ inputs: [],
49
+ outputs: [TRIGGER_OUTPUT],
50
+ configSchema: {
51
+ type: 'object',
52
+ properties: {}
53
+ },
54
+ extensions: { 'agentspec:component_type': 'start_node' }
55
+ }
56
+ });
57
+ // ========================================================================
58
+ // EndNode — Graph exit point
59
+ // ========================================================================
60
+ registry.set('end_node', {
61
+ componentType: 'end_node',
62
+ metadata: {
63
+ id: `${AGENTSPEC_NS}.end_node`,
64
+ name: 'End',
65
+ type: 'terminal',
66
+ description: 'Flow exit point. Defines the final outputs of the flow.',
67
+ category: 'outputs',
68
+ version: '1.0.0',
69
+ icon: 'mdi:stop-circle',
70
+ color: '#ef4444',
71
+ badge: 'END',
72
+ inputs: [TRIGGER_INPUT],
73
+ outputs: [],
74
+ configSchema: {
75
+ type: 'object',
76
+ properties: {}
77
+ },
78
+ extensions: { 'agentspec:component_type': 'end_node' }
79
+ }
80
+ });
81
+ // ========================================================================
82
+ // LLMNode — Text generation from prompts
83
+ // ========================================================================
84
+ registry.set('llm_node', {
85
+ componentType: 'llm_node',
86
+ metadata: {
87
+ id: `${AGENTSPEC_NS}.llm_node`,
88
+ name: 'LLM',
89
+ type: 'default',
90
+ description: 'Generate text using a large language model with configurable prompts.',
91
+ category: 'ai',
92
+ version: '1.0.0',
93
+ icon: 'mdi:brain',
94
+ color: '#8b5cf6',
95
+ badge: 'LLM',
96
+ inputs: [
97
+ TRIGGER_INPUT,
98
+ {
99
+ id: 'prompt',
100
+ name: 'Prompt',
101
+ type: 'input',
102
+ dataType: 'string',
103
+ required: false,
104
+ description: 'Input prompt text (can also use {{variable}} in prompt template)'
105
+ }
106
+ ],
107
+ outputs: [
108
+ TRIGGER_OUTPUT,
109
+ {
110
+ id: 'llm_output',
111
+ name: 'LLM Output',
112
+ type: 'output',
113
+ dataType: 'string',
114
+ description: 'Generated text from the LLM'
115
+ }
116
+ ],
117
+ configSchema: {
118
+ type: 'object',
119
+ properties: {
120
+ prompt_template: {
121
+ type: 'string',
122
+ title: 'Prompt Template',
123
+ description: 'Prompt template with {{variable}} placeholders for dynamic inputs',
124
+ format: 'multiline',
125
+ default: '{{prompt}}'
126
+ },
127
+ system_prompt: {
128
+ type: 'string',
129
+ title: 'System Prompt',
130
+ description: 'System message to set the LLM behavior',
131
+ format: 'multiline',
132
+ default: ''
133
+ },
134
+ llm_config_ref: {
135
+ type: 'string',
136
+ title: 'LLM Configuration',
137
+ description: 'Reference to an LLM configuration (e.g., model name, provider)',
138
+ default: ''
139
+ }
140
+ }
141
+ },
142
+ extensions: { 'agentspec:component_type': 'llm_node' }
143
+ }
144
+ });
145
+ // ========================================================================
146
+ // BranchingNode — Conditional routing
147
+ // ========================================================================
148
+ registry.set('branching_node', {
149
+ componentType: 'branching_node',
150
+ metadata: {
151
+ id: `${AGENTSPEC_NS}.branching_node`,
152
+ name: 'Branch',
153
+ type: 'gateway',
154
+ description: 'Route execution to different paths based on conditions.',
155
+ category: 'logic',
156
+ version: '1.0.0',
157
+ icon: 'mdi:source-branch',
158
+ color: '#f59e0b',
159
+ badge: 'BRANCH',
160
+ inputs: [
161
+ TRIGGER_INPUT,
162
+ {
163
+ id: 'input',
164
+ name: 'Input',
165
+ type: 'input',
166
+ dataType: 'mixed',
167
+ required: false,
168
+ description: 'Data to evaluate branch conditions against'
169
+ }
170
+ ],
171
+ outputs: [],
172
+ configSchema: {
173
+ type: 'object',
174
+ properties: {
175
+ branches: {
176
+ type: 'array',
177
+ title: 'Branches',
178
+ description: 'Conditional branches for routing',
179
+ items: {
180
+ type: 'object',
181
+ properties: {
182
+ name: {
183
+ type: 'string',
184
+ title: 'Branch ID',
185
+ description: 'Unique identifier for the branch'
186
+ },
187
+ label: {
188
+ type: 'string',
189
+ title: 'Label',
190
+ description: 'Display label for the branch'
191
+ },
192
+ condition: {
193
+ type: 'string',
194
+ title: 'Condition',
195
+ description: 'Expression that determines when this branch activates'
196
+ },
197
+ isDefault: {
198
+ type: 'boolean',
199
+ title: 'Default Branch',
200
+ description: 'Whether this is the fallback branch',
201
+ default: false
202
+ }
203
+ },
204
+ required: ['name']
205
+ }
206
+ }
207
+ }
208
+ },
209
+ extensions: { 'agentspec:component_type': 'branching_node' }
210
+ }
211
+ });
212
+ // ========================================================================
213
+ // ToolNode — Tool execution
214
+ // ========================================================================
215
+ registry.set('tool_node', {
216
+ componentType: 'tool_node',
217
+ metadata: {
218
+ id: `${AGENTSPEC_NS}.tool_node`,
219
+ name: 'Tool',
220
+ type: 'tool',
221
+ description: 'Execute a tool function with inputs and receive outputs.',
222
+ category: 'tools',
223
+ version: '1.0.0',
224
+ icon: 'mdi:wrench',
225
+ color: '#06b6d4',
226
+ badge: 'TOOL',
227
+ inputs: [
228
+ TRIGGER_INPUT,
229
+ {
230
+ id: 'tool',
231
+ name: 'Tool',
232
+ type: 'input',
233
+ dataType: 'tool',
234
+ required: false,
235
+ description: 'Tool connection'
236
+ }
237
+ ],
238
+ outputs: [
239
+ TRIGGER_OUTPUT,
240
+ {
241
+ id: 'tool',
242
+ name: 'Tool',
243
+ type: 'output',
244
+ dataType: 'tool',
245
+ description: 'Tool passthrough'
246
+ },
247
+ {
248
+ id: 'result',
249
+ name: 'Result',
250
+ type: 'output',
251
+ dataType: 'mixed',
252
+ description: 'Tool execution result'
253
+ }
254
+ ],
255
+ configSchema: {
256
+ type: 'object',
257
+ properties: {
258
+ tool_ref: {
259
+ type: 'string',
260
+ title: 'Tool Reference',
261
+ description: 'Reference to the tool to execute ($component_ref:tool_name)',
262
+ default: ''
263
+ }
264
+ }
265
+ },
266
+ extensions: { 'agentspec:component_type': 'tool_node' }
267
+ }
268
+ });
269
+ // ========================================================================
270
+ // APINode — API call
271
+ // ========================================================================
272
+ registry.set('api_node', {
273
+ componentType: 'api_node',
274
+ metadata: {
275
+ id: `${AGENTSPEC_NS}.api_node`,
276
+ name: 'API Call',
277
+ type: 'default',
278
+ description: 'Make an HTTP API call with configurable endpoint, method, and headers.',
279
+ category: 'data',
280
+ version: '1.0.0',
281
+ icon: 'mdi:api',
282
+ color: '#3b82f6',
283
+ badge: 'API',
284
+ inputs: [
285
+ TRIGGER_INPUT,
286
+ {
287
+ id: 'body',
288
+ name: 'Request Body',
289
+ type: 'input',
290
+ dataType: 'json',
291
+ required: false,
292
+ description: 'Request body data'
293
+ }
294
+ ],
295
+ outputs: [
296
+ TRIGGER_OUTPUT,
297
+ {
298
+ id: 'response',
299
+ name: 'Response',
300
+ type: 'output',
301
+ dataType: 'json',
302
+ description: 'API response data'
303
+ },
304
+ {
305
+ id: 'status_code',
306
+ name: 'Status Code',
307
+ type: 'output',
308
+ dataType: 'number',
309
+ description: 'HTTP status code'
310
+ }
311
+ ],
312
+ configSchema: {
313
+ type: 'object',
314
+ properties: {
315
+ endpoint: {
316
+ type: 'string',
317
+ title: 'Endpoint URL',
318
+ description: 'The API endpoint to call',
319
+ default: ''
320
+ },
321
+ method: {
322
+ type: 'string',
323
+ title: 'HTTP Method',
324
+ enum: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
325
+ default: 'GET'
326
+ },
327
+ headers: {
328
+ type: 'string',
329
+ title: 'Headers',
330
+ description: 'Request headers as JSON',
331
+ format: 'multiline',
332
+ default: '{}'
333
+ }
334
+ }
335
+ },
336
+ extensions: { 'agentspec:component_type': 'api_node' }
337
+ }
338
+ });
339
+ // ========================================================================
340
+ // AgentNode — Multi-round agent conversation
341
+ // ========================================================================
342
+ registry.set('agent_node', {
343
+ componentType: 'agent_node',
344
+ metadata: {
345
+ id: `${AGENTSPEC_NS}.agent_node`,
346
+ name: 'Agent',
347
+ type: 'default',
348
+ description: 'Run a multi-round agent conversation within the flow.',
349
+ category: 'agents',
350
+ version: '1.0.0',
351
+ icon: 'mdi:robot',
352
+ color: '#ec4899',
353
+ badge: 'AGENT',
354
+ inputs: [
355
+ TRIGGER_INPUT,
356
+ {
357
+ id: 'input',
358
+ name: 'Input',
359
+ type: 'input',
360
+ dataType: 'string',
361
+ required: false,
362
+ description: 'Input message for the agent'
363
+ }
364
+ ],
365
+ outputs: [
366
+ TRIGGER_OUTPUT,
367
+ {
368
+ id: 'output',
369
+ name: 'Output',
370
+ type: 'output',
371
+ dataType: 'string',
372
+ description: 'Agent response output'
373
+ }
374
+ ],
375
+ configSchema: {
376
+ type: 'object',
377
+ properties: {
378
+ agent_ref: {
379
+ type: 'string',
380
+ title: 'Agent Reference',
381
+ description: 'Reference to the agent ($component_ref:agent_name)',
382
+ default: ''
383
+ },
384
+ max_turns: {
385
+ type: 'integer',
386
+ title: 'Max Turns',
387
+ description: 'Maximum number of conversation turns',
388
+ minimum: 1,
389
+ default: 10
390
+ }
391
+ }
392
+ },
393
+ extensions: { 'agentspec:component_type': 'agent_node' }
394
+ }
395
+ });
396
+ // ========================================================================
397
+ // FlowNode — Nested flow execution
398
+ // ========================================================================
399
+ registry.set('flow_node', {
400
+ componentType: 'flow_node',
401
+ metadata: {
402
+ id: `${AGENTSPEC_NS}.flow_node`,
403
+ name: 'Sub-Flow',
404
+ type: 'simple',
405
+ description: 'Execute another flow as a sub-routine within this flow.',
406
+ category: 'processing',
407
+ version: '1.0.0',
408
+ icon: 'mdi:sitemap',
409
+ color: '#14b8a6',
410
+ badge: 'FLOW',
411
+ inputs: [
412
+ TRIGGER_INPUT,
413
+ {
414
+ id: 'input',
415
+ name: 'Input',
416
+ type: 'input',
417
+ dataType: 'mixed',
418
+ required: false,
419
+ description: 'Input data passed to the sub-flow'
420
+ }
421
+ ],
422
+ outputs: [
423
+ TRIGGER_OUTPUT,
424
+ {
425
+ id: 'output',
426
+ name: 'Output',
427
+ type: 'output',
428
+ dataType: 'mixed',
429
+ description: 'Output data from the sub-flow'
430
+ }
431
+ ],
432
+ configSchema: {
433
+ type: 'object',
434
+ properties: {
435
+ flow_ref: {
436
+ type: 'string',
437
+ title: 'Flow Reference',
438
+ description: 'Reference to the flow ($component_ref:flow_name)',
439
+ default: ''
440
+ }
441
+ }
442
+ },
443
+ extensions: { 'agentspec:component_type': 'flow_node' }
444
+ }
445
+ });
446
+ // ========================================================================
447
+ // MapNode — Map-reduce operations
448
+ // ========================================================================
449
+ registry.set('map_node', {
450
+ componentType: 'map_node',
451
+ metadata: {
452
+ id: `${AGENTSPEC_NS}.map_node`,
453
+ name: 'Map',
454
+ type: 'default',
455
+ description: 'Apply a flow or operation to each item in a collection (map-reduce).',
456
+ category: 'processing',
457
+ version: '1.0.0',
458
+ icon: 'mdi:map-marker-path',
459
+ color: '#f97316',
460
+ badge: 'MAP',
461
+ inputs: [
462
+ TRIGGER_INPUT,
463
+ {
464
+ id: 'collection',
465
+ name: 'Collection',
466
+ type: 'input',
467
+ dataType: 'array',
468
+ required: true,
469
+ description: 'Input collection to iterate over'
470
+ }
471
+ ],
472
+ outputs: [
473
+ TRIGGER_OUTPUT,
474
+ {
475
+ id: 'results',
476
+ name: 'Results',
477
+ type: 'output',
478
+ dataType: 'array',
479
+ description: 'Mapped output collection'
480
+ }
481
+ ],
482
+ configSchema: {
483
+ type: 'object',
484
+ properties: {
485
+ input_collection: {
486
+ type: 'string',
487
+ title: 'Input Collection Property',
488
+ description: 'Name of the input property containing the collection',
489
+ default: 'collection'
490
+ },
491
+ output_collection: {
492
+ type: 'string',
493
+ title: 'Output Collection Property',
494
+ description: 'Name of the output property for mapped results',
495
+ default: 'results'
496
+ },
497
+ map_flow_ref: {
498
+ type: 'string',
499
+ title: 'Map Flow Reference',
500
+ description: 'Reference to the flow to execute per item ($component_ref:flow_name)',
501
+ default: ''
502
+ }
503
+ }
504
+ },
505
+ extensions: { 'agentspec:component_type': 'map_node' }
506
+ }
507
+ });
508
+ return registry;
509
+ }
510
+ // ============================================================================
511
+ // Public API
512
+ // ============================================================================
513
+ /** Singleton registry instance */
514
+ const registry = buildRegistry();
515
+ /**
516
+ * Get FlowDrop NodeMetadata for an Agent Spec component type.
517
+ *
518
+ * @param componentType - The Agent Spec component_type value
519
+ * @returns NodeMetadata for the component type, or undefined if not found
520
+ *
521
+ * @example
522
+ * ```typescript
523
+ * const metadata = getAgentSpecNodeMetadata('llm_node');
524
+ * // Returns NodeMetadata with id='agentspec.llm_node', type='default', category='ai', etc.
525
+ * ```
526
+ */
527
+ export function getAgentSpecNodeMetadata(componentType) {
528
+ return registry.get(componentType)?.metadata;
529
+ }
530
+ /**
531
+ * Get all Agent Spec node types as FlowDrop NodeMetadata.
532
+ * Useful for populating the node sidebar with Agent Spec node types.
533
+ *
534
+ * @returns Array of NodeMetadata for all 9 Agent Spec node types
535
+ */
536
+ export function getAllAgentSpecNodeTypes() {
537
+ return Array.from(registry.values()).map((entry) => entry.metadata);
538
+ }
539
+ /**
540
+ * Get a copy of the NodeMetadata for a component type with custom inputs/outputs.
541
+ * Used during import to create node metadata that matches the Agent Spec definition's
542
+ * actual ports rather than the defaults.
543
+ *
544
+ * @param componentType - The Agent Spec component_type value
545
+ * @param inputs - Custom input ports
546
+ * @param outputs - Custom output ports
547
+ * @returns A new NodeMetadata with the custom ports merged in
548
+ */
549
+ export function createAgentSpecNodeMetadata(componentType, inputs, outputs) {
550
+ const base = registry.get(componentType)?.metadata;
551
+ if (!base)
552
+ return undefined;
553
+ return {
554
+ ...base,
555
+ inputs: inputs ?? base.inputs,
556
+ outputs: outputs ?? base.outputs
557
+ };
558
+ }
559
+ /**
560
+ * Check if a FlowDrop node ID belongs to an Agent Spec node type.
561
+ *
562
+ * @example
563
+ * ```typescript
564
+ * isAgentSpecNodeId('agentspec.llm_node') // true
565
+ * isAgentSpecNodeId('calculator') // false
566
+ * ```
567
+ */
568
+ export function isAgentSpecNodeId(nodeId) {
569
+ return nodeId.startsWith(`${AGENTSPEC_NS}.`);
570
+ }
571
+ /**
572
+ * Extract the Agent Spec component_type from a FlowDrop node type ID.
573
+ *
574
+ * @example
575
+ * ```typescript
576
+ * extractComponentType('agentspec.llm_node') // 'llm_node'
577
+ * extractComponentType('calculator') // undefined
578
+ * ```
579
+ */
580
+ export function extractComponentType(nodeTypeId) {
581
+ if (!isAgentSpecNodeId(nodeTypeId))
582
+ return undefined;
583
+ const componentType = nodeTypeId.slice(AGENTSPEC_NS.length + 1);
584
+ return registry.has(componentType)
585
+ ? componentType
586
+ : undefined;
587
+ }
588
+ /** The namespace prefix used for Agent Spec node type IDs */
589
+ export const AGENTSPEC_NAMESPACE = AGENTSPEC_NS;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Agent Spec Validator
3
+ *
4
+ * Validates workflows against Agent Spec constraints for export,
5
+ * and validates imported Agent Spec documents for correctness.
6
+ */
7
+ import type { AgentSpecFlow } from '../../types/agentspec.js';
8
+ import type { StandardWorkflow } from '../WorkflowAdapter.js';
9
+ /** Validation result */
10
+ export interface AgentSpecValidationResult {
11
+ valid: boolean;
12
+ errors: string[];
13
+ warnings: string[];
14
+ }
15
+ /**
16
+ * Validate a FlowDrop StandardWorkflow for Agent Spec export compatibility.
17
+ *
18
+ * Checks:
19
+ * - Must have exactly 1 start node (terminal/triggers)
20
+ * - Must have at least 1 end node (terminal/outputs)
21
+ * - Gateway nodes must have branches defined
22
+ */
23
+ export declare function validateForAgentSpecExport(workflow: StandardWorkflow): AgentSpecValidationResult;
24
+ /**
25
+ * Validate an imported Agent Spec Flow document.
26
+ *
27
+ * Checks:
28
+ * - Has a start_node reference that exists
29
+ * - At least one end_node exists
30
+ * - All edge references point to existing nodes
31
+ * - BranchingNode has branches
32
+ * - Data flow edges reference valid properties
33
+ */
34
+ export declare function validateAgentSpecFlow(flow: AgentSpecFlow): AgentSpecValidationResult;