背景
供应商请求 payload 的最终装配由 payloadPipeline.ts 内一个硬编码的 10 中间件数组完成(anthropic 缓存、长上下文 beta、codex storage/cache hint、native web search、xai/deepseek compat、native attachments、gemini thought guard、debug logging)。新增一个 payload 变换必须直接修改该数组,无法按需注册/卸载,测试也无法隔离验证链序。
目标
把 payload 中间件的组织权反转到 LlmService seam(DSH 风格拦截器注册化,stack 第 4 层):
- 具名
PayloadInterceptor(name + intercept),llm.use(interceptor) 返回幂等 dispose,同名重复注册抛错
- 现有 10 个中间件原样包装为具名默认拦截器按现有顺序预注册;
payload-debug-logging 钉住链尾,自定义拦截器插入默认之后、链尾之前(自定义改动仍被调试日志观测)
finalizeProviderStreamOptions 从注册表组合执行(带失效缓存避免热路径重组);消费方两处调用零改动,中间件实现文件零改动
- 未注册任何自定义拦截器时行为与现状严格等价
验收标准
- 默认注册顺序快照测试锁定 10 个名字的执行顺序
- 空注册态下 finalize 输出与旧数组组合逐字段一致(多形态参数矩阵)
- golden 两套件与既有回归测试零修改通过
- 不触共享 UI 层与 src-tauri
背景
供应商请求 payload 的最终装配由
payloadPipeline.ts内一个硬编码的 10 中间件数组完成(anthropic 缓存、长上下文 beta、codex storage/cache hint、native web search、xai/deepseek compat、native attachments、gemini thought guard、debug logging)。新增一个 payload 变换必须直接修改该数组,无法按需注册/卸载,测试也无法隔离验证链序。目标
把 payload 中间件的组织权反转到 LlmService seam(DSH 风格拦截器注册化,stack 第 4 层):
PayloadInterceptor(name + intercept),llm.use(interceptor)返回幂等 dispose,同名重复注册抛错payload-debug-logging钉住链尾,自定义拦截器插入默认之后、链尾之前(自定义改动仍被调试日志观测)finalizeProviderStreamOptions从注册表组合执行(带失效缓存避免热路径重组);消费方两处调用零改动,中间件实现文件零改动验收标准