Hub 配置参考
Hub 接受以下结构的 YAML:
.paseo/
├── hub.yml
└── workflows/
├── <workflow>.yml
└── partials/
└── <partial>.md
只有 .paseo/workflows/ 下直接的 .yml 子文件才是 workflow。每个文件包含一个触发器及其有序的 step。没有 manifest、includes、uses、可复用的 step、workflow 调用或继承。
hub.yml
.paseo/hub.yml 包含具名的项目资源。名称是映射的键,不会在每个对象内部重复。
environments:
paseo:
kind: daemon
daemon: laptop
cwd: /Users/you/code/paseo
hub:
kind: daemon
daemon: devbox
cwd: /workspace/hub
agents:
codex-safe:
provider: codex
model: gpt-5.5
thinkingOptionId: xhigh
options:
sandbox_workspace_write:
writable_roots: [/var/cache/npm]
network_access: false
claude:
provider: claude
mode: bypassPermissions
顶层只有 environments 和 agents 两个键。triggers 键会被拒绝,并给出迁移错误。
环境
| 字段 | 是否必填 | 说明 |
|---|---|---|
kind | 是 | daemon、fly 或 docker;workflow 的 step 必须选择 daemon 环境。 |
daemon | 仅 daemon | 已注册的 daemon slug,在修订激活时解析。 |
cwd | 仅 daemon | daemon 上的绝对工作目录。 |
image | fly/docker | 镜像名称。 |
worktree | 否 | branch-off、checkout-branch 或 checkout-pr 目标。 |
对于 worktree,branch-off 使用 newBranch 和可选的 base,checkout-branch 使用 branch,checkout-pr 使用正整数 prNumber。
environments:
review:
kind: daemon
daemon: build-server
cwd: /workspace/project
worktree:
mode: branch-off
newBranch: trigger-${{ paseo.execution.id }}
base: origin/main
newBranch 是一个分支名字符串。在其中嵌入 ${{ paseo.execution.id }},它会渲染为该次执行的 UUID,这样每次执行都会从 base 分出自己的分支,并在 Hub 重试或恢复该执行时保留这个分支。
一次执行就是一次 step 运行,因此选择同一环境的两个 step 会得到各自独立的分支。
${{ paseo.execution.id }} 是 newBranch 唯一接受的表达式。paseo.prompt、paseo.context、paseo.inputs.*、values.*、steps.<id>.outputs.* 以及 Provider 事件字段在这里都不可用,任何一个都会在编写它的字段处导致文件包激活失败,例如 .paseo/hub.yml.environments.review.worktree.newBranch。
${{ paseo.execution.id }} 出现在文件包中其他任何位置时,同样会导致激活失败。branch 和 prNumber 只接受字面值。
环境是一个完整的具名对象。step 选择它的名称;对象不会被继承、合并或部分覆盖。
具名 Agent
每个 Agent 是一份完整的 Provider 配置:
| 字段 | 是否必填 | 说明 |
|---|---|---|
provider | 是 | Provider ID。Hub 在无人值守的情况下运行,因此为 claude、codex 或 opencode。 |
model | 否 | Provider 的模型 ID。 |
mode | 否 | Paseo 模式 ID。 |
thinkingOptionId | 否 | Provider 的思考选项。 |
options | 否 | 可安全序列化为 JSON 的 Provider 原生选项,保留名称和嵌套结构。 |
具名选择会保留完整的对象,包括结构化的选项。具名 Agent 没有父级、补丁或按 step 的覆盖。
Hub 把 model、mode、thinkingOptionId 和 options 传给 Paseo daemon,不会重命名或展平 Provider 字段。保存或部署触发器时,所选的 daemon 会按它当前的 Provider schema 校验这些值,因此它不提供的值会在那时被拒绝,而不是等到第一次运行;Hub 不会转换 Provider 原生选项。见保存时会对照 daemon 检查 Agent。
workflow 文件
.paseo/workflows/review.yml:
name: review
on: manual.run
max_runtime: 2h
filters:
from_users: [automation]
inputs:
repo:
type: string
required: true
choices: [paseo, hub]
steps:
- id: inspect
environment: ${{ paseo.inputs.repo }}
max_runtime: 30m
idle_timeout: 5m
agent: codex-safe
prompt:
- text: ${{ paseo.prompt }}
| 字段 | 是否必填 | 说明 |
|---|---|---|
name | 是 | workflow 名称,在整个文件包中唯一。 |
on | 是 | Provider 事件,例如 manual.run 或 discord.mention。 |
max_runtime | 是 | 整次运行的硬性时间上限,最多 24h。 |
filters | 是 | Provider 资源过滤条件和发送者白名单。 |
inputs | 否 | 带类型的调用头部参数。 |
values | 否 | 具名表达式。 |
steps | 是 | 一个或多个有序的内联 step。 |
GitHub 事件和过滤条件
新的 GitHub workflow 请使用以下语义化事件名之一:
on | 匹配 |
|---|---|
github.issue_created | action 为 opened 的 issues 投递。 |
github.pull_request_created | action 为 opened 的 pull_request 投递。 |
github.issue_comment_created | 在 issue 上、action 为 created 的 issue_comment 投递。 |
github.pull_request_comment_created | 在 Pull Request 上、action 为 created 的 issue_comment 投递。 |
github.issue_label_added | action 为 labeled 的 issues 投递。 |
github.pull_request_label_added | action 为 labeled 的 pull_request 投递。 |
已有的配置可以继续使用 github.issues、github.issue_comment、github.pull_request_review、github.pull_request_review_comment 和 github.push。这些旧版事件保持原有的行为。
filters 支持以下 GitHub 字段。对于每个由外部来源触发的 workflow,from_users 都必须非空。所有提供的过滤条件以 AND 组合。
| 字段 | 类型 | 适用于 | 含义 |
|---|---|---|---|
from_users | 非空字符串列表 | 所有 GitHub 事件 | 允许启动该 workflow 的 GitHub 登录名。 |
repo | 非空字符串 | 所有 GitHub 事件 | owner/name 形式的仓库。 |
connection | 字符串 | 所有 GitHub 事件 | GitHub 连接的 slug。 |
contains | 字符串 | issue、Pull Request 和评论事件 | issue 或 Pull Request 的标题加正文中,或评论正文中的子串。 |
pattern | 字符串 | issue、Pull Request 和评论事件 | 同一段文本的开头。 |
label | 非空字符串 | github.issue_label_added、github.pull_request_label_added | 本次投递添加的标签。 |
labels | 由非空字符串组成的非空列表 | issue、Pull Request 和评论事件 | 每个所列标签都必须当前存在于该 issue 或 Pull Request 上。 |
label 和 labels 匹配 GitHub 标签时不区分大小写。label 检查发生变化的那一个标签;labels 检查当前完整的标签集合,并要求每一项都存在。例如,labels: [bug, backend] 要求同时存在 bug 和 backend。
label 只能与添加标签的事件一起使用,在其他事件上永远不会匹配。使用 labels 来要求条目所处的状态,包括由评论启动 workflow 的情况。
完整的分拣、Pull Request 审查和 ready-for-agent workflow,见 GitHub 触发器。
输入和值
输入的类型为 type: string | number | boolean,另有可选的 required、default 和 choices。required 和 default 不能同时使用。当某个输入可以选择权限相关的对象(例如环境或具名 Agent)时,必须提供有限的 choices。
值用于绑定表达式:
values:
selected_environment: ${{ steps.classify.outputs.environment }}
selected_agent: ${{ steps.classify.outputs.agent }}
表达式可以读取已声明的 paseo.inputs、之前的 steps.<id>.outputs 以及 values。语法支持路径、JSON 字面量、括号、!、==、!=、&&、|| 和 ??。
用于选择环境或动态具名 Agent 的表达式,在激活时必须具有一个有限的、可能的字符串结果集合。每个结果都必须是一个已配置资源的名称。运行时的选择从不会退回到其他环境或 Agent。
step
| 字段 | 是否必填 | 说明 |
|---|---|---|
id | 是 | 在 workflow 内唯一。 |
environment | 是 | 字面的环境名称,或解析为某个环境名称的有限表达式。 |
max_runtime | 是 | step 的硬性时间上限。 |
idle_timeout | 是 | 空闲时间上限,不得超过 max_runtime。 |
startup_timeout | 否 | step 启动的等待预算。默认值和限制见启动超时。 |
agent | 是 | 具名 Agent、选择具名 Agent 的有限表达式,或一份完整的静态内联 Agent。 |
prompt | 是 | 有序的 text 和 include 块。 |
if | 否 | 决定该 step 是否运行的表达式。 |
env | 否 | 来自连接值的环境变量。 |
output.schema | 否 | 结构化 step 输出的 JSON Schema。 |
allow_outputs | 否 | Provider 输出能力,可带 max 和 required。 |
auto_archive | 否 | step 结束后归档该 Agent。 |
github | 否 | 该 step 的显式 GitHub 权限。 |
内联 Agent 是静态且完整的:
agent:
provider: codex
model: gpt-5.5
options:
approval_policy: never
sandbox_mode: read-only
表达式形式的 agent 用于选择具名 Agent。内联对象中的动态 Provider 字段会被拒绝。
提示词语义
prompt:
- include: partials/review.md
- text: |
<user-prompt>
${{ paseo.prompt }}
</user-prompt>
${{ paseo.prompt }} 是去掉 Provider 标记和已声明的开头 key=value 输入之后的规范化请求。它不会被改写,也不会附加事件上下文。
${{ paseo.context }} 让该 step 选择加入 Provider 上下文的具体化,并在提示词中把结果渲染为 JSON。它只能用在提示词文本中。除非 workflow 编写了这个表达式,否则 Hub 不会注入它。
include 相对于 .paseo/workflows/ 解析,因此共享片段使用 partials/<name>.md。缺失的文件、绝对路径或越界路径、符号链接、内容不一致以及位于片段目录树之外的文件都会被拒绝。
输出能力
权限保留在使用它的 step 上:
allow_outputs:
- type: discord.reply
max: 1
required: true
Slack workflow 使用 slack.reply;Discord workflow 使用 discord.reply。这项声明授予 hub.reply,提示词必须告诉 Agent 调用它。GitHub 没有回复输出;请使用显式的 github 块。
每个 step 都会获得 hub.finish_execution。提示词必须告诉 Agent 何时调用它;Hub 不会追加完成或回复的指示。如果存在 output.schema,hub.finish_execution 需要一个与该 schema 匹配的 output 值。如果某个 allow_outputs 条目为 required: true,Agent 必须在完成之前发出该输出。max 默认为 1。
迁移单体文件
把 environments 保留在 hub.yml 中,把环境列表转换为具名映射,并把原先的每个触发器移到它自己的 .paseo/workflows/<name>.yml 文件中。把共享的提示词文件移到 .paseo/workflows/partials/。在 agents 下定义完整的具名 Agent 配置,并用有限的具名 Agent 选择替换动态的 Provider 字段。
Hub 不读取 TOML 或单体的 triggers 部分,CLI 也不会改写这两种格式。
完整的路由示例见 workflow。
Agent 延续
自包含的控制台触发器文档接受 run.continuation:
| 值 | 行为 |
|---|---|
{mode: conversation} | 默认值。为事件所属的对话复用项目中的 Agent;事件没有对话时创建新的 Agent。 |
{mode: key, key: "support-${{ paseo.inputs.ticket }}"} | 为求值得到的自定义键复用项目中的 Agent。 |
{mode: new} | 每次到达都创建新的 Agent。 |
键使用现有的表达式语法,必须解析为长度不超过 512 个字符的非空字符串。自定义键和 Provider 的对话标识位于不同的命名空间。不同项目中的相同键不会共享 Agent。
已有的会话会保留它的 daemon、Agent 配置、目标、环境和工具契约。为同一个键修改这些设置会失败并给出说明;请选择另一个键或 New agent。提示词和输出目标属于每次到达,可以变化。worktree 分支在会话首次创建时选定,并在之后的到达中复用。
后续消息会引导正在运行的 Agent,但不会延长它的运行截止时间或凭据有效期。当 run.env 中有 run.github 授权或连接令牌时,后续消息共享正在运行的 Agent 的凭据。所有请求都完成后,Hub 会撤销租用的令牌;下一次到达会用新的凭据启动新的 Agent。没有临时凭据的 Agent 在完成后可以被复用。
升级
在启用新版 Hub 之前,请先升级已连接的 Paseo daemon。Hub 需要 daemon 的常规 Agent RPC 和请求回执能力;较旧的主机会产生一个可操作的发起错误。
Hub 的数据库迁移会添加会话以及可为空的执行关联。已有的执行会保留它们已保存的启动契约和执行专属的 MCP 端点,直到完成。已有自包含触发器文档的新到达使用对话默认值。历史上的 Agent 不会被回填到会话中。
旧版的多 step workflow 文件包保持原有行为。把它转换为自包含触发器时,会显式写入 mode: new;准备好复用 Agent 时,在编辑器中修改它。
赞助商
Cloud coding agents
- 成为赞助商