@marktoflow/gui 2.0.0-alpha.1
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/.turbo/turbo-build.log +26 -0
- package/.turbo/turbo-test.log +22 -0
- package/README.md +179 -0
- package/dist/client/assets/index-DwTI8opO.js +608 -0
- package/dist/client/assets/index-DwTI8opO.js.map +1 -0
- package/dist/client/assets/index-RoEdL6gO.css +1 -0
- package/dist/client/index.html +20 -0
- package/dist/client/vite.svg +9 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +56 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/ai.js +50 -0
- package/dist/server/routes/ai.js.map +1 -0
- package/dist/server/routes/execute.js +62 -0
- package/dist/server/routes/execute.js.map +1 -0
- package/dist/server/routes/workflows.js +99 -0
- package/dist/server/routes/workflows.js.map +1 -0
- package/dist/server/server/index.js +95 -0
- package/dist/server/server/index.js.map +1 -0
- package/dist/server/server/routes/ai.js +87 -0
- package/dist/server/server/routes/ai.js.map +1 -0
- package/dist/server/server/routes/execute.js +63 -0
- package/dist/server/server/routes/execute.js.map +1 -0
- package/dist/server/server/routes/tools.js +518 -0
- package/dist/server/server/routes/tools.js.map +1 -0
- package/dist/server/server/routes/workflows.js +99 -0
- package/dist/server/server/routes/workflows.js.map +1 -0
- package/dist/server/server/services/AIService.js +69 -0
- package/dist/server/server/services/AIService.js.map +1 -0
- package/dist/server/server/services/FileWatcher.js +60 -0
- package/dist/server/server/services/FileWatcher.js.map +1 -0
- package/dist/server/server/services/WorkflowService.js +363 -0
- package/dist/server/server/services/WorkflowService.js.map +1 -0
- package/dist/server/server/services/agents/claude-code-provider.js +250 -0
- package/dist/server/server/services/agents/claude-code-provider.js.map +1 -0
- package/dist/server/server/services/agents/claude-provider.js +204 -0
- package/dist/server/server/services/agents/claude-provider.js.map +1 -0
- package/dist/server/server/services/agents/copilot-provider.js +227 -0
- package/dist/server/server/services/agents/copilot-provider.js.map +1 -0
- package/dist/server/server/services/agents/demo-provider.js +167 -0
- package/dist/server/server/services/agents/demo-provider.js.map +1 -0
- package/dist/server/server/services/agents/index.js +31 -0
- package/dist/server/server/services/agents/index.js.map +1 -0
- package/dist/server/server/services/agents/ollama-provider.js +220 -0
- package/dist/server/server/services/agents/ollama-provider.js.map +1 -0
- package/dist/server/server/services/agents/prompts.js +436 -0
- package/dist/server/server/services/agents/prompts.js.map +1 -0
- package/dist/server/server/services/agents/registry.js +242 -0
- package/dist/server/server/services/agents/registry.js.map +1 -0
- package/dist/server/server/services/agents/types.js +6 -0
- package/dist/server/server/services/agents/types.js.map +1 -0
- package/dist/server/server/websocket/index.js +85 -0
- package/dist/server/server/websocket/index.js.map +1 -0
- package/dist/server/services/AIService.d.ts +30 -0
- package/dist/server/services/AIService.d.ts.map +1 -0
- package/dist/server/services/AIService.js +216 -0
- package/dist/server/services/AIService.js.map +1 -0
- package/dist/server/services/FileWatcher.d.ts +10 -0
- package/dist/server/services/FileWatcher.d.ts.map +1 -0
- package/dist/server/services/FileWatcher.js +62 -0
- package/dist/server/services/FileWatcher.js.map +1 -0
- package/dist/server/services/WorkflowService.d.ts +54 -0
- package/dist/server/services/WorkflowService.d.ts.map +1 -0
- package/dist/server/services/WorkflowService.js +323 -0
- package/dist/server/services/WorkflowService.js.map +1 -0
- package/dist/server/shared/constants.js +175 -0
- package/dist/server/shared/constants.js.map +1 -0
- package/dist/server/shared/types.js +3 -0
- package/dist/server/shared/types.js.map +1 -0
- package/dist/server/websocket/index.d.ts +10 -0
- package/dist/server/websocket/index.d.ts.map +1 -0
- package/dist/server/websocket/index.js +85 -0
- package/dist/server/websocket/index.js.map +1 -0
- package/index.html +19 -0
- package/package.json +96 -0
- package/playwright.config.ts +27 -0
- package/postcss.config.js +6 -0
- package/public/vite.svg +9 -0
- package/src/client/App.tsx +520 -0
- package/src/client/components/Canvas/Canvas.tsx +405 -0
- package/src/client/components/Canvas/ExecutionOverlay.tsx +847 -0
- package/src/client/components/Canvas/NodeContextMenu.tsx +188 -0
- package/src/client/components/Canvas/OutputNode.tsx +111 -0
- package/src/client/components/Canvas/StepNode.tsx +106 -0
- package/src/client/components/Canvas/SubWorkflowNode.tsx +141 -0
- package/src/client/components/Canvas/Toolbar.tsx +189 -0
- package/src/client/components/Canvas/TriggerNode.tsx +128 -0
- package/src/client/components/Editor/InputsEditor.tsx +458 -0
- package/src/client/components/Editor/NewStepWizard.tsx +344 -0
- package/src/client/components/Editor/StepEditor.tsx +532 -0
- package/src/client/components/Editor/YamlEditor.tsx +160 -0
- package/src/client/components/Panels/PropertiesPanel.tsx +589 -0
- package/src/client/components/Prompt/ChangePreview.tsx +281 -0
- package/src/client/components/Prompt/PromptHistoryPanel.tsx +209 -0
- package/src/client/components/Prompt/PromptInput.tsx +108 -0
- package/src/client/components/Sidebar/Sidebar.tsx +343 -0
- package/src/client/components/common/Breadcrumb.tsx +40 -0
- package/src/client/components/common/Button.tsx +68 -0
- package/src/client/components/common/ContextMenu.tsx +202 -0
- package/src/client/components/common/KeyboardShortcuts.tsx +143 -0
- package/src/client/components/common/Modal.tsx +93 -0
- package/src/client/components/common/Tabs.tsx +57 -0
- package/src/client/components/common/ThemeToggle.tsx +63 -0
- package/src/client/components/index.ts +32 -0
- package/src/client/hooks/index.ts +4 -0
- package/src/client/hooks/useAIPrompt.ts +108 -0
- package/src/client/hooks/useCanvas.ts +247 -0
- package/src/client/hooks/useWebSocket.ts +164 -0
- package/src/client/hooks/useWorkflow.ts +138 -0
- package/src/client/main.tsx +10 -0
- package/src/client/stores/canvasStore.ts +348 -0
- package/src/client/stores/editorStore.ts +133 -0
- package/src/client/stores/executionStore.ts +440 -0
- package/src/client/stores/index.ts +4 -0
- package/src/client/stores/layoutStore.ts +103 -0
- package/src/client/stores/navigationStore.ts +49 -0
- package/src/client/stores/promptStore.ts +113 -0
- package/src/client/stores/themeStore.ts +75 -0
- package/src/client/stores/workflowStore.ts +177 -0
- package/src/client/styles/globals.css +346 -0
- package/src/client/utils/cn.ts +9 -0
- package/src/client/utils/index.ts +4 -0
- package/src/client/utils/serviceIcons.tsx +64 -0
- package/src/client/utils/stepValidation.ts +155 -0
- package/src/client/utils/workflowToGraph.ts +299 -0
- package/src/server/index.ts +114 -0
- package/src/server/routes/ai.ts +91 -0
- package/src/server/routes/execute.ts +71 -0
- package/src/server/routes/tools.ts +564 -0
- package/src/server/routes/workflows.ts +106 -0
- package/src/server/services/AIService.ts +105 -0
- package/src/server/services/FileWatcher.ts +69 -0
- package/src/server/services/WorkflowService.ts +441 -0
- package/src/server/services/agents/claude-code-provider.ts +320 -0
- package/src/server/services/agents/claude-provider.ts +248 -0
- package/src/server/services/agents/copilot-provider.ts +311 -0
- package/src/server/services/agents/demo-provider.ts +184 -0
- package/src/server/services/agents/index.ts +31 -0
- package/src/server/services/agents/ollama-provider.ts +267 -0
- package/src/server/services/agents/prompts.ts +482 -0
- package/src/server/services/agents/registry.ts +289 -0
- package/src/server/services/agents/types.ts +146 -0
- package/src/server/websocket/index.ts +104 -0
- package/src/shared/constants.ts +180 -0
- package/src/shared/types.ts +179 -0
- package/tailwind.config.ts +73 -0
- package/tests/e2e/app.spec.ts +90 -0
- package/tests/e2e/canvas.spec.ts +128 -0
- package/tests/e2e/workflow.spec.ts +185 -0
- package/tests/integration/api.test.ts +250 -0
- package/tests/integration/testApp.ts +31 -0
- package/tests/setup.ts +37 -0
- package/tests/unit/canvasStore.test.ts +502 -0
- package/tests/unit/components.test.tsx +151 -0
- package/tests/unit/executionStore.test.ts +527 -0
- package/tests/unit/layoutStore.test.ts +194 -0
- package/tests/unit/navigationStore.test.ts +152 -0
- package/tests/unit/stepValidation.test.ts +226 -0
- package/tests/unit/themeStore.test.ts +141 -0
- package/tests/unit/workflowToGraph.test.ts +289 -0
- package/tsconfig.json +29 -0
- package/tsconfig.server.json +28 -0
- package/vite.config.ts +31 -0
- package/vitest.config.ts +26 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Engineering Module for Workflow Modifications
|
|
3
|
+
*
|
|
4
|
+
* This module provides context-aware prompts for different workflow operations:
|
|
5
|
+
* - Adding/removing steps
|
|
6
|
+
* - Modifying step inputs
|
|
7
|
+
* - Adding error handling
|
|
8
|
+
* - Creating sub-workflows
|
|
9
|
+
* - Adding conditions
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Available service integrations with their SDK mappings
|
|
13
|
+
export const AVAILABLE_SERVICES = {
|
|
14
|
+
slack: {
|
|
15
|
+
sdk: '@slack/web-api',
|
|
16
|
+
description: 'Slack messaging and workspace management',
|
|
17
|
+
commonActions: [
|
|
18
|
+
'chat.postMessage',
|
|
19
|
+
'chat.update',
|
|
20
|
+
'chat.delete',
|
|
21
|
+
'conversations.list',
|
|
22
|
+
'conversations.history',
|
|
23
|
+
'users.list',
|
|
24
|
+
'files.upload',
|
|
25
|
+
'reactions.add',
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
github: {
|
|
29
|
+
sdk: '@octokit/rest',
|
|
30
|
+
description: 'GitHub repository, issues, and PR management',
|
|
31
|
+
commonActions: [
|
|
32
|
+
'pulls.get',
|
|
33
|
+
'pulls.create',
|
|
34
|
+
'pulls.list',
|
|
35
|
+
'issues.create',
|
|
36
|
+
'issues.update',
|
|
37
|
+
'issues.list',
|
|
38
|
+
'repos.getContent',
|
|
39
|
+
'repos.createRelease',
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
jira: {
|
|
43
|
+
sdk: 'jira.js',
|
|
44
|
+
description: 'Jira issue and project tracking',
|
|
45
|
+
commonActions: [
|
|
46
|
+
'issues.createIssue',
|
|
47
|
+
'issues.updateIssue',
|
|
48
|
+
'issues.getIssue',
|
|
49
|
+
'issues.searchJql',
|
|
50
|
+
'projects.getProject',
|
|
51
|
+
'transitions.transitionIssue',
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
gmail: {
|
|
55
|
+
sdk: 'googleapis',
|
|
56
|
+
description: 'Gmail email sending and management',
|
|
57
|
+
commonActions: [
|
|
58
|
+
'users.messages.send',
|
|
59
|
+
'users.messages.list',
|
|
60
|
+
'users.messages.get',
|
|
61
|
+
'users.labels.list',
|
|
62
|
+
'users.drafts.create',
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
outlook: {
|
|
66
|
+
sdk: '@microsoft/microsoft-graph-client',
|
|
67
|
+
description: 'Microsoft Outlook email and calendar',
|
|
68
|
+
commonActions: [
|
|
69
|
+
'mail.sendMail',
|
|
70
|
+
'mail.listMessages',
|
|
71
|
+
'calendar.createEvent',
|
|
72
|
+
'calendar.listEvents',
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
linear: {
|
|
76
|
+
sdk: '@linear/sdk',
|
|
77
|
+
description: 'Linear issue tracking and project management',
|
|
78
|
+
commonActions: [
|
|
79
|
+
'issues.create',
|
|
80
|
+
'issues.update',
|
|
81
|
+
'issues.archive',
|
|
82
|
+
'projects.list',
|
|
83
|
+
'cycles.list',
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
notion: {
|
|
87
|
+
sdk: '@notionhq/client',
|
|
88
|
+
description: 'Notion pages and databases',
|
|
89
|
+
commonActions: [
|
|
90
|
+
'pages.create',
|
|
91
|
+
'pages.update',
|
|
92
|
+
'databases.query',
|
|
93
|
+
'blocks.children.append',
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
discord: {
|
|
97
|
+
sdk: 'discord.js',
|
|
98
|
+
description: 'Discord messaging and server management',
|
|
99
|
+
commonActions: [
|
|
100
|
+
'channels.send',
|
|
101
|
+
'channels.createWebhook',
|
|
102
|
+
'guilds.members.fetch',
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
airtable: {
|
|
106
|
+
sdk: 'airtable',
|
|
107
|
+
description: 'Airtable database and records',
|
|
108
|
+
commonActions: [
|
|
109
|
+
'tables.list',
|
|
110
|
+
'records.create',
|
|
111
|
+
'records.update',
|
|
112
|
+
'records.list',
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
confluence: {
|
|
116
|
+
sdk: 'confluence.js',
|
|
117
|
+
description: 'Atlassian Confluence wiki pages',
|
|
118
|
+
commonActions: [
|
|
119
|
+
'content.getContent',
|
|
120
|
+
'content.createContent',
|
|
121
|
+
'content.updateContent',
|
|
122
|
+
'space.getSpaces',
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
http: {
|
|
126
|
+
sdk: 'built-in',
|
|
127
|
+
description: 'Generic HTTP requests to any API',
|
|
128
|
+
commonActions: ['request', 'get', 'post', 'put', 'delete'],
|
|
129
|
+
},
|
|
130
|
+
claude: {
|
|
131
|
+
sdk: '@anthropic-ai/sdk',
|
|
132
|
+
description: 'Claude AI for text generation and analysis',
|
|
133
|
+
commonActions: ['messages.create', 'completions.create'],
|
|
134
|
+
},
|
|
135
|
+
opencode: {
|
|
136
|
+
sdk: '@anthropic-ai/claude-agent-sdk',
|
|
137
|
+
description: 'OpenCode for code generation and analysis',
|
|
138
|
+
commonActions: ['generate', 'analyze', 'refactor'],
|
|
139
|
+
},
|
|
140
|
+
ollama: {
|
|
141
|
+
sdk: 'ollama',
|
|
142
|
+
description: 'Local Ollama LLM for AI tasks',
|
|
143
|
+
commonActions: ['generate', 'chat', 'embeddings'],
|
|
144
|
+
},
|
|
145
|
+
} as const;
|
|
146
|
+
|
|
147
|
+
// Base system prompt with comprehensive context
|
|
148
|
+
export const BASE_SYSTEM_PROMPT = `You are an expert workflow automation assistant for Marktoflow, a markdown-based workflow automation framework.
|
|
149
|
+
|
|
150
|
+
## Your Role
|
|
151
|
+
Help users modify their workflows based on natural language requests. You must:
|
|
152
|
+
1. Understand the current workflow structure
|
|
153
|
+
2. Make precise modifications based on user requests
|
|
154
|
+
3. Explain what changes you made and why
|
|
155
|
+
4. Return valid YAML that can be parsed
|
|
156
|
+
|
|
157
|
+
## Workflow Structure
|
|
158
|
+
|
|
159
|
+
A workflow consists of:
|
|
160
|
+
- **metadata**: name, description, version, author, tags
|
|
161
|
+
- **inputs**: declared input variables with types and defaults
|
|
162
|
+
- **tools**: service SDK configurations with authentication
|
|
163
|
+
- **steps**: array of actions to execute
|
|
164
|
+
|
|
165
|
+
### Step Structure
|
|
166
|
+
\`\`\`yaml
|
|
167
|
+
- id: unique-step-id # Required: kebab-case identifier
|
|
168
|
+
name: "Human Readable Name" # Optional: display name
|
|
169
|
+
action: service.method # Required: SDK method to call
|
|
170
|
+
inputs: # Required: method parameters
|
|
171
|
+
param1: value
|
|
172
|
+
param2: "{{ variable }}" # Template variables
|
|
173
|
+
output_variable: result_name # Optional: store output
|
|
174
|
+
conditions: # Optional: when to run
|
|
175
|
+
- "{{ previous_step.success }}"
|
|
176
|
+
errorHandling: # Optional: error handling
|
|
177
|
+
action: retry # stop | continue | retry
|
|
178
|
+
maxRetries: 3
|
|
179
|
+
\`\`\`
|
|
180
|
+
|
|
181
|
+
### Template Variables
|
|
182
|
+
- Access inputs: \`{{ inputs.variable_name }}\`
|
|
183
|
+
- Access step outputs: \`{{ step_id.field }}\` or \`{{ output_variable.field }}\`
|
|
184
|
+
- JavaScript expressions: \`{{ inputs.count > 10 ? "many" : "few" }}\`
|
|
185
|
+
|
|
186
|
+
### Available Services
|
|
187
|
+
${Object.entries(AVAILABLE_SERVICES)
|
|
188
|
+
.map(([name, info]) => `- **${name}**: ${info.description} (SDK: ${info.sdk})`)
|
|
189
|
+
.join('\n')}
|
|
190
|
+
|
|
191
|
+
## Response Format
|
|
192
|
+
|
|
193
|
+
Always respond with:
|
|
194
|
+
1. A brief explanation (1-3 sentences) of what you changed
|
|
195
|
+
2. The complete modified workflow in a YAML code block
|
|
196
|
+
|
|
197
|
+
\`\`\`yaml
|
|
198
|
+
# Your modified workflow here
|
|
199
|
+
\`\`\`
|
|
200
|
+
|
|
201
|
+
## Important Guidelines
|
|
202
|
+
- Only make the changes requested - don't "improve" other parts
|
|
203
|
+
- Preserve existing step IDs unless explicitly asked to rename
|
|
204
|
+
- Generate unique IDs for new steps (use kebab-case)
|
|
205
|
+
- Ensure all YAML is valid and properly indented
|
|
206
|
+
- Keep the same workflow structure (don't remove required sections)
|
|
207
|
+
`;
|
|
208
|
+
|
|
209
|
+
// Operation-specific prompts for different modification types
|
|
210
|
+
export const OPERATION_PROMPTS = {
|
|
211
|
+
addStep: `
|
|
212
|
+
## Adding Steps
|
|
213
|
+
When adding a new step:
|
|
214
|
+
1. Generate a unique, descriptive kebab-case ID (e.g., "send-slack-notification")
|
|
215
|
+
2. Add a human-readable name
|
|
216
|
+
3. Use the correct action format: service.method
|
|
217
|
+
4. Include all required inputs for the action
|
|
218
|
+
5. Consider adding an output_variable if the result will be used later
|
|
219
|
+
6. Place the step at a logical position in the workflow
|
|
220
|
+
|
|
221
|
+
Common step patterns:
|
|
222
|
+
- Notifications: slack.chat.postMessage, gmail.users.messages.send
|
|
223
|
+
- API calls: http.request, github.pulls.get
|
|
224
|
+
- Data processing: Transform data between steps
|
|
225
|
+
`,
|
|
226
|
+
|
|
227
|
+
removeStep: `
|
|
228
|
+
## Removing Steps
|
|
229
|
+
When removing a step:
|
|
230
|
+
1. Remove the entire step block from the steps array
|
|
231
|
+
2. Check if other steps reference this step's output_variable
|
|
232
|
+
3. If references exist, either:
|
|
233
|
+
- Update those references to use a different source
|
|
234
|
+
- Warn the user about broken references
|
|
235
|
+
4. Preserve the workflow structure and other steps
|
|
236
|
+
`,
|
|
237
|
+
|
|
238
|
+
modifyInputs: `
|
|
239
|
+
## Modifying Step Inputs
|
|
240
|
+
When modifying inputs:
|
|
241
|
+
1. Only change the specified inputs
|
|
242
|
+
2. Preserve other inputs unless asked to remove them
|
|
243
|
+
3. Use template variables for dynamic values: {{ variable }}
|
|
244
|
+
4. Ensure the value type matches what the action expects
|
|
245
|
+
5. Consider adding validation or error handling if needed
|
|
246
|
+
`,
|
|
247
|
+
|
|
248
|
+
addErrorHandling: `
|
|
249
|
+
## Adding Error Handling
|
|
250
|
+
Error handling options:
|
|
251
|
+
- **stop**: Halt workflow execution on error (default)
|
|
252
|
+
- **continue**: Log error and continue to next step
|
|
253
|
+
- **retry**: Retry the step with backoff
|
|
254
|
+
|
|
255
|
+
Example:
|
|
256
|
+
\`\`\`yaml
|
|
257
|
+
errorHandling:
|
|
258
|
+
action: retry
|
|
259
|
+
maxRetries: 3
|
|
260
|
+
retryDelay: 1000 # milliseconds
|
|
261
|
+
fallback:
|
|
262
|
+
action: slack.chat.postMessage
|
|
263
|
+
inputs:
|
|
264
|
+
channel: "#alerts"
|
|
265
|
+
text: "Step {{ step.name }} failed: {{ error.message }}"
|
|
266
|
+
\`\`\`
|
|
267
|
+
`,
|
|
268
|
+
|
|
269
|
+
addConditions: `
|
|
270
|
+
## Adding Conditions
|
|
271
|
+
Conditions control when a step executes. They are JavaScript-like expressions.
|
|
272
|
+
|
|
273
|
+
Examples:
|
|
274
|
+
\`\`\`yaml
|
|
275
|
+
conditions:
|
|
276
|
+
- "{{ previous_step.success === true }}"
|
|
277
|
+
- "{{ inputs.environment === 'production' }}"
|
|
278
|
+
- "{{ pr_details.state === 'open' && pr_details.draft === false }}"
|
|
279
|
+
\`\`\`
|
|
280
|
+
|
|
281
|
+
Common patterns:
|
|
282
|
+
- Check previous step success: \`{{ step_id.success }}\`
|
|
283
|
+
- Check variable values: \`{{ output_var.field === 'value' }}\`
|
|
284
|
+
- Check input values: \`{{ inputs.flag === true }}\`
|
|
285
|
+
- Combine conditions: \`{{ condition1 && condition2 }}\`
|
|
286
|
+
`,
|
|
287
|
+
|
|
288
|
+
createSubWorkflow: `
|
|
289
|
+
## Creating Sub-Workflows
|
|
290
|
+
A sub-workflow is referenced by path instead of an action:
|
|
291
|
+
|
|
292
|
+
\`\`\`yaml
|
|
293
|
+
- id: run-notification-workflow
|
|
294
|
+
name: "Run Notification Workflow"
|
|
295
|
+
workflowPath: "./workflows/notify.md"
|
|
296
|
+
inputs:
|
|
297
|
+
message: "{{ previous_step.summary }}"
|
|
298
|
+
channel: "{{ inputs.notification_channel }}"
|
|
299
|
+
output_variable: notification_result
|
|
300
|
+
\`\`\`
|
|
301
|
+
|
|
302
|
+
When creating sub-workflows:
|
|
303
|
+
1. Use workflowPath instead of action
|
|
304
|
+
2. Pass inputs that the sub-workflow expects
|
|
305
|
+
3. The sub-workflow's outputs are available via output_variable
|
|
306
|
+
`,
|
|
307
|
+
|
|
308
|
+
addTool: `
|
|
309
|
+
## Adding Tool Configurations
|
|
310
|
+
Tools are configured with their SDK and authentication:
|
|
311
|
+
|
|
312
|
+
\`\`\`yaml
|
|
313
|
+
tools:
|
|
314
|
+
slack:
|
|
315
|
+
sdk: '@slack/web-api'
|
|
316
|
+
auth:
|
|
317
|
+
token: '\${SLACK_BOT_TOKEN}'
|
|
318
|
+
github:
|
|
319
|
+
sdk: '@octokit/rest'
|
|
320
|
+
auth:
|
|
321
|
+
token: '\${GITHUB_TOKEN}'
|
|
322
|
+
\`\`\`
|
|
323
|
+
|
|
324
|
+
Authentication patterns:
|
|
325
|
+
- Environment variables: \${ENV_VAR_NAME}
|
|
326
|
+
- OAuth tokens: Stored and retrieved automatically
|
|
327
|
+
- API keys: Configured per-tool
|
|
328
|
+
`,
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Build a context-aware prompt based on the user's request
|
|
333
|
+
*/
|
|
334
|
+
export function buildPrompt(
|
|
335
|
+
userRequest: string,
|
|
336
|
+
workflow: { metadata?: Record<string, unknown>; steps: unknown[]; tools?: Record<string, unknown> },
|
|
337
|
+
context?: {
|
|
338
|
+
selectedStepId?: string;
|
|
339
|
+
recentHistory?: string[];
|
|
340
|
+
}
|
|
341
|
+
): { systemPrompt: string; userPrompt: string } {
|
|
342
|
+
// Detect the type of operation requested
|
|
343
|
+
const operations = detectOperations(userRequest);
|
|
344
|
+
|
|
345
|
+
// Build system prompt with relevant operation guides
|
|
346
|
+
let systemPrompt = BASE_SYSTEM_PROMPT;
|
|
347
|
+
for (const op of operations) {
|
|
348
|
+
if (OPERATION_PROMPTS[op as keyof typeof OPERATION_PROMPTS]) {
|
|
349
|
+
systemPrompt += '\n' + OPERATION_PROMPTS[op as keyof typeof OPERATION_PROMPTS];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Build user prompt with context
|
|
354
|
+
let userPrompt = `Current workflow:\n\`\`\`yaml\n${formatWorkflow(workflow)}\n\`\`\`\n\n`;
|
|
355
|
+
|
|
356
|
+
if (context?.selectedStepId) {
|
|
357
|
+
const selectedStep = workflow.steps?.find(
|
|
358
|
+
(s: any) => s.id === context.selectedStepId
|
|
359
|
+
);
|
|
360
|
+
if (selectedStep) {
|
|
361
|
+
userPrompt += `Currently selected step: "${context.selectedStepId}"\n\n`;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (context?.recentHistory && context.recentHistory.length > 0) {
|
|
366
|
+
userPrompt += `Recent changes:\n${context.recentHistory.map((h) => `- ${h}`).join('\n')}\n\n`;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
userPrompt += `User request: ${userRequest}`;
|
|
370
|
+
|
|
371
|
+
return { systemPrompt, userPrompt };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Detect what type of operations the user is requesting
|
|
376
|
+
*/
|
|
377
|
+
function detectOperations(request: string): string[] {
|
|
378
|
+
const lower = request.toLowerCase();
|
|
379
|
+
const operations: string[] = [];
|
|
380
|
+
|
|
381
|
+
if (lower.includes('add') && (lower.includes('step') || lower.includes('action'))) {
|
|
382
|
+
operations.push('addStep');
|
|
383
|
+
}
|
|
384
|
+
if (lower.includes('remove') || lower.includes('delete')) {
|
|
385
|
+
operations.push('removeStep');
|
|
386
|
+
}
|
|
387
|
+
if (lower.includes('change') || lower.includes('modify') || lower.includes('update')) {
|
|
388
|
+
operations.push('modifyInputs');
|
|
389
|
+
}
|
|
390
|
+
if (lower.includes('error') || lower.includes('retry') || lower.includes('fallback')) {
|
|
391
|
+
operations.push('addErrorHandling');
|
|
392
|
+
}
|
|
393
|
+
if (lower.includes('condition') || lower.includes('if') || lower.includes('when')) {
|
|
394
|
+
operations.push('addConditions');
|
|
395
|
+
}
|
|
396
|
+
if (lower.includes('sub-workflow') || lower.includes('subworkflow') || lower.includes('nested')) {
|
|
397
|
+
operations.push('createSubWorkflow');
|
|
398
|
+
}
|
|
399
|
+
if (lower.includes('tool') || lower.includes('sdk') || lower.includes('connect')) {
|
|
400
|
+
operations.push('addTool');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Default to addStep if no specific operation detected
|
|
404
|
+
if (operations.length === 0) {
|
|
405
|
+
operations.push('addStep');
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return operations;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Format workflow for prompt (simplified YAML)
|
|
413
|
+
*/
|
|
414
|
+
function formatWorkflow(workflow: {
|
|
415
|
+
metadata?: Record<string, unknown>;
|
|
416
|
+
steps: unknown[];
|
|
417
|
+
tools?: Record<string, unknown>;
|
|
418
|
+
}): string {
|
|
419
|
+
const { stringify } = require('yaml');
|
|
420
|
+
return stringify(workflow, { indent: 2, lineWidth: 0 });
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Generate contextual suggestions based on workflow state
|
|
425
|
+
*/
|
|
426
|
+
export function generateSuggestions(
|
|
427
|
+
workflow: { metadata?: Record<string, unknown>; steps: unknown[]; tools?: Record<string, unknown> },
|
|
428
|
+
selectedStepId?: string
|
|
429
|
+
): string[] {
|
|
430
|
+
const suggestions: string[] = [];
|
|
431
|
+
const steps = workflow.steps || [];
|
|
432
|
+
|
|
433
|
+
// No steps - suggest getting started
|
|
434
|
+
if (steps.length === 0) {
|
|
435
|
+
return [
|
|
436
|
+
'Add a step to send a Slack message',
|
|
437
|
+
'Add a step to fetch data from GitHub',
|
|
438
|
+
'Add an HTTP request step',
|
|
439
|
+
'Create a workflow that monitors a webhook',
|
|
440
|
+
];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Check for missing error handling
|
|
444
|
+
const stepsWithoutErrorHandling = steps.filter((s: any) => !s.errorHandling);
|
|
445
|
+
if (stepsWithoutErrorHandling.length > 0) {
|
|
446
|
+
suggestions.push('Add error handling with retries to all steps');
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Check for missing notifications
|
|
450
|
+
const hasNotification = steps.some(
|
|
451
|
+
(s: any) =>
|
|
452
|
+
s.action?.includes('slack') ||
|
|
453
|
+
s.action?.includes('gmail') ||
|
|
454
|
+
s.action?.includes('discord')
|
|
455
|
+
);
|
|
456
|
+
if (!hasNotification) {
|
|
457
|
+
suggestions.push('Add a Slack notification at the end');
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Step-specific suggestions
|
|
461
|
+
if (selectedStepId) {
|
|
462
|
+
const step = steps.find((s: any) => s.id === selectedStepId) as any;
|
|
463
|
+
if (step) {
|
|
464
|
+
if (!step.errorHandling) {
|
|
465
|
+
suggestions.push(`Add retry logic to "${step.name || step.id}"`);
|
|
466
|
+
}
|
|
467
|
+
if (!step.conditions || step.conditions.length === 0) {
|
|
468
|
+
suggestions.push(`Add a condition to "${step.name || step.id}"`);
|
|
469
|
+
}
|
|
470
|
+
suggestions.push(`Duplicate "${step.name || step.id}" with modifications`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// General suggestions
|
|
475
|
+
if (steps.length >= 3) {
|
|
476
|
+
suggestions.push('Convert these steps into a reusable sub-workflow');
|
|
477
|
+
}
|
|
478
|
+
suggestions.push('Add a step to log results to a database');
|
|
479
|
+
suggestions.push('Add parallel execution for independent steps');
|
|
480
|
+
|
|
481
|
+
return suggestions.slice(0, 5);
|
|
482
|
+
}
|