@d34dman/flowdrop 0.0.55 → 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 (44) 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/defaultPortConfig.js +9 -0
  26. package/dist/config/endpoints.d.ts +6 -0
  27. package/dist/core/index.d.ts +17 -1
  28. package/dist/core/index.js +17 -0
  29. package/dist/form/index.d.ts +2 -0
  30. package/dist/form/index.js +3 -0
  31. package/dist/helpers/workflowEditorHelper.d.ts +24 -0
  32. package/dist/helpers/workflowEditorHelper.js +55 -0
  33. package/dist/services/agentSpecExecutionService.d.ts +106 -0
  34. package/dist/services/agentSpecExecutionService.js +333 -0
  35. package/dist/types/agentspec.d.ts +318 -0
  36. package/dist/types/agentspec.js +48 -0
  37. package/dist/types/events.d.ts +28 -1
  38. package/dist/types/index.d.ts +13 -0
  39. package/dist/types/index.js +1 -0
  40. package/dist/types/uischema.d.ts +144 -0
  41. package/dist/types/uischema.js +51 -0
  42. package/dist/utils/uischema.d.ts +52 -0
  43. package/dist/utils/uischema.js +88 -0
  44. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Agent-Level Adapter
3
+ *
4
+ * Handles conversion between FlowDrop workflows and full Agent Spec Documents
5
+ * (which wrap a Flow with Agent metadata like tools, LLM config, etc.)
6
+ */
7
+ import type { AgentSpecDocument, AgentSpecTool, AgentSpecLLMConfig } from '../../types/agentspec.js';
8
+ import type { StandardWorkflow } from '../WorkflowAdapter.js';
9
+ /**
10
+ * Agent-level configuration that wraps a workflow.
11
+ * Contains the Agent Spec agent metadata that lives outside the flow.
12
+ */
13
+ export interface AgentConfig {
14
+ /** Agent name */
15
+ name: string;
16
+ /** Agent description */
17
+ description?: string;
18
+ /** System prompt for the agent */
19
+ systemPrompt?: string;
20
+ /** Tools available to the agent */
21
+ tools?: AgentSpecTool[];
22
+ /** LLM configuration */
23
+ llmConfig?: AgentSpecLLMConfig;
24
+ }
25
+ /**
26
+ * Result of importing an Agent Spec Document.
27
+ */
28
+ export interface AgentSpecImportResult {
29
+ /** The FlowDrop workflow (from the flow) */
30
+ workflow: StandardWorkflow;
31
+ /** Agent metadata (from the agent, if present) */
32
+ agentConfig?: AgentConfig;
33
+ /** Shared tools declared at document level */
34
+ tools?: AgentSpecTool[];
35
+ /** Shared LLM configurations declared at document level */
36
+ llmConfigs?: AgentSpecLLMConfig[];
37
+ }
38
+ export declare class AgentSpecAgentAdapter {
39
+ private flowAdapter;
40
+ constructor();
41
+ /**
42
+ * Convert a FlowDrop workflow + agent config into a full AgentSpecDocument.
43
+ *
44
+ * The document wraps the flow with agent metadata (tools, LLM config, system prompt).
45
+ */
46
+ toAgentSpecDocument(workflow: StandardWorkflow, agentConfig?: AgentConfig, tools?: AgentSpecTool[], llmConfigs?: AgentSpecLLMConfig[]): AgentSpecDocument;
47
+ /**
48
+ * Import a full AgentSpecDocument, extracting the flow and agent metadata.
49
+ */
50
+ fromAgentSpecDocument(doc: AgentSpecDocument): AgentSpecImportResult;
51
+ /**
52
+ * Export a full AgentSpecDocument as JSON string.
53
+ */
54
+ exportJSON(workflow: StandardWorkflow, agentConfig?: AgentConfig, tools?: AgentSpecTool[], llmConfigs?: AgentSpecLLMConfig[]): string;
55
+ /**
56
+ * Import from JSON string containing an AgentSpecDocument.
57
+ */
58
+ importJSON(json: string): AgentSpecImportResult;
59
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Agent-Level Adapter
3
+ *
4
+ * Handles conversion between FlowDrop workflows and full Agent Spec Documents
5
+ * (which wrap a Flow with Agent metadata like tools, LLM config, etc.)
6
+ */
7
+ import { AgentSpecAdapter } from './AgentSpecAdapter.js';
8
+ export class AgentSpecAgentAdapter {
9
+ flowAdapter;
10
+ constructor() {
11
+ this.flowAdapter = new AgentSpecAdapter();
12
+ }
13
+ /**
14
+ * Convert a FlowDrop workflow + agent config into a full AgentSpecDocument.
15
+ *
16
+ * The document wraps the flow with agent metadata (tools, LLM config, system prompt).
17
+ */
18
+ toAgentSpecDocument(workflow, agentConfig, tools, llmConfigs) {
19
+ const flow = this.flowAdapter.toAgentSpec(workflow);
20
+ const doc = {
21
+ flow,
22
+ metadata: {
23
+ 'flowdrop:exported_at': new Date().toISOString()
24
+ }
25
+ };
26
+ // Add agent definition if config provided
27
+ if (agentConfig) {
28
+ const agent = {
29
+ component_type: 'agent',
30
+ name: agentConfig.name,
31
+ description: agentConfig.description,
32
+ system_prompt: agentConfig.systemPrompt,
33
+ tools: agentConfig.tools,
34
+ llm_config: agentConfig.llmConfig
35
+ };
36
+ doc.agent = agent;
37
+ }
38
+ // Add shared tools
39
+ if (tools && tools.length > 0) {
40
+ doc.tools = tools;
41
+ }
42
+ // Add shared LLM configs
43
+ if (llmConfigs && llmConfigs.length > 0) {
44
+ doc.llm_configs = llmConfigs;
45
+ }
46
+ return doc;
47
+ }
48
+ /**
49
+ * Import a full AgentSpecDocument, extracting the flow and agent metadata.
50
+ */
51
+ fromAgentSpecDocument(doc) {
52
+ if (!doc.flow) {
53
+ throw new Error('AgentSpecDocument has no flow definition');
54
+ }
55
+ const workflow = this.flowAdapter.fromAgentSpec(doc.flow);
56
+ const result = {
57
+ workflow
58
+ };
59
+ // Extract agent config
60
+ if (doc.agent) {
61
+ result.agentConfig = {
62
+ name: doc.agent.name,
63
+ description: doc.agent.description,
64
+ systemPrompt: doc.agent.system_prompt,
65
+ tools: doc.agent.tools?.filter((t) => typeof t !== 'string'),
66
+ llmConfig: doc.agent.llm_config && typeof doc.agent.llm_config !== 'string'
67
+ ? doc.agent.llm_config
68
+ : undefined
69
+ };
70
+ }
71
+ // Extract shared declarations
72
+ if (doc.tools)
73
+ result.tools = doc.tools;
74
+ if (doc.llm_configs)
75
+ result.llmConfigs = doc.llm_configs;
76
+ return result;
77
+ }
78
+ /**
79
+ * Export a full AgentSpecDocument as JSON string.
80
+ */
81
+ exportJSON(workflow, agentConfig, tools, llmConfigs) {
82
+ return JSON.stringify(this.toAgentSpecDocument(workflow, agentConfig, tools, llmConfigs), null, 2);
83
+ }
84
+ /**
85
+ * Import from JSON string containing an AgentSpecDocument.
86
+ */
87
+ importJSON(json) {
88
+ const doc = JSON.parse(json);
89
+ return this.fromAgentSpecDocument(doc);
90
+ }
91
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Auto-Layout for Agent Spec Flows
3
+ *
4
+ * Agent Spec has no visual position information. This module assigns
5
+ * positions to imported nodes using a layered layout algorithm:
6
+ *
7
+ * 1. Topological sort from StartNode using control-flow edges
8
+ * 2. Assign layers based on longest path from StartNode
9
+ * 3. Position nodes with configurable spacing
10
+ * 4. Fan out branches vertically from BranchingNode
11
+ */
12
+ import type { AgentSpecFlow } from '../../types/agentspec.js';
13
+ /** Layout configuration */
14
+ export interface AutoLayoutConfig {
15
+ /** Horizontal spacing between layers (px) */
16
+ horizontalSpacing: number;
17
+ /** Vertical spacing between nodes in the same layer (px) */
18
+ verticalSpacing: number;
19
+ /** Starting X position */
20
+ startX: number;
21
+ /** Starting Y position */
22
+ startY: number;
23
+ }
24
+ /**
25
+ * Compute node positions for an Agent Spec flow using layered layout.
26
+ *
27
+ * @param flow - The Agent Spec flow to layout
28
+ * @param config - Optional layout configuration
29
+ * @returns Map of node name to {x, y} position
30
+ */
31
+ export declare function computeAutoLayout(flow: AgentSpecFlow, config?: Partial<AutoLayoutConfig>): Map<string, {
32
+ x: number;
33
+ y: number;
34
+ }>;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Auto-Layout for Agent Spec Flows
3
+ *
4
+ * Agent Spec has no visual position information. This module assigns
5
+ * positions to imported nodes using a layered layout algorithm:
6
+ *
7
+ * 1. Topological sort from StartNode using control-flow edges
8
+ * 2. Assign layers based on longest path from StartNode
9
+ * 3. Position nodes with configurable spacing
10
+ * 4. Fan out branches vertically from BranchingNode
11
+ */
12
+ const DEFAULT_CONFIG = {
13
+ horizontalSpacing: 300,
14
+ verticalSpacing: 150,
15
+ startX: 100,
16
+ startY: 100
17
+ };
18
+ /**
19
+ * Compute node positions for an Agent Spec flow using layered layout.
20
+ *
21
+ * @param flow - The Agent Spec flow to layout
22
+ * @param config - Optional layout configuration
23
+ * @returns Map of node name to {x, y} position
24
+ */
25
+ export function computeAutoLayout(flow, config = {}) {
26
+ const cfg = { ...DEFAULT_CONFIG, ...config };
27
+ const positions = new Map();
28
+ if (flow.nodes.length === 0)
29
+ return positions;
30
+ // Build adjacency list from control-flow edges
31
+ const adjacency = new Map();
32
+ const inDegree = new Map();
33
+ for (const node of flow.nodes) {
34
+ adjacency.set(node.name, []);
35
+ inDegree.set(node.name, 0);
36
+ }
37
+ for (const edge of flow.control_flow_connections) {
38
+ const neighbors = adjacency.get(edge.from_node);
39
+ if (neighbors) {
40
+ neighbors.push(edge.to_node);
41
+ }
42
+ inDegree.set(edge.to_node, (inDegree.get(edge.to_node) || 0) + 1);
43
+ }
44
+ // Also consider data-flow edges for connectivity (but don't affect layering priority)
45
+ if (flow.data_flow_connections) {
46
+ for (const edge of flow.data_flow_connections) {
47
+ if (!adjacency.get(edge.source_node)?.includes(edge.destination_node)) {
48
+ adjacency.get(edge.source_node)?.push(edge.destination_node);
49
+ }
50
+ }
51
+ }
52
+ // Assign layers using longest path from start node (BFS with level tracking)
53
+ const layers = assignLayers(flow.start_node, adjacency, flow.nodes.length);
54
+ // Group nodes by layer
55
+ const layerGroups = new Map();
56
+ for (const [nodeName, layer] of layers) {
57
+ if (!layerGroups.has(layer)) {
58
+ layerGroups.set(layer, []);
59
+ }
60
+ layerGroups.get(layer).push(nodeName);
61
+ }
62
+ // Handle any disconnected nodes (not reachable from start)
63
+ const assignedNodes = new Set(layers.keys());
64
+ const disconnected = [];
65
+ for (const node of flow.nodes) {
66
+ if (!assignedNodes.has(node.name)) {
67
+ disconnected.push(node.name);
68
+ }
69
+ }
70
+ // Place disconnected nodes in a final layer
71
+ if (disconnected.length > 0) {
72
+ const maxLayer = layerGroups.size > 0 ? Math.max(...layerGroups.keys()) + 1 : 0;
73
+ layerGroups.set(maxLayer, disconnected);
74
+ }
75
+ // Sort layers and assign positions
76
+ const sortedLayers = Array.from(layerGroups.keys()).sort((a, b) => a - b);
77
+ for (const layerIndex of sortedLayers) {
78
+ const nodesInLayer = layerGroups.get(layerIndex);
79
+ const x = cfg.startX + layerIndex * cfg.horizontalSpacing;
80
+ // Center nodes vertically
81
+ const totalHeight = (nodesInLayer.length - 1) * cfg.verticalSpacing;
82
+ const startY = cfg.startY - totalHeight / 2;
83
+ for (let i = 0; i < nodesInLayer.length; i++) {
84
+ positions.set(nodesInLayer[i], {
85
+ x,
86
+ y: startY + i * cfg.verticalSpacing
87
+ });
88
+ }
89
+ }
90
+ return positions;
91
+ }
92
+ /**
93
+ * Assign layers using longest path from the start node (modified BFS).
94
+ * This ensures branching nodes fan out properly and convergence points
95
+ * are placed at the correct depth.
96
+ */
97
+ function assignLayers(startNode, adjacency, nodeCount) {
98
+ const layers = new Map();
99
+ layers.set(startNode, 0);
100
+ // Use BFS but take the maximum layer for each node
101
+ // (longest path ensures proper branching layout)
102
+ const queue = [startNode];
103
+ const visited = new Set();
104
+ let iterations = 0;
105
+ const maxIterations = nodeCount * nodeCount + 100; // Safety limit for cycles
106
+ while (queue.length > 0 && iterations < maxIterations) {
107
+ iterations++;
108
+ const current = queue.shift();
109
+ if (visited.has(current))
110
+ continue;
111
+ visited.add(current);
112
+ const currentLayer = layers.get(current) || 0;
113
+ const neighbors = adjacency.get(current) || [];
114
+ for (const neighbor of neighbors) {
115
+ const existingLayer = layers.get(neighbor);
116
+ const newLayer = currentLayer + 1;
117
+ // Take the max layer (longest path)
118
+ if (existingLayer === undefined || newLayer > existingLayer) {
119
+ layers.set(neighbor, newLayer);
120
+ }
121
+ if (!visited.has(neighbor)) {
122
+ queue.push(neighbor);
123
+ }
124
+ }
125
+ }
126
+ return layers;
127
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Agent Spec Adapter — Barrel Exports
3
+ *
4
+ * Provides bidirectional conversion between FlowDrop and Oracle's Open Agent Spec.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import {
9
+ * AgentSpecAdapter,
10
+ * AgentSpecAgentAdapter,
11
+ * getAgentSpecNodeMetadata,
12
+ * validateForAgentSpecExport,
13
+ * validateAgentSpecFlow
14
+ * } from '@d34dman/flowdrop/core';
15
+ *
16
+ * // Export a FlowDrop workflow as Agent Spec JSON
17
+ * const adapter = new AgentSpecAdapter();
18
+ * const agentSpecJson = adapter.exportJSON(workflow);
19
+ *
20
+ * // Import an Agent Spec flow into FlowDrop
21
+ * const flowDropWorkflow = adapter.importJSON(agentSpecJson);
22
+ *
23
+ * // Validate before export
24
+ * const result = validateForAgentSpecExport(workflow);
25
+ * if (!result.valid) console.error(result.errors);
26
+ * ```
27
+ */
28
+ export { AgentSpecAdapter } from './AgentSpecAdapter.js';
29
+ export { AgentSpecAgentAdapter } from './agentAdapter.js';
30
+ export type { AgentConfig, AgentSpecImportResult } from './agentAdapter.js';
31
+ export { getAgentSpecNodeMetadata, getAllAgentSpecNodeTypes, createAgentSpecNodeMetadata, isAgentSpecNodeId, extractComponentType, AGENTSPEC_NAMESPACE } from './nodeTypeRegistry.js';
32
+ export { validateForAgentSpecExport, validateAgentSpecFlow } from './validator.js';
33
+ export type { AgentSpecValidationResult } from './validator.js';
34
+ export { computeAutoLayout } from './autoLayout.js';
35
+ export type { AutoLayoutConfig } from './autoLayout.js';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Agent Spec Adapter — Barrel Exports
3
+ *
4
+ * Provides bidirectional conversion between FlowDrop and Oracle's Open Agent Spec.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import {
9
+ * AgentSpecAdapter,
10
+ * AgentSpecAgentAdapter,
11
+ * getAgentSpecNodeMetadata,
12
+ * validateForAgentSpecExport,
13
+ * validateAgentSpecFlow
14
+ * } from '@d34dman/flowdrop/core';
15
+ *
16
+ * // Export a FlowDrop workflow as Agent Spec JSON
17
+ * const adapter = new AgentSpecAdapter();
18
+ * const agentSpecJson = adapter.exportJSON(workflow);
19
+ *
20
+ * // Import an Agent Spec flow into FlowDrop
21
+ * const flowDropWorkflow = adapter.importJSON(agentSpecJson);
22
+ *
23
+ * // Validate before export
24
+ * const result = validateForAgentSpecExport(workflow);
25
+ * if (!result.valid) console.error(result.errors);
26
+ * ```
27
+ */
28
+ // Core adapter
29
+ export { AgentSpecAdapter } from './AgentSpecAdapter.js';
30
+ // Agent-level adapter (wraps flow with agent/tools/LLM config)
31
+ export { AgentSpecAgentAdapter } from './agentAdapter.js';
32
+ // Node type registry
33
+ export { getAgentSpecNodeMetadata, getAllAgentSpecNodeTypes, createAgentSpecNodeMetadata, isAgentSpecNodeId, extractComponentType, AGENTSPEC_NAMESPACE } from './nodeTypeRegistry.js';
34
+ // Validation
35
+ export { validateForAgentSpecExport, validateAgentSpecFlow } from './validator.js';
36
+ // Auto-layout
37
+ export { computeAutoLayout } from './autoLayout.js';
@@ -0,0 +1,62 @@
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
+ import type { NodeMetadata, NodePort } from '../../types/index.js';
9
+ import type { AgentSpecNodeComponentType } from '../../types/agentspec.js';
10
+ /**
11
+ * Get FlowDrop NodeMetadata for an Agent Spec component type.
12
+ *
13
+ * @param componentType - The Agent Spec component_type value
14
+ * @returns NodeMetadata for the component type, or undefined if not found
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const metadata = getAgentSpecNodeMetadata('llm_node');
19
+ * // Returns NodeMetadata with id='agentspec.llm_node', type='default', category='ai', etc.
20
+ * ```
21
+ */
22
+ export declare function getAgentSpecNodeMetadata(componentType: AgentSpecNodeComponentType): NodeMetadata | undefined;
23
+ /**
24
+ * Get all Agent Spec node types as FlowDrop NodeMetadata.
25
+ * Useful for populating the node sidebar with Agent Spec node types.
26
+ *
27
+ * @returns Array of NodeMetadata for all 9 Agent Spec node types
28
+ */
29
+ export declare function getAllAgentSpecNodeTypes(): NodeMetadata[];
30
+ /**
31
+ * Get a copy of the NodeMetadata for a component type with custom inputs/outputs.
32
+ * Used during import to create node metadata that matches the Agent Spec definition's
33
+ * actual ports rather than the defaults.
34
+ *
35
+ * @param componentType - The Agent Spec component_type value
36
+ * @param inputs - Custom input ports
37
+ * @param outputs - Custom output ports
38
+ * @returns A new NodeMetadata with the custom ports merged in
39
+ */
40
+ export declare function createAgentSpecNodeMetadata(componentType: AgentSpecNodeComponentType, inputs?: NodePort[], outputs?: NodePort[]): NodeMetadata | undefined;
41
+ /**
42
+ * Check if a FlowDrop node ID belongs to an Agent Spec node type.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * isAgentSpecNodeId('agentspec.llm_node') // true
47
+ * isAgentSpecNodeId('calculator') // false
48
+ * ```
49
+ */
50
+ export declare function isAgentSpecNodeId(nodeId: string): boolean;
51
+ /**
52
+ * Extract the Agent Spec component_type from a FlowDrop node type ID.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * extractComponentType('agentspec.llm_node') // 'llm_node'
57
+ * extractComponentType('calculator') // undefined
58
+ * ```
59
+ */
60
+ export declare function extractComponentType(nodeTypeId: string): AgentSpecNodeComponentType | undefined;
61
+ /** The namespace prefix used for Agent Spec node type IDs */
62
+ export declare const AGENTSPEC_NAMESPACE = "agentspec";