Persistent model tool-call trace recorder: every tool call is durably written to a JSONL file that survives restarts, queryable via a structured call_trace tool and a callTraceHistory service, with size rotation and an optional floating canvas UI add-on.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Huang-zhishi/dsh-plugin-call-trace
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
A persistent LLM tool-call trace recorder for DeepSeek Harness. Every time the
model calls a tool (read / pwsh / subagent / web_search …), this plugin
durably persists the call to a JSONL file — it survives restarts — and
exposes a structured call_trace tool the model can query at any time, plus a
callTraceHistory service for UI add-ons that want to merge history.
- Plain ESM, zero
@deepseek-ai/*runtime imports — loadable from anywhere (--patchoverlay or profile install). - Listens to
agent/request+tools/execute+tools/result(root scope, includes subagent calls). - Records: tool name, arguments, status (
ok/error/running), result summary, duration, turn/step, agent. - Auto-rotates the file above 5 MB — it never grows without bound.
Install
Option A: install into a profile (recommended, distributable)
dsh plugin --profile voice add ./call-trace-plugin
dsh --profile voice --dump-config # expect a "# == dsh-plugin-call-trace" layer
dsh --profile voice # start
Option B: --patch local overlay (fastest to try)
pnpm dsh web --patch D:\Java\dsh-demo\call-trace-plugin\cordis.local.yml
The
nameincordis.local.ymlis afile://URL (a Windows absolute path must be a validfile://URL); update it if you move the plugin.
Option C: tarball / npm
pnpm pack # → dsh-plugin-call-trace-1.0.0.tgz
dsh plugin --profile <name> add ./dsh-plugin-call-trace-1.0.0.tgz
# or after publishing to npm: dsh plugin --profile <name> add dsh-plugin-call-trace
Configuration
Set config on the patch row call-trace-recorder (Option B: cordis.local.yml;
profile install: override the row in $DSH_HOME/profiles/<name>/cordis.patch.yml).
config:
outDir: 'D:/...' # output dir; default $DSH_HOME/call-trace (never node_modules)
Usage
- Query from the model: say "use
call_traceto see the recent calls". The tool returns a structured array (name / status / args / summary / turn / step / agentId / durationMs / ts) the model can read directly. - Clear:
call_trace({ clear: true })(destructive — wipes the whole file). - History service:
callTraceHistory.tail(n)returns parsed recent records for UI merge.
Floating UI (optional add-on)
The ui/ directory ships a dynamic-plugin floating overlay (GraphRAG-style
branching connectors + Chinese tool descriptions + click-to-expand details +
nested subagent branches + history merge + self/all filter). Dynamic plugins live
only in process memory, so rebuild it after a restart: tell the agent "rebuild
the call-trace dynamic plugin from ui/host.js and ui/client.js and run it"
(see ui/DEFINE.md).
Files
call-trace-plugin/
├── package.json # dsh.bundle manifest
├── cordis.patch.yml # bundle layer for profile install (name = package name)
├── cordis.local.yml # --patch overlay (name = file:// URL of index.js)
├── index.js # entry: event listeners + JSONL + rotation + service + tool
├── ui/ # optional floating UI (dynamic-plugin source + rebuild notes)
├── smoke-test.mjs # recorder smoke test
├── check-syntax.mjs # ui/ syntax check
└── README.md / LICENSE
Design notes
- Zero
@deepseek-ai/*runtime imports: out-of-tree plugins can only resolve packages in the installation's node_modules closure, so this plugin usesctx.onevents, raw JSON Schemactx.tools.register, andctx.provide— and exports noConfigschema (Cordis passes the patchconfigthrough untouched; defaults are merged insideapply). - Write on completion:
tools/executerecords the start,tools/resultrecords completion and flushes to disk; a crash mid-call drops that call (acceptable). - Rotation:
trace.jsonlis renamed totrace-<ts>.jsonlabove 5 MB.
Development
node --check index.js # syntax
node smoke-test.mjs # recorder smoke (structured output / history / parallel / rotation / clear)
node check-syntax.mjs # ui/host.js + ui/client.js syntax
Known limitations
- The floating UI is a dynamic plugin: the client half needs the monorepo
client build chain (tsdown + slot types + props share), consistent with the
official docs; it is not built into this bundle — it ships as archived source
under
ui/and is rebuilt on demand. - No tool→plugin mapping: tool registration does not expose its provider, so cards show the tool name plus a Chinese purpose description only.
- Subagent nesting is a time-window heuristic: calls from a different
agentId inside a
subagent/workflowcall's execution window are folded into its "subagent branch"; extreme concurrency may misassign (use the "self" view to filter in multi-session setups). - Recorder + dynamic UI together: both listen to the same events and keep their own state — no conflict.
Links
More in this category
liustack/modlens★ 1358
Vision bridge for text-only models: paste an image, get structured JSON evidence (OCR, layout, semantics).
Anionex/dsh-vision-toolkit★ 348
Vision tasks for text-only models: intent-aware image Q&A, long-screenshot OCR, UI reproduction, grounding, and pixel diff.
zhaoolee/notes★ 141
Export DSH conversations as Smartisan Notes-style PNGs, or create and update Markdown notes in a configured account-scoped workspace.
Lum1104/dsh-browser★ 99
Chrome sidebar extension that lets DSH operate your browser directly, no vision capabilities required.
liustack/modsearch★ 94
Web search bridge for text-only agents: ask the web or X, get structured JSON evidence (search, fetch, citations).
dsh-market/dsh-market★ 86
The plugin market inside DSH: a Settings page to browse and search the full community catalog by category, with confirmed one-click installs and an installed-plugins view.