Run the dsh-archive-agent-notes audit over every active Agent Note on current master, judging each record by whether its rationale still guides work rather than by size or age. - Archive 453 implemented bilingual triplets (417,882 English words): completed UI chrome, narrow adapters, closed bug fixes, implementation walkthroughs whose package READMEs, docs pages, generators, or successor notes now carry the useful behavior, and 51 records fully superseded by a later active note. Keep 201 implemented notes whose ownership rules, negative guarantees, durable or wire semantics, security rules, reintroduction conditions, or still-tempting rejected alternatives remain useful. - Reject 7 proposals whose premise is gone or whose work shipped in amended form under other records; delete 2 rejected notes that no longer prevent a plausible mistake. - Retarget every remaining inbound link to the archived path, and repair active prose that named an archived record as the owner of a live fact: parenthetical citations drop, ownership sentences redirect to the README, docs page, or active note that states the fact, and history citations say so. Chinese files link the English archived path because the pairing gate treats the frozen tree as outside the bilingual corpus. - Seal 1,359 new frozen artifacts; existing seals are unchanged and outbound links from archived notes are neither inspected nor repaired. - Regenerate docs/config-catalog.md after the hook-bridge comment edits shifted two source line numbers.
2.4 KiB
2.4 KiB
Agent Note: 结构化错误分类体系
Status: implemented Archived: 2026-09-04
English | 中文
问题
故障跨越 seam 时只是裸字符串。工具错误被扁平化为一个文本块(name、code 和 stack 全部丢失),导致未来的沙箱/重试插件无法区分 ENOENT 和 EACCES,模型也未能获得本可提供的更具可操作性的反馈。非 Error 的 throw 退化更严重:agent loop(智能体循环)将其包装为 new Error(String(x)),丢弃了所有 code。而 LlmError 是系统中唯一的类型化错误,没有共享基类,消费方无法对其进行通用的 instanceof 判断。
决策
在 dsh-llm(叶子包,所有其他包都已依赖它,不引入新的依赖边)中引入一个 HarnessError extends Error 基类:稳定的 code(与 message 分离)、通过 ErrorOptions 进行 cause 链接、name 默认为子类名。isHarnessError 在 seam 处做类型收窄。
LlmError和ToolArgsError(dsh-tools)继承该基类,保留各自既有的 code。ToolExecutionResult新增可选字段error: { name, code },在注册表的 catch 中当抛出值为HarnessError时填充。agent loop 将其转发到tool/result会话事件(该事件也新增了同一可选字段),使结构化的失败信息保留在日志中,供重试/沙箱插件和回放使用。面向模型的文本块保持不变。- agent loop 的
toError将非 Error 的 throw 包装为HarnessError(code: 'UNKNOWN',原始值作为cause链接),而非裸Error;这样即使是不规范的 throw 也能携带可路由的 code 进入会话的error事件(该事件此前已暴露code)。
后果
- 错误端到端可机器路由:插件可以基于
error.code分支,而无需对消息做子串匹配。 - 一个基类被广泛导入,但它位于所有包已经依赖的包中,代价仅是一条 import 语句,而非新的依赖边。
deriveMessages不会将error暴露到模型历史中——模型仍然看到文本块;结构化字段服务于代码和回放。- 参数校验保留其既有的 code 和行为;包自有的诊断不变式独立携带稳定 code,使不变式注册表无需导入产品包。共享基类增加了跨 seam 的路由元数据,不改变面向模型的文本。