@fieldwangai/agentflow 0.1.159 → 0.1.162
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/bin/lib/auth.mjs +231 -14
- package/bin/lib/catalog-flows.mjs +12 -1
- package/bin/lib/cli-auth-page.mjs +103 -0
- package/bin/lib/control-while.mjs +336 -0
- package/bin/lib/flow-dsl/codegen.mjs +74 -11
- package/bin/lib/flow-dsl/ir.mjs +33 -2
- package/bin/lib/flow-dsl/lint.mjs +128 -3
- package/bin/lib/flow-dsl/parser.mjs +168 -4
- package/bin/lib/marketplace.mjs +10 -2
- package/bin/lib/node-package-manifest.mjs +7 -2
- package/bin/lib/node-ui-kit.mjs +156 -0
- package/bin/lib/paths.mjs +2 -0
- package/bin/lib/skill-runtime.mjs +6 -0
- package/bin/lib/table.mjs +2 -3
- package/bin/lib/ui-server.mjs +220 -17
- package/bin/lib/workspace-draft.mjs +74 -0
- package/bin/lib/workspace-flow-store.mjs +11 -2
- package/bin/lib/workspace-graph-merge.mjs +3 -0
- package/bin/lib/workspace-routes.mjs +307 -5
- package/bin/lib/workspace-server.mjs +598 -11
- package/bin/pipeline/validate-flow.mjs +3 -3
- package/builtin/nodes/control_parse_json.md +25 -0
- package/builtin/nodes/control_subflow_call.md +27 -0
- package/builtin/nodes/control_while.md +124 -0
- package/builtin/nodes/provide_json.md +14 -0
- package/builtin/nodes/workspace_subflow_input.md +14 -0
- package/builtin/pipelines/new/workspace.flow.js +1 -1
- package/builtin/pipelines/subflow-preview/workspace.flow.js +29 -0
- package/builtin/pipelines/subflow-preview/workspace.layout.json +38 -0
- package/builtin/pipelines/subflow-preview/workspace.nodes.json +19 -0
- package/builtin/pipelines/subflow-preview/workspace.state.json +93 -0
- package/builtin/pipelines/while-subflow-preview/workspace.flow.js +55 -0
- package/builtin/pipelines/while-subflow-preview/workspace.layout.json +66 -0
- package/builtin/pipelines/while-subflow-preview/workspace.nodes.json +49 -0
- package/builtin/pipelines/while-subflow-preview/workspace.state.json +194 -0
- package/builtin/web-ui/dist/assets/{WorkflowAssistantThread-CY19DsYq.js → WorkflowAssistantThread-CTrXOZ00.js} +1 -1
- package/builtin/web-ui/dist/assets/index-5uJFccdX.css +1 -0
- package/builtin/web-ui/dist/assets/index-BeUfNQRL.js +873 -0
- package/builtin/web-ui/dist/index.html +2 -2
- package/package.json +6 -1
- package/reference/flow-control-capabilities.md +41 -16
- package/shared/slot-types.js +58 -0
- package/skills/agentflow-author-flow/SKILL.md +81 -8
- package/skills/agentflow-author-flow/agents/openai.yaml +3 -3
- package/skills/agentflow-cli/SKILL.md +130 -25
- package/skills/agentflow-cli/agents/openai.yaml +2 -2
- package/skills/agentflow-cli/runtime/bin/lib/skill-runtime.mjs +14765 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/agent_subAgent.md +34 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_agent_toBool.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_anyOne.md +19 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_cancelled.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_cd_workspace.md +50 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_delay.md +31 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_end.md +13 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_if.md +21 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_interval_loop.md +55 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_load_mcp.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_load_skills.md +35 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_parse_json.md +25 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_start.md +13 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_subflow_call.md +27 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_toBool.md +27 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_user_workspace.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_wait_until.md +34 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/control_while.md +124 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_ascii.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_chart.md +32 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_code.md +39 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_html.md +32 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_image.md +36 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_markdown.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_mermaid.md +24 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_react_app.md +53 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/display_table.md +32 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_bool.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_file.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_json.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_password.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/provide_str.md +14 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_display_share_link.md +47 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_get_env.md +20 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_checkout.md +70 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_worktree_load.md +73 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_git_worktree_unload.md +52 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_gitlab_create_mr.md +114 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_jenkins_build.md +67 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_load_key.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_nodejs.md +52 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_print.md +21 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_save_key.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_set_run_env.md +38 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_user_ask.md +27 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_user_check.md +26 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_wecom_send_app_markdown.md +57 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/tool_wecom_send_group_markdown.md +45 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_one_click_task.md +44 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_run.md +16 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_scheduled_run.md +16 -0
- package/skills/agentflow-cli/runtime/builtin/nodes/workspace_subflow_input.md +14 -0
- package/skills/agentflow-cli/runtime/package.json +6 -0
- package/skills/agentflow-cli/scripts/agentflow-auth-store.mjs +113 -0
- package/skills/agentflow-cli/scripts/agentflow-cli.mjs +393 -28
- package/skills/agentflow-cli/scripts/agentflow-runtime.mjs +11 -4
- package/skills/agentflow-flow-add-instances/SKILL.md +2 -2
- package/skills/agentflow-flow-dsl/SKILL.md +83 -10
- package/skills/agentflow-flow-dsl/agents/openai.yaml +2 -2
- package/skills/agentflow-flow-dsl/references/node-calls.md +3 -0
- package/skills/agentflow-flow-dsl/references/subflow-authoring.md +230 -0
- package/skills/agentflow-flow-edit-node-fields/SKILL.md +3 -3
- package/skills/agentflow-flow-recipes/SKILL.md +1 -1
- package/skills/agentflow-flow-recipes/references/recipes.md +1 -2
- package/skills/agentflow-flow-sync-ui/SKILL.md +1 -1
- package/skills/agentflow-node-dsl/SKILL.md +44 -13
- package/skills/agentflow-node-reference/references/builtin-nodes.md +25 -0
- package/skills/agentflow-workspace-markdown/SKILL.md +1 -1
- package/builtin/web-ui/dist/assets/index-B9ppXv7e.css +0 -1
- package/builtin/web-ui/dist/assets/index-CdEQWRrp.js +0 -872
- package/skills/agentflow-workspace-graph/SKILL.md +0 -85
|
@@ -4,6 +4,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
4
4
|
|
|
5
5
|
const PACKAGE_NAME = "@fieldwangai/agentflow";
|
|
6
6
|
const RUNTIME_ENTRY = path.join("bin", "lib", "skill-runtime.mjs");
|
|
7
|
+
const BUNDLED_RUNTIME_ENTRY = path.join("bin", "lib", "skill-runtime.mjs");
|
|
7
8
|
let explicitRoot = "";
|
|
8
9
|
let resolvedRoot = "";
|
|
9
10
|
let runtimePromise = null;
|
|
@@ -12,7 +13,9 @@ function packageLooksUsable(root) {
|
|
|
12
13
|
if (!root) return false;
|
|
13
14
|
try {
|
|
14
15
|
const manifest = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf-8"));
|
|
15
|
-
|
|
16
|
+
const supportedManifest = manifest?.name === PACKAGE_NAME || manifest?.agentflowSkillRuntime === 1;
|
|
17
|
+
const entry = manifest?.agentflowSkillRuntime === 1 ? BUNDLED_RUNTIME_ENTRY : RUNTIME_ENTRY;
|
|
18
|
+
return supportedManifest && fs.statSync(path.join(root, entry)).isFile();
|
|
16
19
|
} catch {
|
|
17
20
|
return false;
|
|
18
21
|
}
|
|
@@ -65,9 +68,11 @@ export function configureAgentFlowRuntime(options = {}) {
|
|
|
65
68
|
export function resolveAgentFlowPackageRoot() {
|
|
66
69
|
if (resolvedRoot) return resolvedRoot;
|
|
67
70
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
71
|
+
const bundledRoot = path.resolve(scriptDir, "..", "runtime");
|
|
68
72
|
const candidates = [
|
|
69
73
|
explicitRoot,
|
|
70
74
|
String(process.env.AGENTFLOW_PACKAGE_ROOT || "").trim(),
|
|
75
|
+
bundledRoot,
|
|
71
76
|
...rootsNear(process.cwd()),
|
|
72
77
|
...rootsNear(scriptDir),
|
|
73
78
|
...executableCandidates().flatMap(rootsFromExecutable),
|
|
@@ -83,14 +88,16 @@ export function resolveAgentFlowPackageRoot() {
|
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
throw new Error(
|
|
86
|
-
"Cannot locate
|
|
87
|
-
+ "
|
|
91
|
+
"Cannot locate the AgentFlow Skill runtime. Reinstall/update agentflow-cli from SkillHub, "
|
|
92
|
+
+ "or set AGENTFLOW_PACKAGE_ROOT/--agentflow-package-root for an explicit development override.",
|
|
88
93
|
);
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
export function loadAgentFlowRuntime() {
|
|
92
97
|
if (!runtimePromise) {
|
|
93
|
-
const
|
|
98
|
+
const root = resolveAgentFlowPackageRoot();
|
|
99
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf-8"));
|
|
100
|
+
const entry = path.join(root, manifest?.agentflowSkillRuntime === 1 ? BUNDLED_RUNTIME_ENTRY : RUNTIME_ENTRY);
|
|
94
101
|
runtimePromise = import(pathToFileURL(entry).href);
|
|
95
102
|
}
|
|
96
103
|
return runtimePromise;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentflow-flow-add-instances
|
|
3
|
-
description: Legacy Pipeline node authoring is retired. Redirect requests to add nodes to
|
|
3
|
+
description: Legacy Pipeline node authoring is retired. Redirect requests to add nodes to agentflow-flow-dsl.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Legacy Flow Node Authoring(已下线)
|
|
7
7
|
|
|
8
8
|
此 skill 原用于向 `flow.yaml` 添加实例,但旧 Pipeline 的 `Start/End` 执行模式已经下线,不再新增或编辑正式 `flow.yaml`。
|
|
9
9
|
|
|
10
|
-
用户要在画布中加节点时,请改用 `agentflow-
|
|
10
|
+
用户要在画布中加节点时,请改用 `agentflow-flow-dsl`,编辑:
|
|
11
11
|
|
|
12
12
|
```text
|
|
13
13
|
.workspace/agentflow/pipelines/<id>/workspace.flow.js
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: agentflow-flow-dsl
|
|
3
3
|
description: >-
|
|
4
4
|
用 workspace.flow.js(受限 ESM)编写 AgentFlow Workspace 流程图。适用于新建流程、
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
在现有 Workspace 画布中添加或删除节点、修改字段和连线,以及编排控制顺序、分支、
|
|
6
|
+
子流程、受控循环和定时入口;自定义代码节点包改用 agentflow-node-dsl。
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# AgentFlow Flow DSL
|
|
@@ -28,12 +28,14 @@ description: >-
|
|
|
28
28
|
写完必须依次执行:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
agentflow
|
|
32
|
-
agentflow
|
|
31
|
+
node <agentflow-cli-skill-dir>/scripts/agentflow-cli.mjs dsl-lint --file <flowDir>
|
|
32
|
+
node <agentflow-cli-skill-dir>/scripts/agentflow-cli.mjs dsl-layout --file <flowDir>
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
先安装并读取 `agentflow-cli` Skill,把它的 `SKILL.md` 所在目录记为
|
|
36
|
+
`<agentflow-cli-skill-dir>`。CLI/DSL Runtime 已随该 Skill 分发,不要安装 npm 包。
|
|
35
37
|
lint 不通过先修结构,不要排版。`layout` 默认只给缺坐标的新节点补位置,保留用户手工布局。
|
|
36
|
-
|
|
38
|
+
新建流程,或用户明确要求整理整张图时,在 `dsl-layout` 命令末尾加 `--all`。
|
|
37
39
|
不要直接编辑 `workspace.layout.json` 里的 x/y。
|
|
38
40
|
|
|
39
41
|
## 自动排版是交付步骤
|
|
@@ -42,11 +44,25 @@ lint 不通过先修结构,不要排版。`layout` 默认只给缺坐标的新
|
|
|
42
44
|
|
|
43
45
|
1. `lint` 校验节点、引脚和拓扑
|
|
44
46
|
2. `layout` 生成或补齐坐标
|
|
45
|
-
3. 如果本地 UI
|
|
47
|
+
3. 如果本地 UI 已打开,刷新画布加载磁盘结果;需要远端审图和试运行时交给
|
|
48
|
+
`agentflow-author-flow` 创建可运行 Draft
|
|
46
49
|
|
|
47
50
|
自动排版按依赖从左到右放置,控制主链保持同一视觉轴,数据源放在上方,展示节点与同层主链
|
|
48
51
|
错开,分支纵向展开。不要为了“看起来差不多”自行猜坐标。
|
|
49
52
|
|
|
53
|
+
## 直接修改现有 Workspace
|
|
54
|
+
|
|
55
|
+
用户明确要求在现有画布中加节点、改字段或连线时,先读当前 `workspace.flow.js`,只修改目标
|
|
56
|
+
节点和相关引用,不要重建整张图。保留未涉及的节点 id、控制顺序、数据边、子流程契约和用户
|
|
57
|
+
已有布局;新增节点再由 `layout` 补坐标。
|
|
58
|
+
|
|
59
|
+
- 只放展示内容且不需要执行的 `display.*` 节点可以不写进 `flow(...)`。
|
|
60
|
+
- `display.*` 的字面量写在 `content` 输入;连接上游时引用 `source.slot`。它的 `content`
|
|
61
|
+
输出仍可接给后续 agent 作为上下文。
|
|
62
|
+
- 不直接编辑 `workspace.layout.json`、`workspace.nodes.json` 或 `workspace.state.json`。
|
|
63
|
+
- 本地改完仍必须执行 `lint` 和 `layout`。需要可保存、可试运行的远端画布时,交给
|
|
64
|
+
`agentflow-author-flow` 创建 Draft;只读分享才使用 `workspace-preview`。
|
|
65
|
+
|
|
50
66
|
## 交付状态与用户验收
|
|
51
67
|
|
|
52
68
|
`lint`、`layout`、自动化测试和 Mock 外部服务都属于 **Agent 测试环境**。完成这些只能说
|
|
@@ -60,6 +76,9 @@ GitLab 等外部系统时,必须验证真实请求、账号权限、网络、
|
|
|
60
76
|
用户明确确认实际流程跑通后,才能将状态更新为“生产同构验收通过,可发布/可上线”。如果流程里有
|
|
61
77
|
自定义代码节点,同时遵守 `agentflow-node-dsl` 里更严格的两级验证闸门。
|
|
62
78
|
|
|
79
|
+
面向用户的新流程不要直接正式发布。完成 lint/layout 后使用 `agentflow-author-flow` 的
|
|
80
|
+
Draft → 试运行 → 动态修改 → 明确确认 → 发布/定时流程;只读 `workspace-preview` 不能代替试运行。
|
|
81
|
+
|
|
63
82
|
## 图结构:workspace.flow.js
|
|
64
83
|
|
|
65
84
|
```js
|
|
@@ -78,7 +97,8 @@ export const run = flow("Run", collect, analyse, chart);
|
|
|
78
97
|
|------|------|
|
|
79
98
|
| 第 1 个参数(字符串) | 节点显示名。可省略 |
|
|
80
99
|
| 第 2 个参数(对象) | **输入引脚**。每个键都是引脚名,没有例外 |
|
|
81
|
-
| 第 3
|
|
100
|
+
| 第 3 个参数 | 一般是 body;`control.while` 优先传 Condition 子流程,旧模式才传 step 脚本 |
|
|
101
|
+
| 第 4 个参数 | 仅双子流程 `control.while` 使用:Body 子流程 |
|
|
82
102
|
| `const 变量名` | **节点 id**。改名 = 重命名节点 |
|
|
83
103
|
| `x.slotName` | 引用上游输出引脚 = 连一条数据线 |
|
|
84
104
|
|
|
@@ -91,7 +111,7 @@ export const run = flow("Run", collect, analyse, chart);
|
|
|
91
111
|
3. **结构文件禁一切控制流**:`if` / `for` / `while` / `?:` / `.map()` / `await` /
|
|
92
112
|
箭头函数 / `new` / 动态属性。要写逻辑就建代码节点
|
|
93
113
|
4. 一个输出可接多个输入(fan-out 允许);**一个输入只能接一条边**(fan-in 禁止);
|
|
94
|
-
|
|
114
|
+
图不能成环;重复执行用 `control.while`,不要画回边
|
|
95
115
|
|
|
96
116
|
## 控制流
|
|
97
117
|
|
|
@@ -116,6 +136,38 @@ flow.resume(showPlan, stage2); // 闸门:跑到这停,人点第二
|
|
|
116
136
|
flow.detached(draftA, draftB); // 有控制链但没 run 入口
|
|
117
137
|
```
|
|
118
138
|
|
|
139
|
+
### 同 Workspace 子流程
|
|
140
|
+
|
|
141
|
+
需要把一段标准节点拓扑复用为可调用单元时,用 `flow.input` + `flow.subflow` 声明契约,
|
|
142
|
+
再由父流程用 `flow.call` 调用。子流程内部仍然是 AgentFlow 节点和连线,不要包装成一个脚本:
|
|
143
|
+
|
|
144
|
+
创建、修改或验收普通子流程、`control.while` 或其画布投影时,必须读取
|
|
145
|
+
[子流程与 While 编写规范](references/subflow-authoring.md)。该规范同时约束 DSL 契约、状态流、
|
|
146
|
+
Start / Return 边界投影和父子流程引脚映射;不要手工创建边界节点或输入代理连线。
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
const stateIn = flow.input("state", "json");
|
|
150
|
+
const inspect = agent.subAgent("检查下一项", { state: stateIn.value }, `只处理一项并返回 JSON`);
|
|
151
|
+
const save = tool.nodejs("规范化状态", { value: inspect.result }, `node ${flowDir}/scripts/normalize.mjs`);
|
|
152
|
+
|
|
153
|
+
export const advanceOne = flow.subflow(
|
|
154
|
+
"推进一项",
|
|
155
|
+
{ state: stateIn },
|
|
156
|
+
flow(inspect, save),
|
|
157
|
+
{ state: save.result },
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const advance = flow.call("调用推进子流程", advanceOne, { state: read.result });
|
|
161
|
+
const { state } = advance;
|
|
162
|
+
export const run = flow("Run", read, advance, show);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- `flow.input(name, type)` 只能作为某个子流程的输入代理。
|
|
166
|
+
- `flow.subflow(label, inputs, flow(...), outputs)` 的输入值引用 `flow.input`,输出值引用内部节点输出。
|
|
167
|
+
- `flow.call(label, subflow, pins)` 是父流程里的真实控制节点,动态引脚由契约生成。
|
|
168
|
+
- 禁止父流程和内部节点直接跨边界连线;所有值必须经过 `flow.call`。
|
|
169
|
+
- 禁止递归调用。当前第一版也不允许子流程内部 `wait/deferred`;调用帧恢复能力补齐前会明确失败。
|
|
170
|
+
|
|
119
171
|
**`flow.fork` 不是并行。** 它是「一个 `next` 接多个下游」的写法——`flow(a, b, c)` 是线性的,
|
|
120
172
|
没法在链里写出扇出,所以有了它。编译出来就是两条边,图里不存在 fork 这个东西:
|
|
121
173
|
|
|
@@ -131,7 +183,25 @@ build.next → testB.prev
|
|
|
131
183
|
|
|
132
184
|
**分支不能汇合**——fan-in 禁止,`control.anyOne` 运行时没实现。两条分支各自收尾。
|
|
133
185
|
|
|
134
|
-
|
|
186
|
+
### 受控循环
|
|
187
|
+
|
|
188
|
+
**图仍然不能成环。** 重复执行时用 `control.while` 把循环收进一个有上限、超时和 checkpoint 的
|
|
189
|
+
状态机节点;不要画回边,也不要用 DSL 的 JavaScript `while`。优先传入显式 Condition/Body 子流程:
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
const advance = control.while("推进到人工边界", {
|
|
193
|
+
state: initial.value,
|
|
194
|
+
maxIterations: "20",
|
|
195
|
+
timeout: "30m",
|
|
196
|
+
}, shouldContinue, advanceOne);
|
|
197
|
+
export const run4 = flow("Run", advance, report); // done 才继续;wait 会暂停
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
- Condition 固定输出 `decision`,Body 固定输出下一版 `state`;两者都可选输出 `summary`。
|
|
201
|
+
- `state` 是用户可见的业务状态载体。`iteration`、`idempotencyKey` 由运行时注入,保留在 DSL
|
|
202
|
+
契约中,但不要要求普通用户在画布上配置或连接。
|
|
203
|
+
- `maxIterations` 和 `timeout` 必须显式设置。新流程不要使用旧的脚本式 While,除非用户要求兼容。
|
|
204
|
+
- Condition/Body 的完整声明、状态迁移、固定输出和手动画布编辑方式都在专项规范中;不要凭记忆简写。
|
|
135
205
|
|
|
136
206
|
`control.agentToBool` 是 `runtime: degraded`:它靠通用 agent 路径工作,没有任何东西
|
|
137
207
|
约束模型输出,而 `parse-bool` 只认 `true` / `1` / `yes` / `on`。prompt 里必须写死
|
|
@@ -207,8 +277,11 @@ const doc = display.html("使用说明", { content: file("docs/guide.html") });
|
|
|
207
277
|
| 给用户看结果 | `display.markdown` / `.code` / `.html` / `.chart` / `.table` |
|
|
208
278
|
| 加载 skills 给下游 agent | `control.loadSkills` → `skillsContext` |
|
|
209
279
|
| 加载知识库 / 代码仓 | `control.cdWorkspace` → `knowledgeContext` |
|
|
210
|
-
| 固定文本 / 密钥 | `provide.str` / `provide.password` |
|
|
280
|
+
| 固定文本 / JSON / 密钥 | `provide.str` / `provide.json` / `provide.password` |
|
|
281
|
+
| 文本显式解析为 JSON | `control.parseJson` |
|
|
211
282
|
| 文本转 bool 做分支 | `control.agentToBool` → `prediction` |
|
|
283
|
+
| 复用一段标准节点拓扑 | `flow.subflow` + `flow.call` |
|
|
284
|
+
| 重复执行显式条件与单轮拓扑 | `control.while(..., conditionFlow, bodyFlow)` |
|
|
212
285
|
|
|
213
286
|
`display.*` 的内容一般来自连线;写字面量则是手写文档节点(也合法,且不会被运行覆盖)。
|
|
214
287
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "AgentFlow Flow DSL"
|
|
3
|
-
short_description: "Author AgentFlow
|
|
4
|
-
default_prompt: "Use $agentflow-flow-dsl to create or modify an AgentFlow workspace.flow.js graph."
|
|
3
|
+
short_description: "Author AgentFlow graphs, subflows, and controlled loops in DSL"
|
|
4
|
+
default_prompt: "Use $agentflow-flow-dsl to create or modify an AgentFlow workspace.flow.js graph, including subflows and controlled loops."
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
| `control.if` | prediction:bool | — |
|
|
13
13
|
| `control.loadMcp` | serverNames:text | mcpContext:text |
|
|
14
14
|
| `control.loadSkills` | skillKeys:text | skillsContext:text |
|
|
15
|
+
| `control.parseJson` | value:text | result:json |
|
|
15
16
|
| `control.userWorkspace` | — | workspaceContext:text, cwd:file |
|
|
17
|
+
| `control.while` | state:json, maxIterations:text, timeout:text | result:json, state:json, decision:text, iterations:text, summary:text, history:json, checkpointFingerprint:text |
|
|
16
18
|
| `display.ascii` | content:text | content:text |
|
|
17
19
|
| `display.chart` | content:text, filePath:file, workspaceContext:text | content:text |
|
|
18
20
|
| `display.code` | content:text, language:text, fileName:text, wrap:bool | content:text |
|
|
@@ -24,6 +26,7 @@
|
|
|
24
26
|
| `display.table` | content:text, filePath:file, workspaceContext:text | content:text |
|
|
25
27
|
| `provide.bool` | — | value:bool |
|
|
26
28
|
| `provide.file` | — | value:file |
|
|
29
|
+
| `provide.json` | — | value:json |
|
|
27
30
|
| `provide.password` | — | value:text |
|
|
28
31
|
| `provide.str` | — | value:text |
|
|
29
32
|
| `tool.displayShareLink` | title:text, layout:text, nodeIds:text, baseUrl:text | url:text, shareId:text, expiresAt:text |
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# 子流程与 `control.while` 编写规范
|
|
2
|
+
|
|
3
|
+
## 目录
|
|
4
|
+
|
|
5
|
+
1. 选型
|
|
6
|
+
2. 普通子流程 DSL
|
|
7
|
+
3. While 的状态模型
|
|
8
|
+
4. While DSL 契约
|
|
9
|
+
5. 用户可见画布语义
|
|
10
|
+
6. 手动编辑方式
|
|
11
|
+
7. 运行与 Preview 验收
|
|
12
|
+
|
|
13
|
+
## 1. 选型
|
|
14
|
+
|
|
15
|
+
按以下边界选型:
|
|
16
|
+
|
|
17
|
+
- 复用一段标准 AgentFlow 节点拓扑时,用 `flow.subflow` + `flow.call`。
|
|
18
|
+
- 按状态重复执行同一套 Condition/Body 拓扑时,用 `control.while`。
|
|
19
|
+
- 封装一个确定性计算或外部工具调用时,用代码节点,不要伪装成子流程。
|
|
20
|
+
- 多个角色、阶段或业务分支只执行一次时,继续使用父图中的普通节点和控制流,不要全部塞进 While。
|
|
21
|
+
|
|
22
|
+
子流程内部仍是普通 AgentFlow 节点。父流程通过显式输入/输出契约调用它,不得直接连接内部节点。
|
|
23
|
+
|
|
24
|
+
## 2. 普通子流程 DSL
|
|
25
|
+
|
|
26
|
+
按 `flow.input`、`flow.subflow`、`flow.call` 三层声明:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
const issueIn = flow.input("issue", "text");
|
|
30
|
+
const inspect = agent.subAgent(
|
|
31
|
+
"分析单个 Issue",
|
|
32
|
+
{ issue: issueIn.value },
|
|
33
|
+
`只分析本次输入的一个 Issue,给出目标、风险和下一步。`,
|
|
34
|
+
);
|
|
35
|
+
const normalize = agent.subAgent(
|
|
36
|
+
"规范化交付摘要",
|
|
37
|
+
{ analysis: inspect.result },
|
|
38
|
+
`输出父流程可直接展示的摘要。`,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export const inspectIssue = flow.subflow(
|
|
42
|
+
"Issue 单项分析",
|
|
43
|
+
{ issue: issueIn },
|
|
44
|
+
flow(inspect, normalize),
|
|
45
|
+
{ summary: normalize.result, raw: inspect.result },
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const callInspect = flow.call(
|
|
49
|
+
"调用 Issue 分析子流程",
|
|
50
|
+
inspectIssue,
|
|
51
|
+
{ issue: pendingIssue.value },
|
|
52
|
+
);
|
|
53
|
+
const { summary, raw } = callInspect;
|
|
54
|
+
export const run = flow("Run", callInspect, showSummary);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
遵守以下约束:
|
|
58
|
+
|
|
59
|
+
- 每个契约输入绑定一个 `flow.input(name, type)`,内部消费者读取它的 `.value`。
|
|
60
|
+
- `flow.subflow(label, inputs, flow(...), outputs)` 的第三个参数是非空内部控制链。
|
|
61
|
+
- 每个契约输出绑定内部成员节点的输出槽。
|
|
62
|
+
- `flow.call(label, subflow, pins)` 是父流程里的真实执行节点;动态数据引脚来自子流程契约。
|
|
63
|
+
- 一个内部节点只能属于一个子流程。禁止直接跨边界连线、跨子流程连线和递归调用。
|
|
64
|
+
- 当前子流程内部不接受 `wait/deferred`。需要暂停 While 时,由 Condition 返回 `wait`。
|
|
65
|
+
|
|
66
|
+
普通子流程的输出契约可以变化。画布编辑器中把某个内部数据输出拖到 Return 的 `add output`,再命名
|
|
67
|
+
输出;重命名或删除后,所有父图 `SUBFLOW CALL` 的同名输出及相关连线必须同步迁移或移除。
|
|
68
|
+
|
|
69
|
+
## 3. While 的状态模型
|
|
70
|
+
|
|
71
|
+
把 While 理解为以下状态迁移,而不是一条隐藏的回边:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
初始 state₀
|
|
75
|
+
→ Condition(stateₙ)
|
|
76
|
+
├─ continue → Body(stateₙ) → stateₙ₊₁ → 下一轮 Condition
|
|
77
|
+
├─ wait → 保存 checkpoint,暂停 Run
|
|
78
|
+
├─ done → 结束 While,继续父流程下游
|
|
79
|
+
└─ fail → While 失败
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
只把业务上需要跨轮保留的数据放入 `state`,例如:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"cursor": 2,
|
|
87
|
+
"records": [{ "id": "U-001" }, { "id": "U-002" }],
|
|
88
|
+
"valid": [{ "id": "U-001" }],
|
|
89
|
+
"invalid": []
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
每轮 Body 必须返回完整的下一版 `state`。业务变量不要增加成 While 顶层输出,也不要依赖隐藏的
|
|
94
|
+
局部变量;把它们作为 `state` 的 JSON 字段显式更新。
|
|
95
|
+
|
|
96
|
+
`iteration` 是运行时绝对轮次,`idempotencyKey` 是逐轮稳定幂等键。它们属于执行上下文,不是业务
|
|
97
|
+
状态:DSL 契约必须声明,产品画布默认隐藏,普通用户不需要连接或配置。只有高级 DSL/代码节点确实
|
|
98
|
+
需要轮次或外部写幂等时,才在内部消费它们。
|
|
99
|
+
|
|
100
|
+
## 4. While DSL 契约
|
|
101
|
+
|
|
102
|
+
优先使用显式 Condition/Body 子流程:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
const conditionState = flow.input("state", "json");
|
|
106
|
+
const conditionIteration = flow.input("iteration", "text");
|
|
107
|
+
const check = agent.subAgent(
|
|
108
|
+
"判断是否继续",
|
|
109
|
+
{ state: conditionState.value },
|
|
110
|
+
`检查 state。只返回 continue、wait、done 或 fail 之一。`,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
export const shouldContinue = flow.subflow(
|
|
114
|
+
"是否继续",
|
|
115
|
+
{ state: conditionState, iteration: conditionIteration },
|
|
116
|
+
flow(check),
|
|
117
|
+
{ decision: check.result },
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const bodyState = flow.input("state", "json");
|
|
121
|
+
const bodyIteration = flow.input("iteration", "text");
|
|
122
|
+
const bodyKey = flow.input("idempotencyKey", "text");
|
|
123
|
+
const step = tool.nodejs(
|
|
124
|
+
"推进一轮",
|
|
125
|
+
{ state: bodyState.value, idempotencyKey: bodyKey.value },
|
|
126
|
+
`node ${flowDir}/scripts/advance-one.mjs`,
|
|
127
|
+
);
|
|
128
|
+
const nextState = control.parseJson("校验下一版状态", { value: step.result });
|
|
129
|
+
|
|
130
|
+
export const advanceOne = flow.subflow(
|
|
131
|
+
"执行一轮",
|
|
132
|
+
{ state: bodyState, iteration: bodyIteration, idempotencyKey: bodyKey },
|
|
133
|
+
flow(step, nextState),
|
|
134
|
+
{ state: nextState.result },
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const initial = provide.json("初始状态", {
|
|
138
|
+
value: "{\"cursor\":0,\"records\":[],\"valid\":[],\"invalid\":[]}",
|
|
139
|
+
});
|
|
140
|
+
const loop = control.while("逐条处理", {
|
|
141
|
+
state: initial.value,
|
|
142
|
+
maxIterations: "20",
|
|
143
|
+
timeout: "30m",
|
|
144
|
+
}, shouldContinue, advanceOne);
|
|
145
|
+
|
|
146
|
+
const summarize = agent.subAgent("生成最终摘要", { state: loop.state }, `把最终 state 整理成 Markdown。`);
|
|
147
|
+
const report = display.markdown("最终结果", { content: summarize.result });
|
|
148
|
+
export const run = flow("Run", loop, summarize, report);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
固定契约如下:
|
|
152
|
+
|
|
153
|
+
| 子流程 | DSL 输入 | DSL 输出 | 产品画布中用户需要理解的部分 |
|
|
154
|
+
|--------|----------|----------|--------------------------------|
|
|
155
|
+
| Condition | `state:json`, `iteration:text` | 必需 `decision:text`;可选 `summary:text` | `state → decision` |
|
|
156
|
+
| Body | `state:json`, `iteration:text`, `idempotencyKey:text` | 必需 `state:json`;可选 `summary:text` | `stateₙ → stateₙ₊₁` |
|
|
157
|
+
|
|
158
|
+
While Return 是固定契约:Condition 只能返回 `decision/summary`,Body 只能返回 `state/summary`。
|
|
159
|
+
不要在 While Return 添加任意顶层变量。普通 Subflow Return 才支持动态输出。
|
|
160
|
+
|
|
161
|
+
只在兼容旧流程时使用脚本式 While:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
const loop = control.while("推进", {
|
|
165
|
+
state: initial.value,
|
|
166
|
+
maxIterations: "20",
|
|
167
|
+
timeout: "30m",
|
|
168
|
+
}, `node ${flowDir}/scripts/advance-one.mjs`);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
旧脚本 stdout 只能是 `{"decision":"continue|wait|done|fail","state":{},"summary":"..."}`;日志写
|
|
172
|
+
stderr。新流程不要用脚本替代 Condition/Body 子流程。
|
|
173
|
+
|
|
174
|
+
## 5. 用户可见画布语义
|
|
175
|
+
|
|
176
|
+
保持“运行时完整、产品上不暴露噪音”:
|
|
177
|
+
|
|
178
|
+
- 父图把普通调用显示为独立的 **SUBFLOW CALL** 节点,动态输入/输出与声明契约同名。
|
|
179
|
+
- 父图把 While 显示为状态机卡片:左侧 `state` 是初始业务状态输入,右侧 `state` 是最终业务状态。
|
|
180
|
+
- While 卡片中的 Condition/Body 是可进入的子流程入口;`maxIterations` 和 `timeout` 可直接配置。
|
|
181
|
+
- While 卡片明确展示 `stateₙ → check → run → stateₙ₊₁`,运行后展示当前 state、最新结果和历史。
|
|
182
|
+
- `CHECKS`、`RUNS`、`CALLS` 虚线只表示调用关系,由系统生成,不是数据线或控制线,也不能手拉。
|
|
183
|
+
- 点击 Condition、Body 或普通 Subflow 卡片进入独立子流程编辑模式;不要删除父图的调用关系视图。
|
|
184
|
+
- 子图显示可拖动的 **SUBFLOW START** 和 **SUBFLOW RETURN**,复用普通节点的 Port Rail、Handle、
|
|
185
|
+
选中和拖动规则。
|
|
186
|
+
- While 的 Start 只展示业务 `state`;隐藏 `iteration/idempotencyKey`。它们仍留在 DSL/IR 中由运行时注入。
|
|
187
|
+
- While Return 显示固定锁定契约。Body Return 有可用值时展示 state 字段、类型和预览,并可定位来源节点。
|
|
188
|
+
- 普通 Subflow Return 显示 `add output`,允许新增、重命名和删除契约输出。
|
|
189
|
+
- `workspace_subflow_input` 是 IR 输入代理,画布不重复显示;Start 的同名输出线代表它的真实绑定。
|
|
190
|
+
|
|
191
|
+
React 组件名、CSS 类名和像素尺寸属于实现细节,不写入 DSL。
|
|
192
|
+
|
|
193
|
+
## 6. 手动编辑方式
|
|
194
|
+
|
|
195
|
+
创建 While 后按以下方式操作:
|
|
196
|
+
|
|
197
|
+
1. 从普通 JSON 数据节点的输出引脚连接到 While 左侧 `state`。
|
|
198
|
+
2. 在 While 卡片中设置最大轮次和超时。
|
|
199
|
+
3. 点击 Condition 卡片进入编辑器,添加判断节点;连接 Start `next` 到首节点 `prev`,连接 Start
|
|
200
|
+
`state` 到判断节点数据输入,连接末节点 `next` 到 Return `prev`,再把结果连到 Return `decision`。
|
|
201
|
+
4. 点击 Body 卡片进入编辑器,连接 Start `state` 到单轮处理节点,最后把完整下一版 JSON 状态连到
|
|
202
|
+
Return `state`;文本结果先经过 `control.parseJson`。
|
|
203
|
+
5. 需要摘要时连接可选 `summary`。不要寻找或手工连接 `iteration/idempotencyKey` 产品引脚。
|
|
204
|
+
6. 返回父图,确认 Condition/Body 卡片、状态流说明和两条调用虚线仍存在。
|
|
205
|
+
|
|
206
|
+
创建普通子流程时,Start/Return 的控制线和数据线方式相同;区别是 Return 输出可以通过 `add output`
|
|
207
|
+
扩展,父图 SUBFLOW CALL 会同步出现同名输出。
|
|
208
|
+
|
|
209
|
+
## 7. 运行与 Preview 验收
|
|
210
|
+
|
|
211
|
+
完成 DSL 后执行:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
agentflow flow dsl lint <flowDir>
|
|
215
|
+
agentflow flow dsl layout <flowDir>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
涉及子流程或 While 时,不能只凭 lint、单元测试或 DSL 文本宣称完成。打开真实 Workspace Preview:
|
|
219
|
+
|
|
220
|
+
1. 确认父流程只通过 SUBFLOW CALL 或 While 调用子流程,没有直接跨边界线。
|
|
221
|
+
2. 确认调用虚线稳定落到对应 Start,且不会被误读成 `next` 控制线。
|
|
222
|
+
3. 确认 Start/Return 可拖动,保存刷新后位置和契约不丢失。
|
|
223
|
+
4. 确认普通子流程多输出在 Return 与 Call 两侧逐项对应。
|
|
224
|
+
5. 确认 While 只暴露业务 state,Condition/Body 固定输出正确,运行时字段没有泄露到普通 UI。
|
|
225
|
+
6. 确认节点高度随内容收敛,没有大面积空白、越界历史或重叠引脚。
|
|
226
|
+
7. 实际运行至少两轮,验证 `state` 确实变化;`continue` 才启动 Body,`done` 继续下游,`wait` 保存
|
|
227
|
+
checkpoint 且不触发下游。
|
|
228
|
+
8. 重新运行等待中的 While,确认轮次、累计超时、历史和幂等键不重置。
|
|
229
|
+
|
|
230
|
+
任何一项失败,都先修正 DSL、投影或运行时,再重新 lint、测试和预览。
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentflow-flow-edit-node-fields
|
|
3
|
-
description: Legacy Pipeline field editing is retired. Use
|
|
3
|
+
description: Legacy Pipeline field editing is retired. Use agentflow-flow-dsl for Workspace node field changes.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Legacy Flow Node Field Editing(已下线)
|
|
7
7
|
|
|
8
|
-
此 skill 原用于修改 `flow.yaml` 的实例字段。当前新建和操作统一发生在 Workspace 图中,节点字段应修改 `workspace.flow.js` 的节点调用(见 **agentflow-
|
|
8
|
+
此 skill 原用于修改 `flow.yaml` 的实例字段。当前新建和操作统一发生在 Workspace 图中,节点字段应修改 `workspace.flow.js` 的节点调用(见 **agentflow-flow-dsl**),并通过 Workspace 保存/Draft 链路同步。
|
|
9
9
|
|
|
10
|
-
不要修改 `flow.yaml`、`control_start/control_end` 或调用旧 Pipeline 执行接口来完成新需求。请改用 `agentflow-
|
|
10
|
+
不要修改 `flow.yaml`、`control_start/control_end` 或调用旧 Pipeline 执行接口来完成新需求。请改用 `agentflow-flow-dsl`。
|
|
@@ -7,7 +7,7 @@ description: Workspace Graph recipes for AgentFlow canvas tasks (git analysis, d
|
|
|
7
7
|
|
|
8
8
|
组合 Git Checkout、CD Workspace、Load Skills、Agent、Display 等节点时,先读
|
|
9
9
|
[recipes.md](references/recipes.md),在 `workspace.flow.js` 中以 `flow(...)` 为入口组织节点,
|
|
10
|
-
再用 `agentflow-
|
|
10
|
+
再用 `agentflow-flow-dsl` 校验槽位和连线。
|
|
11
11
|
|
|
12
12
|
旧的 `Start → … → End` 流水线 recipe 已下线;不得生成 `control_start` / `control_end`
|
|
13
13
|
或其它已退役的节点类型(recipes.md 末尾列出了完整清单)。
|
|
@@ -102,8 +102,7 @@ draw an edge from a downstream node back to an upstream one.
|
|
|
102
102
|
|
|
103
103
|
## Edit The Graph
|
|
104
104
|
|
|
105
|
-
- Structure, nodes, edges: **agentflow-
|
|
106
|
-
- Full syntax and the node call table: **agentflow-flow-dsl**
|
|
105
|
+
- Structure, nodes, edges, full syntax and node calls: **agentflow-flow-dsl**
|
|
107
106
|
- Node implementations in code: `nodes/<name>/index.mjs`, see **agentflow-flow-dsl**
|
|
108
107
|
|
|
109
108
|
Saving is handled by the Workspace API; there is no separate canvas-sync step.
|
|
@@ -5,4 +5,4 @@ description: Legacy flow.yaml canvas sync is retired. Workspace Graph saves are
|
|
|
5
5
|
|
|
6
6
|
# Legacy Flow Canvas Sync(已下线)
|
|
7
7
|
|
|
8
|
-
旧的 `flow.yaml` + `/api/flow-editor-sync` 刷新链路不再用于新功能。Workspace
|
|
8
|
+
旧的 `flow.yaml` + `/api/flow-editor-sync` 刷新链路不再用于新功能。Workspace 图请按 **agentflow-flow-dsl** 编辑 `workspace.flow.js`,或使用 Workspace 页面/API 的保存机制;需要可编辑、可试运行的远端画布时使用 **agentflow-author-flow** 的 Draft,纯只读分享才使用 `agentflow-cli workspace-preview --file <flowDir>`。
|
|
@@ -27,8 +27,8 @@ description: >-
|
|
|
27
27
|
node <agentflow-cli-skill-dir>/scripts/agentflow-cli.mjs config
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
跨端节点操作要求 `localRuntime.available: true` 和有效 token
|
|
31
|
-
|
|
30
|
+
跨端节点操作要求 `localRuntime.available: true` 和有效 token。Runtime 已包含在 companion
|
|
31
|
+
Skill 中;缺失时重新安装或更新 `agentflow-cli`,不要另装 npm CLI。
|
|
32
32
|
|
|
33
33
|
写新包之前,先搜索服务端目录,避免重复造已有节点:
|
|
34
34
|
|
|
@@ -115,6 +115,45 @@ await fs.writeFile(p, csvText); await fs.writeFile(outputs.deduped, p); // ✗
|
|
|
115
115
|
|
|
116
116
|
可用类型:`text` `file` `bool` `node` `image` `json`。未知类型直接报错。
|
|
117
117
|
|
|
118
|
+
## Node UI Kit(可选)
|
|
119
|
+
|
|
120
|
+
节点需要在画布上解释输入绑定、执行步骤或运行状态时,在 `export default` 中声明 `ui.card`。
|
|
121
|
+
UI 与清单一起静态解析和发布;节点包不能注入 React、HTML 或事件处理器,只能组合平台白名单
|
|
122
|
+
组件:`binding`、`code`、`decision`、`metrics`、`summary`、`history`。
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
export default {
|
|
126
|
+
id: "advance_state",
|
|
127
|
+
version: "1.0.0",
|
|
128
|
+
name: "推进状态",
|
|
129
|
+
inputs: { state: { type: "json" }, max: { type: "text", default: "20" } },
|
|
130
|
+
outputs: { decision: { type: "text" }, iterations: { type: "text" }, history: { type: "json" } },
|
|
131
|
+
ui: {
|
|
132
|
+
card: {
|
|
133
|
+
template: "state-machine", // details | state-machine
|
|
134
|
+
icon: "repeat", // Material Symbols 名称
|
|
135
|
+
tone: "purple", // neutral | blue | purple | green | amber | red
|
|
136
|
+
sections: [
|
|
137
|
+
{ type: "binding", label: "State", input: "state" },
|
|
138
|
+
{ type: "code", label: "Step", field: "script" },
|
|
139
|
+
{ type: "decision", label: "Decision", output: "decision", source: "step.result.decision",
|
|
140
|
+
options: [
|
|
141
|
+
{ value: "continue", label: "continue", tone: "purple" },
|
|
142
|
+
{ value: "done", label: "done", tone: "green" },
|
|
143
|
+
] },
|
|
144
|
+
{ type: "metrics", label: "Progress", items: [
|
|
145
|
+
{ label: "Iteration", output: "iterations", maxInput: "max" },
|
|
146
|
+
] },
|
|
147
|
+
{ type: "history", label: "History", output: "history", limit: 3 },
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
字段里的 `input` / `output` 必须引用本节点已声明的槽位;`code.field` 只能是 `script`、
|
|
155
|
+
`scriptRef`、`body`、`implementationRef`。未知组件或字段会在清单规范化时被丢弃,不会进入 UI。
|
|
156
|
+
|
|
118
157
|
## `run(inputs, outputs, dirs)`
|
|
119
158
|
|
|
120
159
|
| 参数 | 内容 |
|
|
@@ -144,7 +183,7 @@ Agent 自行完成且保留可重现证据:
|
|
|
144
183
|
- 节点包含 `scripts/` / `templates/` / `assets/` 时,用完整 ZIP 安装后再跑一次,不得只测 `index.mjs`
|
|
145
184
|
|
|
146
185
|
```bash
|
|
147
|
-
agentflow
|
|
186
|
+
node <agentflow-cli-skill-dir>/scripts/agentflow-cli.mjs dsl-lint --file <flowDir>
|
|
148
187
|
```
|
|
149
188
|
|
|
150
189
|
这一级通过后只能汇报:**开发验证通过,待生产同构验收**。
|
|
@@ -164,16 +203,8 @@ agentflow flow dsl lint <flowDir>
|
|
|
164
203
|
|
|
165
204
|
## 发布给别的流程用
|
|
166
205
|
|
|
167
|
-
流程自带的 `nodes/<name>/`
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
agentflow marketplace publish-node <flowDir>/nodes/<name>
|
|
171
|
-
agentflow marketplace list
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
包会被复制到 `.workspace/agentflow/marketplace/packages/nodes/<id>/<version>`。
|
|
175
|
-
|
|
176
|
-
要发给另一台机器或另一个 Agent workspace,上传和安装**整个包目录**:
|
|
206
|
+
流程自带的 `nodes/<name>/` 只有那个流程能用。要让其它流程或其它 Agent workspace 复用,
|
|
207
|
+
通过 token-backed CLI 上传和安装**整个包目录**:
|
|
177
208
|
|
|
178
209
|
```bash
|
|
179
210
|
node <agentflow-cli-skill-dir>/scripts/agentflow-cli.mjs node-package-publish --file <flowDir>/nodes/<name>
|