dsh: resume 续谈也挂载 standard preset —— 修复旧会话没有文件工具

根因: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 可写,完整回复。
This commit is contained in:
2026-09-07 06:31:19 +08:00
parent c440df6537
commit be9f46cf73

View File

@ -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 用同一套 APIctx.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 用同一套 APIctx.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 };
}