[desktop 0.1.7-rc.2] dsh-app:// 转发的响应无法流式返回:/plugins/events(SSE) 恒报 net::ERR_FAILED,连带会话状态、权限预设目录、审批提示与插件热更新一起失效 #7868
Replies: 2 comments
补充:官方文档依据 + 一个可 A/B 判真伪的最小复现(接 #7868 正文。以下把根因假设从"推测"推进到"可被维护者几分钟内确认或推翻"。) 1. 官方文档里,
|
你的根因假设在代码里成立——转发层用的就是全局
|
Uh oh!
There was an error while loading. Please reload this page.
[desktop 0.1.7-rc.2] dsh-app:// 转发的响应无法流式返回:
/plugins/events(SSE) 恒报 net::ERR_FAILED,连带会话状态、权限预设目录、审批提示与插件热更新一起失效环境
@deepseek-ai/dsh-desktop-runtime0.1.7-rc.2)desktop(默认 profile)dsh-selection-toolbar、dsh-approval-gate、@tt-a1i/archify-dsh),但请注意:失败的是内置 host 路由(/plugins/events),转发层出错的证据与任何插件代码无关;插件 bundle 走同一转发路径且工作正常(这也正是"有限响应能过、流式响应过不去"这条不对称的对照)。现象
桌面窗口 DevTools(
F12)Console 持续报同一个错误,且自动重试也一直失败(单次会话中出现 3 次以上):关键对照:同一路径直连 HTTP 完全正常
用桌面窗口自身的认证 cookie 直接请求同一个路由(
curl,非浏览器):fetch+response.body.getReader()也能正常拿到 chunk(首 chunk 13B /: connected,随后 28,710B 的 graph 事件);dsh-app://协议转发这一层才失败。已排除的原因
text/event-stream+ 合法首帧。forwardWebRequest的target.pathname = source.pathname; target.search = source.search,转发后 URL 与被请求 URL 逐字节相同(??虽被 URL 解析器归入 search,但序列化后完全一致)。content-encoding被去掉是必要且正确的——host 对插件 bundle 会 gzip(实测Content-Encoding: gzip+Vary: Accept-Encoding),而主进程的 Nodefetch已经解压,原样透传反而会错。实测 10 MB 的插件 bundle 走同一转发路径完全正常。根因假设
forwardWebRequest(main process)使用全局fetch(Node/undici),并把它的response.body直接交给自定义协议的new Response(...):有限长度的响应能通过(Electron 可以读完整个 body 再交付——所以 10 MB 的插件 bundle 正常);无限流式的响应过不去(永远不会"读完"),表现为
net::ERR_FAILED。/plugins/events恰好就是那条永不结束的 SSE。波及面(这是影响最严重的部分)
/plugins/events是客户端获取「host → client 事件/状态」的唯一通道(其首帧即{"type":"graph",...},携带模块图 rev 与模块清单)。它一死,以下四件事同时失效,均在本机稳定复现:sessions.current一直是空值,第三方插件拿不到当前会话 id(只能自行兜底,例如退回 composer 会话)。符合事件通道未送达的状态。~/.dsh/profiles/desktop/cordis.patch.yml里手工添加了permission预设(含auto-approve,name: 自动审批(Flash)),host 侧应已生效,但会话权限下拉里始终不出现该选项;而 label 在 shipped 客户端 locale 字典里的Auto review不受影响。这与@deepseek-ai/dsh-permission-presetsREADME 中「进程级catalog()Remote 返回完整可选快照,注册/移除 Auto 会发出permission-presets/catalog-changed通知,客户端先订阅再重新读取目录」的描述相符——该通路依赖这条事件通道。ask后,需要审批的工具调用会一直等待且不出现任何提示。审批请求需要客户端 UI 应答,事件推不到客户端时即表现为挂起。rev=32092783b4f0→ 404;当前 rev → 200)。客户端因收不到 graph 事件而继续持用旧 URL,模块加载失败,第三方插件静默失效,必须整页刷新或重启应用才恢复。而打包版把「刷新页面」菜单项隐藏了:devToolsItems的toggleDevTools也是visible: false(只留了F12)。因此普通用户既没有"刷新页面",也看不到"开发者工具",只能 ⌘Q 重启。建议修法(任选其一即可)
forwardWebRequest改用 Electron 的net.fetch(Chromium 网络栈),而不是全局fetch,让流式 body 与自定义协议的Response兼容;/plugins/events这类流式路由不走协议转发,像DESKTOP_IPC.boot返回的streamBaseUrl那样,由客户端直连 host origin(http://127.0.0.1:<port>,cookie 注入机制已具备)。附:用户侧临时绕过
在浏览器里打开 host 的 HTTP 源(同一 profile),此时
/plugins/events是同源直连、不经过dsh-app://转发层,事件通道恢复正常:http://127.0.0.1:19387/,用 DevTools → Application → Cookies 写入该 name/value,刷新即可。All reactions