fix(zcode): 真模型跑通后发现的三处缺陷(register / 工具活动日志 / SSE 关停)

真模型端到端(场景 A 通过:6893 事件、175 秒、530 字回信)把三处只有真跑才
暴露的问题照了出来:

1. **register 调不通**:驱动按 pi 的客户端 API 写了 `client.register()`,
   而本插件的 GatewayClient 没有这个方法 —— 靠此前手工注册过才没暴露。
   补上后才发现第二个坑:`/agent/register` 的认证与其它接口**不同**,
   它只认 `Authorization: Bearer` 或 **body 里的 `secret`**,不认 `X-Agent-Secret`
   头(其它接口认)。实测报错:
     HTTP 400 需要 Authorization: Bearer <密钥> 或 body 里的 secret
   所以没密钥时把 secret 放进 body。

2. **一轮 6893 条事件,日志里什么也看不见**:邮件驱动的会话没有界面,
   「模型正在干什么」只能来自日志,否则一个五分钟的回合与一个卡死的回合
   在外部完全一样。新增 `describeRunEvent`,只记工具调用与权限事件
   (全记等于没有日志),并由 runTurn 通过 onEvent 逐个交出来。

3. **关停没真断 SSE**:驱动调的是 `client.stopSSE?.()`,而客户端没有这个方法
   (`?.` 让它静默变成空操作)。改成持有 createSSEClient 的句柄并在关停时 stop。

验证:单元 325/325、授权桥 e2e 5/5、驱动 e2e(桩)7/7、快照握手 12 项。
This commit is contained in:
2026-09-12 16:16:37 +08:00
parent 6a7356ebe7
commit 42816b4d1e
4 changed files with 351 additions and 5 deletions

View File

@ -50,6 +50,28 @@ export class GatewayClient {
return headers;
}
/**
* 向网关登记自己(`POST /agent/register`)。
*
* 驱动启动时调一次。**不能省**:没登记过的新部署只会在心跳与 SSE 上
* 反复受拒,而日志里只有看不见的 4xx —— 而驱动的日志是唯一能被看到的地方。
*
* 注意这个端点的认证方式与其它接口**不同**:它只认
* `Authorization: Bearer <key>` 或 **body 里的 `secret`**
* 不认 `X-Agent-Secret` 头(其它接口认)。实测踩过:
* HTTP 400 需要 Authorization: Bearer <密钥> 或 body 里的 secret
* 所以没密钥时把 secret 放进 body。
*/
async register(extra = {}) {
if (!this.agentName) throw new Error('缺少 AGENTMAIL_AGENT_NAME');
if (!this.agentKey && !this.agentSecret) {
throw new Error('缺少 AGENTMAIL_AGENT_KEY 或 AGENTMAIL_AGENT_SECRET');
}
const body = { name: this.agentName, platform: 'zcode', ...extra };
if (!this.agentKey) body.secret = this.agentSecret;
return this.post('/agent/register', body);
}
async get(path) {
const res = await fetch(`${this.baseURL}/api/v1${path}`, { headers: this.authHeaders() });
return this.#parse(res, path);