Replies: 4 comments
|
补充一条最新版仍然复现的确认(Windows x64,官方桌面版
(本报告由本机会话中的 agent 依据实测整理并代为提交。) |
0 replies
|
Same on my computer. |
0 replies
补充一个复现环境Environment / 环境
|
0 replies
|
补一条加固建议(fs 侧本身的修复另见 #8445,那边有跨平台最小复现)。 当前 for (const root of roots)
for (const skill of await discoverRoot(root, this.ctx, this.name)) // ← 无保护
candidates.push(skill);于是一个 root 的非缺失类错误(本例是 asar 的 建议把 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
环境
0.1.7-rc.2resources/app.asar)cordis(创造模式),以及任何自行提供customSkillDirs的预设standard/ptc/minimal现象
在创造模式下新建会话:
skill工具本身存在、可调用;运行时注册的技能一切正常 —— 例如第三方插件注入的
browser-skill,skill("browser-skill")成功返回;但所有文件系统技能(
C:\Users\<user>\.agents\skills\下的用户技能、项目.agents/skills\下的技能)一律失败:会话上下文里根本没有
<available_skills>技能目录 —— 不是目录不完整,而是一条都没有。切到标准模式(
standard)后同样的技能立刻可用。也就是说:同一个技能目录,换个预设就活/死两态。根因
一行配置解析到了
app.asar内部,而 Electron 的 asar 层不满足fs的 bigint 统计契约。第 1 步:
customSkillDirs落在 asar 里standard/ptc/minimal三个预设的skill-filesystem行都没有config;只有cordis有:该表达式以
baseUrl为锚解析@deepseek-ai/dsh-agent-preset,得到的目录:…\npm\node_modules\@deepseek-ai\dsh\node_modules\@deepseek-ai\dsh-agent-preset\skills—— 实体目录,一切正常;…\resources\app.asar\dsh\node_modules\@deepseek-ai\dsh-agent-preset\skills—— asar 内部。这解释了为什么该预设的写法在 Web 端多年无事、一到桌面端就失效:同一份代码,只有
baseUrl的落点不同。第 2 步:asar 的
bigint统计被降级Electron 的 asar 补丁层对 asar 内部路径的
fs.statSync(p, { bigint: true })返回size: number,而真实文件返回size: bigint。实测:typeof statSync(p, {bigint:true}).sizefs.watchbigint✅number❌ENOENT❌第 3 步:DSH 的 fs 服务做 BigInt 运算 → 抛错
DSH 有包按 bigint 契约调用
stat,例如@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js:拿到
number后再与 BigInt 混算,抛:第 4 步:这个错误不是
ENOENT,因此不被吞掉@deepseek-ai/dsh-skill-filesystem/lib/index.js的discoverRoot只对「路径不存在」类错误做静默跳过:TypeError逃出discoverRoot,整个 provider 被放弃:第 5 步:
complete=false直接掐掉整份技能目录@deepseek-ai/dsh-tool-skill/lib/index.js发布技能目录前有硬门槛:于是技能目录完全不发布(而不是"少几个")。
skill工具查不到任何名字,全部报unknown or no longer available;而运行时注册的技能(browser-skill)走registerProvider的runtime层,不经文件系统,所以照常工作。完整链路
最小复现
对照:把同一段代码指向任意实体目录,
typeof为'bigint'、fs.watch正常。验证「预设 vs 技能可用性」的对应关系:
影响面
cordis、继承其customSkillDirs的自定义预设)下,用户技能与项目技能全部不可用;standard/ptc/minimal;bundledSkillDir默认为undefined(除非设置了DSH_BUNDLED_SKILL_DIR),所以它不是第二个 asar 根 —— 本问题只由customSkillDirs引起。建议的修法
按优先级:
① 让该预设指向 asar 外的实体目录(推荐,改动最小)
上游其实已经在 Office 技能上用了这个模式:
@deepseek-ai/dsh-skill-office的assetRoot指向resources/runtime/office-skills(asar 之外的实体目录),由@deepseek-ai/dsh-desktop-host注入:把
dsh-agent-preset/skills同样以实体目录随包分发(或让customSkillDirs在解析到 asar 路径时改指 unpacked 副本),问题即消失。② 让
dsh-skill-filesystem单根失败不拖垮整个 providerlist()里对每个 root 的discoverRoot加 try/catch:坏根记 warning、complete = false,但其余根照常产出。这样即使某个 root 不可用,用户技能仍然可用。③ 让 fs 服务容忍 asar 的 bigint 降级
在
stat包装层把size归一为 BigInt(或对 asar 路径跳过 bigint 调用)。覆盖面最广,能一并修掉同类问题。④ 让技能目录在
!complete时仍然发布dsh-tool-skill目前对不完整快照直接放弃。改为发布已有的条目并标注不完整,可把"全灭"降级为"缺几个"。个人建议 ① + ②:① 治本且与既有 Office 技能的做法一致;② 把任何单点故障的爆炸半径限制在一个 root 内。
绕过办法(不依赖上游修复)
在自定义预设里把
customSkillDirs换成一个解析到实体目录的表达式,例如把技能目录随自定义预设包一起分发,再用包内子路径锚定:注意两点:
./skills)—— 补丁装载器只把顶层patch.insert行的相对name改写成file://URL,不会递归进config.plugins,预设内部的相对路径在0.1.7下无法解析;用包名子路径引用。相关代码位置
@deepseek-ai/dsh-web-app/presets/cordis.patch.ymlskill-filesystem行customSkillDirs的出厂预设@deepseek-ai/dsh-skill-filesystem/lib/index.jslist()/roots()/discoverRootdiscoverRoot无保护@deepseek-ai/dsh-skill/lib/index.jscomplete影响缓存@deepseek-ai/dsh-tool-skill/lib/index.js!snapshot.complete→ 不发布技能目录@deepseek-ai/dsh-session-persistence-jsonl/lib/index.jsstat调用方,TypeError 来源@deepseek-ai/dsh-desktop-host/lib/index.js本文所述现象在 DSH
0.1.7-rc.2桌面端实测复现;对照实验(同一表达式分别以 Web npm 路径与 asar 路径为baseUrl求值)结果如上表。 #All reactions