@ agent-assistant/webhook-runtime (英语)
共享 Webhook 运行时间原始, 用于将提供者事件正常化、 注册 当地或HTTP的消费者, 并持续推动事件.
此套件会删除重复的 Webhook 管道, 即 sage / nightcto / 今天我高年级的德夫 手卷.
A2A 发现和RPC
registerA2aRoutes 在任何Hono应用中加入一个可重复使用的公用代理对代理发现表面. 它出版 /.well-known/agent-card.json,引导遗产 /.well-known/agent.json 操作 message/send JSON-RPC呼吁 /a2a/rpc。 。 。 .
提供代理名称、公共 URL、版本、技能描述符、认证符和 dispatchSkill 函数。 帮助者用 @relaycast/a2a解码 data 或 JSON 密码 text 消息部件,默认情况下验证 Bearer 认证,并返回一个标准的 A2A 任务/消息对。 使用 buildAgentAssistantA2aCard 当你只需要生成JSON卡.
个人合同(参照运行时间)
每个针对 Cloudflare 运行时间的软件包都输出出两个功能 每个入侵的表面 :
// Ingress side: signature verify + parse + persona-side policy
// (rate-limit, thread-gate, etc.). Returns a turn descriptor that is safe to
// enqueue, or an "ack-only" sentinel.
export function parseSlackWebhook(
req: Request,
env: PersonaBindings,
): Promise<PersonaTurnDescriptor | PersonaAckResponse>;
// Consumer side: runs the harness work synchronously relative to the queue
// handler. Any internal ctx.waitUntil is for legitimately out-of-band telemetry
// only; the turn itself is awaited.
export function runPersonaTurn(
descriptor: PersonaTurnDescriptor,
env: PersonaBindings,
ctx: ExecutionContext,
): Promise<void>;
为什么这个形状,匹配 cloud/workflows/cf-runtime/SPEC.md 变异 6:
- Dedup由每发一次的Cf-runtime内侵包装机拥有. 个人
slack/GitHub 事件取消。 一个描述器到达
runPersonaTurn被建筑拆除。 使用SlackEventDedupGate(此处从@agent-assistant/surfaces作为犬科动物 原始的,有你自己的KV后卫SlackEventDedupStore。 。 。 . - 签名核查留在内部
parseSlackWebhook因为人 拥有每个工作空间的签名秘密搜索. runPersonaTurn绝对不能让孤儿承诺过后返回。 那个假的ExecutionContextcf-runtime 提供的收集waitUntil承诺和 在消费者回来前等待他们, 修复Slack-silence bug.
第一个具体的例子就是Sage的W0分法: parseSlackWebhook 加号
runSageTurn 运入 @agentworkforce/[email protected]新建人名
(单位:千美元)nightcto, (中文(简体) ), my-senior-dev)遵循相同的模式.
不要通过电线人 registerSlackSpecialistConsumer 从
./specialist-bridge 在 Cf-runtime 架构中。 那座桥开着
专家呼唤同步在网络呼唤中
cf-runtime 旨在删除的孤儿承诺模式。 组合 a
specialist_call 队列消息并恢复到一个
specialist_result:<turnId> 启动.
交互式 CLI
运行时间端到端的最快方式是 REPL at
examples/cli.ts数字 :
cd packages/webhook-runtime
npm install # first run only
npm run cli # boots runtime on http://127.0.0.1:3777
你会看到:
webhook-runtime listening at http://127.0.0.1:3777
Registered consumers: echo (all slack), github-sim (app_mention)
Type 'help' for commands.
webhook>
图标
| 命令 | 效果 |
|---|---|
help | 打印命令列表 |
url | 打印网点 URL |
personas | 列出个人目录 |
use <id> | 将一个人登记为活跃的消费者 |
drop <id> | 由 id 注销消费者注册 |
consumers | 列表当前活动人物 |
mention <text> | 后一个 app_mention 固定到 /webhooks/slack |
slack <json> | 原始Slack JSON给 /webhooks/slack |
nango <json> | 包装为 JSON {from:"slack", payload:<json>} 转到 /webhooks/nango |
file <path> | 从磁盘和 POST 装入 JSON /webhooks/slack |
quit 编号 : exit | 关闭( SIGINT 同时工作) |
每个邮件都会打印 HTTP 状态, 扇出结果
(单位:千美元)succeeded 编号 : failed 编号 : skipped 编号),以及由
活动人物.
覆盖端口 PORT=4000 npm run cli。当 REPL 运行您
也可以从另一个外壳击中相同的 URL curl。 。 。 .
人——交换SDK接头直播
CLI号舰载着目录 examples/personas.ts。每个人的地图
不同的选择 @agent-assistant/webhook-runtime 消费者可以做.
echo 财务报告和审定财务报表 github-stub 启动时注册;其余选择
与 use <id>。 。 。 .
| 个人a | 旋转 |
|---|---|
echo | kind: "local" 消费者没有上游。 基线——显示正态事件形状. |
github-stub | registerSlackSpecialistConsumer 带了根棍子 specialistFactory 返回罐头串。 展示专家-桥接线 而不接触真正的专家. |
github-real | 同样的消费者,但是 没有工厂覆盖 - 属于默认动态导入 @agent-assistant/specialists练习真正的SDK路径. |
byoh-relay | 工厂动态进口 @agent-assistant/harness 并引导活动通过 createAgentRelayExecutionAdapter练习BYOH路径. |
http-forward | kind: "http" pOST 常规事件给 HTTP_FORWARD_URL用于通入网络。 一个本地调试服务器. |
failer | 工厂抛出. 显示 failed[] 扇出条目和 [error] 日志线没有设计破损的有效载荷. |
非违约人的环境先决条件如下:
github-real—— 说@agent-assistant/specialists已建成,其运行时间可解析.byoh-relay- 安装@agent-assistant/harness(宣布为可选的对等数据;人物为动态输入)@agent-assistant/harness/agent-relay) (中文(简体) ). 需要一个运行中的中继经纪人和一个已经在频道注册的工人(适配器拒绝)sendMessage至未知代理名称Agent "<name>" not found) (中文(简体) ). 最轻松的路径:在单独的终端上运行捆绑的工人桥-见下文"BYOH端到端". 内文 vars:RELAY_CHANNEL, (中文(简体) ),RELAY_WORKER, (中文(简体) ),RELAY_AUTO_SPAWN, (中文(简体) ),RELAY_CLI, (中文(简体) ),RELAY_MODEL。 。 。 .http-forward—— 说HTTP_FORWARD_URL指向任何JSON接受的终点.
实例会议:
webhook> personas
webhook> use failer
webhook> mention hi # watch the fanout: github-stub succeeds, failer fails
webhook> drop failer
webhook> use http-forward # HTTP_FORWARD_URL must be set before this
webhook> mention ping # same event now fans out to the HTTP target too
BYOH 本地端对端
这个 byoh-relay 发表 agent-assistant.execution-request.v1
给真正的中继经纪人发送信件 名称为工人 必须注册的
在请求到达前的频道上 捆绑的桥在
examples/byoh-worker.ts 是那个工人,它听, 引用
非交互式 CLI 会话( Claude / codex / opencode / gemini),并发出 a
遵守协议 agent-assistant.execution-result.v1 回来.
在两个终端上与 REPL 一起运行 :
1号终点站——工人:
# from the repo root
npm run worker -- --cli claude --model claude-sonnet-4-6
# or whichever CLI you have installed:
npm run worker -- --cli codex
npm run worker -- --cli opencode --model anthropic/claude-sonnet-4-5
npm run worker -- --cli gemini
你会看到:
[byoh-worker] registered as 'specialist-worker' on channel 'specialists' (cli=claude, cwd=/Users/you/...)
[byoh-worker] invoking 'claude' per request; timeout=120000ms
2号航站楼 — Webhook 运行时间:
# from the repo root
npm run agent
这开始REPL RELAY_AUTO_SPAWN=false (你开始的工人)
1号航站楼拥有该责任),并设置为 specialists 频道
财务报告和审定财务报表 specialist-worker 名称。 然后当场说:
webhook> use byoh-relay
webhook> mention summarize the open github issues
这个 byoh-relay 性爱 createAgentRelayExecutionAdapter 将出版
请求 specialist-worker一号航站楼的工人收到它,
引用所配置的带有指令的 CLI 作为快取,抓取 stdout,
并回答结果。 你会看到最后的回复记录下来
终端 2 为 [byoh-relay] channel=C_CLI eventType=app_mention -> <CLI output>。 。 。 .
用于测试而不花费 API 令牌的 Bash stub
npm run worker -- --cli bash --cli-args 'read -d "" prompt; echo "stub echoed: ${prompt:0:40}"'
用于验证运输,而不援引任何真实的AI. 一样
模式驱动 src/byoh-worker-bridge.test.ts 烟雾测试.
工人旗帜
| 旗帜 | 含义 | 默认 |
|---|---|---|
--cli <name> | claude 编号 : codex 编号 : opencode 编号 : gemini 编号 : bash | claude |
--cli-args <string> | shell-split 附加参数,只对 --cli bash | (空虚) |
--channel <id> | 要监听的中继频道 | $RELAY_CHANNEL 或者说 specialists |
--worker-name <name> | 在经纪人注册的代理名称 | $RELAY_WORKER 或者说 specialist-worker |
--cwd <path> | 经纪人 cwd (用于 .agent-relay/connection.json (发现) | process.cwd() |
--model <id> | 模型传入CLI | $RELAY_MODEL 或 CLI 默认 |
--timeout-ms <n> | 每引用 CLI 子进程超时 | 120000 |
CLI证明了什么
运行 REPL 练习这些代码路径 :
- HTTP 摄入量 - 霍诺的路线在
/webhooks/slack财务报告和审定财务报表/webhooks/nango内src/http-runtime.ts,包括: 畸形的尸体. - 有效载荷分析和正常化 —— 说
parseSlackEvent内src/slack-parser.ts。让您确认检测到的eventType, (中文(简体) ),workspaceId, (中文(简体) ),channel, (中文(简体) ),deliveryId,以及data字段看起来像 给生的Slack载荷. - 南戈信封正在打开 - 那个
/webhooks/nango路径条{from, connectionId, payload}并重新规范内部Slack事件. - 登记册扇形语义 —— 说
webhook-registry.ts: 上游比对, 消费者之间的错误隔离以及total编号 :succeeded编号 :failed编号 :skipped计数返回到 HTTP 呼叫器. - 专家-桥接线形状 —— 说
registerSlackSpecialistConsumer构建一个能够构建instruction从活动,电话specialistFactory,引用handler.execute,并将结果交给egress。 。 。 .
换句话说,如果你的事件是 "事件没有达到正确 消费者"或"我的载荷正常化 错误",CLI是一个完整的 复制.
CLI 不默认证明什么
仅登记了默认的人(echo + 键 github-stub页:1
REPL确实如此 没有 验证 :
- 真正的专家来自
@agent-assistant/specialists处理 事件正确(钢管厂从来不碰它)。 • 使用github-real。 。 。 . - BYOH / 中继执行适配器将事件传递给一个工人和
返回真实
ExecutionResult− 使用byoh-relay。 。 。 . - 那外向的外向——发回Slack,写给DB,
通知队列——工作.
github-stub"egress"只是日志。 • 使用http-forward。 。 。 . - 黑请求签名验证. 没有签名的中间软件 今天进入HTTP运行时间 没有一个人能覆盖这个.
- 除了Slack以外的任何供应商.
/webhooks/nango只接受from: slack今时.
上面的每个人都是选入探测器 前三发子弹都满了 可以通过互换个人地址;后两款仍需要更改代码.
线程指南
切入一个问题时,先到达 CLI 并使用输出到 本地化 :
| 症状 | 可能原因 | 在哪里寻找 |
|---|---|---|
POST 返回时 [400] {"error":"..."} | 有效载荷没有解析 | src/slack-parser.ts |
[200] 但你的消费者在 skipped | 上游不匹配 | 上游传至 registerSlackSpecialistConsumer 编号 : registry.register |
[200] 但你的消费者在 failed | 处理器抛出 | 通过登录的堆栈 [error] - 检查 area 源模块的字段 |
已正常化 event.data 缺少您期望的字段 | 事件形状漂移 | src/slack-parser.ts - 延长规范化程序 |
/webhooks/nango 返回时 Unsupported Nango provider | 信封 from 没有 slack | src/http-runtime.ts validateNangoSlackEnvelope |
succeeded 当您预期击中时空出 | 未登记或在错误提供者上登记的消费者 | registry.register(...) 呼叫网站 |
每个这些地图到一个文件,你可以在同一REPL中编辑并重新测试——
重复之间没有建设步骤,因为CLI运行经过 tsx。 。 。 .
运行测试套件
npm test # all suites
npm test -- slack-parser # filter to one file
npm test -- --reporter=verbose
四个套房直接覆盖了原始人: webhook-registry, (中文(简体) ),
slack-parser, (中文(简体) ), http-runtime, (中文(简体) ), specialist-bridge。 。 。 .
直接使用原始语言
如果您想要将运行时间嵌入您的进程, 而不是使用 CLI,形状看起来像:
import {
createWebhookRegistry,
parseSlackEvent,
startHttpRuntime,
} from "@agent-assistant/webhook-runtime";
const registry = createWebhookRegistry();
registry.register({
id: "my-consumer",
kind: "local",
provider: "slack",
handler: (event) => console.log(event.eventType, event.data),
});
const runtime = startHttpRuntime({ registry, port: 3777 });
console.log(`listening at ${runtime.url}`);
消费者生命周期
WebhookRegistry 在长生不老的记忆图中保留注册的消费标识.
启动时登记稳定流程级消费者一次. 如果一个呼叫者创建
消费者的识别码是动态的 它必须叫 unregister(id) 当那个消费者
不再需要或 clear() 在拆卸时发布条目.