krimvp
dsh-otel
OpenTelemetry plugin for DeepSeek Harness (dsh) — traces and metrics for agent runs, tools, and model calls
- Stars
- 1
- Language
- TypeScript
- Created
- Aug 15, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-otel
OpenTelemetry plugin for DeepSeek Harness (dsh).
Status: early development. The plugin emits traces and metrics for the agent loop, the model calls, and the tool calls. The GenAI semantic conventions have the status
Development, so everygen_ai.*name can change. Expect breaking changes before version 0.1.0. DeepSeek Harness is also in developer preview.
What the plugin emits
Traces
| dsh concept | Span | Kind |
|---|---|---|
| Turn | invoke_agent | INTERNAL, root of the trace |
| Step | dsh.step | INTERNAL, child of the turn |
| Model call | chat {model} | CLIENT, child of the step |
| Tool call | execute_tool {name} | INTERNAL, child of the step |
Every span carries gen_ai.conversation.id, the dsh session id.
Metrics
| Instrument | Unit |
|---|---|
gen_ai.client.token.usage | {token} |
gen_ai.client.operation.duration | s |
gen_ai.execute_tool.duration | s |
The plugin does not emit logs.
The harness already ships @deepseek-ai/dsh-session-telemetry-otel for logs.
The two packages work together.
docs/design.md gives the full attribute tables.
Install
dsh plugin --profile <name> add dsh-otel
Then mount the plugin in $DSH_HOME/profiles/<name>/cordis.patch.yml:
- insert:
- id: dsh-otel
name: dsh-otel
config:
endpoint: http://localhost:4318
insert adds a new entry.
A patch that names an id replaces the whole config of that entry.
Confirm the mount with dsh --profile <name> --dump-config.
The plugin needs @deepseek-ai/cordis and @opentelemetry/api as peers.
The plugin sets up its own tracer provider, meter provider, and OTLP HTTP exporters.
You do not need @opentelemetry/sdk-node.
Configuration
The config is flat and has exactly four options.
| Option | Type | Default | Meaning |
|---|---|---|---|
serviceName | string | dsh | The service name. OTEL_SERVICE_NAME wins over this option. |
endpoint | string | http://localhost:4318 | The OTLP HTTP base URL. The plugin uses it only when no OTLP endpoint variable is set. |
captureContent | boolean | false | Records the message content, the tool arguments, and the tool result. |
useGlobalProviders | boolean | false | true uses the @opentelemetry/api globals. The plugin then sets up no SDK. |
A standard environment variable wins over the config option.
| Variable | Effect |
|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | The base URL for both signals. The plugin then passes no URL to the exporters. |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | The URL for one signal, used as it is. |
OTEL_EXPORTER_OTLP_HEADERS, _TIMEOUT, _COMPRESSION, _CERTIFICATE | Read by the exporters. |
OTEL_SERVICE_NAME, OTEL_RESOURCE_ATTRIBUTES | Read by the plugin through the environment resource detector. |
OTEL_SDK_DISABLED=true | The plugin does nothing. |
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true | Turns the content capture on. |
OTEL_BSP_*, OTEL_TRACES_SAMPLER | Read by @opentelemetry/sdk-trace-base. |
The content capture is off by default. The message content can hold user data and personal data.
Development
Read AGENTS.md before you contribute. That file gives the rules for the code, the configuration, and the commits.
Verify each change against the real local stack in otel/.
docker compose -f otel/docker-compose.yml up -d
npm run build
./e2e/verify.sh is the one-command local verification.
The script builds the plugin, runs two tasks in dsh against a mock model,
then reads the traces from Tempo and the metrics from Prometheus.
The script prints one PASS line or one FAIL line for each assertion.
docker compose -f otel/docker-compose.yml up -d
./e2e/verify.sh
The script mounts the fresh build from ./dist with a temporary patch.
The script installs nothing and changes no profile.
The header of the script lists the environment variables for the paths of
dsh, of DSH_HOME, and of the mock server.
Each variable has a default for the local playground.
License
MIT