通知
CLI 事件与自托管的推送通知 (Expo + FCM/APNs)。
Kaiwu 采用 Expo Push Notifications 作为推送机制。当前架构的设计如下:
- 移动端 App 注册 Expo 推送令牌(push token) 并保存至服务端。
- 服务端按账户存储推送令牌(不负责发送推送载荷)。
- CLI 从服务端获取用户保存的令牌,并通过 Expo 的推送 API 发送通知(例如:“已就绪!”或权限请求)。
通知支持的场景
当会话需要处理时,Kaiwu 会向你发送通知,涵盖以下情况:
- 就绪通知:当前轮次执行完毕,Agent 正在等待后续操作
- 权限请求:工具或操作需要人工审批
- 用户操作请求:Agent 需要结构化的人工响应
在移动端 App 上,权限和操作请求通知还会提供操作按钮:
- 权限请求:
Allow/Deny - 用户操作请求:
Answer
当前设计的行为偏向稳妥克制:
- 点击通知会打开目标会话
- 点击通知中的操作按钮同样会打开 App
- 仅当通知对应的服务端处于活跃状态,或已保存在当前设备上时,Kaiwu 才会自动发送权限响应
- 若该服务端尚未保存,Kaiwu 会引导你走最安全的添加/切换流程,而不会在错误的服务端上静默批准操作
有关具体的路由行为,请参阅通知路由。
更丰富的通知详情
与常规的“应用需要权限”这类笼统提示不同,权限与操作请求通知包含了更丰富的上下文信息。
在当前版本中,Kaiwu 会尽可能展示:
- 请求调用的工具或请求类型
- 在兼顾实用与安全的前提下,展示简短的详情提示
详情提示的示例包括:
- 简短的文件提示,如
src/file.ts - 命令提示,如
Command: npm - 紧凑的问题计数,如
1 question或3 questions
Kaiwu 不会将工具的完整原始输入倾倒在推送通知中。这样设计既能提供足够的信息供你快速决策,又避免在锁屏界面泄露不必要的命令参数或请求载荷。
平台适配细节:
- iOS 可将工具或请求名称显示为通知副标题
- Android 为权限请求和操作请求分配了独立通知渠道,便于用户在系统层级分别调整其通知行为
Webhook 通知
Expo 推送并非唯一的触达方式。前往设置 → 通知 → Webhook 通知,即可将同样的远程活动事件发送至自有的 HTTP 端点(如机器人、内部仪表盘、家庭自动化 Webhook 等)。
填写 URL 即可添加通知渠道。每个渠道均具备独立的配置开关:
- 主题——
ready、permissionRequest与userActionRequest,创建渠道时默认全开。可关闭不需要接收的事件。 - 就绪事件中的消息预览——默认关闭。如果不希望端点接收消息正文,请保持关闭。
- 签名密钥——可选,后文会详细说明。
添加渠道后即刻生效;无需删除渠道,随时可以直接停用。
Kaiwu 发送的数据内容
请求为 POST,附带 content-type: application/json,请求体结构如下:
{
"channelId": "webhook-example-com-hooks-Kaiwu",
"createdAt": 1755690000000,
"topic": "permission_request",
"content": { "title": "…", "body": "…" },
"session": { "sessionId": "…", "title": "…" },
"request": {
"requestId": "…",
"kind": "permission",
"toolName": "…",
"toolDetails": null
},
"metadata": {}
}对于 ready 事件,request 的值为 null;而在权限和用户操作事件中,该字段包含具体内容,其中 kind 为 permission 或 user_action。凡是非 2xx 响应均视为推送失败。
验证签名
若为渠道配置了签名密钥,Kaiwu 会对每次推送签名:
x-Kaiwu-signature-256: sha256=<hex>该签名是以密钥对原始请求体计算得出的 HMAC-SHA256 哈希值。请在解析 JSON 之前,直接基于收到的原始字节流计算签名;重新序列化载荷无法还原出一致的摘要。
import { createHmac, timingSafeEqual } from 'node:crypto';
function isFromKaiwu(rawBody, header, secret) {
const expected = `sha256=${createHmac('sha256', secret).update(rawBody).digest('hex')}`;
const a = Buffer.from(expected);
const b = Buffer.from(header ?? '');
return a.length === b.length && timingSafeEqual(a, b);
}若未设置密钥,请求中将不包含该 Header,此时你的端点无法辨别请求是真实推送还是撞库猜测。只要端点涉及关键业务逻辑,务必配置签名密钥。
通知偏好设置
App 提供了通知偏好设置,方便用户按需调整 Kaiwu 的打扰频率。
目前的设置项包括:
- 账户维度的推送通知总开关
- 针对就绪通知、权限请求以及用户操作请求的独立开关
- App 打开时的应用内通知行为:
Full、Silent或Off
当你正停留在某个会话页面时,Kaiwu 会静默该会话的通知,避免在阅读时造成重复打扰。
配置指南
1) 服务端(任意部署方式)
服务端必须暴露以下推送令牌路由:
POST /v1/push-tokensGET /v1/push-tokensDELETE /v1/push-tokens/:token
若自托管服务端,请参阅:Deployment → Docker / Environment variables。
2) 移动端 App(iOS 与 Android)
自托管模式下的推荐流程如下:
- 先自托管服务端;
- 使用 Kaiwu App,并将 Server URL 指向你的服务实例。
在此架构下,你无需自行配置 APNs/FCM。App 已内置所需的推送通知凭据,服务端只需存储用户的 Expo 推送令牌。
3) CLI(发送方)
CLI 发送通知的机制为:
- 调用服务端接口,获取已认证用户保存的 Expo 推送令牌。
- 通过 Expo 推送 API,向这些令牌发送推送载荷。
若用户自行运行服务端与 CLI,必须确保:
- App 与 CLI 指向相同的服务端 URL。
- 服务端支持存储推送令牌(即上述路由生效)。
自托管检查清单
推荐方案(仅自托管服务端)
- 部署服务端。
- 在 Kaiwu App 中,将 Server URL 配置为你的服务端地址。
- 运行 CLI,同样指向该服务端 URL。
一旦 App 向服务端注册了推送令牌,CLI 即可通过 Expo 发送通知(包括权限通知)。
多服务端支持机制
通知系统具备多服务端感知能力。
当收到通知且其目标服务端与 App 当前活跃的服务端不一致时,Kaiwu 会尝试执行正确的路由:
- 若目标服务端此前已保存,Kaiwu 会先自动切换至该服务端
- 若设备上尚未配置任何服务端,Kaiwu 可直接初始化该服务端配置,确保深度链接正常跳转
- 若 App 中已有保存的服务端,但来访的服务端并不在其中,Kaiwu 会打开服务端设置并自动填入 URL,由你核对后显式添加
添加并切换到该服务端后,Kaiwu 会自动继续跳转至最初的会话或请求。
API Key 限制(Android / Firebase)
针对 Firebase Android 配置,嵌入在 google-services.json 中的 API Key 属于客户端凭据。其安全性依赖于访问限制,而非保密性:
应用限制(推荐)
在 Google Cloud Console 中,将该 API Key 限制为:
- Android 应用
- 你的应用包名
- 签名证书的 SHA-1 指纹
如何获取所需添加的 SHA-1 指纹
在开发和发布流程中,通常需要多个 SHA-1 指纹:
- Debug / 开发版构建(本地开发 keystore)
- Release 正式版构建(发布/上传 keystore)
- Play 商店安装版(启用后的 Play 应用签名密钥)
常见的获取途径:
- EAS:查看 Android 凭据并复制 keystore 的 SHA-1(上传/发布密钥)。
- Play Console(启用 Play 应用签名后):应用完整性 → 应用签名密钥证书 → SHA-1。
- Firebase Console:项目设置 → 你的应用 → Android 应用 → 添加 SHA-1 指纹(以便 Firebase 识别签名证书)。
注意:EAS 构建列表中显示的“指纹”与 Android 签名证书的 SHA-1 并不是一回事。
API 限制(Cloud Messaging 推荐最小白名单)
如果仅使用 Firebase Cloud Messaging,Google 官方建议将 Firebase Key 的 API 白名单限制为:
- Firebase Management API(
firebase.googleapis.com) - Cloud Logging API(
logging.googleapis.com) - Firebase Installations API(
firebaseinstallations.googleapis.com) - FCM Registration API(
fcmregistrations.googleapis.com)
若启用了其他 Firebase 产品(如 Firestore/Storage/Auth 等),请相应扩充白名单。
开发版构建(可选)
默认情况下,Kaiwu 不会在 __DEV__ 中注册推送令牌,以防止本地开发期间频繁更替令牌。
如需在开发版构建中启用推送令牌注册,请配置:
EXPO_PUBLIC_ENABLE_DEV_PUSH_TOKEN_REGISTRATION=1