Replies: 1 comment
|
第二条「崩溃后会话永久砖了」和 #1593 同类:日志能加载,但缺一条对应的 dsh-session-surgeon 不会发明缺失的 tool/result,也不会改 call id(那会把对账修得更假)。它可以 如果同时还报 dsh plugin --profile web add "github:xiaoshenming/dsh-session-surgeon#main"第一条模块双实例 / Symbol 对不上,是 profile |
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.
Crashed tool call leaves dangling tool_calls in session history (session permanently bricked) — triggered by profile node_modules shadowing of in-box dsh-tools
Environment
@deepseek-ai/dsh@0.1.1-rc.2(all@deepseek-ai/*runtime packages at0.1.1-rc.2), run via npxwebprofile with out-of-tree plugins installed into~/.dsh/profiles/web/node_modules/(mounted via~/.dsh/cordis.patch.yml), including one plugin whosepeerDependenciesdeclared"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6"Summary
Two distinct robustness gaps that compound into a total outage:
@deepseek-ai/dsh-host-webserver@0.1.0-rc.7(and its transitive@deepseek-ai/dsh-tools@0.1.0-rc.7) into~/.dsh/profiles/web/node_modules/. This shadows the in-box runtime thathealProfilesModuleFallbackprovides via symlinks in~/.dsh/profiles/node_modules. The cordis plugin tree then loads a seconddsh-toolsmodule instance (rc.7) as thetoolsservice, whiledsh-agent-loop(resolved through the fallback symlink to the CLI installation) reads the registry slot with rc.2'sTOOL_RUNTIME_SCHEDULERSymbol. Two module instances → two Symbols →ctx.tools[TOOL_RUNTIME_SCHEDULER]isundefined→ every tool call crashes before dispatch:packages/core/agent-loop(dsh-agent-loop/lib/index.js:193):preparethrows, the agent loop records aturn/enderror event but never appends arole: "tool"result for the already-recordedtool/call. The danglingtool_callstays in the session history forever, so every subsequent turn in that session fails at the provider with:Reproduction
npx @deepseek-ai/dsh webwith a web profile that has out-of-tree plugins under~/.dsh/profiles/web/node_modules/.peerDependenciescontains an old@deepseek-ai/*range (e.g."@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6"), then runnpm installin the profile directory. npm installs0.1.0-rc.7(latest matching the range) of that package — and its dependency closure includingdsh-tools@0.1.0-rc.7— into~/.dsh/profiles/web/node_modules/.run shell command: ls /tmp.tool/callis recorded, then 4 ms later the turn ends withCannot read properties of undefined (reading 'prepare'); notool/resultis ever written.insufficient tool messages following tool_calls message. Repeat forever; the session is dead.Evidence
Session log (
~/.dsh/sessions/<workdir>/session-*/session.jsonl), abridged:{"type":"tool/call","seq":72,"data":{"callId":"call_00_AI7i3sODDzH2y2BvWeDA7782","name":"bash","arguments":"{\"command\": \"ls /tmp\"}"}} {"type":"step/end","seq":73,"data":{"turn":1,"step":1}} {"type":"turn/end","seq":74,"data":{"turn":1,"reason":{"kind":"error","error":{"message":"Cannot read properties of undefined (reading 'prepare')","code":"UNKNOWN"}}}} ... 8 minutes later, same session ... {"type":"turn/end","seq":82,"data":{"turn":2,"reason":{"kind":"error","error":{"message":"An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. (insufficient tool messages following tool_calls message)","code":"INVALID_REQUEST"}}}}Module resolution that produces the Symbol fork (Node's parent-directory walk from the profile):
The plugin tree imports
@deepseek-ai/dsh-toolswithbaseUrlanchored at the profile directory, so it gets rc.7 (thetoolsservice instance).dsh-agent-loopresolves through the fallback symlink to the CLI installation (rc.2) and readsTOOL_RUNTIME_SCHEDULERwith rc.2's Symbol — a different object than rc.7's, so the lookup returnsundefined.Relevant code locations:
packages/core/agent-loop—dsh-agent-loop/lib/index.js:193(.prepare()crash site; every tool call passes through here)packages/core/tools—dsh-tools/lib/index.js:2416(TOOL_RUNTIME_SCHEDULER = Symbol(...), per-module-instance),:2592(super(ctx, "tools"))dsh-app-boot/lib/index.js:409(healProfilesModuleFallback— creates the symlink fallback; assumes profile-localnode_modulescontains only out-of-tree plugins, never@deepseek-aicore packages)Suggested fixes
prepare/dispatch) throws, append a synthetic errortool/resultfor the danglingtool_callbefore ending the turn, so the session history stays protocol-valid and the session remains usable after recovery. Today only aturn/enderror event is written; the OpenAI-compatible history is left permanently invalid.healProfilesModuleFallback(or the loader) should detect when a package in the installation closure is shadowed by a different version under<profile>/node_modules— at minimum log a loud warning at boot (boot currently succeeds silently while every tool call is doomed). This is easy to hit for out-of-tree plugins, since npm auto-installs theirpeerDependenciesinto the profile root.Symbol, so duplicate module copies degrade to "wrong version" errors rather thanundefined.preparecrashes that give no hint about the real cause.Workaround (for anyone hitting this now)
Delete the shadowing package from the profile so resolution falls through to the CLI installation's symlink fallback, then restart:
Affected sessions cannot be repaired through the UI — start a new session (or hand-edit the session history to add the missing tool result).
All reactions