@ai-setting/roy-agent-core 1.7.49 → 1.7.51
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/config/index.js +7 -7
- package/dist/env/agent/index.js +10 -10
- package/dist/env/commands/index.js +7 -7
- package/dist/env/context/index.js +3 -3
- package/dist/env/debug/index.js +7 -7
- package/dist/env/event-source/index.js +17 -14
- package/dist/env/hook/index.js +9 -6
- package/dist/env/index.js +38 -34
- package/dist/env/llm/index.js +7 -7
- package/dist/env/log-trace/index.js +7 -7
- package/dist/env/mcp/index.js +7 -7
- package/dist/env/memory/index.js +11 -11
- package/dist/env/plugin/index.js +7 -7
- package/dist/env/prompt/index.js +8 -8
- package/dist/env/session/index.js +7 -7
- package/dist/env/skill/index.js +7 -7
- package/dist/env/task/delegate/index.js +8 -8
- package/dist/env/task/index.js +17 -17
- package/dist/env/task/plugins/index.js +10 -9
- package/dist/env/task/storage/index.js +2 -2
- package/dist/env/task/tools/index.js +3 -3
- package/dist/env/tool/built-in/index.js +2 -2
- package/dist/env/tool/index.js +8 -8
- package/dist/env/workflow/engine/index.js +12 -9
- package/dist/env/workflow/hooks/index.js +25 -0
- package/dist/env/workflow/index.js +19 -17
- package/dist/env/workflow/nodes/index.js +2 -2
- package/dist/env/workflow/plugins/index.js +18 -0
- package/dist/env/workflow/service/index.js +2 -2
- package/dist/env/workflow/storage/index.js +3 -3
- package/dist/env/workflow/tools/index.js +11 -11
- package/dist/env/workflow/utils/index.js +24 -4
- package/dist/index.js +79 -70
- package/dist/shared/@ai-setting/{roy-agent-core-3ajh3cdj.js → roy-agent-core-0cfaqnz9.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-trd6my5j.js → roy-agent-core-1cv9j4dg.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-48f17g3x.js → roy-agent-core-2gay3sjt.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-e302nvzt.js → roy-agent-core-2k4xffaa.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-1pjct4nj.js → roy-agent-core-35s1w7tc.js} +230 -96
- package/dist/shared/@ai-setting/{roy-agent-core-hqtp5m8v.js → roy-agent-core-39xejr39.js} +13 -13
- package/dist/shared/@ai-setting/{roy-agent-core-v6zdngr7.js → roy-agent-core-3tv1q6f2.js} +8 -8
- package/dist/shared/@ai-setting/{roy-agent-core-mqaht7mm.js → roy-agent-core-4z3rq5gw.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-fm77q3tn.js → roy-agent-core-5apmk4qw.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-xmfyt3dg.js → roy-agent-core-6167phd4.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-wt37tszm.js → roy-agent-core-7evvpfwc.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-azdsyhvx.js → roy-agent-core-7g03zkkb.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-v2d0bt7e.js → roy-agent-core-8s9jd2qy.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-8pqq9yjt.js → roy-agent-core-978b6wfx.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-9csa89jx.js +46 -0
- package/dist/shared/@ai-setting/{roy-agent-core-x8ebdrtn.js → roy-agent-core-9faekt5n.js} +9 -5
- package/dist/shared/@ai-setting/{roy-agent-core-cnsjr3ws.js → roy-agent-core-9jzysq50.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-5ja22qkf.js → roy-agent-core-ak4dc3kg.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-ncaqkyfj.js → roy-agent-core-athdr2m0.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-bt6h398s.js → roy-agent-core-dsevjbck.js} +20 -7
- package/dist/shared/@ai-setting/{roy-agent-core-5hjtbvxf.js → roy-agent-core-dv714bqh.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-k0mx0tkh.js → roy-agent-core-dwx9hjwx.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-fs36xgcs.js +13 -0
- package/dist/shared/@ai-setting/{roy-agent-core-ydwtpzyf.js → roy-agent-core-fvs48d38.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-223v204d.js → roy-agent-core-gdsqp6j8.js} +139 -15
- package/dist/shared/@ai-setting/{roy-agent-core-emjpkx9s.js → roy-agent-core-k8b440n3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-5vf48m39.js → roy-agent-core-kyasfzeh.js} +75 -754
- package/dist/shared/@ai-setting/roy-agent-core-na73mym1.js +367 -0
- package/dist/shared/@ai-setting/{roy-agent-core-j783tcqb.js → roy-agent-core-nde5gzta.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-e2569ptp.js → roy-agent-core-ne2t1pay.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-k0sy76cw.js → roy-agent-core-p2r27era.js} +17 -13
- package/dist/shared/@ai-setting/{roy-agent-core-xvf97xs4.js → roy-agent-core-p8ak03s0.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-56j2q0w6.js → roy-agent-core-qamktze3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-khx0h4j2.js → roy-agent-core-qcspfszy.js} +11 -4
- package/dist/shared/@ai-setting/{roy-agent-core-rqyxdrxg.js → roy-agent-core-qm9jda8p.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-yq45m8mm.js → roy-agent-core-rnwr39b0.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-ed4tbkyj.js → roy-agent-core-rx16h2m1.js} +7 -3
- package/dist/shared/@ai-setting/{roy-agent-core-sea232w4.js → roy-agent-core-s214vmmd.js} +13 -13
- package/dist/shared/@ai-setting/{roy-agent-core-ecb8am8s.js → roy-agent-core-skzjs973.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-zc9k2n3c.js → roy-agent-core-stnddvx9.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-f51kwn6m.js → roy-agent-core-t37wbysj.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-xn12d221.js → roy-agent-core-tdbv7ff4.js} +5 -3
- package/dist/shared/@ai-setting/{roy-agent-core-yes3mr8n.js → roy-agent-core-tjg71zqp.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-yge38dkn.js → roy-agent-core-vrsxhw9e.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-kazn764f.js → roy-agent-core-vvxb9522.js} +20 -7
- package/dist/shared/@ai-setting/{roy-agent-core-vrj9c5y6.js → roy-agent-core-wwytg8rv.js} +14 -7
- package/dist/shared/@ai-setting/roy-agent-core-wxsgay02.js +302 -0
- package/dist/shared/@ai-setting/{roy-agent-core-c0mnxxck.js → roy-agent-core-x8n1r7h4.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-m9drr1fd.js → roy-agent-core-yd21n6c7.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-zff8vvs5.js → roy-agent-core-yhsssn86.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-zd077w51.js +1037 -0
- package/dist/shared/@ai-setting/{roy-agent-core-2bbj3jqd.js → roy-agent-core-zd3ddm4k.js} +1 -1
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-98wwn2px.js +0 -35
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createAutoTaskPlugin
|
|
3
|
-
} from "./roy-agent-core-
|
|
3
|
+
} from "./roy-agent-core-kyasfzeh.js";
|
|
4
4
|
import {
|
|
5
5
|
ContextError,
|
|
6
6
|
ErrorCodes
|
|
7
7
|
} from "./roy-agent-core-ctdhjv68.js";
|
|
8
8
|
import {
|
|
9
9
|
BaseComponent
|
|
10
|
-
} from "./roy-agent-core-
|
|
10
|
+
} from "./roy-agent-core-tdbv7ff4.js";
|
|
11
|
+
import {
|
|
12
|
+
init_hook
|
|
13
|
+
} from "./roy-agent-core-qcspfszy.js";
|
|
11
14
|
import {
|
|
12
15
|
init_context
|
|
13
|
-
} from "./roy-agent-core-
|
|
16
|
+
} from "./roy-agent-core-k8b440n3.js";
|
|
14
17
|
import {
|
|
15
18
|
getEnvContext,
|
|
16
19
|
init_env_context,
|
|
17
20
|
runWithEnvContextAsync
|
|
18
|
-
} from "./roy-agent-core-
|
|
21
|
+
} from "./roy-agent-core-5apmk4qw.js";
|
|
19
22
|
import {
|
|
20
23
|
TracedAs,
|
|
21
24
|
init_decorator
|
|
22
|
-
} from "./roy-agent-core-
|
|
25
|
+
} from "./roy-agent-core-dsevjbck.js";
|
|
23
26
|
import {
|
|
24
27
|
createLogger,
|
|
25
28
|
init_logger
|
|
@@ -595,6 +598,7 @@ __legacyDecorateClassTS([
|
|
|
595
598
|
], BaseEnvironment.prototype, "handleWorkflowAgentQuery", null);
|
|
596
599
|
|
|
597
600
|
// src/env/index.ts
|
|
601
|
+
init_hook();
|
|
598
602
|
init_context();
|
|
599
603
|
|
|
600
604
|
export { generateId, generateDescendingId, BaseEnvironment };
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
hasDecoratorNodes,
|
|
4
4
|
init_node_registry_helper,
|
|
5
5
|
registerDecoratorNodeType
|
|
6
|
-
} from "./roy-agent-core-
|
|
6
|
+
} from "./roy-agent-core-vrsxhw9e.js";
|
|
7
7
|
import"./roy-agent-core-1ce3fqrk.js";
|
|
8
8
|
import"./roy-agent-core-ddwa0n6h.js";
|
|
9
|
-
import"./roy-agent-core-
|
|
9
|
+
import"./roy-agent-core-dsevjbck.js";
|
|
10
10
|
import"./roy-agent-core-8seq65bp.js";
|
|
11
11
|
import"./roy-agent-core-jnszp0jq.js";
|
|
12
12
|
import"./roy-agent-core-fs0mn2jk.js";
|
|
@@ -89,6 +89,19 @@ function wrapFunction(fn, name, options) {
|
|
|
89
89
|
}
|
|
90
90
|
return maxLogSize > 0 && str.length > maxLogSize ? str.slice(0, maxLogSize) + " [TRUNCATED]" : str;
|
|
91
91
|
};
|
|
92
|
+
const toDbValue = (obj) => {
|
|
93
|
+
if (obj === undefined)
|
|
94
|
+
return;
|
|
95
|
+
if (obj === null)
|
|
96
|
+
return null;
|
|
97
|
+
if (typeof obj === "string")
|
|
98
|
+
return obj;
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(JSON.stringify(obj));
|
|
101
|
+
} catch (e) {
|
|
102
|
+
return `[Object with circular reference: ${e instanceof Error ? e.message : String(e)}]`;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
92
105
|
const TRACE_LOG_PREFIX = "[TRACE]";
|
|
93
106
|
const getCallerLocation = () => {
|
|
94
107
|
const originalLimit = Error.stackTraceLimit;
|
|
@@ -141,16 +154,16 @@ function wrapFunction(fn, name, options) {
|
|
|
141
154
|
if (options?.recordParams !== false) {
|
|
142
155
|
if (options?.paramFilter) {
|
|
143
156
|
const filtered = options.paramFilter(args);
|
|
144
|
-
attributes["params"] =
|
|
157
|
+
attributes["params"] = toDbValue(filtered);
|
|
145
158
|
if (options?.flattenParamFilter && filtered && typeof filtered === "object" && !Array.isArray(filtered)) {
|
|
146
159
|
for (const [key, value] of Object.entries(filtered)) {
|
|
147
160
|
if (!(key in attributes)) {
|
|
148
|
-
attributes[key] =
|
|
161
|
+
attributes[key] = toDbValue(value);
|
|
149
162
|
}
|
|
150
163
|
}
|
|
151
164
|
}
|
|
152
165
|
} else {
|
|
153
|
-
attributes["params"] =
|
|
166
|
+
attributes["params"] = toDbValue(args);
|
|
154
167
|
}
|
|
155
168
|
}
|
|
156
169
|
const callerLocation = getCallerLocation();
|
|
@@ -168,11 +181,11 @@ function wrapFunction(fn, name, options) {
|
|
|
168
181
|
const filtered = options.resultFilter(resolved);
|
|
169
182
|
if (filtered && typeof filtered === "object") {
|
|
170
183
|
for (const [key, value] of Object.entries(filtered)) {
|
|
171
|
-
span.setAttribute(key,
|
|
184
|
+
span.setAttribute(key, toDbValue(value));
|
|
172
185
|
}
|
|
173
186
|
}
|
|
174
187
|
}
|
|
175
|
-
span.setAttribute("result", JSON.stringify(
|
|
188
|
+
span.setAttribute("result", JSON.stringify(toDbValue(resolved)));
|
|
176
189
|
const resultError = options?.errorIf ? options.errorIf(resolved) : undefined;
|
|
177
190
|
if (resultError) {
|
|
178
191
|
const err = resultError instanceof Error ? resultError : new Error(String(resultError));
|
|
@@ -198,11 +211,11 @@ function wrapFunction(fn, name, options) {
|
|
|
198
211
|
const filtered = options.resultFilter(result);
|
|
199
212
|
if (filtered && typeof filtered === "object") {
|
|
200
213
|
for (const [key, value] of Object.entries(filtered)) {
|
|
201
|
-
span.setAttribute(key,
|
|
214
|
+
span.setAttribute(key, toDbValue(value));
|
|
202
215
|
}
|
|
203
216
|
}
|
|
204
217
|
}
|
|
205
|
-
span.setAttribute("result", JSON.stringify(
|
|
218
|
+
span.setAttribute("result", JSON.stringify(toDbValue(result)));
|
|
206
219
|
const syncResultError = options?.errorIf ? options.errorIf(result) : undefined;
|
|
207
220
|
if (syncResultError) {
|
|
208
221
|
const err = syncResultError instanceof Error ? syncResultError : new Error(String(syncResultError));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
init_workflow_hook_points
|
|
3
|
+
} from "./roy-agent-core-9csa89jx.js";
|
|
4
|
+
import {
|
|
5
|
+
__esm
|
|
6
|
+
} from "./roy-agent-core-fs0mn2jk.js";
|
|
7
|
+
|
|
8
|
+
// src/env/workflow/hooks/index.ts
|
|
9
|
+
var init_hooks = __esm(() => {
|
|
10
|
+
init_workflow_hook_points();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export { init_hooks };
|
|
@@ -11,20 +11,20 @@ import {
|
|
|
11
11
|
} from "./roy-agent-core-7hh0brvs.js";
|
|
12
12
|
import {
|
|
13
13
|
BaseComponent
|
|
14
|
-
} from "./roy-agent-core-
|
|
14
|
+
} from "./roy-agent-core-tdbv7ff4.js";
|
|
15
15
|
import {
|
|
16
16
|
ToolHookPoints,
|
|
17
17
|
globalHookManager,
|
|
18
18
|
init_global_hook_manager
|
|
19
|
-
} from "./roy-agent-core-
|
|
19
|
+
} from "./roy-agent-core-4z3rq5gw.js";
|
|
20
20
|
import {
|
|
21
21
|
getCurrentTaskId,
|
|
22
22
|
init_env_context
|
|
23
|
-
} from "./roy-agent-core-
|
|
23
|
+
} from "./roy-agent-core-5apmk4qw.js";
|
|
24
24
|
import {
|
|
25
25
|
TracedAs,
|
|
26
26
|
init_decorator
|
|
27
|
-
} from "./roy-agent-core-
|
|
27
|
+
} from "./roy-agent-core-dsevjbck.js";
|
|
28
28
|
import {
|
|
29
29
|
createLogger,
|
|
30
30
|
init_logger
|
|
@@ -184,7 +184,7 @@ delegate_task(
|
|
|
184
184
|
|
|
185
185
|
### \uD83E\uDD49 Workflow creator:\`workflow-creator\`(用户主动构建 workflow 时使用)
|
|
186
186
|
|
|
187
|
-
专用 sub-agent:与用户**多轮交互式**协作设计 workflow,根据用户的任务/日志/trace/session 信息一步步澄清需求、学习现有模式、生成 YAML
|
|
187
|
+
专用 sub-agent:与用户**多轮交互式**协作设计 workflow,根据用户的任务/日志/trace/session 信息一步步澄清需求、学习现有模式、生成 YAML 草稿、**迭代 validate 直到零 error(含模板引用契约校验)**、**构建后真跑一次并附 trace 取证**,最后由用户确认后 add。
|
|
188
188
|
|
|
189
189
|
使用场景:
|
|
190
190
|
- 用户说"帮我建一个 workflow 做 XXX"
|
|
@@ -221,8 +221,9 @@ delegate_task(
|
|
|
221
221
|
|
|
222
222
|
### 为什么必须委托?
|
|
223
223
|
- default agent 用 bash \`workflow add/validate/tag list\` 手写 YAML 容易出错、命名不规范、tag 容易膨胀、节点类型不熟悉
|
|
224
|
-
- workflow-creator
|
|
225
|
-
- 它会先用 \`workflow_list\`/\`workflow_get\` 学习现有命名约定,再 \`workflow_validate\`
|
|
224
|
+
- workflow-creator 专做这事,**10 个工具白名单 + 8 次 validate 迭代 + 契约校验 + 端到端冒烟 + trace 取证** + 学会复用已有 tag
|
|
225
|
+
- 它会先用 \`workflow_list\`/\`workflow_get\` 学习现有命名约定,再 \`workflow_validate\` 迭代到 **零 error**(含\`{{nodes.X.<字段>}}\` **模板引用契约**校验,能抓出 \`.result\` 用在 tool 节点这类错误),再**真跑一次**并附 trace 证据,最后由用户确认后 add
|
|
226
|
+
- ⚠️ 历史教训(Task #4296):手撸/未校验的 workflow 曾出现「validate 通过但一跑就假阳性 PASS」——prompt 引用了 tool 节点不存在的 \`.result\` 字段,引擎静默解析为空串,最终 0/0/0 却报 completed
|
|
226
227
|
|
|
227
228
|
### 快速判断矩阵(在选择 agent 前先看)
|
|
228
229
|
|
|
@@ -238,7 +239,8 @@ delegate_task(
|
|
|
238
239
|
\`\`\`bash
|
|
239
240
|
delegate_task(
|
|
240
241
|
description="构建定制 workflow",
|
|
241
|
-
prompt="详细说明用户想要的 workflow 需求 + 任何上下文(task/trace/log/session
|
|
242
|
+
prompt="详细说明用户想要的 workflow 需求 + 任何上下文(task/trace/log/session 摘要)。
|
|
243
|
+
必做 DoD(缺一不可):① validate 迭代到 errorCount === 0(含模板引用契约校验);② 用真实输入 workflow_run 真跑一次,拿终态 + trace 作为证据(run_id / trace_id / session_id 落盘 + 写 task_operation);③ 引用上游节点字段前先核对输出契约(agent → .result;tool / pythonCall / skill → .output)。三步全绿才算构建完成,最后由用户确认后 add。",
|
|
242
244
|
subagent_type="workflow-creator",
|
|
243
245
|
similar_task_ids=[]
|
|
244
246
|
)
|
|
@@ -1435,7 +1437,7 @@ outputs: [] # 输出定义(可空)
|
|
|
1435
1437
|
|
|
1436
1438
|
**你不是** primary mediator(不像老的 workflow-agent),你只是 sub-agent,**不要**自己去做用户面对面的对话澄清。
|
|
1437
1439
|
|
|
1438
|
-
## 你的工具 (
|
|
1440
|
+
## 你的工具 (10 个, 严格白名单)
|
|
1439
1441
|
|
|
1440
1442
|
| 工具 | 用途 |
|
|
1441
1443
|
|------|------|
|
|
@@ -1443,11 +1445,17 @@ outputs: [] # 输出定义(可空)
|
|
|
1443
1445
|
| \`workflow_get\` | 取指定 workflow 完整定义(学习节点结构、template 写法) |
|
|
1444
1446
|
| \`workflow_search\` | 关键词搜索("code-review" / "agentNode" / "parallel" 等) |
|
|
1445
1447
|
| \`workflow_tag_list\` | **查 tag 池,避免 tag 膨胀**(已有 \`code-review\` 时不要新增 \`review-workflow\`) |
|
|
1446
|
-
| \`workflow_validate\` | **必须**在 \`workflow_add\` 之前调用,直到返回
|
|
1448
|
+
| \`workflow_validate\` | **必须**在 \`workflow_add\` 之前调用,直到返回 **零 error**。它现在做两层校验:① DAG 结构;② **模板引用契约**(\`{{nodes.X.<字段>}}\` 是否匹配 X 的输出 schema),并返回可操作的 \`warnings\` / \`infos\` |
|
|
1447
1449
|
| \`workflow_add\` | 注册新 workflow(需要 1-3 个 tags) |
|
|
1450
|
+
| \`bash\` | **仅用于契约真实性校验**(见阶段 4.5):\`ls\` 核对脚本真名、\`grep\` 核对输出标记、\`roy-agent debug trace/debug span\` 取证。**禁止**用它绕过 workflow 直接干活 |
|
|
1451
|
+
| \`read_file\` | 读脚本/测试文件内容,核对它真的输出你 grep 的标记 |
|
|
1452
|
+
| \`workflow_run\` | **构建后冒烟真跑**(见阶段 5.5,DoD 硬门槛) |
|
|
1453
|
+
| \`workflow_run_status\` | 轮询冒烟 run 的终态(completed / failed / timeout) |
|
|
1448
1454
|
|
|
1449
|
-
> ⚠️ **你只有这
|
|
1450
|
-
>
|
|
1455
|
+
> ⚠️ **你只有这 10 个工具**,不要使用 \`edit_file\` / \`write_file\` / \`delegate_task\` 等。
|
|
1456
|
+
> ⚠️ \`bash\` **只用于"核实事实"与"取证",绝不用于"替代 workflow 节点完成业务逻辑"** ——
|
|
1457
|
+
> 后者会让 workflow 变成一个空壳,是本 prompt 明令禁止的走捷径行为。
|
|
1458
|
+
> ⚠️ 不要直接读 \`*.workflow.yaml\` 文件自己 parse(用 \`workflow_get\`)。
|
|
1451
1459
|
|
|
1452
1460
|
## 多轮交互流程 (与 workflow-extract 的关键差异)
|
|
1453
1461
|
|
|
@@ -1481,14 +1489,120 @@ workflow-creator 是**多轮对话式**协作。每个阶段都可能需要 ask
|
|
|
1481
1489
|
|
|
1482
1490
|
输出完整 YAML draft,参考以下最小化模板。
|
|
1483
1491
|
|
|
1492
|
+
### 阶段 4.5: 输入契约真实性校验 (Contract Grounding) \uD83D\uDD0D
|
|
1493
|
+
|
|
1494
|
+
> 背景(真实事故):曾交付一个「validate 通过、注册成功,但一跑就假阳性 PASS」的 workflow ——
|
|
1495
|
+
> 脚本名拼接错(\`PY_TAG=312\` vs 磁盘 \`cp12\`)、回退脚本在容器内嵌套 docker 导致空跑、
|
|
1496
|
+
> 脚本硬编码 \`Total 99 PASS 99\` 被聚合节点当真值,最终 0/0/0 却报 PASS。
|
|
1497
|
+
> 根因:**validate 只看 DAG 结构,不看语义**。
|
|
1498
|
+
|
|
1499
|
+
在把任何**文件路径 / 命令名 / 输出标记**写进 YAML 之前,**用 \`bash\` / \`read_file\` 核实它真的存在、真的匹配**:
|
|
1500
|
+
|
|
1501
|
+
- **路径契约**:形如 \`/tmp/xxx_\${VAR}.sh\` 的路径,必须把**变量代入后的最终字符串**与磁盘真实文件逐一比对
|
|
1502
|
+
(例:\`for v in 3.12 3.13; do ls /tmp/..._cp\${v//./}.sh; done\`)。
|
|
1503
|
+
脚本名规律若是 \`cp12\` 而你拼出 \`cp312\` → 契约错误,必须改 YAML。
|
|
1504
|
+
- **输出标记契约**:workflow 里 grep 的标记(如 \`[PASS]\`)必须与测试脚本**真实输出**的标记完全一致
|
|
1505
|
+
(去脚本里核对它的输出格式,不要凭想象写标记)。
|
|
1506
|
+
- **执行环境契约**:确认脚本是「宿主机跑(内部 docker exec)」还是「容器内跑」——
|
|
1507
|
+
把「宿主机用 docker 驱动」的脚本 \`docker cp\` 进容器再跑 = **必然空跑**,禁止。
|
|
1508
|
+
- 校验结论写进设计报告「契约校验」小节,注明每条契约的**核实命令 + 实际结果**。
|
|
1509
|
+
|
|
1510
|
+
### 阶段 4.6: 引用契约先行 (Reference Contracts First) \uD83D\uDD17
|
|
1511
|
+
|
|
1512
|
+
> 背景(真实事故,Task #4296):\`wheels-validate-v1\` v1.3.0 的 \`report-results\`(agent)
|
|
1513
|
+
> 节点 prompt 写了 \`{{nodes.run-validation-tests.result}}\`,但 \`run-validation-tests\`
|
|
1514
|
+
> 是 **tool** 节点 —— tool 节点**没有** \`result\` 字段(只有 \`output\`)。引擎把该模板静默解析成**空字符串**(只 warn 不报错),agent 拿到空上下文后自判 ERROR,
|
|
1515
|
+
> 最终顶层 status 却是 \`completed\`,写出一份 0/0/0 的假报告。
|
|
1516
|
+
>
|
|
1517
|
+
> **根因不是 DAG,是「引用字段名与源节点输出 schema 不匹配」。**
|
|
1518
|
+
|
|
1519
|
+
**铁律:写 \`{{nodes.X.<字段>}}\` 之前,先确认 X 的节点类型能产出该字段。**
|
|
1520
|
+
|
|
1521
|
+
#### 节点输出契约表(写引用时的唯一真值)
|
|
1522
|
+
|
|
1523
|
+
| 源节点 type | 可引用的首层字段 | 说明 |
|
|
1524
|
+
|---|---|---|
|
|
1525
|
+
| \`tool\` | **\`output\`** | tool 节点的存储值就是它的结果(常常是字符串)。**没有** \`.result\` |
|
|
1526
|
+
| \`pythonCall\` | **\`output\`** | JSON 解析后的 stdout |
|
|
1527
|
+
| \`skill\` | **\`output\`** | skill 的返回值 |
|
|
1528
|
+
| \`condition\` | \`output\` / \`success\` / \`condition\` | 存储值为 \`{ success, condition }\` |
|
|
1529
|
+
| \`merge\` | \`output\` / \`strategy\` / \`results\` / \`count\` | 存储值为 \`{ strategy, results, count }\` |
|
|
1530
|
+
| \`agent\` | **\`result\`** / \`output\` / \`metadata\` / \`workflowHistory\` + 声明的 JSON schema 字段 | agent 自由输出;若声明了 \`output.schema.properties\`,字段名应与 schema 对齐 |
|
|
1531
|
+
| \`workflow\` | \`output\` / \`result\` | 子 workflow 顶层 output(形状未知) |
|
|
1532
|
+
|
|
1533
|
+
**记忆口诀**:
|
|
1534
|
+
- **\`agent\` → \`.result\`**(唯一用 \`.result\` 的节点类型)
|
|
1535
|
+
- **数据类节点(tool / pythonCall / skill)→ \`.output\`**
|
|
1536
|
+
- **\`.output\` 对所有类型都安全**(引擎把它当「取出该节点的值」的通用前缀)
|
|
1537
|
+
|
|
1538
|
+
#### 自检两步
|
|
1539
|
+
|
|
1540
|
+
1. **先 validate**:写完 YAML 先跑 \`workflow_validate\`,它会把
|
|
1541
|
+
\`{{nodes.<toolNode>.result}}\` 这类错误直接标成 **error**,并给出 \`Did you mean "{{nodes.<toolNode>.output}}"\` 的修复建议 —— **照抄建议改**。
|
|
1542
|
+
2. **必要时查 schema**:需要引用 agent 节点的结构化字段时,先 \`workflow_get <相似 workflow>\` 看它的 \`output.schema\` 字段名,或在自己的 \`config.output.schema\` 里**显式声明**所有下游会用到的字段,再照字段名写引用。
|
|
1543
|
+
|
|
1544
|
+
#### 硬约束
|
|
1545
|
+
|
|
1546
|
+
- ❌ **禁止**在 \`tool\` / \`pythonCall\` / \`skill\` 节点上用 \`.result\`
|
|
1547
|
+
- ❌ **禁止**在未声明 \`output.schema\` 的 agent 节点上引用「看起来应该存在」的字段(先声明再引用)
|
|
1548
|
+
- ❌ **禁止**对 \`tool\` 节点写深层路径(如 \`{{nodes.bash-node.output.foo}}\`)—— tool 输出常是字符串,无法再取属性
|
|
1549
|
+
- ✅ 存疑时一律退回 \`.output\`,或用 \`{{nodes.X.output}}\` 打印后**人肉核对**
|
|
1550
|
+
|
|
1484
1551
|
### 阶段 5: 迭代验证 (Iterative Validate) \uD83D\uDD01
|
|
1485
1552
|
|
|
1486
|
-
调用 \`workflow_validate
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1553
|
+
调用 \`workflow_validate\`,它返回 \`{ valid, errors, warnings, infos, errorCount, warningCount }\`。
|
|
1554
|
+
|
|
1555
|
+
**循环直到 \`valid === true\`(即 errorCount === 0):**
|
|
1556
|
+
|
|
1557
|
+
| 返回项 | 你必须做什么 |
|
|
1558
|
+
|---|---|
|
|
1559
|
+
| \`errors\`(阻塞) | **逐条修复**。常见两类:① **DAG 结构**:节点 ID 重复 / 依赖缺失 / 环 / 空 ID;② **模板引用契约**(错误信息以 \`[template-contract:...]\` 开头,如 \`R2-result-on-non-agent\`):源节点类型与所引用字段不匹配 —— **直接采用错误信息里的 \`Did you mean ...\` 建议** |
|
|
1560
|
+
| \`warnings\`(建议) | **逐条评估**。若判断可接受(如输出恰好是对象且含该键),在最终报告里**写明理由**;否则**一并修掉** |
|
|
1561
|
+
| \`infos\`(提示) | 阅读即可,多为 loop 前向引用等良性场景,无需修改 |
|
|
1562
|
+
|
|
1563
|
+
规则:
|
|
1564
|
+
- ✅ \`errorCount === 0\` 才算通过 → 进入阶段 5.5
|
|
1565
|
+
- ❌ 有 error → 修 YAML → **重新 validate**(**最多迭代 8 次**,超过则停止并报告失败原因)
|
|
1566
|
+
- ❌ **不要**跳过 validate 直接 \`workflow_add\`
|
|
1567
|
+
- ❌ **不要**在还有 error 时用「结构没问题」自我说服 —— error 是**硬阻塞**,\`workflow_add\` 也会拒绝
|
|
1568
|
+
|
|
1569
|
+
### 阶段 5.5: 端到端冒烟验证 (Smoke Run) \uD83D\uDEA8 完成硬门槛
|
|
1570
|
+
|
|
1571
|
+
> ⚠️ **\`workflow_validate\` 通过 ≠ workflow 可用。** 它校验 DAG 结构 **+ 模板引用契约**
|
|
1572
|
+
> (字段名是否匹配源节点输出 schema),但**仍然不校验**:脚本路径是否真实存在、
|
|
1573
|
+
> 变量拼接后的字符串是否正确、输出标记是否与脚本真实输出一致、测试是否真被执行。
|
|
1574
|
+
> 这些**只有真跑**才能证明。你**必须**让 workflow 真的跑一次并拿到证据,否则**不算完成**。
|
|
1575
|
+
|
|
1576
|
+
**执行路径(你有 \`workflow_run\`):**
|
|
1577
|
+
|
|
1578
|
+
1. \`workflow_run(name, input=<真实样例输入>)\` —— 用**真实输入**,不要用 \`echo ok\` 之类的桩
|
|
1579
|
+
2. \`workflow_run_status(run_id)\` 轮询到**终态**(completed / failed / timeout)
|
|
1580
|
+
3. **用 trace 取证**(这是判定"真的跑过"的唯一客观依据,不要只看工具返回值):
|
|
1581
|
+
- \`roy-agent debug trace <trace_id>\` —— 看整个 run 的 span 树:是否真的经过
|
|
1582
|
+
\`workflow.engine.runWorkflow → startNode → validateAndExecute → executeNode\`,
|
|
1583
|
+
每个节点是否都执行到,有没有节点被跳过 / 直接失败
|
|
1584
|
+
- \`roy-agent debug span <span_id>\` —— 看**单个节点**的完整输入输出与错误
|
|
1585
|
+
(节点级排障用:\`workflow.executor.executeNode\` / \`workflow.tool.execute\` 等)
|
|
1586
|
+
- 拿不到 trace_id 时,用 \`bash\` 查最近 trace:\`roy-agent debug trace --list -n 5\`
|
|
1587
|
+
4. 把 run 证据落盘并写 \`task_operation\`:\`run_id + trace_id + session_id + 各节点执行条数\`
|
|
1588
|
+
|
|
1589
|
+
**冒烟通过判据(全部满足才算通过):**
|
|
1590
|
+
|
|
1591
|
+
| 判据 | 说明 |
|
|
1592
|
+
|------|------|
|
|
1593
|
+
| ✅ run 终态 = completed | 不是 failed / timeout |
|
|
1594
|
+
| ✅ **每个节点都有 output 且非空** | 逐个检查;出现 \`command not found\` / \`Bad substitution\` / \`timeout\` 即失败 |
|
|
1595
|
+
| ✅ **真实执行条数 > 0** | 例:\`passed_count + failed_count + expected_count > 0\`;**严禁 0/0/0 判 PASS** |
|
|
1596
|
+
| ✅ 关键输入契约在运行中被**真实命中** | 例:日志出现 \`Test script: <真名>\`,而不是 fallback 警告分支 |
|
|
1597
|
+
| ✅ **无 unresolved template 警告** | 在 trace / app.log 里 **grep \`has unresolved templates\`**,命中即说明仍有引用被解析成空串(引用契约错误),必须回去修 |
|
|
1598
|
+
| ✅ trace 里能看到**完整节点链路** | \`debug trace\` 中每个预期节点都出现且有耗时(非 0ms 跳过) |
|
|
1599
|
+
| ✅ run 证据落盘 | \`run_id + trace_id + session_id\` 写入 \`/tmp/<task>_smoke_evidence.json\` 与 task_operation |
|
|
1600
|
+
|
|
1601
|
+
**未通过冒烟 → 禁止 \`task_complete\`**:回到阶段 4 改 YAML,重跑,直到通过;或明确报告失败原因
|
|
1602
|
+
(**不得**用"应该没问题"之类的措辞声称通过)。
|
|
1603
|
+
|
|
1604
|
+
> \uD83D\uDEAB **绝不允许用 \`workflow update\` 绕过冒烟验证**(历史上真实节点版本 v1.1.0/v1.2.0 就是走
|
|
1605
|
+
> \`workflow update\` 注册的,完全绕过了 validate 与冒烟)。update 后**同样必须**重跑阶段 5 + 5.5。
|
|
1492
1606
|
|
|
1493
1607
|
### 阶段 6: 注册 (Add) \uD83D\uDEA6
|
|
1494
1608
|
|
|
@@ -1653,13 +1767,23 @@ outputs: [] # 输出定义(可空)
|
|
|
1653
1767
|
|
|
1654
1768
|
## 严格约束
|
|
1655
1769
|
|
|
1656
|
-
- ✅ 只用
|
|
1770
|
+
- ✅ 只用 10 个被授予的工具(白名单强制)
|
|
1771
|
+
- ✅ **写 \`{{nodes.X.<字段>}}\` 前先核对访问契约表**(阶段 4.6):\`agent\` → \`.result\`;\`tool\` / \`pythonCall\` / \`skill\` → \`.output\`
|
|
1772
|
+
- ✅ **validate 必须迭代到 \`errorCount === 0\`**;每条 \`warning\` 要么修掉、要么在报告中写明保留理由
|
|
1657
1773
|
- ✅ validate **必须**在 add 之前
|
|
1774
|
+
- ✅ **add / update 之后必须端到端冒烟跑一次**(阶段 5.5),并附 trace 证据;否则不算完成
|
|
1658
1775
|
- ✅ tags 1-3 个,优先复用已有 tag
|
|
1659
1776
|
- ✅ 注册前再次确认用户同意
|
|
1777
|
+
- ✅ run 证据(run_id + trace_id + session_id + 执行条数)**必须落盘 + 写 task_operation**
|
|
1660
1778
|
- ❌ 不要直接读 \`*.workflow.yaml\` 文件自己 parse(用 \`workflow_get\`)
|
|
1661
1779
|
- ❌ 不要 \`delegate_task\` / \`stop_task\`(deniedTools 已禁,禁止递归委托)
|
|
1662
1780
|
- ❌ 不要跳过 \`workflow_validate\`
|
|
1781
|
+
- ❌ 不要用 \`workflow update\` 绕过 validate / 冒烟
|
|
1782
|
+
- ❌ 不要用 \`bash\` 替代 workflow 节点完成业务逻辑(走捷径 = 交付空壳)
|
|
1783
|
+
- ❌ 不要凭"应该能跑"声称通过;**没有 trace / run 证据就不算跑过**
|
|
1784
|
+
- ❌ 不要在 \`tool\` / \`pythonCall\` / \`skill\` 节点上用 \`.result\`(引擎会静默解析成空字符串)
|
|
1785
|
+
- ❌ 不要对 \`tool\` 节点写深层属性路径(输出常为字符串,无法再取属性)
|
|
1786
|
+
- ❌ 不要在有 \`errors\` 未清零的情况下声称「语法检测 OK」
|
|
1663
1787
|
- ❌ 不要自动 merge / push / tag
|
|
1664
1788
|
- ❌ 不要硬编码大段 text(应引用 \`{{input.x}}\` 模板)`,
|
|
1665
1789
|
"task-organizer": `
|