Tencent / Tencent/BrowserSkill

[Bug][dsh-plugin] browser_* tools stay unregistered after a plugin reload — lazy reveal is not restored (`unknown tool "browser_session"`)

Open
#269 0 comments 0 reactions 0 assignees View on GitHub

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-plugin 0.2.1 (lazyTools left at its default true)
  • DeepSeek Harness Desktop 2.0.10, profile desktop, Windows 10 22H2 (19045)
  • bsk CLI / 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-skill was still listed in the skill catalog and loading it still returned the full skill text;
  • this same session had already invoked skill browser-skill successfully twice earlier (its result landed with isError: 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:

  1. tools/result where the tool is skill and the argument name is browser-skill — i.e. only a successful invocation in the current process lifetime;
  2. session/event with source.kind === "skill-invocation";
  3. session/createdscanSession()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)

  1. 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.
  2. Also arm on tools/call for the skill tool (before the result lands). It is nearly free and removes the window in which the tools are still missing.
  3. Diagnose the state instead of a bare runtime error: when a browser_* call is attempted while the suite is unregistered, log a warning such as browser tools are not armed in this session — invoke the browser-skill skill first (or make the plugin expose a tiny browser_session {action:"status"} that is always registered).
  4. Point at the escape hatch in the docs for exactly this failure: lazyTools: false in 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: false for 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.