@ai-setting/roy-agent-cli 1.0.0
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/README.md +126 -0
- package/dist/bin/roy.js +127297 -0
- package/dist/roy-agent-darwin-arm64/bin/roy.js +127297 -0
- package/dist/roy-agent-darwin-x64/bin/roy.js +127297 -0
- package/dist/roy-agent-linux-arm64/bin/roy.js +127297 -0
- package/dist/roy-agent-linux-x64/bin/roy.js +127297 -0
- package/dist/roy-agent-windows-x64/bin/roy.js +127297 -0
- package/package.json +91 -0
- package/src/bin/roy.ts +12 -0
- package/src/cli.ts +101 -0
- package/src/commands/act.ts +480 -0
- package/src/commands/commands-add.ts +110 -0
- package/src/commands/commands-dirs.ts +70 -0
- package/src/commands/commands-info.ts +90 -0
- package/src/commands/commands-list.ts +161 -0
- package/src/commands/commands-remove.ts +147 -0
- package/src/commands/commands.ts +55 -0
- package/src/commands/config/config-service.test.ts +449 -0
- package/src/commands/config/config-service.ts +312 -0
- package/src/commands/config/deep-merge.test.ts +168 -0
- package/src/commands/config/deep-merge.ts +63 -0
- package/src/commands/config/export.ts +97 -0
- package/src/commands/config/filter-history-e2e.test.ts +141 -0
- package/src/commands/config/import-preserve-refs.test.ts +212 -0
- package/src/commands/config/import.ts +119 -0
- package/src/commands/config/index.ts +35 -0
- package/src/commands/config/list.ts +281 -0
- package/src/commands/config/roy-config-e2e.test.ts +297 -0
- package/src/commands/config/types.ts +54 -0
- package/src/commands/debug/index.ts +38 -0
- package/src/commands/debug/log.test.ts +233 -0
- package/src/commands/debug/log.ts +123 -0
- package/src/commands/debug/span.test.ts +297 -0
- package/src/commands/debug/span.ts +211 -0
- package/src/commands/debug/trace.test.ts +254 -0
- package/src/commands/debug/trace.ts +140 -0
- package/src/commands/eventsource/add.ts +133 -0
- package/src/commands/eventsource/index.ts +48 -0
- package/src/commands/eventsource/list.ts +194 -0
- package/src/commands/eventsource/remove.ts +95 -0
- package/src/commands/eventsource/start.ts +103 -0
- package/src/commands/eventsource/status.ts +185 -0
- package/src/commands/eventsource/stop.ts +89 -0
- package/src/commands/index.ts +22 -0
- package/src/commands/input-handler.test.ts +76 -0
- package/src/commands/input-handler.ts +43 -0
- package/src/commands/interactive-esc.test.ts +254 -0
- package/src/commands/interactive.shutdown.test.ts +122 -0
- package/src/commands/interactive.test.ts +221 -0
- package/src/commands/interactive.ts +1015 -0
- package/src/commands/lsp/check.ts +92 -0
- package/src/commands/lsp/index.ts +32 -0
- package/src/commands/lsp/install.ts +126 -0
- package/src/commands/lsp/list.ts +64 -0
- package/src/commands/mcp/index.ts +27 -0
- package/src/commands/mcp/list.ts +116 -0
- package/src/commands/mcp/reload.ts +70 -0
- package/src/commands/mcp/tools.ts +121 -0
- package/src/commands/memory/extract-e2e.test.ts +388 -0
- package/src/commands/memory/index.ts +11 -0
- package/src/commands/memory/memory-simplified.test.ts +58 -0
- package/src/commands/memory/memory.ts +25 -0
- package/src/commands/memory/organize.ts +300 -0
- package/src/commands/memory/recall.test.ts +120 -0
- package/src/commands/memory/recall.ts +88 -0
- package/src/commands/memory/record-extract-handle-query.test.ts +385 -0
- package/src/commands/memory/record-prompt-component.test.ts +343 -0
- package/src/commands/memory/record.test.ts +92 -0
- package/src/commands/memory/record.ts +332 -0
- package/src/commands/plugin.test.ts +292 -0
- package/src/commands/plugin.ts +267 -0
- package/src/commands/sessions/active.ts +96 -0
- package/src/commands/sessions/add-message.ts +96 -0
- package/src/commands/sessions/checkpoints.ts +154 -0
- package/src/commands/sessions/compact.test.ts +215 -0
- package/src/commands/sessions/compact.ts +269 -0
- package/src/commands/sessions/delete.ts +236 -0
- package/src/commands/sessions/get.ts +165 -0
- package/src/commands/sessions/grep.ts +233 -0
- package/src/commands/sessions/index.ts +95 -0
- package/src/commands/sessions/list.ts +210 -0
- package/src/commands/sessions/messages.test.ts +333 -0
- package/src/commands/sessions/messages.ts +248 -0
- package/src/commands/sessions/mock.ts +194 -0
- package/src/commands/sessions/new.ts +82 -0
- package/src/commands/sessions/rename.ts +98 -0
- package/src/commands/shared/event-handler.ts +213 -0
- package/src/commands/shared/event-message-formatter.ts +295 -0
- package/src/commands/shared/index.ts +11 -0
- package/src/commands/shared/query-executor.test.ts +434 -0
- package/src/commands/shared/query-executor.ts +324 -0
- package/src/commands/shared/repl-engine.test.ts +354 -0
- package/src/commands/shared/session-manager.test.ts +212 -0
- package/src/commands/shared/session-manager.ts +114 -0
- package/src/commands/skills/get.ts +90 -0
- package/src/commands/skills/index.ts +39 -0
- package/src/commands/skills/list.ts +129 -0
- package/src/commands/skills/reload.ts +59 -0
- package/src/commands/skills/search.ts +132 -0
- package/src/commands/skills/show-config.ts +93 -0
- package/src/commands/tasks/complete.ts +92 -0
- package/src/commands/tasks/create.ts +118 -0
- package/src/commands/tasks/delete.ts +86 -0
- package/src/commands/tasks/get.ts +116 -0
- package/src/commands/tasks/index.ts +53 -0
- package/src/commands/tasks/list.ts +140 -0
- package/src/commands/tasks/operations.ts +120 -0
- package/src/commands/tasks/update.ts +122 -0
- package/src/commands/tools/exec-tool.ts +128 -0
- package/src/commands/tools/get.ts +114 -0
- package/src/commands/tools/index.ts +35 -0
- package/src/commands/tools/list.ts +107 -0
- package/src/commands/tools/shared/index.ts +7 -0
- package/src/commands/tools/shared/schema-helper.ts +111 -0
- package/src/commands/workflow/commands/add.ts +315 -0
- package/src/commands/workflow/commands/get.ts +193 -0
- package/src/commands/workflow/commands/list.ts +137 -0
- package/src/commands/workflow/commands/nodes.ts +528 -0
- package/src/commands/workflow/commands/remove.ts +94 -0
- package/src/commands/workflow/commands/run.ts +398 -0
- package/src/commands/workflow/commands/status.ts +147 -0
- package/src/commands/workflow/commands/stop.ts +91 -0
- package/src/commands/workflow/commands/update.ts +130 -0
- package/src/commands/workflow/commands/validate.ts +139 -0
- package/src/commands/workflow/commands/workflow-cli.test.ts +196 -0
- package/src/commands/workflow/index.ts +65 -0
- package/src/commands/workflow/renderers.ts +358 -0
- package/src/commands/workflow/validators/index.ts +8 -0
- package/src/commands/workflow/validators/node-validator-factory.ts +40 -0
- package/src/commands/workflow/validators/node-validator.ts +125 -0
- package/src/commands/workflow/validators/nodes/agent-node-validator.ts +58 -0
- package/src/commands/workflow/validators/nodes/condition-node-validator.ts +34 -0
- package/src/commands/workflow/validators/nodes/decorator-node-validator.ts +45 -0
- package/src/commands/workflow/validators/nodes/merge-node-validator.ts +46 -0
- package/src/commands/workflow/validators/nodes/skill-node-validator.ts +33 -0
- package/src/commands/workflow/validators/nodes/tool-node-validator.ts +54 -0
- package/src/commands/workflow/validators/nodes/workflow-node-validator.ts +33 -0
- package/src/commands/workflow/validators/types.ts +78 -0
- package/src/commands/workflow/validators/workflow-validator.test.ts +273 -0
- package/src/commands/workflow/validators/workflow-validator.ts +320 -0
- package/src/index.ts +19 -0
- package/src/plugin/apply.ts +103 -0
- package/src/plugin/discover.ts +219 -0
- package/src/plugin/index.ts +45 -0
- package/src/plugin/registry.ts +272 -0
- package/src/plugin/types.ts +165 -0
- package/src/services/context-handler.service.test.ts +501 -0
- package/src/services/context-handler.service.ts +372 -0
- package/src/services/environment.service.commands-prompt.test.ts +167 -0
- package/src/services/environment.service.ts +656 -0
- package/src/services/output.service.test.ts +92 -0
- package/src/services/output.service.ts +122 -0
- package/src/services/quiet-mode.service.test.ts +114 -0
- package/src/services/quiet-mode.service.ts +81 -0
- package/src/services/stream-output.service.test.ts +214 -0
- package/src/services/stream-output.service.ts +323 -0
- package/src/util/which.test.ts +101 -0
- package/src/util/which.ts +55 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Workflow Nodes Command
|
|
3
|
+
*
|
|
4
|
+
* List all built-in node types with their input/output descriptions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CommandModule } from 'yargs';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
|
|
10
|
+
export interface WorkflowNodesOptions {
|
|
11
|
+
type?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Node type definition
|
|
16
|
+
*/
|
|
17
|
+
export interface NodeDefinition {
|
|
18
|
+
name: string;
|
|
19
|
+
type: string;
|
|
20
|
+
description: string;
|
|
21
|
+
inputs: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
type: string;
|
|
24
|
+
required: boolean;
|
|
25
|
+
description: string;
|
|
26
|
+
}>;
|
|
27
|
+
output: string;
|
|
28
|
+
example?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Common parameters supported by all node types
|
|
33
|
+
*/
|
|
34
|
+
const COMMON_PARAMS = [
|
|
35
|
+
{
|
|
36
|
+
name: 'depends_on',
|
|
37
|
+
type: 'string[]',
|
|
38
|
+
required: false,
|
|
39
|
+
description: 'List of node IDs that must complete before this node runs',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'timeout',
|
|
43
|
+
type: 'number',
|
|
44
|
+
required: false,
|
|
45
|
+
description: 'Execution timeout in milliseconds (default: 30000)',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'retry',
|
|
49
|
+
type: 'object',
|
|
50
|
+
required: false,
|
|
51
|
+
description: 'Retry config: {max_attempts, backoff: "fixed"|"exponential", initial_delay}',
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Built-in node type definitions
|
|
57
|
+
*/
|
|
58
|
+
export const BUILT_IN_NODES: NodeDefinition[] = [
|
|
59
|
+
// =========================================================================
|
|
60
|
+
// Tool Node
|
|
61
|
+
// =========================================================================
|
|
62
|
+
{
|
|
63
|
+
name: 'ToolNode',
|
|
64
|
+
type: 'tool',
|
|
65
|
+
description:
|
|
66
|
+
'Execute a registered tool. Tools are atomic operations that perform specific tasks like bash, file operations, or API calls. Supports template resolution for input values.',
|
|
67
|
+
inputs: [
|
|
68
|
+
{
|
|
69
|
+
name: 'tool / toolName',
|
|
70
|
+
type: 'string',
|
|
71
|
+
required: true,
|
|
72
|
+
description: 'Name of the registered tool to execute (e.g., bash, read-file, web-search)',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'input / args',
|
|
76
|
+
type: 'object',
|
|
77
|
+
required: false,
|
|
78
|
+
description: 'Key-value pairs passed to the tool (use input or args key). Supports template strings like {{nodes.nodeId.output}}',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'command',
|
|
82
|
+
type: 'string',
|
|
83
|
+
required: false,
|
|
84
|
+
description: 'Single command string (for bash tool with {command: "..."} signature). Supports templates.',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'message',
|
|
88
|
+
type: 'string',
|
|
89
|
+
required: false,
|
|
90
|
+
description: 'Single message string (for echo tool with {message: "..."} signature). Supports templates.',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
output: '{output: any, error?: Error, durationMs: number}',
|
|
94
|
+
example: `# Example 1: Execute bash command
|
|
95
|
+
nodes:
|
|
96
|
+
run-tests:
|
|
97
|
+
type: tool
|
|
98
|
+
config:
|
|
99
|
+
tool: bash
|
|
100
|
+
input:
|
|
101
|
+
command: "npm test"
|
|
102
|
+
|
|
103
|
+
# Example 2: Read file with template reference
|
|
104
|
+
nodes:
|
|
105
|
+
read-config:
|
|
106
|
+
type: tool
|
|
107
|
+
config:
|
|
108
|
+
tool: read-file
|
|
109
|
+
input:
|
|
110
|
+
path: "{{input.configPath}}"
|
|
111
|
+
|
|
112
|
+
# Example 3: Web search
|
|
113
|
+
nodes:
|
|
114
|
+
search:
|
|
115
|
+
type: tool
|
|
116
|
+
config:
|
|
117
|
+
tool: web-search
|
|
118
|
+
input:
|
|
119
|
+
query: "AI news"
|
|
120
|
+
numResults: 5`,
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// =========================================================================
|
|
124
|
+
// Skill Node
|
|
125
|
+
// =========================================================================
|
|
126
|
+
{
|
|
127
|
+
name: 'SkillNode',
|
|
128
|
+
type: 'skill',
|
|
129
|
+
description:
|
|
130
|
+
'Invoke a skill processor. Skills are higher-level operations that combine multiple tools and logic for complex tasks. Supports template resolution for input values.',
|
|
131
|
+
inputs: [
|
|
132
|
+
{
|
|
133
|
+
name: 'skill',
|
|
134
|
+
type: 'string',
|
|
135
|
+
required: true,
|
|
136
|
+
description: 'Name of the registered skill to invoke',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'input',
|
|
140
|
+
type: 'object',
|
|
141
|
+
required: false,
|
|
142
|
+
description: 'Input parameters for the skill. Supports template strings like {{nodes.nodeId.output}}',
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
output: '{output: any, error?: Error, durationMs: number}',
|
|
146
|
+
example: `# Example: Summarize text
|
|
147
|
+
nodes:
|
|
148
|
+
summarize:
|
|
149
|
+
type: skill
|
|
150
|
+
config:
|
|
151
|
+
skill: text-summarizer
|
|
152
|
+
input:
|
|
153
|
+
content: "{{nodes.fetch.output}}"
|
|
154
|
+
maxLength: 200
|
|
155
|
+
|
|
156
|
+
# Example: Code review
|
|
157
|
+
nodes:
|
|
158
|
+
review:
|
|
159
|
+
type: skill
|
|
160
|
+
config:
|
|
161
|
+
skill: code-reviewer
|
|
162
|
+
input:
|
|
163
|
+
code: "{{input.code}}"
|
|
164
|
+
language: "{{input.language}}"`,
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// =========================================================================
|
|
168
|
+
// Agent Node
|
|
169
|
+
// =========================================================================
|
|
170
|
+
{
|
|
171
|
+
name: 'AgentNode',
|
|
172
|
+
type: 'agent',
|
|
173
|
+
description:
|
|
174
|
+
'Run an AI agent with reasoning loop. Agents use LLM to reason, plan, and use tools for complex tasks. Supports workflow history for multi-agent collaboration. Prompt templates support {{input.key}} and {{nodes.nodeId.output}} interpolation.',
|
|
175
|
+
inputs: [
|
|
176
|
+
{
|
|
177
|
+
name: 'agent_type',
|
|
178
|
+
type: 'string',
|
|
179
|
+
required: true,
|
|
180
|
+
description: 'Agent type (e.g., general, research, coder, critic). Auto-registers if not found.',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'prompt',
|
|
184
|
+
type: 'string',
|
|
185
|
+
required: true,
|
|
186
|
+
description: 'Prompt template (supports {{input.key}} and {{nodes.nodeId.output}} interpolation)',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: 'options',
|
|
190
|
+
type: 'object',
|
|
191
|
+
required: false,
|
|
192
|
+
description: 'Execution options: {timeout?: number, model?: string}',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'system_prompt / systemPrompt',
|
|
196
|
+
type: 'string',
|
|
197
|
+
required: false,
|
|
198
|
+
description: 'Custom system prompt for this agent (auto-generated if not provided)',
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
output: '{result: any, metadata: {tokens?: number, duration?: number}, workflowHistory: [...]}',
|
|
202
|
+
example: `# Example: Research agent
|
|
203
|
+
nodes:
|
|
204
|
+
analyze:
|
|
205
|
+
type: agent
|
|
206
|
+
config:
|
|
207
|
+
agent_type: research
|
|
208
|
+
prompt: |
|
|
209
|
+
Based on the data: {{nodes.fetch.output}}
|
|
210
|
+
Please analyze and provide insights.
|
|
211
|
+
options:
|
|
212
|
+
timeout: 60000
|
|
213
|
+
model: "minimax"
|
|
214
|
+
|
|
215
|
+
# Example: Multi-agent with history
|
|
216
|
+
nodes:
|
|
217
|
+
planner:
|
|
218
|
+
type: agent
|
|
219
|
+
config:
|
|
220
|
+
agent_type: general
|
|
221
|
+
prompt: "Plan the implementation for {{input.task}}"
|
|
222
|
+
|
|
223
|
+
executor:
|
|
224
|
+
type: agent
|
|
225
|
+
config:
|
|
226
|
+
agent_type: coder
|
|
227
|
+
prompt: "Implement the plan: {{nodes.planner.output}}"
|
|
228
|
+
depends_on:
|
|
229
|
+
- planner`,
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
// =========================================================================
|
|
233
|
+
// Workflow Node (Sub-workflow)
|
|
234
|
+
// =========================================================================
|
|
235
|
+
{
|
|
236
|
+
name: 'WorkflowNode',
|
|
237
|
+
type: 'workflow',
|
|
238
|
+
description:
|
|
239
|
+
'Execute a nested/sub workflow. Allows creating complex workflows by combining simpler ones. Supports template resolution for input values.',
|
|
240
|
+
inputs: [
|
|
241
|
+
{
|
|
242
|
+
name: 'workflow_name',
|
|
243
|
+
type: 'string',
|
|
244
|
+
required: true,
|
|
245
|
+
description: 'Name of the sub-workflow to execute',
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: 'input',
|
|
249
|
+
type: 'object',
|
|
250
|
+
required: false,
|
|
251
|
+
description: 'Input parameters for the sub-workflow. Supports template strings like {{nodes.nodeId.output}}',
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: 'wait_complete',
|
|
255
|
+
type: 'boolean',
|
|
256
|
+
required: false,
|
|
257
|
+
description: 'Whether to wait for sub-workflow completion (default: true)',
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
output: '{success: boolean, output?: any, error?: string, duration: number}',
|
|
261
|
+
example: `# Example: Execute sub-workflow
|
|
262
|
+
nodes:
|
|
263
|
+
data-process:
|
|
264
|
+
type: workflow
|
|
265
|
+
config:
|
|
266
|
+
workflow_name: data-processor
|
|
267
|
+
input:
|
|
268
|
+
data: "{{nodes.fetch.output}}"
|
|
269
|
+
|
|
270
|
+
# Example: Sequential workflows
|
|
271
|
+
nodes:
|
|
272
|
+
step1:
|
|
273
|
+
type: workflow
|
|
274
|
+
config:
|
|
275
|
+
workflow_name: preprocessing
|
|
276
|
+
input:
|
|
277
|
+
raw: "{{input.data}}"
|
|
278
|
+
|
|
279
|
+
step2:
|
|
280
|
+
type: workflow
|
|
281
|
+
config:
|
|
282
|
+
workflow_name: analysis
|
|
283
|
+
input:
|
|
284
|
+
cleaned: "{{nodes.step1.output}}"
|
|
285
|
+
depends_on:
|
|
286
|
+
- step1`,
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
// =========================================================================
|
|
290
|
+
// Condition Node
|
|
291
|
+
// =========================================================================
|
|
292
|
+
{
|
|
293
|
+
name: 'ConditionNode',
|
|
294
|
+
type: 'condition',
|
|
295
|
+
description:
|
|
296
|
+
'Evaluate a condition and decide workflow path. Supports boolean values, template expressions, and references to previous node outputs. Default to true if no condition specified.',
|
|
297
|
+
inputs: [
|
|
298
|
+
{
|
|
299
|
+
name: 'condition',
|
|
300
|
+
type: 'string | boolean',
|
|
301
|
+
required: false,
|
|
302
|
+
description: 'Condition to evaluate: boolean value, template {{nodeId.output.success}}, or template {{input.key}}. Defaults to true if not specified.',
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
output: '{success: boolean, condition: resolved_value}',
|
|
306
|
+
example: `# Example: Check test results
|
|
307
|
+
nodes:
|
|
308
|
+
run-tests:
|
|
309
|
+
type: tool
|
|
310
|
+
config:
|
|
311
|
+
tool: bash
|
|
312
|
+
input:
|
|
313
|
+
command: "npm test"
|
|
314
|
+
|
|
315
|
+
check-result:
|
|
316
|
+
type: condition
|
|
317
|
+
config:
|
|
318
|
+
condition: "{{run-tests.output.success}}"
|
|
319
|
+
depends_on:
|
|
320
|
+
- run-tests
|
|
321
|
+
|
|
322
|
+
# Example: Check input value
|
|
323
|
+
nodes:
|
|
324
|
+
validate:
|
|
325
|
+
type: condition
|
|
326
|
+
config:
|
|
327
|
+
condition: "{{input.validate}}"
|
|
328
|
+
depends_on: []`,
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
// =========================================================================
|
|
332
|
+
// Merge Node
|
|
333
|
+
// =========================================================================
|
|
334
|
+
{
|
|
335
|
+
name: 'MergeNode',
|
|
336
|
+
type: 'merge',
|
|
337
|
+
description:
|
|
338
|
+
'Collect and merge outputs from multiple dependency nodes. Supports strategies: collect (default), first, last, merge.',
|
|
339
|
+
inputs: [
|
|
340
|
+
{
|
|
341
|
+
name: 'strategy',
|
|
342
|
+
type: 'string',
|
|
343
|
+
required: false,
|
|
344
|
+
description: 'Merge strategy: collect (default, returns map), first (returns first output), last (returns last output), merge (deep merge objects)',
|
|
345
|
+
},
|
|
346
|
+
],
|
|
347
|
+
output: '{strategy: string, results: any, count: number}',
|
|
348
|
+
example: `# Example: Collect parallel results
|
|
349
|
+
nodes:
|
|
350
|
+
parallel-fetch:
|
|
351
|
+
type: merge
|
|
352
|
+
config:
|
|
353
|
+
strategy: collect
|
|
354
|
+
depends_on:
|
|
355
|
+
- fetch-user
|
|
356
|
+
- fetch-orders
|
|
357
|
+
- fetch-preferences
|
|
358
|
+
|
|
359
|
+
# Example: Get first successful result
|
|
360
|
+
nodes:
|
|
361
|
+
first-success:
|
|
362
|
+
type: merge
|
|
363
|
+
config:
|
|
364
|
+
strategy: first
|
|
365
|
+
depends_on:
|
|
366
|
+
- primary-source
|
|
367
|
+
- backup-source
|
|
368
|
+
|
|
369
|
+
# Example: Merge objects
|
|
370
|
+
nodes:
|
|
371
|
+
merge-data:
|
|
372
|
+
type: merge
|
|
373
|
+
config:
|
|
374
|
+
strategy: merge
|
|
375
|
+
depends_on:
|
|
376
|
+
- metadata
|
|
377
|
+
- content
|
|
378
|
+
- analytics`,
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
// =========================================================================
|
|
382
|
+
// Decorator Node
|
|
383
|
+
// =========================================================================
|
|
384
|
+
{
|
|
385
|
+
name: 'DecoratorNode',
|
|
386
|
+
type: 'decorator',
|
|
387
|
+
description:
|
|
388
|
+
'Execute a class method decorated with @Workflow or @NodeAs. Supports retry logic and timeout. Automatically extracts output from decorated methods.',
|
|
389
|
+
inputs: [
|
|
390
|
+
{
|
|
391
|
+
name: '_methodName',
|
|
392
|
+
type: 'string',
|
|
393
|
+
required: true,
|
|
394
|
+
description: 'Name of the decorated method to execute',
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: '_instance',
|
|
398
|
+
type: 'object',
|
|
399
|
+
required: true,
|
|
400
|
+
description: 'Class instance containing the decorated method',
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: 'retry',
|
|
404
|
+
type: 'object',
|
|
405
|
+
required: false,
|
|
406
|
+
description: 'Retry config: {max_attempts: number, backoff: "fixed"|"exponential", initial_delay: number}',
|
|
407
|
+
},
|
|
408
|
+
],
|
|
409
|
+
output: '{success: boolean, output?: any, error?: string, duration: number, metadata: {methodName: string}}',
|
|
410
|
+
example: `# Example: Execute decorated method
|
|
411
|
+
nodes:
|
|
412
|
+
process-data:
|
|
413
|
+
type: decorator
|
|
414
|
+
config:
|
|
415
|
+
_methodName: "processData"
|
|
416
|
+
_instance: "{{input.workflowInstance}}"
|
|
417
|
+
timeout: 30000
|
|
418
|
+
retry:
|
|
419
|
+
max_attempts: 3
|
|
420
|
+
backoff: exponential
|
|
421
|
+
initial_delay: 1000
|
|
422
|
+
depends_on:
|
|
423
|
+
- fetch-data`,
|
|
424
|
+
},
|
|
425
|
+
];
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Render node types table
|
|
429
|
+
*/
|
|
430
|
+
function renderNodeTypesTable(nodes: NodeDefinition[]): string {
|
|
431
|
+
const lines: string[] = [];
|
|
432
|
+
|
|
433
|
+
lines.push(chalk.bold('\n📦 Built-in Node Types\n'));
|
|
434
|
+
lines.push('┌────────────┬────────────────────┬─────────────────────────────────────────────────────────────┐');
|
|
435
|
+
lines.push('│ Type │ Name │ Description │');
|
|
436
|
+
lines.push('├────────────┼────────────────────┼─────────────────────────────────────────────────────────────┤');
|
|
437
|
+
|
|
438
|
+
for (const node of nodes) {
|
|
439
|
+
const type = node.type.padEnd(10);
|
|
440
|
+
const name = node.name.padEnd(18);
|
|
441
|
+
const desc = node.description.substring(0, 59).padEnd(59);
|
|
442
|
+
lines.push(`│ ${type} │ ${name} │ ${desc} │`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
lines.push('└────────────┴────────────────────┴─────────────────────────────────────────────────────────────┘');
|
|
446
|
+
|
|
447
|
+
return lines.join('\n');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Render detailed node information
|
|
452
|
+
*/
|
|
453
|
+
function renderNodeDetail(node: NodeDefinition): string {
|
|
454
|
+
const lines: string[] = [];
|
|
455
|
+
|
|
456
|
+
lines.push(chalk.bold(`\n[${node.type}] ${node.name}`));
|
|
457
|
+
lines.push(chalk.dim('─'.repeat(60)) + '\n');
|
|
458
|
+
|
|
459
|
+
lines.push(chalk.bold('Description:'));
|
|
460
|
+
lines.push(` ${node.description}\n`);
|
|
461
|
+
|
|
462
|
+
lines.push(chalk.bold('Configuration:'));
|
|
463
|
+
lines.push(' type: "' + node.type + '"');
|
|
464
|
+
lines.push(' config:');
|
|
465
|
+
|
|
466
|
+
for (const input of node.inputs) {
|
|
467
|
+
const required = input.required ? chalk.red('*') : ' ';
|
|
468
|
+
lines.push(` ${input.name} (${input.type})${required}`);
|
|
469
|
+
lines.push(` ${input.description}`);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
lines.push(`\n${chalk.bold('Output:')} ${node.output}`);
|
|
473
|
+
|
|
474
|
+
if (node.example) {
|
|
475
|
+
lines.push(chalk.bold('\nExample:'));
|
|
476
|
+
lines.push(chalk.gray('```yaml'));
|
|
477
|
+
lines.push(node.example);
|
|
478
|
+
lines.push(chalk.gray('```'));
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return lines.join('\n');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* WorkflowNodesCommand - List built-in node types
|
|
486
|
+
*/
|
|
487
|
+
export const WorkflowNodesCommand: CommandModule<object, WorkflowNodesOptions> = {
|
|
488
|
+
command: 'nodes [type]',
|
|
489
|
+
describe: '列出所有内置节点类型及其配置说明',
|
|
490
|
+
|
|
491
|
+
builder: (yargs) =>
|
|
492
|
+
yargs.positional('type', {
|
|
493
|
+
describe: '节点类型 (tool/skill/agent/workflow/condition/merge/decorator/end)',
|
|
494
|
+
type: 'string',
|
|
495
|
+
}),
|
|
496
|
+
|
|
497
|
+
async handler(args) {
|
|
498
|
+
const nodeType = (args as any).type?.toLowerCase();
|
|
499
|
+
|
|
500
|
+
// List all node types
|
|
501
|
+
if (!nodeType) {
|
|
502
|
+
console.log(renderNodeTypesTable(BUILT_IN_NODES));
|
|
503
|
+
console.log(
|
|
504
|
+
chalk.gray('\nUse ') +
|
|
505
|
+
chalk.cyan('roy workflow nodes <type>') +
|
|
506
|
+
chalk.gray(' for detailed information')
|
|
507
|
+
);
|
|
508
|
+
console.log(
|
|
509
|
+
chalk.gray('Available types: ') +
|
|
510
|
+
chalk.yellow(BUILT_IN_NODES.map((n) => n.type).join(', '))
|
|
511
|
+
);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Show specific node type
|
|
516
|
+
const node = BUILT_IN_NODES.find((n) => n.type === nodeType);
|
|
517
|
+
if (!node) {
|
|
518
|
+
console.log(chalk.red(`\n❌ Unknown node type: ${nodeType}`));
|
|
519
|
+
console.log(
|
|
520
|
+
chalk.gray('Available types: ') +
|
|
521
|
+
chalk.yellow(BUILT_IN_NODES.map((n) => n.type).join(', '))
|
|
522
|
+
);
|
|
523
|
+
process.exit(1);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
console.log(renderNodeDetail(node));
|
|
527
|
+
},
|
|
528
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Workflow Remove Command
|
|
3
|
+
*
|
|
4
|
+
* Delete a workflow
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CommandModule } from 'yargs';
|
|
8
|
+
import { EnvironmentService } from '../../../services/environment.service';
|
|
9
|
+
import { OutputService } from '../../../services/output.service';
|
|
10
|
+
import { renderWorkflowDeleted } from '../renderers';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import type { WorkflowService } from '@ai-setting/roy-agent-core/env/workflow/service';
|
|
13
|
+
|
|
14
|
+
export interface WorkflowRemoveOptions {
|
|
15
|
+
name: string;
|
|
16
|
+
force?: boolean;
|
|
17
|
+
config?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* WorkflowRemoveCommand - Delete a workflow
|
|
22
|
+
*/
|
|
23
|
+
export const WorkflowRemoveCommand: CommandModule<object, WorkflowRemoveOptions> = {
|
|
24
|
+
command: 'remove <name>',
|
|
25
|
+
describe: '删除 Workflow',
|
|
26
|
+
|
|
27
|
+
builder: (yargs) =>
|
|
28
|
+
yargs
|
|
29
|
+
.positional('name', {
|
|
30
|
+
describe: 'Workflow 名称',
|
|
31
|
+
type: 'string',
|
|
32
|
+
demandOption: true,
|
|
33
|
+
})
|
|
34
|
+
.option('force', {
|
|
35
|
+
alias: 'f',
|
|
36
|
+
describe: '强制删除(不确认)',
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
default: false,
|
|
39
|
+
})
|
|
40
|
+
.option('config', {
|
|
41
|
+
describe: '配置文件路径',
|
|
42
|
+
type: 'string',
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
async handler(args) {
|
|
46
|
+
const output = new OutputService();
|
|
47
|
+
const envService = new EnvironmentService(output);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
await envService.create({ configPath: args.config });
|
|
51
|
+
const env = envService.getEnvironment();
|
|
52
|
+
if (!env) {
|
|
53
|
+
output.error("Failed to create environment");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const workflowComponent = env.getComponent('workflow') as any;
|
|
57
|
+
|
|
58
|
+
if (!workflowComponent) {
|
|
59
|
+
output.error('WorkflowComponent not available');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const service = workflowComponent.getService() as WorkflowService;
|
|
64
|
+
|
|
65
|
+
// Check if workflow exists
|
|
66
|
+
const existing = service.getWorkflow(args.name);
|
|
67
|
+
if (!existing) {
|
|
68
|
+
output.error(`Workflow not found: ${args.name}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Confirm deletion if not forced
|
|
73
|
+
if (!args.force) {
|
|
74
|
+
output.log(chalk.yellow(`Are you sure you want to delete workflow '${args.name}'?`));
|
|
75
|
+
output.log(chalk.gray('Use --force to skip confirmation'));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Delete workflow
|
|
80
|
+
const deleted = await service.deleteWorkflow(args.name);
|
|
81
|
+
if (!deleted) {
|
|
82
|
+
output.error(`Failed to delete workflow: ${args.name}`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
output.log(renderWorkflowDeleted(args.name));
|
|
87
|
+
} catch (error) {
|
|
88
|
+
output.error(`Failed to delete workflow: ${error}`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
} finally {
|
|
91
|
+
await envService.dispose();
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|