@charliesu/workflow-core 0.0.1-alpha
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/README.md +133 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/code-generator.d.ts +4 -0
- package/dist/lib/code-generator.d.ts.map +1 -0
- package/dist/lib/code-generator.js +283 -0
- package/dist/lib/code-generator.js.map +1 -0
- package/dist/lib/execution-engine.d.ts +12 -0
- package/dist/lib/execution-engine.d.ts.map +1 -0
- package/dist/lib/execution-engine.js +109 -0
- package/dist/lib/execution-engine.js.map +1 -0
- package/dist/lib/node-utils.d.ts +2 -0
- package/dist/lib/node-utils.d.ts.map +1 -0
- package/dist/lib/node-utils.js +15 -0
- package/dist/lib/node-utils.js.map +1 -0
- package/dist/lib/topological-sort.d.ts +5 -0
- package/dist/lib/topological-sort.d.ts.map +1 -0
- package/dist/lib/topological-sort.js +69 -0
- package/dist/lib/topological-sort.js.map +1 -0
- package/dist/lib/validation.d.ts +16 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +281 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/types/execution.d.ts +25 -0
- package/dist/types/execution.d.ts.map +1 -0
- package/dist/types/execution.js +2 -0
- package/dist/types/execution.js.map +1 -0
- package/dist/types/validation.d.ts +23 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +2 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/types/workflow.d.ts +31 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Charlie Su
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# @charliesu/workflow-core
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@charliesu/workflow-core)
|
|
4
|
+
[](https://www.npmjs.com/package/@charliesu/workflow-core)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
Shared workflow engine for TopFlow and TaraFlow - React Flow based workflow orchestration library.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @charliesu/workflow-core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or using other package managers:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# pnpm
|
|
19
|
+
pnpm add @charliesu/workflow-core
|
|
20
|
+
|
|
21
|
+
# yarn
|
|
22
|
+
yarn add @charliesu/workflow-core
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { WorkflowEngine, WorkflowNode, WorkflowEdge } from '@charliesu/workflow-core';
|
|
29
|
+
|
|
30
|
+
// Define your workflow
|
|
31
|
+
const nodes: WorkflowNode[] = [
|
|
32
|
+
{
|
|
33
|
+
id: '1',
|
|
34
|
+
type: 'start',
|
|
35
|
+
position: { x: 0, y: 0 },
|
|
36
|
+
data: { label: 'Start' }
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: '2',
|
|
40
|
+
type: 'textModel',
|
|
41
|
+
position: { x: 200, y: 0 },
|
|
42
|
+
data: { model: 'gpt-4', temperature: 0.7 }
|
|
43
|
+
}
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const edges: WorkflowEdge[] = [
|
|
47
|
+
{
|
|
48
|
+
id: 'e1-2',
|
|
49
|
+
source: '1',
|
|
50
|
+
target: '2'
|
|
51
|
+
}
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
// Use the workflow engine
|
|
55
|
+
// ... (your implementation)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Features
|
|
59
|
+
|
|
60
|
+
- 🔄 **React Flow Integration** - Built on top of React Flow for visual workflow editing
|
|
61
|
+
- 📦 **TypeScript Support** - Full type safety with TypeScript definitions
|
|
62
|
+
- 🎯 **Shared Engine** - Common workflow engine for TopFlow and TaraFlow projects
|
|
63
|
+
- ⚡ **Type-Safe Workflows** - Strongly typed workflow definitions
|
|
64
|
+
- 🔐 **Security-First** - Built with security patterns in mind
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
This package has peer dependencies that you need to install:
|
|
69
|
+
|
|
70
|
+
- React >= 19.0.0
|
|
71
|
+
- React DOM >= 19.0.0
|
|
72
|
+
|
|
73
|
+
## Node Types
|
|
74
|
+
|
|
75
|
+
The workflow engine supports various node types including:
|
|
76
|
+
|
|
77
|
+
- **Entry/Exit**: `start`, `end`
|
|
78
|
+
- **AI Nodes**: `textModel`, `embeddingModel`, `imageGeneration`, `audio`
|
|
79
|
+
- **Data Nodes**: `prompt`, `javascript`, `structuredOutput`
|
|
80
|
+
- **Flow Control**: `conditional`, `httpRequest`
|
|
81
|
+
- **Tools**: `tool`
|
|
82
|
+
|
|
83
|
+
## Development
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Install dependencies
|
|
87
|
+
pnpm install
|
|
88
|
+
|
|
89
|
+
# Build
|
|
90
|
+
pnpm build
|
|
91
|
+
|
|
92
|
+
# Watch mode for development
|
|
93
|
+
pnpm build:watch
|
|
94
|
+
|
|
95
|
+
# Clean build artifacts
|
|
96
|
+
pnpm clean
|
|
97
|
+
|
|
98
|
+
# Run tests
|
|
99
|
+
pnpm test
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Architecture
|
|
103
|
+
|
|
104
|
+
This package provides the core workflow engine that is shared between:
|
|
105
|
+
|
|
106
|
+
- **[TopFlow](https://topflow.dev)** - Privacy-first visual workflow builder for AI systems
|
|
107
|
+
- **TaraFlow** - AI workflow orchestration platform
|
|
108
|
+
|
|
109
|
+
The forked foundation architecture allows both projects to share common workflow logic while maintaining their unique features.
|
|
110
|
+
|
|
111
|
+
## Contributing
|
|
112
|
+
|
|
113
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT © [Charlie Su](https://charliesu.com)
|
|
118
|
+
|
|
119
|
+
## Links
|
|
120
|
+
|
|
121
|
+
- **TopFlow**: [topflow.dev](https://topflow.dev)
|
|
122
|
+
- **GitHub**: [github.com/csupenn/workflow-core](https://github.com/csupenn/workflow-core)
|
|
123
|
+
- **npm**: [npmjs.com/package/@charliesu/workflow-core](https://www.npmjs.com/package/@charliesu/workflow-core)
|
|
124
|
+
- **Issues**: [github.com/csupenn/workflow-core/issues](https://github.com/csupenn/workflow-core/issues)
|
|
125
|
+
|
|
126
|
+
## Related Projects
|
|
127
|
+
|
|
128
|
+
- **[TopFlow](https://github.com/csupenn/topflow)** - Open-source visual workflow builder for secure AI applications
|
|
129
|
+
- **TaraFlow** - AI workflow orchestration (coming soon)
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
**Built with ❤️ by [Charlie Su](https://charliesu.com) | Former CISO | AI Security Expert**
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ExecutionEngine } from './lib/execution-engine';
|
|
2
|
+
export { validateWorkflow, validateApiKeys, calculateValidationScore, getValidationGrade, detectCycles, isUrlSafe } from './lib/validation';
|
|
3
|
+
export { generateAISDKCode, generateRouteHandlerCode } from './lib/code-generator';
|
|
4
|
+
export { topologicalSort, getNodeInputs } from './lib/topological-sort';
|
|
5
|
+
export * from './lib/node-utils';
|
|
6
|
+
export * from './types/workflow';
|
|
7
|
+
export * from './types/execution';
|
|
8
|
+
export * from './types/validation';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACV,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACvE,cAAc,kBAAkB,CAAA;AAGhC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ExecutionEngine } from './lib/execution-engine';
|
|
2
|
+
export { validateWorkflow, validateApiKeys, calculateValidationScore, getValidationGrade, detectCycles, isUrlSafe } from './lib/validation';
|
|
3
|
+
export { generateAISDKCode, generateRouteHandlerCode } from './lib/code-generator';
|
|
4
|
+
export { topologicalSort, getNodeInputs } from './lib/topological-sort';
|
|
5
|
+
export * from './lib/node-utils';
|
|
6
|
+
export * from './types/workflow';
|
|
7
|
+
export * from './types/execution';
|
|
8
|
+
export * from './types/validation';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACV,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACvE,cAAc,kBAAkB,CAAA;AAGhC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-generator.d.ts","sourceRoot":"","sources":["../../src/lib/code-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAE/C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CA+PtE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAkE7E"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
export function generateAISDKCode(nodes, edges) {
|
|
2
|
+
const nodeMap = new Map(nodes.map((node) => [node.id, node]));
|
|
3
|
+
const edgeMap = new Map();
|
|
4
|
+
edges.forEach((edge) => {
|
|
5
|
+
if (!edgeMap.has(edge.source)) {
|
|
6
|
+
edgeMap.set(edge.source, []);
|
|
7
|
+
}
|
|
8
|
+
edgeMap.get(edge.source)?.push(edge.target);
|
|
9
|
+
});
|
|
10
|
+
const incomingEdges = new Set(edges.map((e) => e.target));
|
|
11
|
+
const entryNodes = nodes.filter((node) => !incomingEdges.has(node.id) || node.type === "start");
|
|
12
|
+
let code = `import { generateText, embed, generateObject, tool } from 'ai';\n`;
|
|
13
|
+
code += `import { google } from '@ai-sdk/google';\n`;
|
|
14
|
+
code += `import { openai } from '@ai-sdk/openai';\n`;
|
|
15
|
+
code += `import { z } from 'zod';\n\n`;
|
|
16
|
+
code += `export async function runAgentWorkflow(initialInput?: string) {\n`;
|
|
17
|
+
const processedNodes = new Set();
|
|
18
|
+
const nodeVariables = new Map();
|
|
19
|
+
const getInputVariables = (nodeId) => {
|
|
20
|
+
const inputEdges = edges.filter((e) => e.target === nodeId);
|
|
21
|
+
return inputEdges.map((e) => nodeVariables.get(e.source) || '""').filter(Boolean);
|
|
22
|
+
};
|
|
23
|
+
const generateNodeCode = (nodeId, indent = " ") => {
|
|
24
|
+
if (processedNodes.has(nodeId)) {
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
processedNodes.add(nodeId);
|
|
28
|
+
const node = nodeMap.get(nodeId);
|
|
29
|
+
if (!node)
|
|
30
|
+
return "";
|
|
31
|
+
const data = node.data;
|
|
32
|
+
let nodeCode = "";
|
|
33
|
+
const varName = `node_${nodeId.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
34
|
+
nodeVariables.set(nodeId, varName);
|
|
35
|
+
switch (node.type) {
|
|
36
|
+
case "start":
|
|
37
|
+
nodeCode += `${indent}// Start Node\n`;
|
|
38
|
+
nodeCode += `${indent}const ${varName} = initialInput || '';\n\n`;
|
|
39
|
+
break;
|
|
40
|
+
case "end":
|
|
41
|
+
nodeCode += `${indent}// End Node\n`;
|
|
42
|
+
const endInputVars = getInputVariables(nodeId);
|
|
43
|
+
const endInputVar = endInputVars.length > 0 ? endInputVars[0] : '""';
|
|
44
|
+
nodeCode += `${indent}const ${varName} = ${endInputVar};\n`;
|
|
45
|
+
nodeCode += `${indent}return ${varName};\n\n`;
|
|
46
|
+
break;
|
|
47
|
+
case "prompt":
|
|
48
|
+
nodeCode += `${indent}// Prompt Node\n`;
|
|
49
|
+
const inputVars = getInputVariables(nodeId);
|
|
50
|
+
if (inputVars.length > 0) {
|
|
51
|
+
const content = data.content || "";
|
|
52
|
+
let interpolatedContent = content;
|
|
53
|
+
inputVars.forEach((inputVar, index) => {
|
|
54
|
+
interpolatedContent = interpolatedContent.replace(new RegExp(`\\$input${index + 1}`, "g"), `\${${inputVar}}`);
|
|
55
|
+
});
|
|
56
|
+
nodeCode += `${indent}const ${varName} = \`${interpolatedContent}\`;\n\n`;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
nodeCode += `${indent}const ${varName} = ${JSON.stringify(data.content || "")};\n\n`;
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
case "textModel":
|
|
63
|
+
nodeCode += `${indent}// Text Model Node\n`;
|
|
64
|
+
const textInputVars = getInputVariables(nodeId);
|
|
65
|
+
const textInputVar = textInputVars.length > 0 ? textInputVars[0] : '""';
|
|
66
|
+
if (data.structuredOutput && data.schema) {
|
|
67
|
+
nodeCode += `${indent}const ${varName}_schema = z.object(${data.schema});\n`;
|
|
68
|
+
nodeCode += `${indent}const ${varName}_result = await generateObject({\n`;
|
|
69
|
+
nodeCode += `${indent} model: '${data.model || "openai/gpt-4o-mini"}',\n`;
|
|
70
|
+
nodeCode += `${indent} schema: ${varName}_schema,\n`;
|
|
71
|
+
nodeCode += `${indent} prompt: ${textInputVar},\n`;
|
|
72
|
+
nodeCode += `${indent}});\n`;
|
|
73
|
+
nodeCode += `${indent}const ${varName} = JSON.stringify(${varName}_result.object);\n\n`;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
nodeCode += `${indent}const ${varName}_result = await generateText({\n`;
|
|
77
|
+
nodeCode += `${indent} model: '${data.model || "openai/gpt-4o-mini"}',\n`;
|
|
78
|
+
nodeCode += `${indent} prompt: ${textInputVar},\n`;
|
|
79
|
+
nodeCode += `${indent} temperature: ${data.temperature || 0.7},\n`;
|
|
80
|
+
nodeCode += `${indent} maxTokens: ${data.maxTokens || 2000},\n`;
|
|
81
|
+
nodeCode += `${indent}});\n`;
|
|
82
|
+
nodeCode += `${indent}const ${varName} = ${varName}_result.text;\n\n`;
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case "imageGeneration":
|
|
86
|
+
nodeCode += `${indent}// Image Generation Node\n`;
|
|
87
|
+
const imgInputVars = getInputVariables(nodeId);
|
|
88
|
+
const imgInputVar = imgInputVars.length > 0 ? imgInputVars[0] : '""';
|
|
89
|
+
nodeCode += `${indent}const ${varName}_result = await generateText({\n`;
|
|
90
|
+
nodeCode += `${indent} model: google('${data.model || "gemini-2.5-flash-image"}'),\n`;
|
|
91
|
+
nodeCode += `${indent} prompt: ${imgInputVar},\n`;
|
|
92
|
+
nodeCode += `${indent}});\n`;
|
|
93
|
+
nodeCode += `${indent}// Extract images from files\n`;
|
|
94
|
+
nodeCode += `${indent}const ${varName} = ${varName}_result.files?.filter(f => f.mediaType.startsWith('image/')).map(f => f.base64) || [];\n\n`;
|
|
95
|
+
break;
|
|
96
|
+
case "audio":
|
|
97
|
+
nodeCode += `${indent}// Audio Generation Node\n`;
|
|
98
|
+
const audioInputVars = getInputVariables(nodeId);
|
|
99
|
+
const audioInputVar = audioInputVars.length > 0 ? audioInputVars[0] : '""';
|
|
100
|
+
nodeCode += `${indent}// Note: Audio generation requires appropriate TTS setup\n`;
|
|
101
|
+
nodeCode += `${indent}const ${varName}_result = await fetch('https://api.openai.com/v1/audio/speech', {\n`;
|
|
102
|
+
nodeCode += `${indent} method: 'POST',\n`;
|
|
103
|
+
nodeCode += `${indent} headers: {\n`;
|
|
104
|
+
nodeCode += `${indent} 'Authorization': \`Bearer \${process.env.OPENAI_API_KEY}\`,\n`;
|
|
105
|
+
nodeCode += `${indent} 'Content-Type': 'application/json',\n`;
|
|
106
|
+
nodeCode += `${indent} },\n`;
|
|
107
|
+
nodeCode += `${indent} body: JSON.stringify({\n`;
|
|
108
|
+
nodeCode += `${indent} model: '${data.model || "tts-1"}',\n`;
|
|
109
|
+
nodeCode += `${indent} input: ${audioInputVar},\n`;
|
|
110
|
+
nodeCode += `${indent} voice: '${data.voice || "alloy"}',\n`;
|
|
111
|
+
nodeCode += `${indent} speed: ${data.speed || 1.0},\n`;
|
|
112
|
+
nodeCode += `${indent} }),\n`;
|
|
113
|
+
nodeCode += `${indent}});\n`;
|
|
114
|
+
nodeCode += `${indent}const ${varName} = await ${varName}_result.arrayBuffer();\n\n`;
|
|
115
|
+
break;
|
|
116
|
+
case "embeddingModel":
|
|
117
|
+
nodeCode += `${indent}// Embedding Model Node\n`;
|
|
118
|
+
const embInputVars = getInputVariables(nodeId);
|
|
119
|
+
const embInputVar = embInputVars.length > 0 ? embInputVars[0] : '""';
|
|
120
|
+
nodeCode += `${indent}const ${varName}_result = await embed({\n`;
|
|
121
|
+
nodeCode += `${indent} model: openai.embedding('${data.model || "text-embedding-3-small"}'),\n`;
|
|
122
|
+
nodeCode += `${indent} value: ${embInputVar},\n`;
|
|
123
|
+
nodeCode += `${indent}});\n`;
|
|
124
|
+
nodeCode += `${indent}const ${varName} = ${varName}_result.embedding;\n\n`;
|
|
125
|
+
break;
|
|
126
|
+
case "tool":
|
|
127
|
+
nodeCode += `${indent}// Tool Node\n`;
|
|
128
|
+
const toolCode = data.code || "return { result: 'Tool executed' };";
|
|
129
|
+
nodeCode += `${indent}const ${varName} = tool({\n`;
|
|
130
|
+
nodeCode += `${indent} description: '${data.description || "A custom tool"}',\n`;
|
|
131
|
+
nodeCode += `${indent} parameters: z.object({\n`;
|
|
132
|
+
nodeCode += `${indent} input: z.string().describe('Input parameter'),\n`;
|
|
133
|
+
nodeCode += `${indent} }),\n`;
|
|
134
|
+
nodeCode += `${indent} execute: async ({ input }) => {\n`;
|
|
135
|
+
nodeCode += `${indent} ${toolCode.split("\n").join(`\n${indent} `)}\n`;
|
|
136
|
+
nodeCode += `${indent} },\n`;
|
|
137
|
+
nodeCode += `${indent}});\n\n`;
|
|
138
|
+
break;
|
|
139
|
+
case "javascript":
|
|
140
|
+
nodeCode += `${indent}// JavaScript Execution Node\n`;
|
|
141
|
+
const jsInputVars = getInputVariables(nodeId);
|
|
142
|
+
const jsCode = data.code || "return input1;";
|
|
143
|
+
nodeCode += `${indent}const ${varName} = (() => {\n`;
|
|
144
|
+
jsInputVars.forEach((inputVar, index) => {
|
|
145
|
+
nodeCode += `${indent} const input${index + 1} = ${inputVar};\n`;
|
|
146
|
+
});
|
|
147
|
+
nodeCode += `${indent} ${jsCode.split("\n").join(`\n${indent} `)}\n`;
|
|
148
|
+
nodeCode += `${indent}})();\n\n`;
|
|
149
|
+
break;
|
|
150
|
+
case "httpRequest":
|
|
151
|
+
nodeCode += `${indent}// HTTP Request Node\n`;
|
|
152
|
+
const httpInputVars = getInputVariables(nodeId);
|
|
153
|
+
const url = data.url || "https://api.example.com";
|
|
154
|
+
const method = data.method || "GET";
|
|
155
|
+
nodeCode += `${indent}const ${varName}_response = await fetch('${url}', {\n`;
|
|
156
|
+
nodeCode += `${indent} method: '${method}',\n`;
|
|
157
|
+
if (method !== "GET" && httpInputVars.length > 0) {
|
|
158
|
+
nodeCode += `${indent} headers: { 'Content-Type': 'application/json' },\n`;
|
|
159
|
+
nodeCode += `${indent} body: JSON.stringify({ data: ${httpInputVars[0]} }),\n`;
|
|
160
|
+
}
|
|
161
|
+
nodeCode += `${indent}});\n`;
|
|
162
|
+
nodeCode += `${indent}const ${varName} = await ${varName}_response.json();\n\n`;
|
|
163
|
+
break;
|
|
164
|
+
case "conditional":
|
|
165
|
+
nodeCode += `${indent}// Conditional Node\n`;
|
|
166
|
+
const condInputVars = getInputVariables(nodeId);
|
|
167
|
+
const condition = data.condition || "true";
|
|
168
|
+
nodeCode += `${indent}const ${varName} = (() => {\n`;
|
|
169
|
+
condInputVars.forEach((inputVar, index) => {
|
|
170
|
+
nodeCode += `${indent} const input${index + 1} = ${inputVar};\n`;
|
|
171
|
+
});
|
|
172
|
+
nodeCode += `${indent} return ${condition};\n`;
|
|
173
|
+
nodeCode += `${indent}})();\n\n`;
|
|
174
|
+
const outgoingEdges = edges.filter((e) => e.source === nodeId);
|
|
175
|
+
const trueEdge = outgoingEdges.find((e) => e.sourceHandle === "true");
|
|
176
|
+
const falseEdge = outgoingEdges.find((e) => e.sourceHandle === "false");
|
|
177
|
+
if (trueEdge || falseEdge) {
|
|
178
|
+
nodeCode += `${indent}if (${varName}) {\n`;
|
|
179
|
+
if (trueEdge) {
|
|
180
|
+
nodeCode += `${indent} // True branch\n`;
|
|
181
|
+
}
|
|
182
|
+
nodeCode += `${indent}} else {\n`;
|
|
183
|
+
if (falseEdge) {
|
|
184
|
+
nodeCode += `${indent} // False branch\n`;
|
|
185
|
+
}
|
|
186
|
+
nodeCode += `${indent}}\n\n`;
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
return nodeCode;
|
|
191
|
+
};
|
|
192
|
+
const processNode = (nodeId) => {
|
|
193
|
+
const inputEdges = edges.filter((e) => e.target === nodeId);
|
|
194
|
+
inputEdges.forEach((edge) => {
|
|
195
|
+
if (!processedNodes.has(edge.source)) {
|
|
196
|
+
processNode(edge.source);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
code += generateNodeCode(nodeId);
|
|
200
|
+
const outputNodes = edgeMap.get(nodeId) || [];
|
|
201
|
+
outputNodes.forEach((targetId) => {
|
|
202
|
+
if (!processedNodes.has(targetId)) {
|
|
203
|
+
processNode(targetId);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
entryNodes.forEach((node) => processNode(node.id));
|
|
208
|
+
const endNode = nodes.find((n) => n.type === "end");
|
|
209
|
+
const returnNode = endNode || nodes[nodes.length - 1];
|
|
210
|
+
if (returnNode && !endNode) {
|
|
211
|
+
const lastVar = nodeVariables.get(returnNode.id);
|
|
212
|
+
if (lastVar) {
|
|
213
|
+
code += ` return ${lastVar};\n`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
code += `}\n`;
|
|
217
|
+
return code;
|
|
218
|
+
}
|
|
219
|
+
export function generateRouteHandlerCode(nodes, edges) {
|
|
220
|
+
let code = `import { generateText, embed, generateObject } from 'ai';\n`;
|
|
221
|
+
code += `import { google } from '@ai-sdk/google';\n`;
|
|
222
|
+
code += `import { openai } from '@ai-sdk/openai';\n`;
|
|
223
|
+
code += `import { z } from 'zod';\n\n`;
|
|
224
|
+
code += `export const maxDuration = 60;\n\n`;
|
|
225
|
+
code += `export async function POST(req: Request) {\n`;
|
|
226
|
+
code += ` try {\n`;
|
|
227
|
+
code += ` const { input } = await req.json();\n\n`;
|
|
228
|
+
const hasTextModel = nodes.some((n) => n.type === "textModel");
|
|
229
|
+
const hasImageGen = nodes.some((n) => n.type === "imageGeneration");
|
|
230
|
+
const hasHttpRequest = nodes.some((n) => n.type === "httpRequest");
|
|
231
|
+
if (hasHttpRequest) {
|
|
232
|
+
const httpNode = nodes.find((n) => n.type === "httpRequest");
|
|
233
|
+
if (httpNode) {
|
|
234
|
+
const data = httpNode.data;
|
|
235
|
+
code += ` // HTTP Request\n`;
|
|
236
|
+
code += ` const apiResponse = await fetch('${data.url || "https://api.example.com"}', {\n`;
|
|
237
|
+
code += ` method: '${data.method || "GET"}',\n`;
|
|
238
|
+
code += ` });\n`;
|
|
239
|
+
code += ` const apiData = await apiResponse.json();\n\n`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (hasTextModel) {
|
|
243
|
+
const textNode = nodes.find((n) => n.type === "textModel");
|
|
244
|
+
if (textNode) {
|
|
245
|
+
const data = textNode.data;
|
|
246
|
+
code += ` // Text Generation\n`;
|
|
247
|
+
code += ` const result = await generateText({\n`;
|
|
248
|
+
code += ` model: '${data.model || "openai/gpt-4o-mini"}',\n`;
|
|
249
|
+
code += ` prompt: input,\n`;
|
|
250
|
+
code += ` temperature: ${data.temperature || 0.7},\n`;
|
|
251
|
+
code += ` maxTokens: ${data.maxTokens || 2000},\n`;
|
|
252
|
+
code += ` });\n\n`;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (hasImageGen) {
|
|
256
|
+
const imgNode = nodes.find((n) => n.type === "imageGeneration");
|
|
257
|
+
if (imgNode) {
|
|
258
|
+
const data = imgNode.data;
|
|
259
|
+
code += ` // Image Generation\n`;
|
|
260
|
+
code += ` const imageResult = await generateText({\n`;
|
|
261
|
+
code += ` model: google('${data.model || "gemini-2.5-flash-image"}'),\n`;
|
|
262
|
+
code += ` prompt: input,\n`;
|
|
263
|
+
code += ` });\n`;
|
|
264
|
+
code += ` const images = imageResult.files?.filter(f => f.mediaType.startsWith('image/')).map(f => f.base64) || [];\n\n`;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
code += ` return Response.json({ \n`;
|
|
268
|
+
if (hasTextModel)
|
|
269
|
+
code += ` text: result.text,\n`;
|
|
270
|
+
if (hasImageGen)
|
|
271
|
+
code += ` images,\n`;
|
|
272
|
+
if (hasHttpRequest)
|
|
273
|
+
code += ` apiData,\n`;
|
|
274
|
+
code += ` success: true \n`;
|
|
275
|
+
code += ` });\n`;
|
|
276
|
+
code += ` } catch (error) {\n`;
|
|
277
|
+
code += ` console.error('Workflow error:', error);\n`;
|
|
278
|
+
code += ` return Response.json({ error: 'Workflow execution failed' }, { status: 500 });\n`;
|
|
279
|
+
code += ` }\n`;
|
|
280
|
+
code += `}\n`;
|
|
281
|
+
return code;
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=code-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-generator.js","sourceRoot":"","sources":["../../src/lib/code-generator.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAa;IAC5D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;IAE3C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAC9B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IAE/F,IAAI,IAAI,GAAG,mEAAmE,CAAA;IAC9E,IAAI,IAAI,4CAA4C,CAAA;IACpD,IAAI,IAAI,4CAA4C,CAAA;IACpD,IAAI,IAAI,8BAA8B,CAAA;IACtC,IAAI,IAAI,mEAAmE,CAAA;IAE3E,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA;IACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE/C,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAY,EAAE;QACrD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;QAC3D,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACnF,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAE,MAAM,GAAG,IAAI,EAAU,EAAE;QACjE,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAA;QACX,CAAC;QACD,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAE1B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAA;QAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAW,CAAA;QAC7B,IAAI,QAAQ,GAAG,EAAE,CAAA;QACjB,MAAM,OAAO,GAAG,QAAQ,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,EAAE,CAAA;QAC9D,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAElC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,OAAO;gBACV,QAAQ,IAAI,GAAG,MAAM,iBAAiB,CAAA;gBACtC,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,4BAA4B,CAAA;gBACjE,MAAK;YAEP,KAAK,KAAK;gBACR,QAAQ,IAAI,GAAG,MAAM,eAAe,CAAA;gBACpC,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC9C,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBACpE,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,MAAM,WAAW,KAAK,CAAA;gBAC3D,QAAQ,IAAI,GAAG,MAAM,UAAU,OAAO,OAAO,CAAA;gBAC7C,MAAK;YAEP,KAAK,QAAQ;gBACX,QAAQ,IAAI,GAAG,MAAM,kBAAkB,CAAA;gBACvC,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAE3C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;oBAClC,IAAI,mBAAmB,GAAG,OAAO,CAAA;oBACjC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;wBACpC,mBAAmB,GAAG,mBAAmB,CAAC,OAAO,CAC/C,IAAI,MAAM,CAAC,WAAW,KAAK,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EACvC,MAAM,QAAQ,GAAG,CAClB,CAAA;oBACH,CAAC,CAAC,CAAA;oBACF,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,QAAQ,mBAAmB,SAAS,CAAA;gBAC3E,CAAC;qBAAM,CAAC;oBACN,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,CAAA;gBACtF,CAAC;gBACD,MAAK;YAEP,KAAK,WAAW;gBACd,QAAQ,IAAI,GAAG,MAAM,sBAAsB,CAAA;gBAC3C,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC/C,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAEvE,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBACzC,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,sBAAsB,IAAI,CAAC,MAAM,MAAM,CAAA;oBAC5E,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,oCAAoC,CAAA;oBACzE,QAAQ,IAAI,GAAG,MAAM,aAAa,IAAI,CAAC,KAAK,IAAI,oBAAoB,MAAM,CAAA;oBAC1E,QAAQ,IAAI,GAAG,MAAM,aAAa,OAAO,YAAY,CAAA;oBACrD,QAAQ,IAAI,GAAG,MAAM,aAAa,YAAY,KAAK,CAAA;oBACnD,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;oBAC5B,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,qBAAqB,OAAO,sBAAsB,CAAA;gBACzF,CAAC;qBAAM,CAAC;oBACN,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,kCAAkC,CAAA;oBACvE,QAAQ,IAAI,GAAG,MAAM,aAAa,IAAI,CAAC,KAAK,IAAI,oBAAoB,MAAM,CAAA;oBAC1E,QAAQ,IAAI,GAAG,MAAM,aAAa,YAAY,KAAK,CAAA;oBACnD,QAAQ,IAAI,GAAG,MAAM,kBAAkB,IAAI,CAAC,WAAW,IAAI,GAAG,KAAK,CAAA;oBACnE,QAAQ,IAAI,GAAG,MAAM,gBAAgB,IAAI,CAAC,SAAS,IAAI,IAAI,KAAK,CAAA;oBAChE,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;oBAC5B,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,MAAM,OAAO,mBAAmB,CAAA;gBACvE,CAAC;gBACD,MAAK;YAEP,KAAK,iBAAiB;gBACpB,QAAQ,IAAI,GAAG,MAAM,4BAA4B,CAAA;gBACjD,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC9C,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAEpE,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,kCAAkC,CAAA;gBACvE,QAAQ,IAAI,GAAG,MAAM,oBAAoB,IAAI,CAAC,KAAK,IAAI,wBAAwB,OAAO,CAAA;gBACtF,QAAQ,IAAI,GAAG,MAAM,aAAa,WAAW,KAAK,CAAA;gBAClD,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;gBAC5B,QAAQ,IAAI,GAAG,MAAM,gCAAgC,CAAA;gBACrD,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,MAAM,OAAO,4FAA4F,CAAA;gBAC9I,MAAK;YAEP,KAAK,OAAO;gBACV,QAAQ,IAAI,GAAG,MAAM,4BAA4B,CAAA;gBACjD,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAChD,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAE1E,QAAQ,IAAI,GAAG,MAAM,4DAA4D,CAAA;gBACjF,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,qEAAqE,CAAA;gBAC1G,QAAQ,IAAI,GAAG,MAAM,qBAAqB,CAAA;gBAC1C,QAAQ,IAAI,GAAG,MAAM,gBAAgB,CAAA;gBACrC,QAAQ,IAAI,GAAG,MAAM,mEAAmE,CAAA;gBACxF,QAAQ,IAAI,GAAG,MAAM,2CAA2C,CAAA;gBAChE,QAAQ,IAAI,GAAG,MAAM,QAAQ,CAAA;gBAC7B,QAAQ,IAAI,GAAG,MAAM,4BAA4B,CAAA;gBACjD,QAAQ,IAAI,GAAG,MAAM,eAAe,IAAI,CAAC,KAAK,IAAI,OAAO,MAAM,CAAA;gBAC/D,QAAQ,IAAI,GAAG,MAAM,cAAc,aAAa,KAAK,CAAA;gBACrD,QAAQ,IAAI,GAAG,MAAM,eAAe,IAAI,CAAC,KAAK,IAAI,OAAO,MAAM,CAAA;gBAC/D,QAAQ,IAAI,GAAG,MAAM,cAAc,IAAI,CAAC,KAAK,IAAI,GAAG,KAAK,CAAA;gBACzD,QAAQ,IAAI,GAAG,MAAM,SAAS,CAAA;gBAC9B,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;gBAC5B,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,YAAY,OAAO,4BAA4B,CAAA;gBACpF,MAAK;YAEP,KAAK,gBAAgB;gBACnB,QAAQ,IAAI,GAAG,MAAM,2BAA2B,CAAA;gBAChD,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC9C,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAEpE,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,2BAA2B,CAAA;gBAChE,QAAQ,IAAI,GAAG,MAAM,8BAA8B,IAAI,CAAC,KAAK,IAAI,wBAAwB,OAAO,CAAA;gBAChG,QAAQ,IAAI,GAAG,MAAM,YAAY,WAAW,KAAK,CAAA;gBACjD,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;gBAC5B,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,MAAM,OAAO,wBAAwB,CAAA;gBAC1E,MAAK;YAEP,KAAK,MAAM;gBACT,QAAQ,IAAI,GAAG,MAAM,gBAAgB,CAAA;gBACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,qCAAqC,CAAA;gBACnE,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,aAAa,CAAA;gBAClD,QAAQ,IAAI,GAAG,MAAM,mBAAmB,IAAI,CAAC,WAAW,IAAI,eAAe,MAAM,CAAA;gBACjF,QAAQ,IAAI,GAAG,MAAM,4BAA4B,CAAA;gBACjD,QAAQ,IAAI,GAAG,MAAM,sDAAsD,CAAA;gBAC3E,QAAQ,IAAI,GAAG,MAAM,SAAS,CAAA;gBAC9B,QAAQ,IAAI,GAAG,MAAM,qCAAqC,CAAA;gBAC1D,QAAQ,IAAI,GAAG,MAAM,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,MAAM,CAAC,IAAI,CAAA;gBAC5E,QAAQ,IAAI,GAAG,MAAM,QAAQ,CAAA;gBAC7B,QAAQ,IAAI,GAAG,MAAM,SAAS,CAAA;gBAC9B,MAAK;YAEP,KAAK,YAAY;gBACf,QAAQ,IAAI,GAAG,MAAM,gCAAgC,CAAA;gBACrD,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,gBAAgB,CAAA;gBAE5C,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,eAAe,CAAA;gBACpD,WAAW,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;oBACtC,QAAQ,IAAI,GAAG,MAAM,gBAAgB,KAAK,GAAG,CAAC,MAAM,QAAQ,KAAK,CAAA;gBACnE,CAAC,CAAC,CAAA;gBACF,QAAQ,IAAI,GAAG,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,IAAI,CAAA;gBACtE,QAAQ,IAAI,GAAG,MAAM,WAAW,CAAA;gBAChC,MAAK;YAEP,KAAK,aAAa;gBAChB,QAAQ,IAAI,GAAG,MAAM,wBAAwB,CAAA;gBAC7C,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,yBAAyB,CAAA;gBACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;gBAEnC,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,4BAA4B,GAAG,QAAQ,CAAA;gBAC5E,QAAQ,IAAI,GAAG,MAAM,cAAc,MAAM,MAAM,CAAA;gBAC/C,IAAI,MAAM,KAAK,KAAK,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACjD,QAAQ,IAAI,GAAG,MAAM,sDAAsD,CAAA;oBAC3E,QAAQ,IAAI,GAAG,MAAM,kCAAkC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAA;gBACjF,CAAC;gBACD,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;gBAC5B,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,YAAY,OAAO,uBAAuB,CAAA;gBAC/E,MAAK;YAEP,KAAK,aAAa;gBAChB,QAAQ,IAAI,GAAG,MAAM,uBAAuB,CAAA;gBAC5C,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;gBAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAA;gBAE1C,QAAQ,IAAI,GAAG,MAAM,SAAS,OAAO,eAAe,CAAA;gBACpD,aAAa,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;oBACxC,QAAQ,IAAI,GAAG,MAAM,gBAAgB,KAAK,GAAG,CAAC,MAAM,QAAQ,KAAK,CAAA;gBACnE,CAAC,CAAC,CAAA;gBACF,QAAQ,IAAI,GAAG,MAAM,YAAY,SAAS,KAAK,CAAA;gBAC/C,QAAQ,IAAI,GAAG,MAAM,WAAW,CAAA;gBAGhC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;gBAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAA;gBACrE,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,OAAO,CAAC,CAAA;gBAEvE,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;oBAC1B,QAAQ,IAAI,GAAG,MAAM,OAAO,OAAO,OAAO,CAAA;oBAC1C,IAAI,QAAQ,EAAE,CAAC;wBACb,QAAQ,IAAI,GAAG,MAAM,oBAAoB,CAAA;oBAC3C,CAAC;oBACD,QAAQ,IAAI,GAAG,MAAM,YAAY,CAAA;oBACjC,IAAI,SAAS,EAAE,CAAC;wBACd,QAAQ,IAAI,GAAG,MAAM,qBAAqB,CAAA;oBAC5C,CAAC;oBACD,QAAQ,IAAI,GAAG,MAAM,OAAO,CAAA;gBAC9B,CAAC;gBACD,MAAK;QACT,CAAC;QAED,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,MAAc,EAAQ,EAAE;QAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;QAC3D,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAA;QAEhC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAC7C,WAAW,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC/B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClC,WAAW,CAAC,QAAQ,CAAC,CAAA;YACvB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IAElD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IACnD,MAAM,UAAU,GAAG,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACrD,IAAI,UAAU,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QAChD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,IAAI,YAAY,OAAO,KAAK,CAAA;QAClC,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,CAAA;IAEb,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAa,EAAE,KAAa;IACnE,IAAI,IAAI,GAAG,6DAA6D,CAAA;IACxE,IAAI,IAAI,4CAA4C,CAAA;IACpD,IAAI,IAAI,4CAA4C,CAAA;IACpD,IAAI,IAAI,8BAA8B,CAAA;IACtC,IAAI,IAAI,oCAAoC,CAAA;IAC5C,IAAI,IAAI,8CAA8C,CAAA;IACtD,IAAI,IAAI,WAAW,CAAA;IACnB,IAAI,IAAI,6CAA6C,CAAA;IAErD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA;IAC9D,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAA;IACnE,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;IAElE,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;QAC5D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAW,CAAA;YACjC,IAAI,IAAI,uBAAuB,CAAA;YAC/B,IAAI,IAAI,wCAAwC,IAAI,CAAC,GAAG,IAAI,yBAAyB,QAAQ,CAAA;YAC7F,IAAI,IAAI,kBAAkB,IAAI,CAAC,MAAM,IAAI,KAAK,MAAM,CAAA;YACpD,IAAI,IAAI,WAAW,CAAA;YACnB,IAAI,IAAI,mDAAmD,CAAA;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA;QAC1D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAW,CAAA;YACjC,IAAI,IAAI,0BAA0B,CAAA;YAClC,IAAI,IAAI,2CAA2C,CAAA;YACnD,IAAI,IAAI,iBAAiB,IAAI,CAAC,KAAK,IAAI,oBAAoB,MAAM,CAAA;YACjE,IAAI,IAAI,wBAAwB,CAAA;YAChC,IAAI,IAAI,sBAAsB,IAAI,CAAC,WAAW,IAAI,GAAG,KAAK,CAAA;YAC1D,IAAI,IAAI,oBAAoB,IAAI,CAAC,SAAS,IAAI,IAAI,KAAK,CAAA;YACvD,IAAI,IAAI,aAAa,CAAA;QACvB,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAA;QAC/D,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,OAAO,CAAC,IAAW,CAAA;YAChC,IAAI,IAAI,2BAA2B,CAAA;YACnC,IAAI,IAAI,gDAAgD,CAAA;YACxD,IAAI,IAAI,wBAAwB,IAAI,CAAC,KAAK,IAAI,wBAAwB,OAAO,CAAA;YAC7E,IAAI,IAAI,wBAAwB,CAAA;YAChC,IAAI,IAAI,WAAW,CAAA;YACnB,IAAI,IAAI,mHAAmH,CAAA;QAC7H,CAAC;IACH,CAAC;IAED,IAAI,IAAI,+BAA+B,CAAA;IACvC,IAAI,YAAY;QAAE,IAAI,IAAI,4BAA4B,CAAA;IACtD,IAAI,WAAW;QAAE,IAAI,IAAI,iBAAiB,CAAA;IAC1C,IAAI,cAAc;QAAE,IAAI,IAAI,kBAAkB,CAAA;IAC9C,IAAI,IAAI,wBAAwB,CAAA;IAChC,IAAI,IAAI,WAAW,CAAA;IACnB,IAAI,IAAI,uBAAuB,CAAA;IAC/B,IAAI,IAAI,gDAAgD,CAAA;IACxD,IAAI,IAAI,sFAAsF,CAAA;IAC9F,IAAI,IAAI,OAAO,CAAA;IACf,IAAI,IAAI,KAAK,CAAA;IAEb,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Node, Edge } from '@xyflow/react';
|
|
2
|
+
import type { ExecutionContext, ExecutionResult, ExecutionUpdate } from '../types/workflow';
|
|
3
|
+
export declare class ExecutionEngine {
|
|
4
|
+
private abortController?;
|
|
5
|
+
executeWorkflow(nodes: Node[], edges: Edge[], context: ExecutionContext, onUpdate?: (update: ExecutionUpdate) => void): Promise<ExecutionResult>;
|
|
6
|
+
protected executeNode(node: Node, inputs: Record<string, any>, context: ExecutionContext): Promise<any>;
|
|
7
|
+
private executePromptNode;
|
|
8
|
+
private executeJavaScriptNode;
|
|
9
|
+
private executeConditionalNode;
|
|
10
|
+
abort(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=execution-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-engine.d.ts","sourceRoot":"","sources":["../../src/lib/execution-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EAChB,MAAM,mBAAmB,CAAA;AAG1B,qBAAa,eAAe;IAC1B,OAAO,CAAC,eAAe,CAAC,CAAiB;IAKnC,eAAe,CACnB,KAAK,EAAE,IAAI,EAAE,EACb,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,gBAAgB,EACzB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAC3C,OAAO,CAAC,eAAe,CAAC;cAyEX,WAAW,CACzB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,GAAG,CAAC;IAuBf,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,sBAAsB;IAe9B,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { topologicalSort, getNodeInputs } from './topological-sort';
|
|
2
|
+
export class ExecutionEngine {
|
|
3
|
+
async executeWorkflow(nodes, edges, context, onUpdate) {
|
|
4
|
+
this.abortController = new AbortController();
|
|
5
|
+
try {
|
|
6
|
+
const { sorted, hasCycle, cycleNodes } = topologicalSort(nodes, edges);
|
|
7
|
+
if (hasCycle) {
|
|
8
|
+
throw new Error(`Workflow contains cycles: ${cycleNodes?.join(', ')}`);
|
|
9
|
+
}
|
|
10
|
+
const results = new Map();
|
|
11
|
+
for (const node of sorted) {
|
|
12
|
+
if (this.abortController.signal.aborted) {
|
|
13
|
+
throw new Error('Execution aborted');
|
|
14
|
+
}
|
|
15
|
+
onUpdate?.({
|
|
16
|
+
type: 'node_start',
|
|
17
|
+
nodeId: node.id
|
|
18
|
+
});
|
|
19
|
+
try {
|
|
20
|
+
const inputs = getNodeInputs(node.id, edges, results, nodes);
|
|
21
|
+
const result = await this.executeNode(node, inputs, context);
|
|
22
|
+
results.set(node.id, result);
|
|
23
|
+
onUpdate?.({
|
|
24
|
+
type: 'node_complete',
|
|
25
|
+
nodeId: node.id,
|
|
26
|
+
output: result
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
31
|
+
onUpdate?.({
|
|
32
|
+
type: 'node_error',
|
|
33
|
+
nodeId: node.id,
|
|
34
|
+
error: errorMessage
|
|
35
|
+
});
|
|
36
|
+
throw new Error(`Node ${node.id} failed: ${errorMessage}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
onUpdate?.({ type: 'complete' });
|
|
40
|
+
return {
|
|
41
|
+
success: true,
|
|
42
|
+
results: Object.fromEntries(results)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
47
|
+
onUpdate?.({
|
|
48
|
+
type: 'error',
|
|
49
|
+
error: errorMessage
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
results: {},
|
|
54
|
+
error: errorMessage
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async executeNode(node, inputs, context) {
|
|
59
|
+
switch (node.type) {
|
|
60
|
+
case 'start':
|
|
61
|
+
return inputs.input1 || context.variables?.initialInput || '';
|
|
62
|
+
case 'end':
|
|
63
|
+
return inputs.input1 || '';
|
|
64
|
+
case 'prompt':
|
|
65
|
+
return this.executePromptNode(node, inputs);
|
|
66
|
+
case 'javascript':
|
|
67
|
+
return this.executeJavaScriptNode(node, inputs);
|
|
68
|
+
case 'conditional':
|
|
69
|
+
return this.executeConditionalNode(node, inputs);
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Node type ${node.type} not implemented in base ExecutionEngine. Products must extend this class.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
executePromptNode(node, inputs) {
|
|
75
|
+
const data = node.data;
|
|
76
|
+
let template = data.prompt || '';
|
|
77
|
+
Object.entries(inputs).forEach(([key, value]) => {
|
|
78
|
+
const varName = `$${key}`;
|
|
79
|
+
template = template.replace(new RegExp(`\\${varName}`, 'g'), String(value));
|
|
80
|
+
});
|
|
81
|
+
return template;
|
|
82
|
+
}
|
|
83
|
+
executeJavaScriptNode(node, inputs) {
|
|
84
|
+
const data = node.data;
|
|
85
|
+
const code = data.code || 'return ""';
|
|
86
|
+
try {
|
|
87
|
+
const fn = new Function(...Object.keys(inputs), code);
|
|
88
|
+
return fn(...Object.values(inputs));
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new Error(`JavaScript execution failed: ${error}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
executeConditionalNode(node, inputs) {
|
|
95
|
+
const data = node.data;
|
|
96
|
+
const condition = data.condition || 'true';
|
|
97
|
+
try {
|
|
98
|
+
const fn = new Function(...Object.keys(inputs), `return ${condition}`);
|
|
99
|
+
return Boolean(fn(...Object.values(inputs)));
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw new Error(`Condition evaluation failed: ${error}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
abort() {
|
|
106
|
+
this.abortController?.abort();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=execution-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-engine.js","sourceRoot":"","sources":["../../src/lib/execution-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-utils.d.ts","sourceRoot":"","sources":["../../src/lib/node-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,EAC9D,QAAQ,EAAE,OAAO,GAChB,MAAM,CAaR"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function getStatusColor(status, selected) {
|
|
2
|
+
switch (status) {
|
|
3
|
+
case "running":
|
|
4
|
+
return "border-yellow-500/70 shadow-lg shadow-yellow-500/30 ring-1 ring-yellow-500/50";
|
|
5
|
+
case "completed":
|
|
6
|
+
return "border-green-500/70 shadow-lg shadow-green-500/30 ring-1 ring-green-500/50";
|
|
7
|
+
case "error":
|
|
8
|
+
return "border-red-500/70 shadow-lg shadow-red-500/30 ring-1 ring-red-500/50";
|
|
9
|
+
default:
|
|
10
|
+
return selected
|
|
11
|
+
? "border-primary/80 shadow-xl shadow-primary/20 ring-2 ring-primary/50"
|
|
12
|
+
: "border-border/60 shadow-md";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=node-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-utils.js","sourceRoot":"","sources":["../../src/lib/node-utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAC5B,MAA8D,EAC9D,QAAiB;IAEjB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,+EAA+E,CAAA;QACxF,KAAK,WAAW;YACd,OAAO,4EAA4E,CAAA;QACrF,KAAK,OAAO;YACV,OAAO,sEAAsE,CAAA;QAC/E;YACE,OAAO,QAAQ;gBACb,CAAC,CAAC,sEAAsE;gBACxE,CAAC,CAAC,4BAA4B,CAAA;IACpC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Node, Edge } from '@xyflow/react';
|
|
2
|
+
import type { TopologicalSortResult } from '../types/execution';
|
|
3
|
+
export declare function topologicalSort(nodes: Node[], edges: Edge[]): TopologicalSortResult;
|
|
4
|
+
export declare function getNodeInputs(nodeId: string, edges: Edge[], results: Map<string, any>, nodes?: Node[]): Record<string, any>;
|
|
5
|
+
//# sourceMappingURL=topological-sort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topological-sort.d.ts","sourceRoot":"","sources":["../../src/lib/topological-sort.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAM/D,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,qBAAqB,CAgEnF;AAMD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,KAAK,CAAC,EAAE,IAAI,EAAE,GACb,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAoBrB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function topologicalSort(nodes, edges) {
|
|
2
|
+
const visited = new Set();
|
|
3
|
+
const recursionStack = new Set();
|
|
4
|
+
const sorted = [];
|
|
5
|
+
let hasCycle = false;
|
|
6
|
+
const cycleNodes = [];
|
|
7
|
+
const adjacencyList = new Map();
|
|
8
|
+
nodes.forEach(node => adjacencyList.set(node.id, []));
|
|
9
|
+
edges.forEach(edge => {
|
|
10
|
+
const targets = adjacencyList.get(edge.source) || [];
|
|
11
|
+
targets.push(edge.target);
|
|
12
|
+
adjacencyList.set(edge.source, targets);
|
|
13
|
+
});
|
|
14
|
+
function dfs(nodeId) {
|
|
15
|
+
if (recursionStack.has(nodeId)) {
|
|
16
|
+
hasCycle = true;
|
|
17
|
+
cycleNodes.push(nodeId);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (visited.has(nodeId)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
visited.add(nodeId);
|
|
24
|
+
recursionStack.add(nodeId);
|
|
25
|
+
const neighbors = adjacencyList.get(nodeId) || [];
|
|
26
|
+
neighbors.forEach(neighborId => dfs(neighborId));
|
|
27
|
+
recursionStack.delete(nodeId);
|
|
28
|
+
const node = nodes.find(n => n.id === nodeId);
|
|
29
|
+
if (node) {
|
|
30
|
+
sorted.unshift(node);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const nodesWithIncoming = new Set(edges.map(e => e.target));
|
|
34
|
+
const entryNodes = nodes.filter(n => !nodesWithIncoming.has(n.id));
|
|
35
|
+
if (entryNodes.length === 0 && nodes.length > 0) {
|
|
36
|
+
dfs(nodes[0].id);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
entryNodes.forEach(node => dfs(node.id));
|
|
40
|
+
}
|
|
41
|
+
nodes.forEach(node => {
|
|
42
|
+
if (!visited.has(node.id)) {
|
|
43
|
+
dfs(node.id);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
sorted,
|
|
48
|
+
hasCycle,
|
|
49
|
+
cycleNodes: hasCycle ? Array.from(new Set(cycleNodes)) : undefined
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function getNodeInputs(nodeId, edges, results, nodes) {
|
|
53
|
+
const incomingEdges = edges.filter(e => e.target === nodeId);
|
|
54
|
+
if (nodes) {
|
|
55
|
+
const nodePositions = new Map(nodes.map(n => [n.id, n.position.x]));
|
|
56
|
+
incomingEdges.sort((a, b) => {
|
|
57
|
+
const posA = nodePositions.get(a.source) || 0;
|
|
58
|
+
const posB = nodePositions.get(b.source) || 0;
|
|
59
|
+
return posA - posB;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const inputs = {};
|
|
63
|
+
incomingEdges.forEach((edge, index) => {
|
|
64
|
+
const key = `input${index + 1}`;
|
|
65
|
+
inputs[key] = results.get(edge.source);
|
|
66
|
+
});
|
|
67
|
+
return inputs;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=topological-sort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topological-sort.js","sourceRoot":"","sources":["../../src/lib/topological-sort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Node, Edge } from "@xyflow/react";
|
|
2
|
+
export type ValidationIssue = {
|
|
3
|
+
id: string;
|
|
4
|
+
type: "error" | "warning" | "info";
|
|
5
|
+
title: string;
|
|
6
|
+
description: string;
|
|
7
|
+
nodeIds: string[];
|
|
8
|
+
fixable: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function isUrlSafe(url: string): boolean;
|
|
11
|
+
export declare function detectCycles(nodes: Node[], edges: Edge[]): string[][];
|
|
12
|
+
export declare function validateWorkflow(nodes: Node[], edges: Edge[]): ValidationIssue[];
|
|
13
|
+
export declare function validateApiKeys(apiKeys: Record<string, string>, nodes: Node[]): ValidationIssue[];
|
|
14
|
+
export declare function calculateValidationScore(issues: ValidationIssue[]): number;
|
|
15
|
+
export declare function getValidationGrade(score: number): string;
|
|
16
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAE/C,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAaD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAsB9C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,EAAE,CA+CrE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,eAAe,EAAE,CA6LhF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,eAAe,EAAE,CA6BjG;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAa1E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMxD"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
const BLOCKED_HOSTS = [
|
|
2
|
+
"localhost",
|
|
3
|
+
"127.0.0.1",
|
|
4
|
+
"0.0.0.0",
|
|
5
|
+
"169.254.169.254",
|
|
6
|
+
"metadata.google.internal",
|
|
7
|
+
"10.",
|
|
8
|
+
"172.16.",
|
|
9
|
+
"192.168.",
|
|
10
|
+
];
|
|
11
|
+
export function isUrlSafe(url) {
|
|
12
|
+
try {
|
|
13
|
+
const parsed = new URL(url);
|
|
14
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
15
|
+
for (const blocked of BLOCKED_HOSTS) {
|
|
16
|
+
if (hostname === blocked || hostname.startsWith(blocked)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function detectCycles(nodes, edges) {
|
|
30
|
+
const graph = new Map();
|
|
31
|
+
nodes.forEach((node) => graph.set(node.id, []));
|
|
32
|
+
edges.forEach((edge) => {
|
|
33
|
+
const neighbors = graph.get(edge.source) || [];
|
|
34
|
+
neighbors.push(edge.target);
|
|
35
|
+
graph.set(edge.source, neighbors);
|
|
36
|
+
});
|
|
37
|
+
const cycles = [];
|
|
38
|
+
const visited = new Set();
|
|
39
|
+
const recStack = new Set();
|
|
40
|
+
const currentPath = [];
|
|
41
|
+
function dfs(nodeId) {
|
|
42
|
+
visited.add(nodeId);
|
|
43
|
+
recStack.add(nodeId);
|
|
44
|
+
currentPath.push(nodeId);
|
|
45
|
+
const neighbors = graph.get(nodeId) || [];
|
|
46
|
+
for (const neighbor of neighbors) {
|
|
47
|
+
if (!visited.has(neighbor)) {
|
|
48
|
+
if (dfs(neighbor))
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
else if (recStack.has(neighbor)) {
|
|
52
|
+
const cycleStart = currentPath.indexOf(neighbor);
|
|
53
|
+
const cycle = currentPath.slice(cycleStart);
|
|
54
|
+
cycles.push([...cycle, neighbor]);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
recStack.delete(nodeId);
|
|
59
|
+
currentPath.pop();
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
for (const node of nodes) {
|
|
63
|
+
if (!visited.has(node.id)) {
|
|
64
|
+
dfs(node.id);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return cycles;
|
|
68
|
+
}
|
|
69
|
+
export function validateWorkflow(nodes, edges) {
|
|
70
|
+
const issues = [];
|
|
71
|
+
const cycles = detectCycles(nodes, edges);
|
|
72
|
+
if (cycles.length > 0) {
|
|
73
|
+
cycles.forEach((cycle, index) => {
|
|
74
|
+
issues.push({
|
|
75
|
+
id: `cycle-${index}`,
|
|
76
|
+
type: "error",
|
|
77
|
+
title: "Cycle Detected",
|
|
78
|
+
description: `Infinite loop detected. Execution will never complete.`,
|
|
79
|
+
nodeIds: cycle,
|
|
80
|
+
fixable: false,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const connectedNodes = new Set();
|
|
85
|
+
edges.forEach((edge) => {
|
|
86
|
+
connectedNodes.add(edge.source);
|
|
87
|
+
connectedNodes.add(edge.target);
|
|
88
|
+
});
|
|
89
|
+
const orphanNodes = nodes.filter((node) => !connectedNodes.has(node.id) && node.type !== "start" && nodes.length > 1);
|
|
90
|
+
if (orphanNodes.length > 0) {
|
|
91
|
+
issues.push({
|
|
92
|
+
id: "orphan-nodes",
|
|
93
|
+
type: "warning",
|
|
94
|
+
title: `${orphanNodes.length} Orphan Node${orphanNodes.length > 1 ? "s" : ""}`,
|
|
95
|
+
description: "These nodes are not connected to the workflow and will not execute.",
|
|
96
|
+
nodeIds: orphanNodes.map((n) => n.id),
|
|
97
|
+
fixable: true,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const hasStartNode = nodes.some((node) => node.type === "start");
|
|
101
|
+
if (!hasStartNode && nodes.length > 0) {
|
|
102
|
+
issues.push({
|
|
103
|
+
id: "no-start-node",
|
|
104
|
+
type: "warning",
|
|
105
|
+
title: "No Start Node",
|
|
106
|
+
description: "Add a Start node to define the workflow entry point.",
|
|
107
|
+
nodeIds: [],
|
|
108
|
+
fixable: false,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const endNodes = nodes.filter((node) => node.type === "end");
|
|
112
|
+
endNodes.forEach((endNode) => {
|
|
113
|
+
const hasPath = edges.some((edge) => edge.target === endNode.id);
|
|
114
|
+
if (!hasPath && nodes.length > 1) {
|
|
115
|
+
issues.push({
|
|
116
|
+
id: `unreachable-end-${endNode.id}`,
|
|
117
|
+
type: "warning",
|
|
118
|
+
title: "Unreachable End Node",
|
|
119
|
+
description: "This end node cannot be reached from any other node.",
|
|
120
|
+
nodeIds: [endNode.id],
|
|
121
|
+
fixable: false,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
nodes.forEach((node) => {
|
|
126
|
+
const data = node.data;
|
|
127
|
+
switch (node.type) {
|
|
128
|
+
case "textModel":
|
|
129
|
+
if (!data.model) {
|
|
130
|
+
issues.push({
|
|
131
|
+
id: `missing-model-${node.id}`,
|
|
132
|
+
type: "error",
|
|
133
|
+
title: "Missing Model Configuration",
|
|
134
|
+
description: "Text Model node requires a model to be selected.",
|
|
135
|
+
nodeIds: [node.id],
|
|
136
|
+
fixable: false,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
case "httpRequest":
|
|
141
|
+
if (!data.url) {
|
|
142
|
+
issues.push({
|
|
143
|
+
id: `missing-url-${node.id}`,
|
|
144
|
+
type: "error",
|
|
145
|
+
title: "Missing URL",
|
|
146
|
+
description: "HTTP Request node requires a URL.",
|
|
147
|
+
nodeIds: [node.id],
|
|
148
|
+
fixable: false,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else if (!isUrlSafe(data.url)) {
|
|
152
|
+
issues.push({
|
|
153
|
+
id: `unsafe-url-${node.id}`,
|
|
154
|
+
type: "error",
|
|
155
|
+
title: "Unsafe URL Detected",
|
|
156
|
+
description: "URL points to private network or uses an unsupported protocol. Only public HTTP/HTTPS endpoints are allowed.",
|
|
157
|
+
nodeIds: [node.id],
|
|
158
|
+
fixable: false,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
case "prompt":
|
|
163
|
+
if (!data.content) {
|
|
164
|
+
issues.push({
|
|
165
|
+
id: `missing-prompt-${node.id}`,
|
|
166
|
+
type: "warning",
|
|
167
|
+
title: "Empty Prompt",
|
|
168
|
+
description: "Prompt node has no content.",
|
|
169
|
+
nodeIds: [node.id],
|
|
170
|
+
fixable: false,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
case "conditional":
|
|
175
|
+
if (!data.condition) {
|
|
176
|
+
issues.push({
|
|
177
|
+
id: `missing-condition-${node.id}`,
|
|
178
|
+
type: "error",
|
|
179
|
+
title: "Missing Condition",
|
|
180
|
+
description: "Conditional node requires a condition expression.",
|
|
181
|
+
nodeIds: [node.id],
|
|
182
|
+
fixable: false,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const targetNodes = new Set(edges.map((e) => e.target));
|
|
189
|
+
const unusedOutputs = nodes.filter((node) => !targetNodes.has(node.id) && node.type !== "end" && nodes.length > 1);
|
|
190
|
+
if (unusedOutputs.length > 0) {
|
|
191
|
+
issues.push({
|
|
192
|
+
id: "unused-outputs",
|
|
193
|
+
type: "info",
|
|
194
|
+
title: `${unusedOutputs.length} Node${unusedOutputs.length > 1 ? "s" : ""} with Unused Outputs`,
|
|
195
|
+
description: "These nodes have outputs that are not connected to any other nodes.",
|
|
196
|
+
nodeIds: unusedOutputs.map((n) => n.id),
|
|
197
|
+
fixable: false,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
const chainLengths = new Map();
|
|
201
|
+
function calculateChainLength(nodeId) {
|
|
202
|
+
if (chainLengths.has(nodeId)) {
|
|
203
|
+
return chainLengths.get(nodeId);
|
|
204
|
+
}
|
|
205
|
+
const incomingEdges = edges.filter((e) => e.target === nodeId);
|
|
206
|
+
if (incomingEdges.length === 0) {
|
|
207
|
+
chainLengths.set(nodeId, 1);
|
|
208
|
+
return 1;
|
|
209
|
+
}
|
|
210
|
+
const maxParentChain = Math.max(...incomingEdges.map((e) => calculateChainLength(e.source)));
|
|
211
|
+
const length = maxParentChain + 1;
|
|
212
|
+
chainLengths.set(nodeId, length);
|
|
213
|
+
return length;
|
|
214
|
+
}
|
|
215
|
+
nodes.forEach((node) => calculateChainLength(node.id));
|
|
216
|
+
const longChains = nodes.filter((node) => {
|
|
217
|
+
const length = chainLengths.get(node.id) || 0;
|
|
218
|
+
return length > 10;
|
|
219
|
+
});
|
|
220
|
+
if (longChains.length > 0) {
|
|
221
|
+
issues.push({
|
|
222
|
+
id: "long-chains",
|
|
223
|
+
type: "info",
|
|
224
|
+
title: "Long Execution Chains Detected",
|
|
225
|
+
description: "Consider adding checkpoints or breaking long chains into smaller workflows for better debugging.",
|
|
226
|
+
nodeIds: longChains.map((n) => n.id),
|
|
227
|
+
fixable: false,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return issues;
|
|
231
|
+
}
|
|
232
|
+
export function validateApiKeys(apiKeys, nodes) {
|
|
233
|
+
const issues = [];
|
|
234
|
+
const requiredProviders = new Set();
|
|
235
|
+
nodes.forEach((node) => {
|
|
236
|
+
const data = node.data;
|
|
237
|
+
if (node.type === "textModel" && data.model) {
|
|
238
|
+
const provider = data.model.split("/")[0];
|
|
239
|
+
requiredProviders.add(provider);
|
|
240
|
+
}
|
|
241
|
+
if (node.type === "imageGeneration") {
|
|
242
|
+
requiredProviders.add("google");
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
requiredProviders.forEach((provider) => {
|
|
246
|
+
if (!apiKeys[provider] || apiKeys[provider].trim() === "") {
|
|
247
|
+
issues.push({
|
|
248
|
+
id: `missing-api-key-${provider}`,
|
|
249
|
+
type: "error",
|
|
250
|
+
title: `Missing ${provider.charAt(0).toUpperCase() + provider.slice(1)} API Key`,
|
|
251
|
+
description: `Your workflow uses ${provider} models but no API key is configured. Click API Keys to add it.`,
|
|
252
|
+
nodeIds: [],
|
|
253
|
+
fixable: true,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
return issues;
|
|
258
|
+
}
|
|
259
|
+
export function calculateValidationScore(issues) {
|
|
260
|
+
const errorCount = issues.filter((i) => i.type === "error").length;
|
|
261
|
+
const warningCount = issues.filter((i) => i.type === "warning").length;
|
|
262
|
+
if (errorCount > 0) {
|
|
263
|
+
return Math.max(0, 40 - errorCount * 10);
|
|
264
|
+
}
|
|
265
|
+
if (warningCount > 0) {
|
|
266
|
+
return Math.max(60, 90 - warningCount * 10);
|
|
267
|
+
}
|
|
268
|
+
return 100;
|
|
269
|
+
}
|
|
270
|
+
export function getValidationGrade(score) {
|
|
271
|
+
if (score >= 90)
|
|
272
|
+
return "A";
|
|
273
|
+
if (score >= 80)
|
|
274
|
+
return "B";
|
|
275
|
+
if (score >= 70)
|
|
276
|
+
return "C";
|
|
277
|
+
if (score >= 60)
|
|
278
|
+
return "D";
|
|
279
|
+
return "F";
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Node } from '@xyflow/react';
|
|
2
|
+
export interface TopologicalSortResult {
|
|
3
|
+
sorted: Node[];
|
|
4
|
+
hasCycle: boolean;
|
|
5
|
+
cycleNodes?: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface NodeExecutionResult {
|
|
8
|
+
success: boolean;
|
|
9
|
+
output: any;
|
|
10
|
+
error?: string;
|
|
11
|
+
executionTime?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ExecutionConfig {
|
|
14
|
+
timeout?: number;
|
|
15
|
+
maxRetries?: number;
|
|
16
|
+
abortSignal?: AbortSignal;
|
|
17
|
+
}
|
|
18
|
+
export interface ExecutionMetrics {
|
|
19
|
+
totalNodes: number;
|
|
20
|
+
executedNodes: number;
|
|
21
|
+
failedNodes: number;
|
|
22
|
+
totalExecutionTime: number;
|
|
23
|
+
nodeExecutionTimes: Record<string, number>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/types/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAQ,MAAM,eAAe,CAAA;AAE1C,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,IAAI,EAAE,CAAA;IACd,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/types/execution.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ValidationIssueType = 'error' | 'warning' | 'info';
|
|
2
|
+
export interface ValidationIssue {
|
|
3
|
+
type: ValidationIssueType;
|
|
4
|
+
nodeId?: string;
|
|
5
|
+
message: string;
|
|
6
|
+
field?: string;
|
|
7
|
+
suggestion?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ValidationResult {
|
|
10
|
+
valid: boolean;
|
|
11
|
+
issues: ValidationIssue[];
|
|
12
|
+
score: number;
|
|
13
|
+
grade: 'A' | 'B' | 'C' | 'D' | 'F';
|
|
14
|
+
canExecute: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ValidationConfig {
|
|
17
|
+
checkCycles?: boolean;
|
|
18
|
+
checkSsrf?: boolean;
|
|
19
|
+
checkApiKeys?: boolean;
|
|
20
|
+
checkConfiguration?: boolean;
|
|
21
|
+
strictMode?: boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/types/validation.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE9D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IAClC,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/types/validation.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Node, Edge } from '@xyflow/react';
|
|
2
|
+
export type WorkflowStatus = 'idle' | 'running' | 'completed' | 'error';
|
|
3
|
+
export type NodeStatus = 'idle' | 'running' | 'completed' | 'error';
|
|
4
|
+
export interface WorkflowMetadata {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
updatedAt: string;
|
|
10
|
+
version?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SavedWorkflow extends WorkflowMetadata {
|
|
13
|
+
nodes: Node[];
|
|
14
|
+
edges: Edge[];
|
|
15
|
+
}
|
|
16
|
+
export interface ExecutionContext {
|
|
17
|
+
apiKeys: Record<string, string>;
|
|
18
|
+
variables?: Record<string, any>;
|
|
19
|
+
}
|
|
20
|
+
export interface ExecutionUpdate {
|
|
21
|
+
type: 'node_start' | 'node_complete' | 'node_error' | 'complete' | 'error';
|
|
22
|
+
nodeId?: string;
|
|
23
|
+
output?: any;
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ExecutionResult {
|
|
27
|
+
success: boolean;
|
|
28
|
+
results: Record<string, any>;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/types/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAE1C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;AAEvE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,KAAK,EAAE,IAAI,EAAE,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,GAAG,eAAe,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAA;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/types/workflow.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@charliesu/workflow-core",
|
|
3
|
+
"version": "0.0.1-alpha",
|
|
4
|
+
"description": "Shared workflow engine for TopFlow and TaraFlow - React Flow based workflow orchestration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"build:watch": "tsc --watch",
|
|
15
|
+
"test": "echo \"Tests coming soon\"",
|
|
16
|
+
"lint": "echo \"Linting coming soon\"",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"prepublishOnly": "pnpm build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"workflow",
|
|
22
|
+
"react-flow",
|
|
23
|
+
"ai",
|
|
24
|
+
"automation",
|
|
25
|
+
"topflow",
|
|
26
|
+
"orchestration",
|
|
27
|
+
"visual-programming",
|
|
28
|
+
"workflow-engine",
|
|
29
|
+
"taraflow"
|
|
30
|
+
],
|
|
31
|
+
"author": "Charlie Su <cssu@upenn.edu>",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/csupenn/workflow-core.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/csupenn/workflow-core/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/csupenn/workflow-core#readme",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@xyflow/react": "^12.8.6"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/react": "^19.0.0",
|
|
46
|
+
"@types/react-dom": "^19.0.0",
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"typescript": "^5.7.0"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"react": ">=19.0.0",
|
|
52
|
+
"react-dom": ">=19.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|