Hub workflow
一个 workflow 文件包含一个触发器,以及它启动的有序 step。文件从 .paseo/workflows/*.yml 中发现。
你的第一个 workflow
假设 .paseo/hub.yml 定义了一个名为 dev 的环境和一个名为 codex 的 Agent。添加 .paseo/workflows/slack-help.yml:
name: slack-help
on: slack.mention
max_runtime: 1h
filters:
workspace: T01234567
channels: [C01234567]
from_users: [U01234567]
steps:
- id: answer
environment: dev
max_runtime: 30m
idle_timeout: 5m
agent: codex
prompt:
- text: |
Answer the request. Call hub.reply once, then call hub.finish_execution.
<user-prompt>
${{ paseo.prompt }}
</user-prompt>
allow_outputs:
- { type: slack.reply, max: 1, required: true }
Hub 会先去掉提及和已声明的输入头部,再把剩余文本作为 ${{ paseo.prompt }} 提供。回复能力在 Slack 触发器旁边显式声明。Discord 使用 discord.reply;GitHub 使用 step 级的 github 块,而不是 hub.reply。
选择 step 在哪里运行
字面值选择一个命名环境:
environment: dev
有限取值的输入可以在多个完整的命名环境中选择:
name: route-repository
on: manual.run
max_runtime: 1h
filters:
from_users: [automation]
inputs:
repo:
type: string
required: true
choices: [paseo, hub]
steps:
- id: work
environment: ${{ paseo.inputs.repo }}
max_runtime: 30m
idle_timeout: 5m
agent: codex
prompt:
- text: ${{ paseo.prompt }}
激活时会检查每一个 choices 结果。环境对象永远不会被 workflow 合并或覆盖。
选择 Agent
step 可以选择一个命名 Agent:
agent: codex-safe
也可以提供一份完整的静态内联配置:
agent:
provider: claude
mode: full-access
对于动态路由,用一个有限取值的表达式在多个完整的命名 Agent 中选择:
name: route-agent
on: manual.run
max_runtime: 1h
filters:
from_users: [automation]
inputs:
agent:
type: string
required: true
choices: [codex-safe, claude]
steps:
- id: work
environment: paseo
max_runtime: 30m
idle_timeout: 5m
agent: ${{ paseo.inputs.agent }}
prompt:
- text: ${{ paseo.prompt }}
如果 codex-safe 在 hub.yml 中包含结构化的沙箱选项,选择它时会原样带上这些选项。像 provider: ${{ paseo.inputs.agent }} 这样的动态内联对象会被拒绝。
由分类器路由
前面的 step 可以返回有限取值的结构化输出。之后的权限必须由该输出 schema 中的 enum 或 const 加以限定。
name: classify-request
on: discord.mention
max_runtime: 2h
filters:
guild: "123456789012345678"
from_users: ["345678901234567890"]
values:
selected_environment: ${{ steps.classify.outputs.environment }}
selected_agent: ${{ steps.classify.outputs.agent }}
steps:
- id: classify
environment: hub
max_runtime: 5m
idle_timeout: 1m
agent: claude
prompt:
- include: partials/classify.md
- text: ${{ paseo.prompt }}
output:
schema:
type: object
required: [environment, agent]
properties:
environment: { enum: [paseo, hub] }
agent: { enum: [codex-safe, claude] }
additionalProperties: false
- id: work
environment: ${{ values.selected_environment }}
max_runtime: 1h
idle_timeout: 10m
agent: ${{ values.selected_agent }}
prompt:
- text: |
Complete the request. Call hub.reply once, then call hub.finish_execution.
- text: ${{ paseo.prompt }}
allow_outputs:
- { type: discord.reply, max: 1, required: true }
.paseo/workflows/partials/classify.md:
Choose one configured repository environment and one complete named agent configuration.
这个 workflow 保留了一个分类器分支和一个执行者分支,不需要为每个环境/Provider 组合重复编写执行者 step。
提示词与上下文
提示词块保持有序。include 的内容是文件的字面内容;Hub 不会递归扫描片段文本。
prompt:
- include: partials/instructions.md
- text: |
Provider evidence:
${{ paseo.context }}
<user-prompt>
${{ paseo.prompt }}
</user-prompt>
${{ paseo.prompt }}是规范化后的请求文本。它始终在编写的提示词中显式出现。${{ paseo.context }}让该 step 选择加入 Provider 上下文的物化,并插入 JSON。没有这个表达式时,Hub 不会获取或注入环境上下文。
把不受信任的请求文本放在界限清晰的块中。片段是指令文本,而不是隐藏的权限。
条件与有序输出
step 按文件顺序运行。if 可以读取输入、值和之前 step 的输出:
name: conditional-review
on: manual.run
max_runtime: 1h
filters:
from_users: [automation]
steps:
- id: inspect
environment: paseo
max_runtime: 10m
idle_timeout: 2m
agent: codex-safe
prompt:
- text: ${{ paseo.prompt }}
output:
schema:
type: object
required: [needs_review]
properties:
needs_review: { type: boolean }
additionalProperties: false
- id: review
if: ${{ steps.inspect.outputs.needs_review == true }}
environment: paseo
max_runtime: 30m
idle_timeout: 5m
agent: claude
prompt:
- text: Review the prior result and call hub.finish_execution.
step 不能读取之后的 step。step ID 在 workflow 内唯一。
告诉 Agent 调用哪个工具
allow_outputs 授予一项能力;它不会改写提示词。请写明需要执行的操作:
prompt:
- text: |
Send the final answer with hub.reply.
Then call hub.finish_execution.
allow_outputs:
- type: slack.reply
max: 1
required: true
max 默认为 1。required: true 会阻止成功完成,直到该能力被使用过。请把 Slack 和 Discord 的回复类型分别放在各自 Provider 的 workflow 文件中。
时限
workflow 的 max_runtime 限制整次运行。每个 step 都有自己的 max_runtime 和 idle_timeout;workflow 的剩余时间同时为两者封顶。超时会让运行失败,并停止之后的 step。
赞助商
Cloud coding agents
- 成为赞助商