dsh-llm-call-inspector
English | 中文
A local, session-scoped LLM request and response inspector for DeepSeek Harness Web. It adds an LLM Calls view beside Chat and Trajectory so developers can inspect each session-associated normalized llm/stream call without changing what the model receives or what the caller receives.
This is a community plugin, not an official DeepSeek Harness release. Version 0.1.x is verified against the 0.1.0-rc.8 API surface.

[!WARNING] Request and response bodies can contain prompts, source code, tool arguments, tool results, personal data, or secrets embedded in content. Installing this plugin opts the Host into body capture by default. Read Privacy and data handling before using it with sensitive sessions.
What it shows
- A newest-first list of calls for the active DSH session.
- Provider, model, purpose, status, start time, duration, chunk count, and body-capture state.
- Search plus status and purpose filters.
- A master/detail layout with separate request and response tabs, expandable JSON, and copy actions.
- Live polling, explicit refresh, session-local clear, error and empty states, keyboard focus, responsive layout, and English/Chinese labels.
- Calls made for assistant work, compaction, session-title generation, or another normalized purpose when the call carries a
sessionId.
The captured normalized request allowlist is:
provider, model, reasoningEffort, messages, system, tools, temperature, maxTokens, stop, sessionId, and purpose.
The captured response is the ordered array of DSH StreamChunk values observed at llm/stream. The observer delegates exactly once, yields the original chunk objects in the original order, and preserves downstream throws. Whole-chunk capture also preserves JSON-compatible adapter replay metadata, including finish.replayState when an adapter emits it.
Scope boundary
This plugin inspects the DSH-normalized LLM boundary. It is not a provider wire proxy.
It does not capture:
- provider-native HTTP request or response bodies;
- HTTP headers, top-level API keys, abort signals, or undeclared adapter-private fields on the request object;
- raw SSE frames, transport retries hidden inside an adapter, or provider-side processing;
- sessionless
llm/streamcalls; or - hidden reasoning that the provider does not return as a normalized chunk.
Top-level structural exclusion is not content redaction. A key pasted into a prompt or returned by a tool can still be captured.
Response chunks are preserved whole, so adapter-private JSON inside finish.replayState can also be captured and must be treated as sensitive content.
Why a separate view instead of merging with Trajectory
DeepSeek Harness 0.1.0-rc.8 exposes conversation.view as the public additive UI seam. The built-in Trajectory uses that seam but does not expose a supported inner row or panel extension point.
Trajectory and this inspector also answer different questions:
- Trajectory explains the durable session story: user/assistant/tool events, steps, timing, usage, and outcomes.
- LLM Calls exposes each normalized invocation boundary: the exact captured request snapshot and ordered response chunks observed for that invocation.
The plugin therefore registers an adjacent view at order 20 instead of copying, patching, or depending on Trajectory internals. If Trajectory later publishes a stable cross-link or inner-extension seam, the two views can be connected without changing capture ownership.
Architecture
session-associated GenerateOptions
|
v
llm/stream observer
|
v
bounded per-session memory store
|
v
Connection RPC /dsh-llm-call-inspector (loopback only)
|
v
conversation.view / LLM Calls
One package contains both runtime faces:
- Host injects
llmandconnection, prepends a transparentllm/streamobserver, owns bounded memory, and registers one loopback-only Connection RPC channel. - Client injects
connection,slots, andlocale, then registers oneconversation.viewentry. It polls body-free summaries and fetches the full body only for the selected call. - Bundle declares
dsh.bundle.patchand a Web client export, sodsh pluginadds both faces through the supported profile mechanism.
The store never writes captured bodies to disk. Records disappear when you clear the current session in the UI, the configured per-session/session/global-body bounds evict them, the plugin reloads, or DSH restarts.
Install
Prerequisites:
- DeepSeek Harness
0.1.0-rc.8; - Node.js
22.19or newer supported by the package engine; and - pnpm on
PATH, as required bydsh plugin.
Install the GitHub repository into the Web profile:
dsh plugin --profile web add github:striveh/dsh-llm-call-inspector
dsh --profile web --dump-config
dsh web
Restart a running Web profile after adding, updating, or removing a bundle. The config dump should contain a # == dsh-llm-call-inspector layer.
For reproducible use, pin a reviewed commit:
dsh plugin --profile web add github:striveh/dsh-llm-call-inspector#<commit-sha>
The repository ships checked-in lib/ artifacts and deliberately has no prepare or install lifecycle script. A GitHub install therefore does not need pnpm allowBuilds permission.
Configuration
The bundle defaults are:
| Field | Default | Meaning |
|---|---|---|
captureBodies |
true |
Capture allowlisted request fields and ordered response chunks. false keeps call metadata but marks both bodies omitted. |
maxCallsPerSession |
100 |
Maximum retained calls in one session; oldest calls are evicted first. |
maxSessions |
32 |
Maximum retained session buckets; least-recently-used buckets are evicted. |
maxRequestBytes |
524288 |
UTF-8 JSON byte ceiling for one request snapshot. |
maxResponseBytes |
1048576 |
UTF-8 JSON byte ceiling for one response chunk array. |
maxTotalBodyBytes |
67108864 |
Global retained captured-JSON budget across all sessions; settled calls are evicted before running calls, then oldest creation order first. |
pollIntervalMs |
750 |
Interval advertised to the mounted browser view. |
To override them, add a later row to $DSH_HOME/profiles/web/cordis.patch.yml. A DSH patch replaces the row's complete config, so this example restates every field:
- id: dsh-llm-call-inspector
config:
captureBodies: true
maxCallsPerSession: 50
maxSessions: 16
maxRequestBytes: 262144
maxResponseBytes: 524288
maxTotalBodyBytes: 33554432
pollIntervalMs: 1000
If a body exceeds its limit, the plugin drops the whole body and exposes an explicit size-limit omission with measured bytes. Non-JSON-compatible values and disabled capture also produce explicit omission states; metadata and chunk counts remain available.
Metadata-only mode
Set captureBodies: false when provider/model, status, timing, and chunk counts are sufficient:
- id: dsh-llm-call-inspector
config:
captureBodies: false
maxCallsPerSession: 100
maxSessions: 32
maxRequestBytes: 524288
maxResponseBytes: 1048576
maxTotalBodyBytes: 67108864
pollIntervalMs: 750
Changing this configuration reloads the plugin and discards its current in-memory records.
Disable or uninstall
To keep the dependency installed but disable the plugin, add this later profile patch and restart Web:
- id: dsh-llm-call-inspector
disabled: true
To remove the dependency and its bundle layer:
dsh plugin --profile web remove dsh-llm-call-inspector
Restart the profile after removal. Uninstalling or disabling the plugin cannot recover already-evicted in-memory records; none are persisted by this plugin.
Existing options and when to use them
This landscape changes quickly; follow each linked project's current documentation before choosing one.
| Option | Primary data and UI | Better fit when |
|---|---|---|
| Built-in Trajectory | Durable session events in the native UI | You need the agent/session narrative, tool flow, usage, and outcomes rather than call bodies. |
| dsh-devtools | Metadata-first runtime profiler in a Web view; intentionally omits prompts and tool bodies | You need performance and runtime diagnostics with a smaller content-privacy surface. |
| dsh-llm-inspector | Reasoning controls, traffic statistics, a think workflow, and optional audit files; no native request/detail Web UI documented |
You explicitly want those behavior-changing or file-audit features. |
| dsh-plugin-langfuse | Session events exported as OpenTelemetry traces to Langfuse | You need centralized, cross-session observability and accept/configure external export. |
| dsh-llm-call-inspector | Local native master/detail UI over normalized call bodies; bounded process memory only | You need focused trace, debug, teaching, or research inspection on the local Web surface. |
GitHub topics are discovery metadata, not a security review or official endorsement.
Development
pnpm install --frozen-lockfile
pnpm verify
pnpm pack --dry-run
pnpm verify runs host and client typechecks, automated tests, a clean build, and read-only package checks. The package verifier checks the public exports, committed build artifacts, Web loader identity, bundle patch, DSH client declaration, documentation install command, and absence of install-time lifecycle scripts.
To test a local checkout after building it:
dsh plugin --profile web add .
dsh --profile web --dump-config
dsh web
See CONTRIBUTING.md for change constraints and SECURITY.md for private vulnerability reporting.
Compatibility
DeepSeek Harness is in developer preview and does not promise plugin compatibility across prereleases. This release's source, peer dependencies, tests, and package verification use @deepseek-ai/dsh-* 0.1.0-rc.8. No other DSH version is claimed as verified until it passes the same gates.
No comments yet. Be the first to write one.