agency-orchestrator 0.3.0 → 0.3.2

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 CHANGED
@@ -150,6 +150,22 @@ analyze ──→ tech_review ──→ summary
150
150
 
151
151
  ## Features
152
152
 
153
+ ### AI Workflow Composer
154
+
155
+ Describe your workflow in one sentence — AI selects the right roles, designs the DAG, and generates a ready-to-run YAML:
156
+
157
+ ```bash
158
+ ao compose "PR code review covering security and performance"
159
+ ```
160
+
161
+ The AI will:
162
+ 1. Select matching roles from 186 available (e.g., Code Reviewer, Security Engineer, Performance Benchmarker)
163
+ 2. Design the DAG (3-way parallel → summary)
164
+ 3. Generate complete YAML with variable passing and task descriptions
165
+ 4. Save to `workflows/` — ready to `ao run`
166
+
167
+ Supports `--provider` and `--model` flags (default: DeepSeek).
168
+
153
169
  ### Condition Branching
154
170
 
155
171
  ```yaml
@@ -160,7 +176,7 @@ analyze ──→ tech_review ──→ summary
160
176
  condition: "{{job_type}} contains technical"
161
177
 
162
178
  - id: biz_path
163
- role: "marketing/marketing-strategist"
179
+ role: "marketing/marketing-social-media-strategist"
164
180
  task: "Business evaluation: {{requirements}}"
165
181
  depends_on: [classify]
166
182
  condition: "{{job_type}} contains business"
@@ -176,12 +192,12 @@ Supported operators: `contains`, `equals`, `not_contains`, `not_equals`.
176
192
 
177
193
  ```yaml
178
194
  - id: write_draft
179
- role: "content/content-creator"
195
+ role: "marketing/marketing-content-creator"
180
196
  task: "Write article: {{topic}}"
181
197
  output: draft
182
198
 
183
199
  - id: brand_review
184
- role: "marketing/brand-guardian"
200
+ role: "design/design-brand-guardian"
185
201
  task: "Review brand compliance: {{draft}}"
186
202
  output: review_result
187
203
  depends_on: [write_draft]
@@ -238,6 +254,7 @@ All providers support custom `base_url` and `api_key`, compatible with any OpenA
238
254
  ```bash
239
255
  ao init # Download 186 AI roles
240
256
  ao init --workflow # Interactive workflow creator
257
+ ao compose "description" # AI-powered workflow generation
241
258
  ao run <workflow.yaml> [options] # Execute workflow
242
259
  ao validate <workflow.yaml> # Validate without running
243
260
  ao plan <workflow.yaml> # Show execution plan (DAG)
package/README.zh-CN.md CHANGED
@@ -200,6 +200,7 @@ analyze ──→ tech_review ──→ summary
200
200
  ```bash
201
201
  ao init # 下载 186 个 AI 角色
202
202
  ao init --workflow # 交互式创建工作流
203
+ ao compose "一句话描述" # AI 智能编排工作流
203
204
  ao run <workflow.yaml> [选项] # 执行工作流
204
205
  ao validate <workflow.yaml> # 校验(不执行)
205
206
  ao plan <workflow.yaml> # 查看执行计划(DAG)
@@ -217,6 +218,22 @@ ao roles # 列出所有角色
217
218
  | `--watch` | 实时终端进度显示 |
218
219
  | `--quiet` | 静默模式 |
219
220
 
221
+ ### AI 智能编排(Compose)
222
+
223
+ 一句话描述需求,AI 自动从 186 个角色中选角色、设计 DAG、生成完整 workflow YAML:
224
+
225
+ ```bash
226
+ ao compose "PR 代码审查,要覆盖安全和性能"
227
+ ```
228
+
229
+ AI 会自动:
230
+ 1. 从 186 角色中匹配出 Code Reviewer、Security Engineer、Performance Benchmarker
231
+ 2. 设计 DAG(三路并行 → 汇总)
232
+ 3. 生成带 `depends_on`、变量串联的完整 YAML
233
+ 4. 保存到 `workflows/` — 直接 `ao run` 就能跑
234
+
235
+ 支持 `--provider` 和 `--model` 参数(默认使用 DeepSeek)。
236
+
220
237
  ### 迭代优化(Resume)
221
238
 
222
239
  **问题**:`ao run` 跑完一轮后,所有步骤的输出都丢了。想基于叙事学家的结构重写小说,只能整个工作流从头跑。
@@ -82,6 +82,7 @@ export function listAgents(agentsDir) {
82
82
  const rolePath = `${dept.name}/${file.name.replace('.md', '')}`;
83
83
  try {
84
84
  const agent = loadAgent(agentsDir, rolePath);
85
+ agent.rolePath = rolePath;
85
86
  agents.push(agent);
86
87
  }
87
88
  catch {
@@ -0,0 +1,43 @@
1
+ import type { LLMConfig } from '../types.js';
2
+ /** 精简的角色摘要,供 LLM 选角色用 */
3
+ export interface RoleSummary {
4
+ path: string;
5
+ name: string;
6
+ description: string;
7
+ category: string;
8
+ }
9
+ /**
10
+ * 从 agents 目录构建精简的角色目录
11
+ */
12
+ export declare function buildRoleCatalog(agentsDir: string): RoleSummary[];
13
+ /**
14
+ * 格式化角色目录为紧凑文本(给 LLM 看)
15
+ */
16
+ export declare function formatCatalogForPrompt(roles: RoleSummary[]): string;
17
+ /**
18
+ * 构建发给 LLM 的 system prompt
19
+ */
20
+ export declare function buildComposeSystemPrompt(catalog: string): string;
21
+ /**
22
+ * 构建 user prompt
23
+ */
24
+ export declare function buildComposeUserPrompt(description: string): string;
25
+ /**
26
+ * 从 LLM 回复中提取 YAML 内容
27
+ */
28
+ export declare function extractYamlFromResponse(response: string): string;
29
+ /**
30
+ * 根据描述生成文件名
31
+ */
32
+ export declare function generateFileName(description: string): string;
33
+ /**
34
+ * 执行 compose 流程
35
+ */
36
+ export declare function composeWorkflow(options: {
37
+ description: string;
38
+ agentsDir: string;
39
+ llmConfig: LLMConfig;
40
+ }): Promise<{
41
+ yaml: string;
42
+ savedPath: string;
43
+ }>;
@@ -0,0 +1,210 @@
1
+ /**
2
+ * ao compose — AI 智能编排工作流
3
+ *
4
+ * 用户用一句话描述需求,AI 从 186 个角色中选角色、设计 DAG、生成完整 workflow YAML。
5
+ */
6
+ import { listAgents } from '../agents/loader.js';
7
+ import { existsSync, writeFileSync, mkdirSync } from 'node:fs';
8
+ import { resolve } from 'node:path';
9
+ /**
10
+ * 从 agents 目录构建精简的角色目录
11
+ */
12
+ export function buildRoleCatalog(agentsDir) {
13
+ const agents = listAgents(agentsDir);
14
+ return agents
15
+ .filter(a => a.rolePath) // 只保留有路径的
16
+ .map(a => ({
17
+ path: a.rolePath,
18
+ name: a.name,
19
+ description: a.description || '',
20
+ category: a.rolePath.split('/')[0],
21
+ }));
22
+ }
23
+ /**
24
+ * 格式化角色目录为紧凑文本(给 LLM 看)
25
+ */
26
+ export function formatCatalogForPrompt(roles) {
27
+ const byCategory = new Map();
28
+ for (const r of roles) {
29
+ const list = byCategory.get(r.category) || [];
30
+ list.push(r);
31
+ byCategory.set(r.category, list);
32
+ }
33
+ const lines = [];
34
+ for (const [cat, list] of byCategory) {
35
+ lines.push(`## ${cat}`);
36
+ for (const r of list) {
37
+ lines.push(`- ${r.path} | ${r.name} | ${r.description}`);
38
+ }
39
+ lines.push('');
40
+ }
41
+ return lines.join('\n');
42
+ }
43
+ /**
44
+ * 构建发给 LLM 的 system prompt
45
+ */
46
+ export function buildComposeSystemPrompt(catalog) {
47
+ return `你是一个 AI 工作流编排专家。用户会用一句话描述他想要的工作流,你需要:
48
+
49
+ 1. 从下方角色目录中选择最合适的角色(通常 2-6 个)
50
+ 2. 设计合理的 DAG 依赖关系(哪些步骤可以并行,哪些必须串行)
51
+ 3. 为每个步骤编写详细的 task 描述
52
+ 4. 设计合理的输入变量
53
+ 5. 生成完整的 workflow YAML
54
+
55
+ ## 输出格式
56
+
57
+ 直接输出一个完整的 YAML 代码块,格式如下:
58
+
59
+ \`\`\`yaml
60
+ name: "工作流名称"
61
+ description: "一句话描述"
62
+
63
+ agents_dir: "agency-agents-zh"
64
+
65
+ llm:
66
+ provider: deepseek
67
+ model: deepseek-chat
68
+ max_tokens: 4096
69
+
70
+ concurrency: 2
71
+
72
+ inputs:
73
+ - name: variable_name
74
+ description: "变量描述"
75
+ required: true
76
+
77
+ steps:
78
+ - id: step_id
79
+ role: "category/role-name"
80
+ task: |
81
+ 详细的任务描述...
82
+ 使用 {{variable_name}} 引用输入变量
83
+ 使用 {{previous_output}} 引用上游步骤的输出
84
+ output: output_variable_name
85
+ depends_on: [upstream_step_id] # 仅在有依赖时添加
86
+ \`\`\`
87
+
88
+ ## 设计原则
89
+
90
+ - **并行优先**:没有数据依赖的步骤应该并行执行(不加 depends_on)
91
+ - **变量串联**:上游步骤的 output 变量名要和下游步骤 task 中的 {{变量}} 对应
92
+ - **角色匹配**:选择最专业的角色,不要用一个角色做所有事
93
+ - **任务详细**:task 描述要具体,告诉角色要做什么、输出什么格式
94
+ - **合理输入**:提取用户需求中的关键变量作为 inputs
95
+ - **最终汇总**:如果有多路并行,最后应该有一个汇总步骤
96
+
97
+ ## 可用角色目录
98
+
99
+ ${catalog}
100
+
101
+ ## 注意
102
+
103
+ - role 的值必须严格使用角色目录中的 path(如 "engineering/engineering-code-reviewer"),不要自己编造
104
+ - 只输出 YAML 代码块,不要输出其他内容
105
+ - concurrency 设为并行步骤的最大数量`;
106
+ }
107
+ /**
108
+ * 构建 user prompt
109
+ */
110
+ export function buildComposeUserPrompt(description) {
111
+ return `请为以下需求设计一个多智能体协作工作流:
112
+
113
+ ${description}`;
114
+ }
115
+ /**
116
+ * 从 LLM 回复中提取 YAML 内容
117
+ */
118
+ export function extractYamlFromResponse(response) {
119
+ // 尝试从 ```yaml ... ``` 代码块中提取
120
+ const yamlBlock = response.match(/```ya?ml\s*\n([\s\S]*?)```/);
121
+ if (yamlBlock)
122
+ return yamlBlock[1].trim();
123
+ // 尝试从 ``` ... ``` 代码块中提取
124
+ const codeBlock = response.match(/```\s*\n([\s\S]*?)```/);
125
+ if (codeBlock)
126
+ return codeBlock[1].trim();
127
+ // 没有代码块,整个回复当 YAML
128
+ return response.trim();
129
+ }
130
+ /**
131
+ * 根据描述生成文件名
132
+ */
133
+ export function generateFileName(description) {
134
+ const cleaned = description
135
+ .replace(/[^\u4e00-\u9fffa-zA-Z0-9\s-]/g, '')
136
+ .trim()
137
+ .slice(0, 40)
138
+ .toLowerCase()
139
+ .replace(/\s+/g, '-')
140
+ .replace(/^-|-$/g, '');
141
+ return (cleaned || 'composed-workflow') + '.yaml';
142
+ }
143
+ /**
144
+ * 创建 LLM connector(动态导入)
145
+ */
146
+ async function createConnector(config) {
147
+ switch (config.provider) {
148
+ case 'deepseek': {
149
+ const { OpenAICompatibleConnector } = await import('../connectors/openai-compatible.js');
150
+ return new OpenAICompatibleConnector({
151
+ apiKey: config.api_key || process.env.DEEPSEEK_API_KEY,
152
+ baseUrl: config.base_url || 'https://api.deepseek.com/v1',
153
+ });
154
+ }
155
+ case 'openai': {
156
+ const { OpenAICompatibleConnector } = await import('../connectors/openai-compatible.js');
157
+ return new OpenAICompatibleConnector({
158
+ apiKey: config.api_key || process.env.OPENAI_API_KEY,
159
+ baseUrl: config.base_url || 'https://api.openai.com/v1',
160
+ });
161
+ }
162
+ case 'claude': {
163
+ const { ClaudeConnector } = await import('../connectors/claude.js');
164
+ return new ClaudeConnector(config.api_key);
165
+ }
166
+ case 'ollama': {
167
+ const { OllamaConnector } = await import('../connectors/ollama.js');
168
+ return new OllamaConnector(config.base_url);
169
+ }
170
+ default:
171
+ throw new Error(`不支持的 provider: ${config.provider}`);
172
+ }
173
+ }
174
+ /**
175
+ * 执行 compose 流程
176
+ */
177
+ export async function composeWorkflow(options) {
178
+ const { description, agentsDir, llmConfig } = options;
179
+ // 1. 构建角色目录
180
+ const roles = buildRoleCatalog(agentsDir);
181
+ if (roles.length === 0) {
182
+ throw new Error(`角色目录为空: ${agentsDir}\n请先运行 ao init 下载角色定义`);
183
+ }
184
+ const catalog = formatCatalogForPrompt(roles);
185
+ // 2. 构建 prompt
186
+ const systemPrompt = buildComposeSystemPrompt(catalog);
187
+ const userPrompt = buildComposeUserPrompt(description);
188
+ // 3. 调用 LLM
189
+ console.log(` 正在用 AI 编排工作流...(${roles.length} 个角色可选)\n`);
190
+ const connector = await createConnector(llmConfig);
191
+ const result = await connector.chat(systemPrompt, userPrompt, {
192
+ ...llmConfig,
193
+ max_tokens: llmConfig.max_tokens || 4096,
194
+ });
195
+ // 4. 提取 YAML
196
+ const yaml = extractYamlFromResponse(result.content);
197
+ if (!yaml || !yaml.includes('steps:')) {
198
+ throw new Error('AI 生成的内容不是有效的 workflow YAML,请重试或调整描述');
199
+ }
200
+ // 5. 保存
201
+ const fileName = generateFileName(description);
202
+ const workflowsDir = resolve('workflows');
203
+ if (!existsSync(workflowsDir)) {
204
+ mkdirSync(workflowsDir, { recursive: true });
205
+ }
206
+ const savedPath = resolve(workflowsDir, fileName);
207
+ writeFileSync(savedPath, yaml + '\n', 'utf-8');
208
+ console.log(` Token 用量: 输入 ${result.usage.input_tokens}, 输出 ${result.usage.output_tokens}`);
209
+ return { yaml, savedPath };
210
+ }
@@ -34,7 +34,7 @@ function buildLayers(steps) {
34
34
  remaining.delete(s.id);
35
35
  for (const [id, depList] of deps) {
36
36
  if (depList.includes(s.id)) {
37
- inDegree.set(id, (inDegree.get(id) || 1) - 1);
37
+ inDegree.set(id, (inDegree.get(id) ?? 0) - 1);
38
38
  }
39
39
  }
40
40
  }
@@ -77,10 +77,12 @@ export function explainWorkflow(workflow) {
77
77
  for (const step of layer.steps) {
78
78
  const role = formatRole(step.role);
79
79
  // 取 task 的第一行作为摘要
80
- const taskSummary = (step.task || '').split('\n')[0].trim().slice(0, 60);
80
+ const firstLine = (step.task || '').split('\n')[0].trim();
81
+ const taskSummary = firstLine.slice(0, 60);
82
+ const truncated = firstLine.length > 60 || (step.task || '').includes('\n');
81
83
  lines.push(` • ${step.id} (${role})`);
82
84
  if (taskSummary) {
83
- lines.push(` ${taskSummary}${(step.task || '').length > 60 ? '...' : ''}`);
85
+ lines.push(` ${taskSummary}${truncated ? '...' : ''}`);
84
86
  }
85
87
  // 标注条件
86
88
  if (step.condition) {
@@ -96,7 +98,7 @@ export function explainWorkflow(workflow) {
96
98
  }
97
99
  // 汇总
98
100
  const totalSteps = workflow.steps.length;
99
- const maxParallel = Math.max(...layers.map(l => l.steps.length));
101
+ const maxParallel = layers.length > 0 ? Math.max(...layers.map(l => l.steps.length)) : 0;
100
102
  const hasLoop = workflow.steps.some(s => s.loop);
101
103
  const hasCondition = workflow.steps.some(s => s.condition);
102
104
  lines.push(`总计 ${totalSteps} 个步骤,${layers.length} 层执行,最大并行度 ${maxParallel}。`);
@@ -4,10 +4,14 @@
4
4
  import { createInterface } from 'readline';
5
5
  import { writeFileSync, mkdirSync, existsSync } from 'fs';
6
6
  import { resolve } from 'path';
7
+ /** Escape double quotes for YAML string values */
8
+ function yamlEscape(s) {
9
+ return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
10
+ }
7
11
  export function generateWorkflowYaml(opts) {
8
12
  const lines = [
9
- `name: "${opts.name}"`,
10
- `description: "${opts.description}"`,
13
+ `name: "${yamlEscape(opts.name)}"`,
14
+ `description: "${yamlEscape(opts.description)}"`,
11
15
  '',
12
16
  'agents_dir: "agency-agents-zh"',
13
17
  '',
@@ -21,22 +25,27 @@ export function generateWorkflowYaml(opts) {
21
25
  if (opts.hasInputs && opts.inputs.length > 0) {
22
26
  lines.push('', 'inputs:');
23
27
  for (const input of opts.inputs) {
24
- lines.push(` - name: ${input.name}`);
25
- lines.push(` description: "${input.description}"`);
28
+ lines.push(` - name: "${yamlEscape(input.name)}"`);
29
+ lines.push(` description: "${yamlEscape(input.description)}"`);
26
30
  lines.push(` required: ${input.required}`);
27
31
  }
28
32
  }
29
33
  lines.push('', 'steps:');
30
34
  for (let i = 0; i < opts.roles.length; i++) {
31
35
  const step = opts.roles[i];
32
- lines.push(` - id: ${step.id}`);
33
- lines.push(` role: "${step.role}"`);
34
- lines.push(` task: |`);
35
- // Indent task lines for YAML block scalar
36
- for (const taskLine of step.task.split('\n')) {
37
- lines.push(` ${taskLine}`);
36
+ lines.push(` - id: "${yamlEscape(step.id)}"`);
37
+ lines.push(` role: "${yamlEscape(step.role)}"`);
38
+ // 单行 task 用引号,多行用 block scalar
39
+ if (step.task.includes('\n')) {
40
+ lines.push(` task: |`);
41
+ for (const taskLine of step.task.split('\n')) {
42
+ lines.push(` ${taskLine}`);
43
+ }
44
+ }
45
+ else {
46
+ lines.push(` task: "${yamlEscape(step.task)}"`);
38
47
  }
39
- lines.push(` output: ${step.output}`);
48
+ lines.push(` output: "${yamlEscape(step.output)}"`);
40
49
  if (i > 0) {
41
50
  lines.push(` depends_on: [${opts.roles[i - 1].id}]`);
42
51
  }
package/dist/cli/watch.js CHANGED
@@ -6,7 +6,7 @@ const ICONS = {
6
6
  running: '🔄',
7
7
  done: '✅',
8
8
  error: '❌',
9
- skipped: '⏭️',
9
+ skipped: '',
10
10
  };
11
11
  /**
12
12
  * 创建 watch 渲染器,返回 ProgressCallback
@@ -50,7 +50,9 @@ export function createWatchRenderer(workflowName, stepIds, roles) {
50
50
  lines.push(line);
51
51
  }
52
52
  lines.push(`│${''.padEnd(boxWidth - 2)}│`);
53
- lines.push(`│ Progress: ${bar} ${completed}/${total} ${elapsed}s${''.padEnd(Math.max(0, boxWidth - 38 - elapsed.length))}│`);
53
+ const progressContent = `Progress: ${bar} ${completed}/${total} ${elapsed}s`;
54
+ const progressPad = Math.max(0, boxWidth - 4 - progressContent.length);
55
+ lines.push(`│ ${progressContent}${''.padEnd(progressPad)} │`);
54
56
  lines.push(`└${'─'.repeat(boxWidth - 2)}┘`);
55
57
  // 写到 stderr 避免与正常输出混合
56
58
  for (const line of lines) {
package/dist/cli.js CHANGED
@@ -41,13 +41,16 @@ async function main() {
41
41
  case 'explain':
42
42
  await handleExplain();
43
43
  break;
44
+ case 'compose':
45
+ await handleCompose();
46
+ break;
44
47
  case '--version':
45
48
  case '-v':
46
49
  console.log(getVersion());
47
50
  break;
48
51
  default: {
49
52
  // 容错:用户可能漏了空格,如 "planworkflows/x.yaml"
50
- const knownCmds = ['run', 'validate', 'plan', 'explain', 'roles'];
53
+ const knownCmds = ['run', 'validate', 'plan', 'explain', 'compose', 'roles', 'init'];
51
54
  const match = knownCmds.find(c => command.startsWith(c) && command.length > c.length);
52
55
  if (match) {
53
56
  console.error(`看起来少了个空格?试试:\n ao ${match} ${command.slice(match.length)}\n`);
@@ -166,6 +169,53 @@ async function handleExplain() {
166
169
  process.exit(1);
167
170
  }
168
171
  }
172
+ async function handleCompose() {
173
+ const description = args[1];
174
+ if (!description) {
175
+ console.error('用法: ao compose "用一句话描述你想要的工作流"');
176
+ console.error('');
177
+ console.error('示例:');
178
+ console.error(' ao compose "PR 代码审查,要覆盖安全和性能"');
179
+ console.error(' ao compose "写一篇技术博客,需要调研、写稿、审校"');
180
+ console.error(' ao compose "用户反馈分析,分类后分别给产品和技术团队"');
181
+ console.error('');
182
+ console.error('选项:');
183
+ console.error(' --provider <name> LLM 提供商 (默认 deepseek)');
184
+ console.error(' --model <name> 模型名 (默认 deepseek-chat)');
185
+ process.exit(1);
186
+ }
187
+ const provider = (getArgValue('--provider') || 'deepseek');
188
+ const model = getArgValue('--model') || (provider === 'deepseek' ? 'deepseek-chat' : provider === 'claude' ? 'claude-sonnet-4-20250514' : 'gpt-4o');
189
+ const agentsDir = getArgValue('--agents-dir') || resolveAgentsDir();
190
+ try {
191
+ const { composeWorkflow } = await import('./cli/compose.js');
192
+ const { yaml, savedPath } = await composeWorkflow({
193
+ description,
194
+ agentsDir: resolve(agentsDir),
195
+ llmConfig: { provider, model },
196
+ });
197
+ console.log(`\n ✅ 工作流已生成: ${savedPath}\n`);
198
+ console.log(' 预览:');
199
+ // 显示前 30 行
200
+ const previewLines = yaml.split('\n').slice(0, 30);
201
+ for (const line of previewLines) {
202
+ console.log(` ${line}`);
203
+ }
204
+ if (yaml.split('\n').length > 30) {
205
+ console.log(' ...');
206
+ }
207
+ console.log('');
208
+ console.log(' 接下来可以:');
209
+ console.log(` ao plan ${savedPath} 查看执行计划`);
210
+ console.log(` ao validate ${savedPath} 校验工作流`);
211
+ console.log(` ao run ${savedPath} 运行工作流`);
212
+ console.log('');
213
+ }
214
+ catch (err) {
215
+ console.error(`\n错误: ${err instanceof Error ? err.message : err}`);
216
+ process.exit(1);
217
+ }
218
+ }
169
219
  async function handleInit() {
170
220
  // ao init --workflow: 交互式创建工作流
171
221
  if (args.includes('--workflow')) {
@@ -302,6 +352,7 @@ function printHelp() {
302
352
  Commands:
303
353
  init 下载/更新 agency-agents-zh
304
354
  init --workflow 交互式创建新工作流
355
+ compose "描述" AI 智能编排工作流(一句话生成 YAML)
305
356
  run <workflow.yaml> 执行工作流
306
357
  validate <workflow.yaml> 校验工作流定义
307
358
  plan <workflow.yaml> 查看执行计划
@@ -320,6 +371,7 @@ function printHelp() {
320
371
 
321
372
  Examples:
322
373
  ao init
374
+ ao compose "PR 代码审查,覆盖安全和性能"
323
375
  ao run workflows/story-creation.yaml -i premise='一个时间旅行的故事' -i style='悬疑'
324
376
  ao run workflows/product-review.yaml -i prd_content=@prd.md
325
377
  ao plan workflows/content-pipeline.yaml
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ export { ClaudeConnector } from './connectors/claude.js';
14
14
  export { OllamaConnector } from './connectors/ollama.js';
15
15
  export { OpenAICompatibleConnector } from './connectors/openai-compatible.js';
16
16
  export { saveResults, loadPreviousContext, findLatestOutput } from './output/reporter.js';
17
+ export { composeWorkflow, buildRoleCatalog, extractYamlFromResponse } from './cli/compose.js';
17
18
  export type { WorkflowDefinition, StepDefinition, LLMConfig, LLMConnector, LLMResult, AgentDefinition, WorkflowResult, StepResult, DAGNode, } from './types.js';
18
19
  /**
19
20
  * 一行运行工作流(高级 API)
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ export { ClaudeConnector } from './connectors/claude.js';
14
14
  export { OllamaConnector } from './connectors/ollama.js';
15
15
  export { OpenAICompatibleConnector } from './connectors/openai-compatible.js';
16
16
  export { saveResults, loadPreviousContext, findLatestOutput } from './output/reporter.js';
17
+ export { composeWorkflow, buildRoleCatalog, extractYamlFromResponse } from './cli/compose.js';
17
18
  import { parseWorkflow, validateWorkflow } from './core/parser.js';
18
19
  import { buildDAG } from './core/dag.js';
19
20
  import { executeDAG } from './core/executor.js';
package/dist/types.d.ts CHANGED
@@ -71,6 +71,7 @@ export interface AgentDefinition {
71
71
  description: string;
72
72
  emoji?: string;
73
73
  tools?: string;
74
+ rolePath?: string;
74
75
  systemPrompt: string;
75
76
  }
76
77
  /** 执行结果 */
@@ -5,18 +5,25 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 将 AGENTS.md 复制到项目根目录
13
- cp integrations/antigravity/AGENTS.md AGENTS.md
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
15
+ cp .ao-tmp/integrations/antigravity/AGENTS.md ./AGENTS.md
16
+ rm -rf .ao-tmp
17
+
18
+ # 3. 开始使用
19
+ # 在 Antigravity 中直接说:运行 workflows/story-creation.yaml
14
20
  ```
15
21
 
16
- 如果项目根目录已有 `AGENTS.md`,将内容追加:
22
+ 如果项目根目录已有 `AGENTS.md`,可将内容追加而非覆盖:
17
23
 
18
24
  ```bash
19
- cat integrations/antigravity/AGENTS.md >> AGENTS.md
25
+ # 替换上面第 2 步中的 cp 命令为:
26
+ cat .ao-tmp/integrations/antigravity/AGENTS.md >> ./AGENTS.md
20
27
  ```
21
28
 
22
29
  ## 使用方式
@@ -5,19 +5,26 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 复制 workflow-runner 指令到 .codex 目录
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
13
15
  mkdir -p .codex
14
- cp integrations/codex/instructions.md .codex/instructions.md
16
+ cp .ao-tmp/integrations/codex/instructions.md .codex/instructions.md
17
+ rm -rf .ao-tmp
18
+
19
+ # 3. 开始使用
20
+ # 在 Codex CLI 中直接说:运行 workflows/story-creation.yaml
15
21
  ```
16
22
 
17
- 如果 `.codex/instructions.md` 已存在,将内容追加:
23
+ 如果 `.codex/instructions.md` 已存在,可将内容追加而非覆盖:
18
24
 
19
25
  ```bash
20
- cat integrations/codex/instructions.md >> .codex/instructions.md
26
+ # 替换上面第 2 步中的 cp 命令为:
27
+ cat .ao-tmp/integrations/codex/instructions.md >> .codex/instructions.md
21
28
  ```
22
29
 
23
30
  ## 使用方式
@@ -5,16 +5,19 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义到项目
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 复制工作流模板
13
- git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp && cp -r .ao-tmp/workflows ./workflows && rm -rf .ao-tmp
14
-
15
- # 3. 添加工作流执行规则
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
16
15
  mkdir -p .cursor/rules
17
- cp agency-orchestrator/integrations/cursor/workflow-runner.mdc .cursor/rules/
16
+ cp .ao-tmp/integrations/cursor/workflow-runner.mdc .cursor/rules/
17
+ rm -rf .ao-tmp
18
+
19
+ # 3. 开始使用
20
+ # 在 Cursor 中直接说:运行 workflows/story-creation.yaml
18
21
  ```
19
22
 
20
23
  ## 使用方式
@@ -87,11 +90,11 @@ ao run workflows/story-creation.yaml -i 'premise=时间旅行'
87
90
 
88
91
  ## 可用工作流
89
92
 
90
- | 工作流 | 说明 | 角色 |
93
+ | 工作流 | 文件 | 说明 |
91
94
  |--------|------|------|
92
- | `story-creation.yaml` | 短篇小说创作 | 叙事学家 → 心理学家 + 叙事设计师 → 内容创作者 |
93
- | `product-review.yaml` | 产品需求评审 | 产品经理 → 架构师 + UX 研究员 → 产品经理 |
94
- | `content-pipeline.yaml` | 内容创作流水线 | 策略师 → 创作者 + SEO → 编辑 |
95
+ | 短篇小说创作 | `story-creation.yaml` | 叙事学家 → 心理学家 + 叙事设计师 → 内容创作者 |
96
+ | 产品需求评审 | `product-review.yaml` | 产品经理 → 架构师 + UX 研究员 → 产品经理 |
97
+ | 内容流水线 | `content-pipeline.yaml` | 策略师 → 创作者 + SEO → 编辑 |
95
98
 
96
99
  ## 自定义
97
100
 
@@ -5,13 +5,19 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 将 SKILL.md 复制到 DeerFlow 的自定义技能目录
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
13
15
  mkdir -p skills/custom/ao-workflow-runner
14
- cp integrations/deerflow/SKILL.md skills/custom/ao-workflow-runner/SKILL.md
16
+ cp .ao-tmp/integrations/deerflow/SKILL.md skills/custom/ao-workflow-runner/SKILL.md
17
+ rm -rf .ao-tmp
18
+
19
+ # 3. 开始使用
20
+ # 在 DeerFlow 中直接说:运行 workflows/story-creation.yaml
15
21
  ```
16
22
 
17
23
  ## 使用方式
@@ -5,18 +5,25 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 将 workflow-runner 指令追加到项目根目录的 GEMINI.md
13
- cat integrations/gemini-cli/GEMINI.md >> GEMINI.md
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
15
+ cp .ao-tmp/integrations/gemini-cli/GEMINI.md ./GEMINI.md
16
+ rm -rf .ao-tmp
17
+
18
+ # 3. 开始使用
19
+ # 在 Gemini CLI 中直接说:运行 workflows/story-creation.yaml
14
20
  ```
15
21
 
16
- 如果项目根目录还没有 `GEMINI.md`,直接复制即可:
22
+ 如果项目根目录已有 `GEMINI.md`,可将内容追加而非覆盖:
17
23
 
18
24
  ```bash
19
- cp integrations/gemini-cli/GEMINI.md GEMINI.md
25
+ # 替换上面第 2 步中的 cp 命令为:
26
+ cat .ao-tmp/integrations/gemini-cli/GEMINI.md >> ./GEMINI.md
20
27
  ```
21
28
 
22
29
  ## 使用方式
@@ -5,16 +5,19 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义到项目
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 复制工作流模板
13
- git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp && cp -r .ao-tmp/workflows ./workflows && rm -rf .ao-tmp
14
-
15
- # 3. 添加工作流执行规则
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
16
15
  mkdir -p .kiro/steering
17
- cp agency-orchestrator/integrations/kiro/ao-workflow-runner.md .kiro/steering/
16
+ cp .ao-tmp/integrations/kiro/ao-workflow-runner.md .kiro/steering/
17
+ rm -rf .ao-tmp
18
+
19
+ # 3. 开始使用
20
+ # 在 Kiro 中直接说:运行 workflows/story-creation.yaml
18
21
  ```
19
22
 
20
23
  ## 使用方式
@@ -5,16 +5,19 @@
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- # 1. 安装角色定义到项目
8
+ # 1. 下载 186 个 AI 角色
9
9
  cd your-project
10
10
  git clone --depth 1 https://github.com/jnMetaCode/agency-agents-zh.git
11
11
 
12
- # 2. 复制工作流模板
13
- git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp && cp -r .ao-tmp/workflows ./workflows && rm -rf .ao-tmp
14
-
15
- # 3. 添加工作流执行规则
12
+ # 2. 下载工作流模板和技能文件
13
+ git clone --depth 1 https://github.com/jnMetaCode/agency-orchestrator.git .ao-tmp
14
+ cp -r .ao-tmp/workflows ./workflows
16
15
  mkdir -p .trae/rules
17
- cp agency-orchestrator/integrations/trae/ao-workflow-runner.md .trae/rules/
16
+ cp .ao-tmp/integrations/trae/ao-workflow-runner.md .trae/rules/
17
+ rm -rf .ao-tmp
18
+
19
+ # 3. 开始使用
20
+ # 在 Trae 中直接说:运行 workflows/story-creation.yaml
18
21
  ```
19
22
 
20
23
  ## 使用方式
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agency-orchestrator",
3
- "version": "0.3.0",
4
- "description": "Multi-agent workflow orchestrator — 186 ready-to-use AI roles, YAML-defined pipelines, auto DAG parallelism, zero code required",
3
+ "version": "0.3.2",
4
+ "description": "Multi-agent workflow orchestrator — 186 AI roles, YAML pipelines, auto DAG parallelism, AI-powered workflow composer",
5
5
  "keywords": [
6
6
  "multi-agent",
7
7
  "ai-agents",
@@ -44,7 +44,7 @@
44
44
  "scripts": {
45
45
  "build": "tsc",
46
46
  "dev": "tsc --watch",
47
- "test": "npx tsx test/run.ts && npx tsx test/condition.ts && npx tsx test/cli.ts && npx tsx test/e2e.ts && npx tsx test/e2e-condition.ts && npx tsx test/e2e-loop.ts",
47
+ "test": "npx tsx test/run.ts && npx tsx test/condition.ts && npx tsx test/cli.ts && npx tsx test/compose.ts && npx tsx test/e2e.ts && npx tsx test/e2e-condition.ts && npx tsx test/e2e-loop.ts",
48
48
  "prepublishOnly": "npm run build"
49
49
  },
50
50
  "files": [