From be9f46cf73c8bd9faf71d1246cc34c67f368ff03 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 7 Sep 2026 06:31:19 +0800 Subject: [PATCH] =?UTF-8?q?dsh:=20resume=20=E7=BB=AD=E8=B0=88=E4=B9=9F?= =?UTF-8?q?=E6=8C=82=E8=BD=BD=20standard=20preset=20=E2=80=94=E2=80=94=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A7=E4=BC=9A=E8=AF=9D=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:startAgent 的 resume 分支 setup: undefined,注释说 「resume 从磁盘恢复,工具已在」—— 实际上工具是通过 setup 回调 presets.mount 注册的,resume 不传 setup 就没有任何文件工具。 presets.mount 修复之前创建的旧会话(setup:undefined 时代)从此 没有 read/write/edit/bash/glob/grep,用户反馈「dsh 无法看到工作区文件」。 修复:把 presets.mount 抽成 setupPreset 函数,create 与 resume 共用。 resume 恢复的是会话历史,不是工具注册 —— 两者必须都挂。 实测:旧会话 318f0703 resume 续谈后 setup 回调触发、mount 成功, 模型用 glob 列出工作区文件、read 读取、write/edit 可写,完整回复。 --- plugins/dsh-mail-bridge/src/index.ts | 45 +++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/plugins/dsh-mail-bridge/src/index.ts b/plugins/dsh-mail-bridge/src/index.ts index ed58966..4bed0d7 100644 --- a/plugins/dsh-mail-bridge/src/index.ts +++ b/plugins/dsh-mail-bridge/src/index.ts @@ -644,6 +644,32 @@ export function apply(ctx: any, config: PluginConfig): void { // route 为 undefined 表示不指定模型,交给平台自己选 const agentOptions = route ? { provider: route.provider, model: route.model } : {}; + // 注册 standard preset 的工具(bash、fs、fs-search 等)。 + // dsh-a2a 用同一套 API(ctx.get('agentPresets') + presets.mount)并稳定运行。 + // + // create 与 resume 都必须挂:resume 从磁盘恢复的是**会话历史**, + // 不是工具注册 —— 工具是 setup 回调里 mount 的,resume 不传 setup + // 就等于回到 setup:undefined 时代(邮件会话没有任何文件工具)。 + const setupPreset = async (agentCtx: any) => { + console.error(`[dsh-mail-bridge] setup 回调触发,agentCtx keys=${JSON.stringify(Object.keys(agentCtx || {}))}`); + try { + const presets = ctx.get('agentPresets'); + console.error(`[dsh-mail-bridge] agentPresets: ${presets ? '存在' : '不存在'}`); + if (presets) { + const preset = await presets.resolve('standard'); + console.error(`[dsh-mail-bridge] standard preset: id=${preset?.id} keys=${JSON.stringify(Object.keys(preset || {}))}`); + if (preset?.id) { + await presets.mount(agentCtx, preset.id); + console.error(`[dsh-mail-bridge] presets.mount 成功`); + } else { + console.error(`[dsh-mail-bridge] standard preset 无 id,跳过 mount`); + } + } + } catch (e: any) { + console.error(`[dsh-mail-bridge] presets.mount 失败(工具注册降级): ${e?.message || e}\n${e?.stack?.slice(0,300)}`); + } + }; + const onDisk = await persistedCwd(sessionId); if (onDisk !== undefined) { // 用 console.error 而不是 ctx.logger.info:后者不进 journalctl(实测), @@ -652,7 +678,7 @@ export function apply(ctx: any, config: PluginConfig): void { const handle = await ctx.agents.resume({ resumeSessionId: sessionId as any, agentOptions, - setup: undefined, // resume 从磁盘恢复,工具已在 + setup: setupPreset, }); return { handle, resumed: true }; } @@ -661,22 +687,7 @@ export function apply(ctx: any, config: PluginConfig): void { sessionId, meta: { cwd }, agentOptions, - // 注册标准 preset 的工具(bash、fs、fs-search 等)。 - // dsh-a2a 用同一套 API(ctx.get('agentPresets') + presets.mount)并稳定运行。 - // 之前的崩溃来自尝试在 resume 路径上调用,create 路径经 a2a 实测可靠。 - setup: async (agentCtx: any) => { - try { - const presets = ctx.get('agentPresets'); - if (presets) { - const preset = await presets.resolve('standard'); - if (preset?.id) { - await presets.mount(agentCtx, preset.id); - } - } - } catch (e: any) { - console.error(`[dsh-mail-bridge] presets.mount 失败(工具注册降级): ${e?.message || e}`); - } - }, + setup: setupPreset, }); return { handle, resumed: false }; }