适用版本:ChengOS v0.1.0+ | 最后核对:2026-08-12 | 来源:
crates/cheng-core/src/domain/workflow_template.rs、crates/cheng-api/src/rest/handlers/workflow_template/mod.rs、deploy/workflow-templates/、chengflow-ui/src/api/workflowTemplateSync.ts
工作流模板是 ChengOS 内置的工作流,它会被安装到你的工作区,成为一个普通的、可编辑的工作流。安装之后这份副本就是你的:随便改。模板系统额外提供的能力是——日后告诉你上游变了,并让你自己决定怎么办。
已安装的副本是工作区的私有工作流,绝不是公开模板。
目录
模板放在 deploy/workflow-templates/ 下,每个模板一个目录,各含 template.json(清单)和 workflow.json(图)。
目前随附九个模板:
| Key | 排序 | 演示什么 |
|---|---|---|
create-workflow |
10 | 从一段描述生成工作流 |
http-tools |
20 | 调用外部 HTTP API |
main-chat |
30 | 按意图路由到三个子工作流 |
memory-chat |
40 | 带历史的对话 |
no-memory-chat |
50 | 单轮问答 |
scheduled-task |
60 | 定时触发的执行 |
skills-run |
70 | 运行一个技能 |
skills-importer |
80 | 导入一个 Skill 包 |
tools-user |
90 | 一个做文件操作的 ReAct 智能体 |
最该先读的是 main-chat:一个 utils/condition_router 评估用户意图,并以子流程的方式分发到 memory-chat、no-memory-chat 或 tools-user。它是那个大多数真实部署最终都会需要的路由模式的可运行示例。
清单
{
"schemaVersion": 1,
"key": "main-chat",
"version": "1.0.0",
"name": "main_chat",
"description": "…",
"sortOrder": 30,
"enabledByDefault": true
}
key 必须等于目录名,且要稳定、唯一、小写 kebab-case。
version 只是展示与审计用的元数据。变更检测使用的是规范化工作流文件的、与身份无关的内容哈希(sha256:…)——其中 workflowId 被刻意省略,因此哈希描述的是图本身而不是某次安装。一个版本号从不变化的模板,依然能给出正确的更新信号。
更新状态
安装由一条持久化记录跟踪,它把 (workspace_id, template_key) 关联到唯一的 workflow_id,并保存 applied_hash——最后一次安装或同步时的上游修订。比较三个东西——上游哈希、applied_hash、当前已安装文件的哈希——即可为每个模板得出一个三方状态:
| 状态 | 含义 |
|---|---|
new |
本工作区没有安装记录 |
up_to_date |
上游和你的副本都没变 |
locally_modified |
你改了副本,上游没变 |
update_available |
上游变了,你的副本仍然干净 |
conflict |
两边都变了 |
destination_conflict |
未安装,但规范目标位置已被占用 |
missing_file |
有安装记录但文件不见了 |
invalid_copy |
目标存在但无法解码或校验 |
inconsistent |
安装记录、工作流行、路径与工作流 id 互相对不上 |
orphaned |
安装它的模板 key 已不在目录中 |
区分 locally_modified 与 conflict 正是把 applied_hash 与当前文件哈希分开存储的全部意义。没有它,任何被编辑过的工作流都会看起来像冲突,系统就会没完没了地打扰你。
同步
两种模式:
| 模式 | 行为 |
|---|---|
add_missing |
安装 new 的以及显式选中的模板;绝不覆盖 |
overwrite_all |
安装缺失的默认模板并覆盖已有安装 |
流程是「先预览再确认」:GET /updates 返回每个模板的状态,你做出选择,POST /sync 执行。同步带乐观守卫——如果状态在预览与确认之间发生了变化,该项会返回 state_changed,而不是拿一份过期视图去应用。
逐模板的结果:
| 结果 | 含义 |
|---|---|
installed |
创建了新安装 |
overwritten |
已有安装被上游内容覆盖 |
already_installed |
原样保留(add_missing 遇到已安装项) |
skipped |
不符合所请求模式的处理条件 |
failed |
见 error_code / error_message |
state_changed |
状态在预览与确认之间发生了变化 |
not_found |
该 key 不在当前目录中 |
blocked |
存在目标冲突或未解决的不一致 |
错误码是稳定的机器可读字符串——TEMPLATE_NOT_FOUND、INVALID_TEMPLATE_SELECTION、DESTINATION_CONFLICT、STATE_CHANGED……——由同步服务与 HTTP 层共享,因此客户端可以按码分支,而不必去解析文案。
overwrite_all 会丢弃已安装模板上的本地修改。 如果你已经改造了某个模板并想保留改动,先把它分离出来。
分离
DELETE /installations/:template_key
分离会删除安装记录,而保留工作流本身。该工作流变成一个没有模板关联的普通工作区工作流,从此不再出现在更新检查里,也永远不会被同步覆盖。一份模板副本一旦演化成你自己的东西,就该这么做。
分离同样带乐观守卫:若安装在确认被捕获之后发生了变化,它会返回冲突并要求你刷新重试。
REST 接口
GET /workflows/templates 列出目录中的模板
GET /workflows/templates/:id 获取单个模板
PUT /workflows/:id/template 把某个工作流标记为模板
DELETE /workflows/:id/template 取消该标记
GET /updates 各模板的更新状态(工作区范围)
POST /sync 执行一批同步
DELETE /installations/:template_key 分离
API 暴露的目录投影绝不包含工作流图,也不包含任何文件系统路径——只有 key、名称、描述、分类、版本、排序和 enabledByDefault。

暂无评论内容