跳到主要内容

Envoy

Envoy

一个 envoy 是工作区 Agent 通过别人的线路被触及的方式——Telegram 或 WhatsApp。到达的是一条来自工作区可能没有用户行的人的消息,所以关键问题不是“我如何说这种协议”,而是 Agent 回答时以谁的权限行事 。这就是 policies ,也是为什么 envoy 是源码中的声明而不是宿主配置:答案应该出现在一次 diff 里。

传输本身仍然由宿主提供。保持一个 socket 打开不是按需伸缩(scale-to-zero)的租户能做的事,所以工作区指明传输方式,宿主提供它——Colony 拥有凭据与 socket。

声明

每个 envoy 一个文件,位于 src/envoys/+<lower_snake_case>.ts ;文件名就是 envoy 键。

// src/envoys/+sales_desk.ts
export default {
	transport: 'telegram',
	audience: 'public',
	policies: ['commercial_shared', 'sales_rep'],
	groupMessages: 'disabled',
	task: 'Answer questions about quotes and accounts for this customer.'
} satisfies Envoy;
字段含义
transport触及它的线路( telegramwhatsapp )。传输方式决定了地址如何规范化与比较。
audience谁可以触及它:`public`(任何能发消息的人)或 `authenticated`(已验证地址属于他们的成员)。这是可达性而非对话形态——后者由 `groupMessages` 回答。
policies该 envoy 可做的全部——绑定到生成的策略名,因此 envoy 不能指向不存在的策略。它是一个数组,安全仅因为编译器拒绝在同一集合上无条件授权与收窄授权并存。
taskEnvoy 的常驻指令,叠加在工作区的 `src/+agents.md` 之上。
groupMessages群消息如何触发一轮:`disabled`、`mention_or_reply` 或 `all`。
delegation该 envoy 是否可以创建并协调沙箱 Agent 会话:`enabled`(默认)或 `disabled`。窄入口 envoy 应禁用它,独自行动。

Agent 以谁的权限行事

Envoy 可能是群聊,所以背后没有可以继承权限的单独个人。每个声明的 envoy 都获得自己的 Agent 主体 ——恰好持有它声明的 policies ,此外一无所有——并且每条入站消息在 Agent 循环开始前都以该主体重新进入工作区。公开 envoy 的线程路由到管理员收件箱,不进任何成员收件箱;策略没有任何授权的 envoy 什么也做不了,与任何其他客户端一样,相同的钩子与审批门都适用。

工作台、文档与委派

每个 envoy 都只有 一个共享工作台 ,只保存委派 Agent 会话。入站文本和文档绝不进入工作台:每个 chat_session 都拥有自己的转录、入站缓冲区、排空租约和 chat_document 绑定。读取文档时,必须同时解析对象键与会话绑定,才会返回字节。共享工作台可以安全提供 spawn_subagent ,因为其中没有发送者上传的内容。

delegation 设为 'disabled' 后,该 envoy 完全不会派生子 Agent——正是窄入口表面应有的形态。

一次突发消息就是一个回合
Envoy 对话落入租户数据库—— envoy_key 的 `envoy_key` 把外部对话绑定到 chat_session 。入口只做准入与缓冲,不调用模型;一个带租约的排空任务按顺序取得整批消息,持久保存完整发送者归属,只运行一个回合,并且最多发送一条已完成回复。
  • Agent ——每条 envoy 消息都会经过的循环
  • 策略 ——envoy 的主体可以看到和更改什么
  • 工作区源码 ——envoy 角色在布局中的位置