fix(desktop): 供应商上游错误事件补 errorType 与本地代理 reqId (#2333) - #2472
Conversation
|
| Filename | Overview |
|---|---|
| apps/desktop/src/main/maker-host/provider-upstream-error-observer.ts | 新增 errorType 的 fail-closed 白名单提取,并在 observer 路径透传本地代理 reqId;上一轮指出的不可信 errorType 透传问题已修复。 |
| apps/desktop/src/main/maker-host/tests/providerUpstreamErrorObserver.test.ts | 覆盖标准及 bridge 错误体、未知与凭证形值、非 JSON、截断输入、reqId 透传和节流行为。 |
| apps/desktop/src/main/maker-ipc/channels.ts | 更新供应商上游错误广播的 payload 契约注释,记录两个新增可选诊断字段。 |
| apps/desktop/src/renderer/vite-env.d.ts | 将新增可选字段同步到 renderer 的 ElectronAPI 类型声明。 |
Sequence Diagram
sequenceDiagram
participant Provider as 自定义供应商
participant Main as Desktop main
participant Filter as errorType 白名单
participant IPC as PROVIDER_UPSTREAM_ERROR
participant Renderer as Renderer
Provider-->>Main: 上游错误响应
Main->>Filter: 解析 error.type
alt 命中已知类型
Filter-->>Main: errorType
else 未知、可疑或无效
Filter-->>Main: undefined
end
Main->>IPC: 广播错误事件(observer 路径附带 reqId)
IPC-->>Renderer: 结构化诊断字段
Reviews (9): Last reviewed commit: "chore: trigger design-basis recheck" | Re-trigger Greptile
MagicLizi
left a comment
There was a problem hiding this comment.
🔴 安全门:发现凭证/密钥内容
文件: apps/desktop/src/main/maker-host/__tests__/providerUpstreamErrorObserver.test.ts
行号: 148
类型: sk-api-key
需要的操作
- 移除该文件中的真实凭证内容,替换为占位符或测试桩
- 清理分支历史(该凭证已进入 Git 历史,需通过
git rebase/git filter-branch彻底清除) - 轮换已泄露的凭证(该密钥已暴露在公开仓库中,请立即到对应平台吊销并重新生成)
说明
- 在通过安全门之前,该 PR 不会被合并
- 修复后请 push 新 commit,自动审查会重新扫描
- 测试文件中如需使用 API key,请使用环境变量或测试专用占位符
|
维护者确认门触发:arch(核心路径改动 177 行 ≥ 150)。此 PR 为 讨论 issue:#2476 |
模型请求失败时错误横幅只显示状态码,中转层返回的 errorType(如 agent_router_api_error)只出现在日志里。它是判断失败性质的决定性信息—— 说明拒绝动作发生在中转层自身路由逻辑,而非官方 Anthropic(官方 400 的 error.type 只有 invalid_request_error)。同时本地代理 reqId 可让用户对照 日志拉出完整往返。 把这两个低风险字段补进 PROVIDER_UPSTREAM_ERROR 事件契约: - errorType:从错误体提取 error.type(只取 type,不取 message——message 常回显请求字段值会泄漏 prompt 片段,与 proxy 包 extractErrorType 同口径); 钳制到惯例形态(snake_case / kebab-case / 点分小写,限长 64)并拦截 凭证形前缀,避免上游可控字符串未经约束进入 renderer 契约(Greptile 建议); - reqId:observer 路径透传 compat-proxy 的 ResponseObserverCtx.reqId; localHandler 桥接路径绕开转发层,无此值,仅带 errorType。 契约向后兼容(新增 optional 字段),renderer 现有消费不受影响;仅 main 层结构化广播增强,不碰日志上传链路与脱敏规则。 Closes makecindy#2333 Signed-off-by: GardenX <20606485+gardenZzz@users.noreply.github.com>
3882f24 to
c2cb234
Compare
|
@MagicLizi 分支历史已按安全门要求清理:
请重新扫描,谢谢。 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2cb2340d6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…cindy#2333) chatgpt-codex-connector P1:responses-chat bridge 在 SSE 200 流内的错误帧 把 event.error 解包后 JSON.stringify 传给 onUpstreamError 回调,bodyText 形态是 { type, ... } 而非 { error: { type, ... } }。原提取器只解析后者, 桥接路径的 errorType 被遗漏。提取器改为同时接受两种形态(root.error 优先, 否则用 root 本身),补测试覆盖解包形态。 Signed-off-by: GardenX <20606485+gardenZzz@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: acded4bf84
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
维护者 arch 分析(makecindy#2476)非阻塞建议:测试名「errorType 仍取最新错误体」 与实际断言不符——30s 节流后只保留首次事件,断言得到的是 first_type。 改名「节流期间保留首次已广播事件」,避免后续维护者误解语义。 Signed-off-by: GardenX <20606485+gardenZzz@users.noreply.github.com>
|
@MagicLizi 已按 arch 门分析(#2476)落实两点后请重新扫描:
fork CI 已对新 HEAD |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d7a40362f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0becb91ed7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
chatgpt-codex-connector P1(两轮):前缀黑名单无法穷尽凭证形态—— ghp_...(GitHub PAT)、sk_ant_...、任意纯字母不透明 token 都能伪装成 「小写 snake_case」穿透。仓库既有 redactSensitiveText 也只在带 key=/ token= 字段名上下文时脱敏,对裸 errorType 值无效。 改为 fail-closed 已知错误类型白名单:只接受 Anthropic / OpenAI / litellm 与常见兼容网关的标准 error.type 枚举,外加 makecindy#2333 核心诊断信号 agent_router_api_error(中转层自身路由拒绝)。未知 / 可疑值一律省略 (errorType 是增强诊断字段,丢了只少展示细节,不损失主流程)。 测试改为断言凭证形(sk_/pk_/ak_/ghp_/bearer 各分隔形态)、未知类型、 点分非白名单形态全部缺省,白名单内类型保留。 Signed-off-by: GardenX <20606485+gardenZzz@users.noreply.github.com>
0becb91 to
f68be57
Compare
|
@MagicLizi 全部 review 已处理,请对当前 HEAD 已完成事项:
4 条 review 线程全部 resolve。13 条单测全过 + typecheck 通过,fork CI 已对新 HEAD 重跑(run 31524387725)。 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f68be57dc2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
安全门复核(MagicLizi CHANGES_REQUESTED)已复核最终 head
请 MagicLizi 对最终 head 重新扫描安全门。谢谢。 |
Signed-off-by: GardenX <20606485+gardenZzz@users.noreply.github.com>
这次改了什么
摘要
修复 #2333:模型请求失败时错误横幅只显示状态码,中转层返回的
errorType(如agent_router_api_error)只出现在日志里。它是判断失败性质的决定性信息——说明拒绝动作发生在中转层自身路由逻辑而非官方 Anthropic(官方 400 的error.type只有invalid_request_error,且不存在content-blocked)。同时本地代理reqId可让用户对照日志拉出完整往返。本 PR 把这两个低风险字段补进
PROVIDER_UPSTREAM_ERROR事件契约,为后续 renderer 详情展示铺路(#2206 正在改 renderer Toast 展示层,未合并)。变更类型
fix缺陷修复范围
ProviderUpstreamErrorEvent增加errorType?: string与reqId?: number(向后兼容,新增 optional 字段);errorType:从错误体提取error.type,只取 type、不取 message(message 常回显请求字段值会泄漏 prompt 片段,与 proxy 包extractErrorType同口径),非 JSON / 截断 / 字段缺失一律缺省;采用 fail-closed 已知错误类型白名单(Anthropic / OpenAI / litellm 标准error.type+agent_router_api_error),未知 / 可疑值一律省略——前缀黑名单无法穷尽凭证形态(ghp_.../sk_ant_...等纯字母 token 能伪装成小写 snake_case),白名单彻底杜绝上游把凭证塞进 type 字段穿透到 renderer;reqId:observer 路径透传 compat-proxy 的ResponseObserverCtx.reqId;localHandler 桥接路径绕开转发层,无此值、仅带 errorType;channels.ts契约注释与vite-env.d.ts类型投影。docs/dev-rules/remote-and-mobile-adaptation.md§ PR 门禁):PROVIDER_UPSTREAM_ERROR广播 payload 的字段;该广播由 Desktop 本地 renderer 消费,SSH 远程的 agent 进程 / 文件 / 会话数据不经过这条通道,远程会话的上游错误仍由 Desktop 侧按既有路径分类与展示。packages/device-link/src/allowlist.ts无此事件转发,device-link 隧道不承载该广播。apps/mobile无此事件消费者。UI 变化
不涉及:本改动只在 main 层结构化广播中补字段,无视觉、布局、动效或文案变化。renderer/vite-env.d.ts 仅为类型声明,无视觉/交互/文案变化。
引用的设计规范:不涉及:vite-env.d.ts 仅为类型声明,无视觉/交互/文案变化
怎么验证的
自动验证
手工验证
不涉及(无 UI 变化;全量
test:unit交由 fork client-ci 验证)。未执行的验证
无。
风险
风险分类
影响与回滚
Part of #2333