Graph
Graph(任务图 / 工作流)是任务编排中枢:用节点 + 边描述一条完整的多步骤工作流。每个 Graph 是一个独立文件夹,由运行时引擎解析并按拓扑顺序执行。 A graph is the orchestration hub: a full multi-step workflow described as nodes and edges. Each graph is a folder that the runtime parses and executes in topological order.
graphs/<graph-name>/ # 市场仓库中的单元
├── graph.json # 图定义(必需)
└── asset/ # 静态资源:看板 html 等(可选)
文件夹名必须与 graph.json 里的 name 字段严格一致(CI 校验)。
The folder name must match the name field inside graph.json exactly; CI checks it.
| 顶层字段Top-level field | 说明Notes |
|---|---|
name |
安装标识,必须与文件夹名一致Install id, identical to the folder name |
description / description-zh |
英文 / 中文描述(市场展示)English and Chinese descriptions for the market |
version |
Graph 规范版本,当前 "2.0"Graph spec version, currently "2.0" |
core |
该图执行所用模型,缺省 openai:deepseek-v4-flashModel used to run the graph, default openai:deepseek-v4-flash |
global_schema |
全局输入变量的类型声明与必填校验,驱动前端表单与运行时校验;缺失或多余参数会把任务直接置为 ERROR。 Type declarations and required checks for the graph's inputs. Drives the front-end form and the runtime validation; missing or extra parameters put the task straight into ERROR. |
nodes / edges |
节点定义数组与连边定义数组Node and edge arrays |
dashboard |
看板地址:单个字符串,或多看板数组 [{ "name", "url" }]
Dashboard URL, or an array of them: [{ "name", "url" }]
|
节点类型清单Node types
节点定义由 GET /api/graphs/nodes 返回,源码位于
src/harness/node/extensions/<type>/<type>.json。
GET /api/graphs/nodes returns the definitions; the source lives in
src/harness/node/extensions/<type>/<type>.json.
type |
用途Purpose | 主要端口Main ports |
|---|---|---|
task_input |
声明外部参数Declare external parameters | — → global_vars |
task_output |
定义最终返回的数据Define the final return value | target_vars → — |
string |
直接书写内容,派生字符串/数字/布尔/JSON 四类输出 A literal value, derivable as string, number, boolean, or JSON | trigger → text / number / boolean / json |
template_renderer |
用 Jinja2 把 {{变量}} 注入模板Render a template with Jinja2 |
template / dynamic_vars → rendered_text |
message_card_builder |
把文本 + 角色包装成标准 MessageListWrap text and a role into a MessageList | content / role → message_list |
appender |
把 append_list 追到 base_list 后Append one list to another |
base_list / append_list → merged_list |
json_builder / json_extractor |
按 kv_pairs 组装 JSON / 按 extract_keys 精准取值
Build JSON from key-value pairs, or pull exact keys back out
|
kv_pairs → json_string / data → extract_keys |
env_loader |
读图目录 env.json,按 exposed_keys 暴露Read env.json next to the graph and expose selected keys |
— → exposed_keys |
skill_info / mcp_info |
按声明拼装 Skill / MCP 工具的描述提示词 Assemble descriptive prompts for skills or MCP tools | trigger → skill_kit_string / mcp_kit_string |
agent_loop |
范式驱动的 Agent 大循环,见 AgentLoop 一节 The paradigm-driven agent loop, covered in the AgentLoop section | messages / agentloop → messages / summary |
human_intervention |
挂起工作流,等人于前端输入指令后放行Pause the workflow until a human answers in the front end | trigger / context_data / prompt → human_reply |
command |
按目标 OS 在宿主机执行命令行Run a command on the host for the target OS | command / os → stdout / stderr / exit_code |
file_reader / file_writer |
读取/预览 string 或 file(图片 / 文本 / HTML / SVG / PDF) / 把文本写入文件 Read or preview a value or file; write text to a file | source → content / file / content / filename → file |
边与数据流映射Edges and data flow
{ "source": "nd_input", "target": "nd_tpl",
"sourceHandle": "prompt", "targetHandle": "prompt" }
-
source/target是上游 / 下游节点id,sourceHandle/targetHandle是端口名(不写默认为"default")。同一节点可被多条边连入 / 连出,实现字段级精确映射。sourceandtargetare node ids; the handles name the ports (defaulting to"default"). A node can be wired many-to-many, giving field-level mapping. -
端口分 static 与 dynamic;动态端口由
dynamic_rules驱动(如{ "watch_config": "template", "method": "regex" }按模板里的变量名生成)。 Ports are either static or dynamic; dynamic ones are driven bydynamic_rules, for example{ "watch_config": "template", "method": "regex" }to derive ports from template variables. -
触发端口
trigger:未连线时该节点开局自动执行;连线后则等上游数据再执行。 Thetriggerport decides when a node fires: left unconnected, the node runs at the start; connected, it waits for upstream data. -
节点间流转的是带类型的信封(Envelope);已废弃的旧节点类型在加载时会报错并提示改用
file_reader/string/agent_loop。 Values travel between nodes as typed envelopes. Removed node types fail loudly at load time and point you atfile_reader,string, oragent_loop.
看板与 purrcat:// URI
Dashboards and purrcat:// URIs
-
purrcat://graph/<name>/asset/<file>→{GRAPHS_DIR}/<name>/asset/<file>purrcat://graph/<name>/asset/<file>resolves to{GRAPHS_DIR}/<name>/asset/<file>. -
dashboard指向asset/下的 html 时写作"purrcat://graph/my_graph/asset/dashboard.html";产物可用GET /api/tasks/{task_id}/artifact?uri=<uri>下载。 Pointdashboardat an HTML file underasset/, e.g."purrcat://graph/my_graph/asset/dashboard.html". Artifacts download throughGET /api/tasks/{task_id}/artifact?uri=<uri>.
开发与提交Build & submit
- 可视化编辑:前端 DAG 画布内置编辑与一键 JSON 导入/导出。 Visual editing: the front-end DAG canvas edits graphs and imports or exports the JSON in one click.
-
保存 / 读取:
GET/POST /api/graphs/{name}、GET /api/graphs/{name}/schema。 Save and load:GET/POST /api/graphs/{name}andGET /api/graphs/{name}/schema. -
运行:
POST /api/tasks/run(后台异步),状态走GET /api/tasks/{task_id}/state。 Run:POST /api/tasks/runis asynchronous; pollGET /api/tasks/{task_id}/state. -
提交:在
extension/graphs/graphs/<name>/提 PR;CI 校验文件夹名与name一致、描述字段非空,合并后自动并入全局registry.json。 Submit: open a PR againstextension/graphs/graphs/<name>/. CI verifies the name match and the description fields, and the merge updates the globalregistry.json.