agency-orchestrator 0.6.10 → 0.6.12
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/dist/cli/compose.js
CHANGED
|
@@ -700,12 +700,15 @@ inputs: ${inputNames.length > 0 ? inputNames.join('、') : '(无)'}
|
|
|
700
700
|
});
|
|
701
701
|
const fixedYaml = extractYamlFromResponse(result.content);
|
|
702
702
|
if (!fixedYaml || !fixedYaml.includes('steps:')) {
|
|
703
|
+
process.stderr.write(' ⚠️ LLM 二次修复返回的内容不是有效 YAML,保留原文件\n');
|
|
703
704
|
return { ok: false, replaced: false };
|
|
704
705
|
}
|
|
705
706
|
writeFileSync(yamlPath, fixedYaml + '\n', 'utf-8');
|
|
706
707
|
return { ok: true, replaced: true };
|
|
707
708
|
}
|
|
708
|
-
catch {
|
|
709
|
+
catch (err) {
|
|
710
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
711
|
+
process.stderr.write(` ⚠️ LLM 二次修复调用失败: ${msg.slice(0, 120)}\n`);
|
|
709
712
|
return { ok: false, replaced: false };
|
|
710
713
|
}
|
|
711
714
|
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* 安装: curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
|
|
6
6
|
* 文档: https://hermes-agent.nousresearch.com/
|
|
7
7
|
*
|
|
8
|
-
* 使用 hermes
|
|
8
|
+
* 使用 hermes -z "prompt" 的 oneshot 模式(非交互式)
|
|
9
|
+
* 旧版 hermes chat -q 已废弃,详见 issue #14
|
|
9
10
|
* 支持 --model 指定模型(如 anthropic/claude-sonnet-4、openai/gpt-4o 等)
|
|
10
11
|
*/
|
|
11
12
|
import { CLIBaseConnector } from './cli-base.js';
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* 安装: curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
|
|
6
6
|
* 文档: https://hermes-agent.nousresearch.com/
|
|
7
7
|
*
|
|
8
|
-
* 使用 hermes
|
|
8
|
+
* 使用 hermes -z "prompt" 的 oneshot 模式(非交互式)
|
|
9
|
+
* 旧版 hermes chat -q 已废弃,详见 issue #14
|
|
9
10
|
* 支持 --model 指定模型(如 anthropic/claude-sonnet-4、openai/gpt-4o 等)
|
|
10
11
|
*/
|
|
11
12
|
import { CLIBaseConnector } from './cli-base.js';
|
|
@@ -16,7 +17,7 @@ export class HermesCLIConnector extends CLIBaseConnector {
|
|
|
16
17
|
displayName: 'Hermes Agent CLI',
|
|
17
18
|
installHint: 'curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash',
|
|
18
19
|
buildArgs: (prompt, config) => {
|
|
19
|
-
const args = ['
|
|
20
|
+
const args = ['-z', prompt];
|
|
20
21
|
if (config.model) {
|
|
21
22
|
args.push('--model', config.model);
|
|
22
23
|
}
|
package/dist/core/parser.js
CHANGED
|
@@ -62,6 +62,41 @@ export function parseWorkflow(filePath) {
|
|
|
62
62
|
export function validateWorkflow(workflow) {
|
|
63
63
|
const errors = [];
|
|
64
64
|
const stepIds = new Set(workflow.steps.map(s => s.id));
|
|
65
|
+
const stepById = new Map(workflow.steps.map(s => [s.id, s]));
|
|
66
|
+
// step.output 唯一性检查:两个 step 不能 output 到同一个变量名
|
|
67
|
+
// 否则下游引用拿到的值取决于 context Map 的写入顺序,不可预期
|
|
68
|
+
const outputToSteps = new Map();
|
|
69
|
+
for (const step of workflow.steps) {
|
|
70
|
+
if (!step.output)
|
|
71
|
+
continue;
|
|
72
|
+
const owners = outputToSteps.get(step.output) || [];
|
|
73
|
+
owners.push(step.id);
|
|
74
|
+
outputToSteps.set(step.output, owners);
|
|
75
|
+
}
|
|
76
|
+
for (const [outName, owners] of outputToSteps) {
|
|
77
|
+
if (owners.length > 1) {
|
|
78
|
+
errors.push(`output 变量 "${outName}" 被多个 step 同时产出: ${owners.join(', ')}(重名会让下游引用结果不确定)`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// 计算每个 step 的 DAG 上游 step ids(递归 depends_on 闭包,不含自身)。
|
|
82
|
+
// 用于校验"变量必须来自 inputs 或当前 step 的上游"——和 autoFix 的拓扑约束保持一致
|
|
83
|
+
function upstreamStepIds(stepId) {
|
|
84
|
+
const out = new Set();
|
|
85
|
+
const stack = [stepId];
|
|
86
|
+
while (stack.length > 0) {
|
|
87
|
+
const cur = stack.pop();
|
|
88
|
+
const step = stepById.get(cur);
|
|
89
|
+
if (!step)
|
|
90
|
+
continue;
|
|
91
|
+
for (const dep of step.depends_on || []) {
|
|
92
|
+
if (out.has(dep))
|
|
93
|
+
continue;
|
|
94
|
+
out.add(dep);
|
|
95
|
+
stack.push(dep);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
65
100
|
for (const step of workflow.steps) {
|
|
66
101
|
// 检查 depends_on 引用
|
|
67
102
|
if (step.depends_on) {
|
|
@@ -92,17 +127,55 @@ export function validateWorkflow(workflow) {
|
|
|
92
127
|
errors.push(`step "${step.id}" 的 loop 缺少 exit_condition`);
|
|
93
128
|
}
|
|
94
129
|
}
|
|
95
|
-
// 检查 {{变量}}
|
|
96
|
-
|
|
130
|
+
// 检查 {{变量}} 引用:必须来自 inputs,或来自当前 step 的 DAG 上游 step.output
|
|
131
|
+
// (之前只检查"任意 step 是否产出该变量",让"早期 step 引用下游 output"这种
|
|
132
|
+
// 拓扑反向错误漏过 validate,到 run 阶段才崩。和 autoFix 的拓扑约束对齐)
|
|
133
|
+
// 范围: step.task / step.condition / step.loop.exit_condition / step.prompt
|
|
134
|
+
const refTexts = [];
|
|
135
|
+
if (step.task)
|
|
136
|
+
refTexts.push(step.task);
|
|
137
|
+
if (step.condition)
|
|
138
|
+
refTexts.push(step.condition);
|
|
139
|
+
if (step.loop?.exit_condition)
|
|
140
|
+
refTexts.push(step.loop.exit_condition);
|
|
141
|
+
if (step.prompt)
|
|
142
|
+
refTexts.push(step.prompt);
|
|
143
|
+
const varRefs = [];
|
|
144
|
+
for (const text of refTexts) {
|
|
145
|
+
const matches = text.match(/\{\{(\w+)\}\}/g) || [];
|
|
146
|
+
varRefs.push(...matches);
|
|
147
|
+
}
|
|
148
|
+
if (varRefs.length === 0)
|
|
149
|
+
continue;
|
|
150
|
+
const upStepIds = upstreamStepIds(step.id);
|
|
151
|
+
const upstreamOutputs = new Set();
|
|
152
|
+
for (const id of upStepIds) {
|
|
153
|
+
const s = stepById.get(id);
|
|
154
|
+
if (s?.output)
|
|
155
|
+
upstreamOutputs.add(s.output);
|
|
156
|
+
}
|
|
157
|
+
const reportedVars = new Set(); // 同 step 内同名变量只报一次
|
|
97
158
|
for (const ref of varRefs) {
|
|
98
159
|
const varName = ref.slice(2, -2);
|
|
99
|
-
|
|
160
|
+
if (varName === '_loop_iteration')
|
|
161
|
+
continue;
|
|
162
|
+
if (reportedVars.has(varName))
|
|
163
|
+
continue;
|
|
100
164
|
const inputDef = workflow.inputs?.find(i => i.name === varName);
|
|
101
|
-
|
|
102
|
-
|
|
165
|
+
if (inputDef)
|
|
166
|
+
continue;
|
|
167
|
+
if (upstreamOutputs.has(varName))
|
|
168
|
+
continue;
|
|
169
|
+
// 不在 inputs 也不在上游 outputs:错误
|
|
170
|
+
// 区分两种错误信息,方便 autoFix / repairWithLLM 处理
|
|
171
|
+
const producedBySomeStep = workflow.steps.some(s => s.output === varName);
|
|
172
|
+
if (producedBySomeStep) {
|
|
173
|
+
errors.push(`step "${step.id}" 引用了未定义的变量: {{${varName}}} (该变量由非上游 step 产出,需要把对应 step 加进 depends_on)`);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
103
176
|
errors.push(`step "${step.id}" 引用了未定义的变量: {{${varName}}}`);
|
|
104
177
|
}
|
|
105
|
-
|
|
178
|
+
reportedVars.add(varName);
|
|
106
179
|
}
|
|
107
180
|
}
|
|
108
181
|
// 检查循环依赖
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agency-orchestrator",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.12",
|
|
4
4
|
"description": "Multi-agent YAML workflow engine — 211 AI roles, auto DAG parallelism, zero code. One sentence → multiple AI roles collaborate → complete plan in minutes. 10 LLM providers, 7 need no API key.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multi-agent",
|