Skip to content

feat: add DeepSeek Harness (dsh) provider - #1001

Open
MiloMMIN wants to merge 1 commit into
getagentseal:mainfrom
MiloMMIN:feat/dsh-provider
Open

feat: add DeepSeek Harness (dsh) provider#1001
MiloMMIN wants to merge 1 commit into
getagentseal:mainfrom
MiloMMIN:feat/dsh-provider

Conversation

@MiloMMIN

Copy link
Copy Markdown

Summary

  • Adds a provider for DeepSeek Harness (dsh): reads sessions from $DSH_HOME/sessions/<encoded-cwd>/session-<uuid>/session.jsonl.zstd (default ~/.dsh, plus the uncompressed session.jsonl variant).
  • DSH session logs are concatenations of independent zstd frames (one per appended event batch), which node:zlib's one-shot API cannot decode as a whole. The provider ports the frame-boundary scan (scanZstdFrames) from the official @deepseek-ai/dsh-session-persistence-jsonl package and decompresses frame by frame using only public APIs. zstd requires Node >= 22.15; older runtimes get a stderr notice and DSH data is skipped (same pattern as the Zed provider).
  • Usage accounting mirrors dsh-token-meter's projection semantics: an assistant/message usage report is the final value for its (turn, step) and replaces the earlier assistant/chunk sample (adjacent reports of the same API call), never double counting. Model attribution comes from the most recent request/header config; reasoning tokens are billed at the output rate (same as Hermes/Gemini). One parsed call per (turn, step), dedup key dsh:<sessionId>:<turn>:<step>.

Testing

  • I have tested this locally against real data (not just unit tests)
  • npm test passes — the new suite (tests/providers/dsh.test.ts, 22 tests) plus registry/env/probe-roots/session-cache suites are green. Full tests/providers on this Windows machine shows 45 failures that exist identically on the unmodified baseline (home-dir-related: claude-config-dirs, copilot, devin, ...); none are dsh-related.
  • npm run build succeeds — build:cli (tsup) and tsc --noEmit are clean. Note: the full build script's first step (bundle-litellm, re-fetching the upstream pricing snapshot) fails on this machine with ECONNRESET due to local network restrictions; that fetch is unrelated to this change, which does not touch pricing data.

For new providers only:

  • I installed the tool and generated real sessions by using it
  • npm run dev -- today shows correct costs and session counts for this provider
  • npm run dev -- models --provider dsh shows correct model names and pricing
  • Screenshot or terminal output attached below proving it works with real data

report --provider dsh -p all --format json against a real ~/.dsh (25 sessions):

overview: cost $3.54, calls 1027, sessions 25, cache hit 96.5%
tokens:   input 6,380,935 / output 1,096,378 / cacheRead 174,656,064 / cacheWrite 0
models:   DeepSeek v4 Pro    501 calls  $2.8229
          DeepSeek v4 Flash  525 calls  $0.7158
          grok-4.6             1 call   $0.0000
projects: Desktop/share/script, Documents/WK, ... (grouped by session cwd)

Cross-check: token totals summed independently from the raw session logs (frame-by-frame decode + the replace-on-final usage rule) match the report exactly (sessions=25, calls=1027, input/output/cacheRead/cacheWrite identical).

Dashboard (npm run dev) with DSH included in the all view:

│ By Model                                                  │
│ DeepSeek v4 Pro    $2.82  97.0%  501  100.0%              │
│ DeepSeek v4 Flash ~$0.934 96.2%  571  100.0%              │
│ By Project                                                │
│ Desktop/share/script  $4.51  $0.215  21                   │

Provider cycling (p) detects dsh and the TUI shows it as DeepSeek Harness; codeburn doctor probes $DSH_HOME/sessions.

Copilot AI lite review requested due to automatic review settings August 16, 2026 08:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new dsh provider to CodeBurn to ingest DeepSeek Harness session logs (including multi-frame zstd JSONL), enabling cost/token attribution by model/project/turn and integrating the provider into discovery, caching, docs, and the macOS menubar change guard.

Changes:

  • Implement src/providers/dsh.ts with multi-frame zstd frame scanning + per-(turn,step) usage projection semantics and tool/skill/bash extraction.
  • Register dsh across the provider registry, env var declarations, and session-cache parse-versioning.
  • Add provider documentation and a comprehensive vitest suite for discovery/parsing/display-name behavior.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/providers/dsh.test.ts New test suite covering DSH discovery/parsing semantics (zstd + plain JSONL) and display-name normalization.
tests/provider-registry.test.ts Updates expected core provider registration list to include dsh.
tests/provider-env-declarations.test.ts Declares dsh.ts as a provider that reads env vars.
src/session-cache.ts Adds DSH_HOME invalidation and a dsh parse-version key.
src/providers/index.ts Eagerly registers the new dsh provider.
src/providers/dsh.ts New DSH provider implementation (discovery + parsing + zstd frame handling).
README.md Updates supported-tool count and adds DSH to the supported tools section.
mac/Sources/CodeBurnMenubar/Data/UsageDataChangeGuard.swift Adds DSH sessions directory to the menubar refresh change-detection roots.
docs/providers/README.md Adds DSH to the provider docs index table.
docs/providers/dsh.md New DSH provider documentation (paths, format, deduping, quirks).
docs/architecture.md Updates provider registration tier list to include eager dsh.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +16 to +17
const zstdCompress = (zlib as { zstdCompressSync?: (buf: Buffer) => Buffer }).zstdCompressSync

Comment thread src/providers/dsh.ts
Comment on lines +189 to +196
// Cheap discovery probe: decompress ONLY the first frame (the session header
// batch) instead of the whole log. The header frame is tiny, so a bounded head
// read almost always contains it; fall back to a full read when it does not.
async function readSessionHeader(filePath: string): Promise<DshEvent | null> {
const firstLine = async (): Promise<string | null> => {
if (filePath.endsWith('.zstd')) {
if (!zstdDecompress) return null
let head: Buffer
Reads DSH sessions from $DSH_HOME/sessions (default ~/.dsh/sessions):
one directory per session holding session.jsonl.zstd (or an
uncompressed session.jsonl when compression=none).

The .zstd log is a concatenation of independent zstd frames (one per
appended event batch), which node:zlib's one-shot API cannot decode
whole; the provider ports the frame-boundary scan from the official
@deepseek-ai/dsh-session-persistence-jsonl package and decompresses
frame by frame. zstd needs Node >= 22.15; older runtimes get a notice
and DSH data is skipped.

Usage follows dsh-token-meter semantics: an assistant/message usage
report is the final value for its (turn, step) and replaces the
earlier assistant/chunk sample instead of double counting. Models come
from the most recent request/header config; reasoning tokens are
billed at the output rate. One parsed call per (turn, step), dedup key
dsh:<sessionId>:<turn>:<step>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants