npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-tracing

v0.1.1

Published

OpenTelemetry (OTLP/HTTP) + Langfuse trace exporter for DeepSeek Harness — GenAI semconv, sanitized before send, batched with retry, off by default.

Readme

dsh-tracing

npm package name is dsh-tracing (dsh-trace is blocked by npm name-similarity rules); the harness plugin id stays dsh-trace.

OpenTelemetry-compatible tracing for DeepSeek Harness sessions. Projects session events into a span tree and exports them over OTLP/HTTP (JSON) or the Langfuse v3 ingestion API — no vendor lock, no built-in panel, your existing observability stack stays the source of truth.

What you get

  • Span tree per session turn: invoke_agent turn N (root) → step N → execute_tool {name} / chat {model}, with deterministic trace IDs (sha1(sessionId:turn)) so replays and cross-references stay stable.
  • GenAI semantic conventions: gen_ai.operation.name, gen_ai.request.model, gen_ai.usage.input_tokens / output_tokens, plus cache-read and reasoning token details. Token invariants are respected: cache-read counts inside input, reasoning inside output — details are exported as attributes, never re-summed.
  • Two backends, fan-out enabled: OTLP/HTTP (Jaeger, Tempo, Alloy, …) and Langfuse (traces map to trace-create, tools/steps to span-create, LLM calls to generation-create with usage in Langfuse token units).
  • Sanitize before send: built-in key redaction (key, token, secret, password, authorization, …), credential patterns (sk-…, ghp_…, AKIA…, Bearer …, PEM blocks), per-field truncation budgets, and an attribute-length cap. Custom keys/regexes merge in.
  • Batching with bounded memory: records queue up to batch.maxQueueRecords, flush every batch.flushIntervalMs or batch.maxRecords, retried with exponential backoff up to retry.maxAttempts, then dropped with a warning — tracing never blocks or crashes a session.
  • Fail-safe lifecycle: flushes on session/flush and session/disposed; missing starts still emit best-effort spans (zero-duration, status derived).

Install & enable

dsh plugin --profile web add dsh-tracing

The bundled row ships enabled: false. Enable it in your profile patch:

- insert:
  - id: dsh-trace
    name: dsh-tracing
    config:
      enabled: true
      otlp:
        endpoint: http://localhost:4318   # /v1/traces is appended
        serviceName: deepseek-harness
      # langfuse:
      #   publicKey: pk-lf-...
      #   secretKey: sk-lf-...
      #   baseUrl: https://cloud.langfuse.com

A profile-level patch targeting this id replaces the whole row config (no deep merge) — restate every key you want to keep.

Configuration

| Key | Type | Default | Notes | | --- | --- | --- | --- | | enabled | boolean | false | No-op when false (logs and exits). | | otlp | object? | – | OTLP/HTTP backend. endpoint required; /v1/traces appended automatically. Optional serviceName (deepseek-harness), serviceVersion, headers. | | langfuse | object? | – | Langfuse backend. publicKey/secretKey required (Basic auth); optional baseUrl (cloud default), release, tags. | | capture.turns / capture.steps / capture.tools / capture.llm | boolean | true | Per-kind capture switches. | | capture.llm.prompt / capture.llm.completion | boolean | true | Include prompt/completion text (subject to truncation + sanitization). | | sanitize.enabled | boolean | true | Master switch. | | sanitize.redactKeys | string[] | [] | Extra key names to redact (case-insensitive substring match, merged with builtins). | | sanitize.redactPatterns | string[] | [] | Extra regexes for values (invalid entries are skipped, not thrown). | | sanitize.truncatePromptChars / …CompletionChars / …ToolInputChars / …ToolOutputChars | number | 4000/4000/2000/2000 | Per-field truncation budgets (marker appended: …[truncated N chars]). | | sanitize.truncateAttributeChars | number | 1000 | Cap for any single span attribute string. | | metadata | object | {} | Static key/values copied onto every span (dsh.trace.* prefix is reserved). | | batch.maxRecords / batch.flushIntervalMs / batch.maxQueueRecords | number | 256 / 5000 / 2000 | Batching and queue bound. | | retry.maxAttempts / retry.baseDelayMs / retry.factor / retry.maxDelayMs | number | 5 / 1000 / 2 / 60000 | Export retry backoff. |

Event mapping

The collector consumes harness session/event broadcasts and makes a best-effort projection (snake_case/camelCase, type/event/kind, nested or flat payloads all tolerated):

| Event shape | Projection | | --- | --- | | turn/start, turn/end | invoke_agent turn N span (root of the turn's trace) | | step/start, step/end | step N child span | | tool/start + tool/end (matched by callId) | execute_tool {name} span | | assistant/model/chat/message/attempt events | chat {model} span; usage fields (input_tokens, output_tokens, cache_read…, reasoning…) accepted in both cases |

Events this plugin does not model are silently skipped. Unpaired ends still emit a best-effort span; the first end for a session closes any dangling parents.

Known limitations (v0.1)

  • Session events are shaped best-effort; harness payloads may evolve and the projector will miss fields it does not recognize (never crash).
  • OTel SpanKind is always INTERNAL (1).
  • The Langfuse mapping identifies observations by OTel span IDs — queries that join both views should use trace IDs.

Compatibility

Targets @deepseek-ai/cordis ^4.0.1. See the repo-level compatibility policy and the monthly CI job.

License

MIT