[dsh] profile 内出现第二份核心包 → Symbol/instanceof 跨实例失效 → 工具派发崩溃(reading 'prepare') #6416
Replies: 4 comments 1 reply
更新:端到端验证通过(2026-09-12)Hi maintainers — an end-to-end confirmation of the instance split, plus a browser-free repro recipe that may be useful for your own e2e tests. 方式:起一个 结果(修复后): 对比修复前(同一路径): 静态证据:对 web profile 的 795 个解析基点( 无浏览器复现脚本 BASE=http://127.0.0.1:3080
# ① 用启动日志里的 token 换签名 cookie(303 + Set-Cookie)
curl -s -c /tmp/jar.txt "$BASE/?token=<LAUNCH_TOKEN>"
# ② 建会话
curl -s -b /tmp/jar.txt -X POST "$BASE/api/session/create" -H 'content-type: application/json' \
-d '{"type":"client-request","rpcId":"11111111-1111-4111-8111-111111111111","method":"session/create",
"payload":{"args":{"request":{"cwd":"/tmp/probe","agentPreset":"standard"}}}}'
# ③ 发消息,触发一次真实工具调用
curl -s -b /tmp/jar.txt -X POST "$BASE/api/session/prompt" -H 'content-type: application/json' \
-d '{"type":"client-request","rpcId":"33333333-3333-4333-8333-333333333333","method":"session/prompt",
"payload":{"args":{"request":{"requestId":"44444444-4444-4444-8444-444444444444",
"sessionId":"<SESSION_ID>","mode":"queue",
"content":[{"type":"text","text":"请用 bash 工具执行:echo dsh-tool-ok"}]}}}}'顺带的文档小坑:一元 Remote 调用似乎只能走路径形式 |
补充:这些实体副本从哪来(以及上游文档中对应的规则)本机时间线:
即 fallback 不会覆盖已存在的 pnpm 条目。因此只要在 profile 里跑过一次 可能的修复落点:
|
|
我把你指的三处代码逐一对照了宿主源码,三条都成立,另外补两条你可能还没看到的。 1. 逐条核实
2. 你观察到的「每次
|
|
两点都复核过, 你的补充成立, 而且它把触发面显著扩大了.
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
dsh 0.1.5-rc.2:profile 内出现第二份核心包 → Symbol/instanceof 跨实例失效 → 工具派发崩溃(
Cannot read properties of undefined (reading 'prepare'))English: When a profile's
node_modulescontains a second physical copy of@deepseek-ai/dsh-tools(anything that triggerspnpm installin the profile, e.g. the plugin manager UI, does this), module-privateSymbols no longer match across copies.ctx.tools[TOOL_RUNTIME_SCHEDULER]becomesundefined, and every tool call dies withCannot read properties of undefined (reading 'prepare')— an error message that points nowhere near the real cause.环境
@deepseek-ai/dsh0.1.5-rc.2(npm 全局安装,Node v26.7.0,Linux)web,挂载若干第三方 bundle 与本地插件(含官方插件管理 UIdsh-web-plugin-manager)pnpm-workspace.yaml使用nodeLinker: hoisted,且profiles/web/package.json显式声明了若干@deepseek-ai/*核心包复现步骤
让 profile 树里出现 harness 核心包的第二份实体(本机实测:在 profile 里执行一次
pnpm install即可,例如通过插件管理 UI 安装/升级插件):在
webprofile 里发起一轮对话并触发任意工具调用(例如 bash)。实际结果
会话事件(
~/.dsh/sessions/<cwd>/session-<id>/session.v3.jsonl.zstd):{"type":"tool/call","name":"bash","arguments":"{\"command\":\"ls -la ~/.dsh/\"}"} {"type":"turn/end","data":{"turn":3,"reason":{"kind":"error", "error":{"message":"Cannot read properties of undefined (reading 'prepare')","code":"UNKNOWN"}}}}模型回复与工具调用都正常生成,只在这一步崩。同一个 harness 用
dsh --profile headless跑同样的 bash 工具正常,说明不是工具本身的问题。根因
@deepseek-ai/dsh-tools/lib/index.js:2430:@deepseek-ai/dsh-agent-loop/lib/index.js:588:Symbol()是模块实例私有的。profile 内的第三方插件import '@deepseek-ai/dsh-tools'解析到副本 B,harness 解析到副本 A:于是 A 侧构造的
ctx.tools上永远查不到 A 的 Symbol →undefined.prepare。受影响的不止这一个 Symbol:
ToolRuntime等类的instanceof同样跨实例失效(实测两份类不相等)。凡"对象跨插件/harness 边界传递 + 用 Symbol/instanceof 判定"的地方都会出问题。期望行为(任一即可)
@deepseek-ai/*核心包时应解析到与 harness 完全相同的那一份(例如走.dsh-module-fallback机制,或安装时以 peer + 符号链接处理,而不是复制实体);Symbol.for('@deepseek-ai/dsh-tools.scheduler')/全局注册表,使跨实例也能命中;ctx.tools[TOOL_RUNTIME_SCHEDULER]缺失时应抛明确错误(如 "tools service comes from a different @deepseek-ai/dsh-tools instance"),而不是让undefined.prepare掩盖真因——目前这个字符串在任何日志里都不出现,用户完全无从下手。用户侧规避(本机已把符号层面验证通过)
把 profile 里与 harness 同名的核心包换成指向 harness 的符号链接(
@deepseek-ai/dsh-tools、dsh-session、dsh-llm、cordis、schemastery等 13 个),保留 harness 里没有的客户端包(dsh-client-ui-primitives、dsh-client-ui-slots)。之后:注意:任何一次
pnpm install(含插件管理 UI)都会把实体副本装回来,问题复发。All reactions