Replies: 7 comments
|
Follow-up after repairing this locally — one correction to my report, plus a verified fix. Correction:
|
|
Second, distinct consequence of the same crash — a poisoned session history Repairing an affected install turned up a follow-on defect: the crash does not just fail the turn, it makes the session unusable for every later turn. A turn that ends with an error has already appended the assistant message carrying its tool calls, while the results never arrive: Every subsequent turn re-sends that history, and the provider protocol refuses it: (
What worked locally: truncate each log after the last Suggested fix: when a turn ends with an error, synthesize results for its pending calls through the same closers path, so a crashed turn cannot poison the rest of a session. |
|
Independent confirmation, on a different platform, plus one constraint on the fix space. Environment: macOS arm64, Node v25.2.1, pnpm 11.7.0, In-process probe of the booted profile (no model involved, so it cannot be a provider-protocol artifact):
The session log matches your report exactly: Resolution matrix (what the loaded
So tsx projects the bare specifier to Constraint on the fix space: "disable tsx paths so everything is
Also confirming your built-launch workaround on macOS: |
|
Independent confirmation from Windows, in case a third platform helps pin this down. Same commit I didn't have your loader-hook instrumentation, so I approached it by flipping a single line —
That's consistent with your The correction in your first comment deserves a highlight, by the way. It would have been easy to conclude "link doesn't boot" from a probe that was itself broken, and drop the one thing that actually fixes it. Glad you went back and checked. |
|
You are a lifesaver. Thanks!! |
|
已把这批 本帖属于其中的
本地 CLI 聚焦测试 16/16、tools scheduler key 测试和 CLI/tools/agent-loop TypeScript build 已通过。详细补丁、用户恢复步骤、会话处理和回归门禁见上面的集中回复。 |
|
One refinement to the resolution matrix above, plus a measured table from a third platform. The discriminator is the importer's path, not the planetsx 4.22.4 applies the Oe=l(async(e,r,t,s)=>{const o=ne(e);if(n.logEsm(3,"resolveTsPaths",{specifier:e,context:r,
tsconfigPathAliasSpecifier:o,tsconfig:s.parsedTsconfig,
fromNodeModules:r.parentURL?.includes("/node_modules/")}),
o&&s.parsedTsconfig&&!r.parentURL?.includes("/node_modules/")){const a=n.wt(s.parsedTsconfig,e);...This slightly changes how "tsx projects the bare specifier to It also explains why Same split, measured with a synchronous resolve hook (macOS, Node 24.16)macOS 27.0 arm64, Node v24.16.0, pnpm 11.7.0, tsx 4.22.4, checkout The last row is the one worth keeping in mind for the fix space: a file inside Symbol creation sites, same two boots: source route 2 ( Probe gotcha for anyone re-running this: Status today
|
Uh oh!
There was an error while loading. Please reload this page.
Summary
On 0.1.6-alpha.2, the documented source launch vector (
pnpm dsh <app>, i.e.node --import tsx/esm apps/cli/src/bin.ts) boots normally, but the first turn that calls a tool ends with:recorded as
turn/endwithreason.kind: "error"andcode: "UNKNOWN". From then on every tool call in that process fails — in new sessions and in pre-existing ones alike. The built launch (node apps/cli/lib/bin.js <app>) is unaffected.Unlike #6529 / #6416 (a profile that owns a second physical copy of
@deepseek-ai/dsh-tools) and #4508 (web mode, scope-proxy hypothesis), this reproduces on a single clean checkout with no version skew and no profile-local install: the source launch itself loads the package from two planes (srcandlib), and the 0.1.6-alpha.2 resolution-default change made that split reach the tool path.This is the same double-load phenomenon already documented for another package in #2091 ("Source launch loads workspace packages twice"), now fatal because
@deepseek-ai/dsh-toolskeys its scheduler by a module-privateSymbol.Environment
@deepseek-ai/dsh0.1.6-alpha.2, source checkout ofmasteratddefc45fbcpnpm install && pnpm run buildcompletedweb(default). Also reproduced with--profile headlessin an isolatedDSH_HOME0d1f50007f→ddefc45fbc(882 commits). Sessions before the update completed tool calls; the first tool-attempting turn after it failed (a text-only turn in the same process still completes).Root cause
dsh-agent-loopreads the tool scheduler through a module-private symbol key:Under the source launcher the process ends up with two module instances of
@deepseek-ai/dsh-tools, so two distinct symbols exist. The loop imported one;ctx.toolswas constructed from the other; the lookup isundefinedand the property read throws.Instrumented
module.registerload/resolvehooks in a single boot (paths relative to the checkout):i.e. plugin entries are imported from the runtime anchor (
lib/), while the tsx ESM hook re-projects the bare workspace specifiers made inside those lib files tosrc/through tsconfigpaths. Two planes in one process.Symbol identity check from the same boot (symbols compared with
===, not by description):{"tools": ["packages/core/tools/src/index.ts", "packages/core/tools/lib/index.js"], "loop": ["packages/core/agent-loop/lib/index.js"], "loopSymbolFoundInTools": [["packages/core/tools/src/index.ts"]]}which means the outcome depends on which copy registered the
toolsservice — a load-order race. The same boot with the built entry (node apps/cli/lib/bin.js) loads exactly one copy (lib) and is stable.Suspected trigger (regression in the pulled range)
#4471/9ddef327a4("feat: resolution mode link to runtime") changed the non-packaged default inapps/cli/src/profile-boot.ts:263:Under
linkthe loader resolves plugins by bare specifier, so tsx'spathsprojection keeps the whole graph on thesrcplane. Underruntimethe resolution generation hands out runtime-anchor (lib) entries, and the two planes coexist. The desktop half of the same change was reverted before the release (d9a55c7c0d"fix: revert desktop"), the CLI half shipped in 0.1.6-alpha.2.Reproduction (keyless, ~1 minute)
Uses the in-repo mock provider, so no API key is needed:
Observed:
dsh: UNKNOWN: Cannot read properties of undefined (reading 'prepare')on the tool-executing turn.DSH_HOMEthis is intermittent (roughly 1 in 7 fresh boots; presumably the service-registration race).web, users' normalpnpm dsh web) it was consistent: a text-only turn completed, the next tool-calling turn failed; a brand-new session failed on its first tool call as well.What does not work as a workaround
Reverting the default to
'link'is not viable on 0.1.6-alpha.2 for an existing profile — the boot then fails outright:Workaround that does work (verified): launch the built entry, i.e.
pnpm run buildonce and thennode apps/cli/lib/bin.js web # equivalent of `pnpm dsh web`Secondary observation from the same default change
Plugins inserted through a profile patch that are not in the install-anchor closure now fail to import under
runtimemode, where they used to resolve through tsx in a source launch:@deepseek-ai/dsh-computer-useexists in the tree but is not a dependency ofapps/cli, so the runtime generation cannot route it. Installing them into the profile via the documented command restores them:CI gap
Nothing in the current gates covers the source launch's plugin plane:
test:snapshotresolves workspace imports through vite + tsconfigpaths(single plane);apps/cli/tests/built-bin.e2e.tslaunches the builtlib/(single plane);apps/cli/tests/source-launch.compat.spec.tsonly asserts the TTY refusal.A gate that boots the source vector and asserts a single
dsh-toolsmodule instance (or that executes one tool call) would have caught this.Suggested fixes
libwhile tsx re-projects their internal workspace specifiers tosrc— either route every workspace specifier through the same plane, or keep the tsconfigpathsprojection from applying to files underlib/.Symbol.for('@deepseek-ai/dsh-tools.scheduler'), or a string-keyed/Service-method scheduler, would make a duplicate instance degrade instead of taking down every tool call in the process (same suggestion as Idea: tool-scheduler prepare() failures are very hard to diagnose (Symbol mismatch invisible) #5758).tool-calls.ts:170could name the duplicate-instance cause instead of emitting a bare property-readTypeError(Idea: tool-scheduler prepare() failures are very hard to diagnose (Symbol mismatch invisible) #5758).Related reports
dsh-typert-protocol, silent@Remotesplit): same root phenomenon, different consumerpreparecrash when a profile owns a second physical copy ofdsh-toolsprepare()failures; maintainer comment confirms the symbol-identity mechanism中文摘要:0.1.6-alpha.2 上,用文档里的源码启动方式(
pnpm dsh web)时,@deepseek-ai/dsh-tools会从src和lib两个平面各加载一份,两个模块私有的Symbol('@deepseek-ai/dsh-tools.scheduler')不相等,于是ctx.tools[TOOL_RUNTIME_SCHEDULER]为undefined,任何工具调用都抛Cannot read properties of undefined (reading 'prepare')。触发点是本版把非打包运行的resolutionMode默认值从link改成runtime(#4471;desktop 那一半已在发版前回退)。临时可用办法是用构建产物启动(node apps/cli/lib/bin.js web)。All reactions