Vai al contenuto principale
P

dsh-observe

perrylink/dsh-observe

Esporta il flusso di eventi della sessione verso OpenTelemetry OTLP e Langfuse come trace e metriche sanificate e bufferizzate, disattivato per impostazione predefinita.

Installazione

dsh plugin --profile web add github:perrylink/dsh-observe

README

📊 dsh-observe

  • 1024 store channel: npm i -g dsh1024 once, then dsh1024 plugin --profile web add dsh-observe (counts toward the deepseek1024.com install ranking). Gitee dshfind OpenSSF Scorecard

OpenTelemetry and Langfuse observability exporter for DeepSeek Harness.

Turn session events into OTLP traces and Langfuse observations — sanitized, buffered, off by default.

License DSH plugin dsh-doctor DSH Market Node CI Version npm version npm downloads

English · 简体中文 · Español · Português · हिन्दी


⭐ 如果它帮到了你

这个插件是 DSH 插件家族的一员(40+ 个,全部 Apache-2.0)。如果你在用,给个 star —— 它不会解锁任何功能,但会让下一个人在搜索里更容易找到它。

English: part of a 40+ plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.

Compatibility

SurfaceStatus
HarnessDeepSeek Harness dsh-v0.1.7-rc.2 (adapted 2026-09-22): session format V4 represents a tool result as a first-class role: 'tool' message carrying top-level toolCallId + content + optional isError — the V3 tool-result content block is gone from the host's ContentBlockMap, and this plugin reads only the V4 shape (a pre-upgrade V3 log still projects through a read-only compatibility path). Session format V3's other traits carry over: the assistant stream is embedded in assistant/message / assistant/attempt, and the system prompt is surface node 0 (system/message); the plugin consumes only the live event stream and never reads session log files. The peer range >=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0 || >=0.1.6-0 <0.2.0 || >=0.1.7-0 <0.2.0 keeps every published line installable (full local gate chain; the compat workflow covers the profile install smoke).
Node^22.19.0 || >=24.0.0
BackendsOpenTelemetry OTLP/HTTP (traces + metrics, JSON encoding) and Langfuse (LLM observability) — either or both
ModelModel-agnostic: it exports the session/event stream; no model calls are made

What you get

dsh-observe turns the harness's session/event stream into standard observability protocols:

  • Spans — turn, step, tool-call (duration, status, retry derivation), and LLM generation spans, linked into per-turn traces with deterministic ids.
  • Metrics — per-provider/model token counters, USD cost counters (configurable pricing table), and the optional context-pressure gauge from ctx.tokenMeter.
  • Sanitized capture — prompt and completion bodies are redacted (structural key names + built-in secret patterns + your patterns) and truncated before anything is queued or sent.
  • Reliability — async batching (size- and timer-triggered), a bounded durable offline buffer (storage-domain) with oldest-first eviction, and deterministic exponential-backoff retries; undeliverable batches survive restarts.
  • Runtime kill switch — the optional Typert remote (observe/status, observe/setEnabled) lets a settings page stop and resume exporting without unmounting.
  • Off by default — enabled: true plus at least one backend is an explicit opt-in; nothing is captured or exported otherwise.
session/event stream
   │ collector (turn/step/tool/llm spans, metrics)
   │ sanitize (keys, secrets, budgets)
   ├──▶ pipeline "otlp"  ── queue ── flush ──▶ OTLP /v1/traces + /v1/metrics
   │         └─ retry/backoff ─┐
   ├──▶ pipeline "langfuse" ── queue ── flush ──▶ Langfuse ingestion
   │         └─ retry/backoff ─┤
   └────────── durable spool (offline buffer, bounded) ◀┘

Quick start

# 1. install the bundle into your profile
dsh plugin --profile web add "github:PerryLink/dsh-observe#main"

# or from npm (published releases)
dsh plugin --profile web add dsh-observe

# 2. configure a backend in your profile patch (cordis.yml) and restart
dsh --profile web

Minimal OTLP configuration (the row ships commented out in cordis.patch.yml):

- insert:
    - id: dsh-observe
      name: dsh-observe
      config:
        enabled: true
        otlp:
          endpoint: http://localhost:4318

Then verify the row mounts:

dsh --profile web --dump-config | grep -A2 'id: dsh-observe'

Install & uninstall

  • git channel (latest main): dsh plugin --profile web add "github:PerryLink/dsh-observe#main" — the prepare script builds with production dependencies only.
  • npm channel (published releases): dsh plugin --profile web add dsh-observe.
  • tarball channel: pnpm pack in this repo, then dsh plugin --profile web add ./dsh-observe-<version>.tgz.
  • uninstall: dsh plugin --profile web remove dsh-observe (or remove the row from the profile patch).

If pnpm reports ERR_PNPM_IGNORED_BUILDS for this package (esbuild's harmless platform-binary validation), add allowBuilds: { esbuild: true } to your pnpm-workspace.yaml — the dsh CLI prints the exact snippet.

Configuration

All tunables are Schemastery Config fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. cordis.patch.yml documents each key inline.

KeyDefaultMeaning
enabledfalseMaster switch; true plus at least one backend is the explicit opt-in
otlpnullOTLP backend config, or null to disable it
otlp.endpoint(required)OTLP base URL; /v1/traces and /v1/metrics are appended
otlp.serviceNamedeepseek-harnessservice.name resource attribute
otlp.serviceVersion(none)service.version resource attribute
otlp.headers{}Extra headers merged into every export request
otlp.timeoutMs10000Per-request timeout
langfusenullLangfuse backend config, or null to disable it
langfuse.baseUrlhttps://cloud.langfuse.comLangfuse base URL
langfuse.publicKey(required)Project public key
langfuse.secretKey(required)Project secret key
langfuse.release(none)Release tag stamped onto traces
langfuse.traceNamesession {session} turn {turn}Trace-name template; {session}/{turn} interpolate per trace
langfuse.tags[]Static tags stamped onto every trace
langfuse.timeoutMs10000Per-request timeout
capture.turnstrueTurn lifecycle spans
capture.stepstrueStep lifecycle spans
capture.toolstrueTool-call spans with sanitized arguments/results
capture.llmtrueLLM generation spans
llm.prompttrueCapture the sanitized request prompt (false = sizes only)
llm.completiontrueCapture the sanitized completion (false = sizes only)
metadata.sessionIdtrueSession id attribute
metadata.cwdfalseSession working directory (a local path — off by default)
metadata.agentPresettrueAgent preset id attribute
metadata.modeltrueProvider/model attributes
metrics.tokenstruePer-provider/model token counters
metrics.costtrueUSD cost counters (need pricing rules to match)
metrics.contextTokenstrueContext-pressure gauge (needs ctx.tokenMeter)
pricing[]Pricing table, first match wins: { provider?, model, inputPerToken, outputPerToken, cacheReadPerToken?, cacheWritePerToken? }
sanitize.enabledtrueRedaction master switch (false disables redaction, never truncation)
sanitize.redactKeys[]Extra key-name substrings (key/token/secret/password/authorization/credential/apiKey are always included)
sanitize.redactPatterns[]Extra secret regular expressions
sanitize.truncatePromptChars4000Prompt character budget
sanitize.truncateCompletionChars4000Completion character budget
sanitize.truncateToolInputChars2000Tool argument character budget
sanitize.truncateToolOutputChars2000Tool result character budget
sanitize.truncateAttributeChars512Span attribute string budget
batch.maxRecords256Flush once the queue holds this many records
batch.flushIntervalMs5000Timer flush interval
batch.maxQueueRecords2000In-memory queue bound; excess spills to the buffer
batch.maxBufferRecords10000Durable offline buffer bound; oldest records drop first
batch.bufferRetryIntervalMs30000Offline buffer retry interval
retry.maxAttempts5Attempts per batch, including the first try
retry.baseDelayMs1000First backoff delay
retry.factor2Backoff multiplier per consecutive failure
retry.maxDelayMs60000Backoff ceiling
remote.enabledfalseMount the observe Typert remote (kill switch)

Tools & surfaces

This plugin registers no model tools — it is a background exporter. Its surfaces:

  • Consumes session/event (span/metric collection), session/flush (best-effort export kick — the durability checkpoint never waits on a remote backend), and session/disposed.
  • Optional remote service observe — observe/status returns the kill-switch state, configured backends, queue depths, and buffer occupancy; observe/setEnabled stops and resumes exporting at runtime.

Permissions & data

  • Permissions: network:outbound to the endpoints you configure, session:read for the event stream, storage:write for the offline buffer; no native code, no filesystem access.
  • Data: everything sent is derived from the session log and sanitized (redaction + truncation) before it is queued, buffered, or transmitted. The offline buffer stores only sanitized records, re-validated when read back.
  • Credentials: Langfuse public/secret keys travel only to the configured Langfuse endpoint; OTLP headers only to the configured OTLP endpoint. The plugin stores no credentials itself — keep them in credential references or environment-injected values.

Security boundaries

  • Off by default — nothing is captured or exported unless you opt in explicitly.
  • Sanitize before send — structural key redaction, built-in secret patterns (API keys, GitHub tokens, AWS keys, bearer credentials, private keys), your patterns, and character budgets all apply before any record leaves memory.
  • Durable boundary re-validation — records read back from storage are checked again before a sink can see them.
  • Failure loud, failure contained — export failures warn, count, retry, and finally spool; a failing session handler is caught and logged so observability can never break the harness hot path.
  • Model-visible ⟺ logged — prompt/completion exports project only the session surface (whose node 0 is the system prompt) and the logged header (call config and tools); the exporter invents no content.

Known limitations

  • npm 0.1.7-rc.2 — the plugin is developed and tested against @deepseek-ai/dsh@0.1.7-rc.2 (devDeps and CI's primary ruler); the peer range >=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0 || >=0.1.6-0 <0.2.0 || >=0.1.7-0 <0.2.0 keeps every published line installable, and the second ruler (typecheck:ci) plus the compat workflow cover the older baselines.
  • Audit events are not persisted — the exporter's own observe/* records are audit-only: on the current host line the session append gate admits surface events, so no observe/* event is written to the session log, and the plugin does not fake one with an unmarked append (that would make sessions unreadable). Treat /observe status output and the OTLP/Langfuse backends as the audit surface.
  • Metrics bypass the retry/spool path — OTLP metrics are aggregated cumulatively, so a lost flush self-heals on the next one (by design, not a bug).
  • No sampling — every enabled span family is exported; set capture.* switches and batch.maxBufferRecords for high-volume sessions.

Development

pnpm install        # node ^22.19 || >=24
pnpm run typecheck  # tsc: src + tests against the 0.1.7-rc.2 devDeps (no tsconfig paths)
pnpm run typecheck:ci  # tsc against the published line (no paths)
pnpm run check:ruler-live  # canary: must fail to compile, proving the ruler is live
pnpm test           # vitest: 126 tests, 18 suites (real Context/Session/storage seam)
pnpm run test:coverage  # coverage gate (90/80/90/90)
pnpm run build      # tsdown bundle + tsc declarations (lib/)
pnpm run verify:self-contained  # dependency specs resolve from the registry
pnpm run verify:artifacts       # built ESM face + bundle patch present
node scripts/check-readme-sync.mjs  # five-language README sync gate
pnpm pack           # the published tarball

Topics

dsh, dsh-plugin, deepseek-harness, deepseek, cordis, observability, opentelemetry, otlp, langfuse, tracing

Contributors

  • @PerryLink — creator and maintainer: collector, pipelines, spool, OTLP/Langfuse sinks, sanitization, and the five-language docs.

This project is one of the 45 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:

PluginOne-liner
dsh-auto-reviewSecond-model auto-review on the approval chain, fail-closed by default
dsh-autotierAutomatic strong/cheap model-tier routing with deterministic risk guards and a /tier command
dsh-background-agentsDurable background child agents with a Web UI sidebar, messaging and interrupt
dsh-budgetCost governance for DeepSeek Harness: budgets, carbon, and latency in one panel.
dsh-catalogDSH Desktop Market standard catalog source for the PerryLink family
dsh-cert-mcpRead-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence
dsh-checkpoint-rewindClaude Code /rewind-equivalent: snapshots, session forks, one-shot restore
dsh-claude-moveMigrate Claude Code sessions, memory, skills and CLAUDE.md into DSH
dsh-clickCross-platform native desktop control for DeepSeek Harness — Windows first.
dsh-composer-historyTerminal-style input history for the web composer: arrows, Ctrl+R search
dsh-data-qualityDataset quality checks and citation cross-checks (the optional numeric bridge consumed here)
dsh-defendPrompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness.
dsh-doublecheckEngineering-discipline guard: requirements grill, test gates, adversary review
dsh-drawUnified static-image generation routing for DeepSeek Harness.
dsh-fastRead-only performance diagnostics for DeepSeek Harness.
dsh-fund-researchDeterministic research reports for Chinese public mutual funds
dsh-githubGitHub PR/issues integration for DSH, every write gated by approval
dsh-industry-researchIndustry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble
dsh-layaLaya typed decisions (noul/choice/score) as a first-class Cordis service and model-visible tools
dsh-libraryLocal document knowledge base for DeepSeek Harness.
dsh-local-aiLocal-model (Ollama) integration for DeepSeek Harness.
dsh-lsp-actionsLSP diagnostics, formatting, completion, code actions and rename over language servers
dsh-maskPII masking middleware: anonymize at the model boundary, restore at the display layer
dsh-mcp-panelRead-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors
dsh-mementoApproval-gated cross-session memory: ctx.memory seam + SQLite + memory tool
dsh-observeOpenTelemetry and Langfuse observability exporter for DeepSeek Harness.
dsh-output-stylesClaude Code outputStyles-equivalent runtime style switching
dsh-permission-rulesClaude Code-style declarative allow/deny/ask permission rules with audit
dsh-plugin-certificationCommunity certification registry with repro-checkable grades and badges
dsh-plugin-doctorZero-dependency static + sandbox smoke detector for DSH plugins
dsh-plugin-guidePlugin-development knowledge base as an on-demand agent skill
dsh-plugin-kitShared zero-runtime-dependency toolkit for the PerryLink DSH plugins
dsh-plugin-upgradeOne-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card
dsh-plugin-upgrade-015Merged 0.1.3-alpha.1 → 0.1.5-rc.1 upgrade corridor card plus a zero-dependency seam scanner
dsh-reachMulti-channel approval/question bridge: WeChat/Telegram/Feishu, session console
dsh-research-reportVerifiable research-report engine: content-addressed evidence ledger and sealed versions
dsh-scoreMulti-dimensional quality scoring for DeepSeek Harness plugins.
dsh-session-pinPin sessions in the Web sidebar with durable ordering
dsh-session-syncCross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store.
dsh-skill-pack-securitySecurity-audit skill pack: secret scan, dependency and supply-chain review
dsh-talkVoice-first session loop for DeepSeek Harness: talk to it, hear it answer.
dsh-team-roomsCross-session team rooms: shared message bus, task board and timeline
dsh-test-driveIsolated install-and-smoke test drives for DeepSeek Harness plugins.
dsh-ticktickTickTick/Dida365 task bridge: session-header panel + 11 tools
dsh-translateVendor parameter translation and deterministic JSON repair for DeepSeek Harness.

Install from the DSH Desktop Market

All PerryLink plugins are browsable in the built-in DSH Desktop Market: Market → Sources → add source → paste https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → select it. Installation still goes through the Market's npm-identity verification and your confirmation.

License

Apache License 2.0 © 2026 dsh-observe contributors

Plugin correlati