MCPcopy Create free account
hub / github.com/ShipSecAI/studio / compileWorkflowGraph

Function compileWorkflowGraph

backend/src/dsl/compiler.ts:61–297  ·  view source on GitHub ↗
(graph: WorkflowGraphDto)

Source from the content-addressed store, hash-verified

59}
60
61export function compileWorkflowGraph(graph: WorkflowGraphDto): WorkflowDefinition {
62 // Filter out UI-only nodes (like text-block) that shouldn't be executed
63 const executableNodes = graph.nodes.filter((node: WorkflowNodeDto) => {
64 const component = componentRegistry.get(node.type);
65 if (!component) {
66 return true; // Let validation catch unknown components
67 }
68 // Skip UI-only components (they're for documentation/notes, not execution)
69 const isUiOnly = (component.ui as any)?.uiOnly === true;
70 return !isUiOnly;
71 });
72
73 const nodeIds = executableNodes.map((node: WorkflowNodeDto) => node.id);
74
75 // Ensure all executable nodes reference registered components.
76 for (const node of executableNodes) {
77 if (!componentRegistry.get(node.type)) {
78 throw new Error(`Component not registered: ${node.type}`);
79 }
80 }
81
82 const orderedIds = topoSort(nodeIds, graph.edges);
83 const incomingEdges = new Map<string, Set<string>>();
84 type GraphEdge = (typeof graph.edges)[number];
85 const edgesByTarget = new Map<string, GraphEdge[]>();
86 for (const nodeId of nodeIds) {
87 incomingEdges.set(nodeId, new Set());
88 edgesByTarget.set(nodeId, []);
89 }
90 for (const edge of graph.edges) {
91 incomingEdges.get(edge.target)?.add(edge.source);
92 edgesByTarget.get(edge.target)?.push(edge);
93 }
94
95 const nodesMetadata: Record<string, WorkflowNodeMetadata> = {};
96 for (const node of executableNodes) {
97 const config = (node.data?.config ?? {}) as Record<string, unknown>;
98 const joinStrategyValue = config.joinStrategy;
99 const joinStrategy =
100 typeof joinStrategyValue === 'string' && ['all', 'any', 'first'].includes(joinStrategyValue)
101 ? (joinStrategyValue as WorkflowNodeMetadata['joinStrategy'])
102 : undefined;
103
104 const streamIdValue = config.streamId;
105 const groupIdValue = config.groupId;
106 const maxConcurrencyValue = config.maxConcurrency;
107
108 const mode = (config.mode as WorkflowNodeMetadata['mode']) ?? 'normal';
109 const toolConfig = config.toolConfig as WorkflowNodeMetadata['toolConfig'];
110
111 const connectedToolNodeIds = edgesByTarget
112 .get(node.id)
113 ?.filter((edge) => edge.targetHandle === 'tools')
114 .map((edge) => edge.source);
115
116 nodesMetadata[node.id] = {
117 ref: node.id,
118 mode,

Callers 7

createMethod · 0.90
updateMethod · 0.90
commitMethod · 0.90
compiler.spec.tsFile · 0.90

Calls 13

getCredentialInputIdsFunction · 0.90
extractPortsFunction · 0.90
validateWorkflowGraphFunction · 0.90
topoSortFunction · 0.85
getMetadataMethod · 0.80
resolvePortsMethod · 0.80
warnMethod · 0.80
hasMethod · 0.80
fromMethod · 0.80
parseMethod · 0.80
getMethod · 0.65
pushMethod · 0.65

Tested by

no test coverage detected