Language

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")。同一节点可被多条边连入 / 连出,实现字段级精确映射。 source and target are 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 by dynamic_rules, for example { "watch_config": "template", "method": "regex" } to derive ports from template variables.
  • 触发端口 trigger:未连线时该节点开局自动执行;连线后则等上游数据再执行。 The trigger port 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 at file_reader, string, or agent_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> 下载。 Point dashboard at an HTML file under asset/, e.g. "purrcat://graph/my_graph/asset/dashboard.html". Artifacts download through GET /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} and GET /api/graphs/{name}/schema.
  • 运行:POST /api/tasks/run(后台异步),状态走 GET /api/tasks/{task_id}/state。 Run: POST /api/tasks/run is asynchronous; poll GET /api/tasks/{task_id}/state.
  • 提交:在 extension/graphs/graphs/<name>/ 提 PR;CI 校验文件夹名与 name 一致、描述字段非空,合并后自动并入全局 registry.json。 Submit: open a PR against extension/graphs/graphs/<name>/. CI verifies the name match and the description fields, and the merge updates the global registry.json.