Tencent / Tencent/BrowserSkill
[Bug][dsh-plugin] browser_* tools stay unregistered after a plugin reload — lazy reveal is not restored (`unknown tool "browser_session"`)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 5.7k
- Forks
- 399
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 74
Description
Environment
@wxg-prc-cpg/browser-skill-dsh-plugin0.2.1 (lazyToolsleft at its defaulttrue)- DeepSeek Harness Desktop 2.0.10, profile
desktop, Windows 10 22H2 (19045) bskCLI / daemon 0.2.1 (protocol 1.1), extension ext-v0.3.0 (protocol 1.3)
Symptom
After the daemon churn described in #265-family report (a daemon was killed and respawned, which reloads the plugin), a call to browser_session failed with:
Error: unknown tool "browser_session"
At that moment:
- the plugin package was installed and enabled (
~/.dsh/profiles/desktop/node_modules/@wxg-prc-cpg/browser-skill-dsh-plugin); browser-skillwas still listed in the skill catalog and loading it still returned the full skill text;- this same session had already invoked
skill browser-skillsuccessfully twice earlier (its result landed withisError: false).
Calling skill browser-skill once more returned the same text and the six tools were registered again immediately (browser_session {action:"list"} → no active browser sessions). So the state is recoverable — but nothing in the failure tells the user that, and from the model's point of view the tools simply do not exist any more.
Why it looks like the reveal is not restored (read from lib/index.mjs)
armLazyTools() registers the suite on three triggers:
tools/resultwhere the tool isskilland the argument name isbrowser-skill— i.e. only a successful invocation in the current process lifetime;session/eventwithsource.kind === "skill-invocation";session/created→scanSession()→hasSuccessfulSkillInvocation(session.events).
The suite is disposed on plugin teardown, and a plugin reload is exactly what happens around a daemon restart. After the reload, trigger 3 did not re-arm this session even though its event log already contained a successful invocation. I did not instrument the plugin, so I can only list the candidates: the scan running before the session registry is reachable (ctx.get("sessions")), sessions.list() returning nothing at that moment, or session.events being a bounded/pruned in-memory tail that no longer contains the invocation.
Note the stacking: daemon restarts are common in agent harnesses (#180, #183, #245, and the daemon-lifetime report), and each restart is a chance to lose the tool suite for the rest of the session.
Expected behavior (suggested)
- Persist the reveal decision per session (e.g. a flag written into the session store on the first successful invocation) so a reload can restore it deterministically, instead of re-deriving it from a bounded event scan.
- Also arm on
tools/callfor the skill tool (before the result lands). It is nearly free and removes the window in which the tools are still missing. - Diagnose the state instead of a bare runtime error: when a
browser_*call is attempted while the suite is unregistered, log a warning such asbrowser tools are not armed in this session — invoke the browser-skill skill first(or make the plugin expose a tinybrowser_session {action:"status"}that is always registered). - Point at the escape hatch in the docs for exactly this failure:
lazyTools: falsein the plugin config registers the full suite at load (cost: six tool schemas in every request). It is documented as a configuration option today, but not as the fix for "the tools vanished".
Workaround (verified)
- Re-invoke
skill browser-skill— the suite is registered immediately and the next call works. - Or set
lazyTools: falsefor the plugin in the profile patch (~/.dsh/profiles/desktop/cordis.patch.yml).
Related
- #180, #183, #245 — the daemon/plugin hang that makes daemon restarts frequent and leaves an unregistered Agent Window behind
- #196 — the docs change that introduced
lazyTools
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lib/index.mjs with armLazyTools(), scanSession(), and the session event handlers; trace plugin teardown and reload alongside session availability and event history. Reproduce a daemon/plugin reload after a successful browser-skill invocation, then verify that browser_* tools are restored or that the missing-tool state gives the documented recovery path, including lazyTools: false.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100