DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Plugin Greptimedb — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
P

dsh-plugin-greptimedb

Plugin Greptimedb

面向 DeepSeek Harness 的 OpenTelemetry 链路追踪、指标和日志,直接写入 GreptimeDB。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:tma1-ai/dsh-otel#d7659f7a6927a4a1984a79d7e792468f6f26682b
README兼容性版本

兼容性与来源证明

Plugin Greptimedb 以 dsh-plugin-greptimedb 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/8/25

版本

0.1.0stable
2026/8/25

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
Apache-2.0
发布源
github
GitHub
★ 9
周下载
0
最近提交
2026/9/3
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Sdk Minimal@deepseek-ai/dsh-sdk-minimal独立的最小 SDK 配置包:JSON-RPC、一个 DeepSeek 适配器、持久化 Shell 和 JSONL 会话Sdk App@deepseek-ai/dsh-sdk-appdsh SDK 配置包:基于 dsh-base 提供 stdio JSON-RPC 服务和进程生命周期管理Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序

README

dsh-plugin-greptimedb

English | 中文

Send DeepSeek Harness telemetry to GreptimeDB as OpenTelemetry traces, metrics, and logs.

No collector. No sidecar. No fork of DSH. It installs as an ordinary plugin, and every turn, model call, and tool execution becomes a row you can query:

-- Slowest tool calls, with the model that requested them
SELECT span_name,
       "span_attributes.gen_ai.request.model" AS model,
       duration_nano / 1000000 AS ms
FROM opentelemetry_traces
WHERE span_name LIKE 'execute_tool%'
ORDER BY duration_nano DESC
LIMIT 10;
-- Cache hit rate per model
SELECT "span_attributes.gen_ai.request.model" AS model,
       SUM("span_attributes.dsh.usage.cache_read_tokens") AS cached,
       SUM("span_attributes.gen_ai.usage.input_tokens") AS billed
FROM opentelemetry_traces
WHERE span_name LIKE 'chat%'
GROUP BY model;

Install

dsh plugin --profile headless add dsh-plugin-greptimedb

The package ships a bundle patch, so that one command wires it into the profile. To point it at your own database, override the row in $DSH_HOME/profiles/<name>/cordis.patch.yml:

- id: greptimedb-otel
  name: 'dsh-plugin-greptimedb'
  config:
    endpoint: https://<host>/v1/otlp
    database: <dbname>
    username: <user>
    password: <password>

A profile patch replaces the row's whole config instead of merging into it, so restate every field you want to keep.

The defaults already point at a local GreptimeDB:

docker run -p 127.0.0.1:4000-4003:4000-4003 \
  -v "$(pwd)/greptimedb_data:/greptimedb_data" \
  --name greptime --rm greptime/greptimedb:v1.0.0 standalone start \
  --http-addr 0.0.0.0:4000 --rpc-bind-addr 0.0.0.0:4001 \
  --mysql-addr 0.0.0.0:4002 --postgres-addr 0.0.0.0:4003

Configuration

KeyDefaultNotes
endpoint(required)OTLP base URL, e.g. http://localhost:4000/v1/otlp. The plugin appends each signal's /v1/{traces,metrics,logs} suffix; a per-signal path is rejected at load.
databasepublicSent as X-Greptime-DB-Name.
username / password(none)Basic auth. Both or neither.
signalsall threeAny subset of traces, metrics, logs. A disabled signal builds no exporter.
contentnoneHow much payload may leave the process. See What leaves the machine.
serviceNamedshOTel service.name.
logTable / traceTableGreptimeDB defaultsDestination table overrides.
shutdownTimeoutMillis3000Deadline for the entire teardown sequence.
metricIntervalMillis30000Metric collection period. Must be at least exportTimeoutMillis.
maxExportBatchSize / maxQueueSize512 / 2048Batch and buffer bounds.
scheduledDelayMillis / exportTimeoutMillis5000 / 30000Export cadence and per-request deadline.

Bad configuration fails at plugin load with the offending field named, not at the first export.

Traces

Turn spans are roots. Chat and tool spans hang off them as siblings, correlated by dsh.step:

invoke_agent dsh              turn/start → turn/end
├── chat deepseek-chat        step/start → assistant/message
├── execute_tool bash         tool/call  → tool/result
└── chat deepseek-chat

Siblings, not nesting. DSH appends assistant/message first and executes the requested tools afterwards, so a tool span nested under a chat span would start after its parent ended. That breaks waterfall and latency views.

Timestamps come from the session event that justifies them, never from a clock read while handling it.

A chat span closes on one of four paths, each with a defined end time:

SituationEnd timeStatus
Model respondedassistant/messageOK
Stream interruptedassistant/messageOK, plus dsh.response.interrupted
Request failedthat step's step/endERROR, exception recorded
No end event (crash, teardown)last event seenUNSET, plus dsh.span.unclosed

The last row covers genuinely missing boundaries only. A failed request is measured, not written off.

Token accounting

DSH reports disjoint counts. inputTokens is uncached input alone; cache reads and writes are separate fields. The GenAI convention's gen_ai.usage.input_tokens is the billed total, so the plugin exports:

gen_ai.usage.input_tokens  = inputTokens + cacheReadTokens + cacheWriteTokens
gen_ai.usage.output_tokens = outputTokens          (reasoning tokens included)

Exporting inputTokens alone understates every cached request, often by an order of magnitude. The breakdown stays queryable as dsh.usage.uncached_input_tokens, dsh.usage.cache_read_tokens, dsh.usage.cache_write_tokens, and dsh.usage.reasoning_tokens.

Metrics

InstrumentTypeDimensions
gen_ai.client.token.usageHistogramgen_ai.token.type (input/output only), model, provider
gen_ai.client.operation.durationHistogramgen_ai.operation.name, model
dsh.token.detailHistogramdsh.token.detail_kind (cache_read/cache_write/reasoning)
dsh.tool.invocationsCountergen_ai.tool.name, dsh.tool.outcome
dsh.turns / dsh.stepsCounter

Cache and reasoning counts stay off the standard token histogram so a plain SUM() over it cannot double-count.

Logs

One record per session event. Four attributes become real columns through X-Greptime-Log-Extract-Keys:

SELECT session_id, event_type, turn, step, body
FROM dsh_logs
WHERE session_id = '...' AND event_type = 'tool/result'
ORDER BY timestamp;

Every attribute is underscore-named for a reason. GreptimeDB keeps unextracted attributes in a JSON column read with json_get_string(), which treats a dotted key like session.id as a nested path and cannot address it.

assistant/chunk is never exported. It runs to tens of thousands of token deltas per session, and the assembled message already carries every fact they hold.

What leaves the machine

content decides this. The default withholds all payloads.

ModeExported
none (default)Structure and accounting: event types, turn and step numbers, token counts, tool names, durations, outcomes, error name and code.
fullAdds user and assistant message content, tool arguments, tool results.
full+promptAdds request/header: the complete system prompt and every tool schema.

Two things never leave, in any mode. A tool's private meta payload is opaque and arbitrary by design. The internal error.message of a failed turn is provider text that can quote the prompt back.

The projection is a positive allowlist. An event type the plugin does not know, including one a future DSH plugin declares, exports its identity and nothing else. A generic clone of event.data would quietly start leaking whatever that type happens to carry.

For contrast, DSH's own session-telemetry-otel defaults the other way: its FULL mode ships the complete event.data, system prompt included, with no redaction rules of its own.

Dashboards

Four Grafana dashboards ship in grafana/, along with a compose stack that brings up GreptimeDB and Grafana together.

cd grafana && docker compose up -d && open http://localhost:3000

Trace explorer

DashboardAnswers
OverviewWhat did this cost, how fast was it, how much came from cache
Agent loopWhich tools ran, how often they failed, how many model calls a turn needed
Trace explorerWhat happened inside one specific turn, span by span
Log explorerEvery session event, filterable by session, type, and full-text search

Every panel query is checked against a live database by node grafana/verify.mjs. See grafana/README.md for the datasource split and grafana/indexes.sql for the indexes these queries want.

With TMA1

TMA1 proxies OTLP into a GreptimeDB it manages. Point endpoint at it and DSH shows up in the OTel GenAI view:

endpoint: http://localhost:14318/v1/otlp

TMA1's tma1_token_usage_1m, cost_1m, latency_1m, and status_1m flow tables derive from span_attributes.gen_ai.*, which this plugin populates by convention.

Development

pnpm test     # unit, profile composition, Loader boot
pnpm smoke    # packaging checks against a freshly packed tarball
GREPTIMEDB_OTLP_ENDPOINT=http://localhost:4000/v1/otlp pnpm test   # adds the live database round trip

Four tiers, each catching what the ones below cannot:

TierWhat only it catches
UnitSpan state machine, token arithmetic, projection allowlist
Profile compositionA bundle patch that fails to resolve, parse, or compose into an entry
Loader bootBare-name resolution, !!js evaluation, inject satisfaction, real OTLP bytes and headers
Live GreptimeDBTrace pipeline acceptance, extracted log columns, SQL-visible values

Known limitations

DSH is pre-release. It reserves the right to rename and repackage freely before its first tagged release. This plugin reads only the session event stream and documented payload fields, and pins its peer range to the version it is tested against (0.1.1-rc.2).

The GenAI conventions are experimental. Attribute names come from @opentelemetry/semantic-conventions/incubating and move with it. Spans carry both gen_ai.provider.name and the deprecated gen_ai.system with the same value: existing GenAI dashboards select on the old name, and a span without it is invisible to them.

No per-turn flush. Export follows the batch processors' own cadence. A forced flush per turn would be this pipeline's only source of concurrent flushes, and their interaction with the shutdown drain drops tail records.

Shutdown is bounded, and the bound cannot cancel a transport. Records still in flight when shutdownTimeoutMillis expires may be lost at process exit. The alternative, an unbounded wait, hangs the CLI.

Subagent sessions get their own trace. Each session's spans form a separate tree. They are not stitched into the parent session's trace.

License

Apache-2.0