TOOL_RUNTIME_SCHEDULER 符号用裸 Symbol(...) 导致源码启动时模块双份副本间身份不一致 #7449
liyuyuan6969
started this conversation in
General
Replies: 0 comments
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.
Summary
packages/core/tools/src/index.ts 中的跨模块身份键 TOOL_RUNTIME_SCHEDULER 用裸 Symbol('@deepseek-ai/dsh-tools.scheduler') 声明(当前 master 第 470 行)。
该键是"调度器实例写入 / 读取"的约定键:ToolRuntime 服务把调度器挂到这个键上,agent-loop 消费方通过 ctx.tools[TOOL_RUNTIME_SCHEDULER] 读取。在源码启动(tsx ESM hook / tsconfig paths→src)时,@deepseek-ai/dsh-tools 的 src 平面与 npm exports→lib 产物平面两份模块可共存于同一进程,裸 Symbol 在这两份副本中是不等价的,导致读方取不到写方放入的值。
受影响场景:dsh 源码启动下运行含并行/独占工具调度的 agent-loop(读方会拿到 undefined)。
Reproduction
触发条件(源码启动,src 平面与 lib 平面同时装载 @deepseek-ai/dsh-tools):
dsh 通过 tsx 从源码启动;agent-loop 经 tsconfig paths 解析 @deepseek-ai/dsh-tools 到 src,拿到 Symbol('…') 的 src 副本。
Cordis 加载 ToolRuntime 服务时经 npm exports 解析 "."→lib/index.js,拿到产物平面 Symbol('…') 的另一实例。
两个 Symbol 不相等,ctx.tools[TOOL_RUNTIME_SCHEDULER] 读不到 ToolRuntime 写入的调度器(挂载点见 packages/core/tools/src/index.ts:798 的 [TOOL_RUNTIME_SCHEDULER])。
关键代码位置:
生产者:packages/core/tools/src/index.ts:470 声明,:798 用 [TOOL_RUNTIME_SCHEDULER] 挂载调度器。
消费者:packages/core/agent-loop/src/tool-calls.ts:17 导入,:153-154,:170,:174 调用 ctx.tools[TOOL_RUNTIME_SCHEDULER].prepare/.dispatch/.finalize/.finish。
Current behavior
当 src 与 lib 两平面共存于同一进程时,消费侧取到 ctx.tools[TOOL_RUNTIME_SCHEDULER] === undefined,随后调用其 prepare/dispatch 方法触发运行时错误;若进程内恰好只有一份模块副本,则无异常——属于非确定性 / 环境相关故障。
Expected behavior
无论 @deepseek-ai/dsh-tools 在进程内被加载多少份副本,写入方与读取方都应认到同一符号。用 Symbol.for('@deepseek-ai/dsh-tools.scheduler') 走全局符号注册表即可保证进程内身份一致;该键也符合仓库"跨模块身份型符号用 Symbol.for"的既有约定(例如 SHADOW = Symbol.for('cordis.shadow'))。
Environment
源码启动(tsx ESM,tsconfig paths→src)+ 产物平面(npm exports→lib)共存。
任选运行 dsh 源码的 Node / macOS 环境即可复现。
All reactions