deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
This plugin is designed for the dsh ecosystem (a plugin-based DeepSeek harness where everything is a plugin): once you configure an OpenAI-compatible API host in dsh (official API, relay gateway, local inference service, etc.), the plugin automatically pulls model information from that host's endpoints — model listings, pricing (input/output/cache prices per million tokens), inference parameters (context length, max output, capability flags: tool calling / structured output / vision / parallel tools, etc.) — normalizes it, and generates ready-to-use model configs, saving you the manual work.
Core value:
/models with pricing and parameter lists) / multiplier-priced gateway (quota system) / capability-flag proxy (/model/info capability booleans) / Ollama / vLLM; fails with an error when all endpoint probes fail, and supports manual --kind.id / context window / max output / pricing family (input, output, cache_read, cache_write, internal_reasoning, in USD/1M) / capability flags / source provenance.(baseUrl, model).pick command lists models and prices; select one to generate a dsh config fragment.baseUrl + apiKey
│
▼
① Host detection (probe endpoints, result cached 1h)
├─ /models rich metadata → augmented
├─ /v1/models → ├─ /api/pricing → quota
│ ├─ /version → vllm
│ ├─ /model/info → flag
│ └─ otherwise → bare
├─ /api/tags → ollama
└─ all failed → unknown (error; override with --kind)
│
▼
② Fetch (parse model listings/pricing/capabilities by type)
│
▼
③ Normalize (unit conversion + source-chain completion + alias resolution)
│
▼
④ Capability probing (optional; only fills gaps missing from metadata)
│
▼
⑤ Output
├─ out/catalog.json full catalog (schema: model-catalog/v1)
├─ out/dsh-models.json dsh config fragment (schema: dsh/models/v1)
└─ out/report.md human-readable report
dsh plugin --profile demo add github:JohnXu22786/model-catalog
Remove with:
dsh plugin --profile demo remove model-catalog
Requirements: Node.js ≥ 21 (no runtime dependencies; only TypeScript needed to build).
npm install # install dev dependencies
npm run build # compile to dist/
# Discover the DeepSeek official API model catalog
export DEEPSEEK_API_KEY=sk-xxx
node dist/src/main.js discover --base-url https://api.deepseek.com
# Discover a local Ollama
node dist/src/main.js discover --base-url http://127.0.0.1:11434 --probe always
# Relay gateway (multiplier pricing)
node dist/src/main.js discover --base-url https://gateway.example.com --api-key-env GATEWAY_KEY
# Interactively pick models and generate a dsh config fragment (answers can be piped in one shot:
# line 1 = baseUrl, line 2 = key env var name (blank = auto-detect), line 3 = model number)
node dist/src/main.js pick --base-url https://api.deepseek.com
After running, three artifacts land in the out/ directory. Hand dsh-models.json to the dsh harness to complete model configuration (field docs in integration docs).
| Type | Detection | Pricing source | Notes |
|---|---|---|---|
bare standard compatible |
/v1/models with minimal fields only |
none → fallback chain | The most basic OpenAI-compatible form; the DeepSeek official API is this type, completed by the built-in default table |
augmented rich metadata |
/models includes context_length/pricing/supported_parameters |
provided directly by the host (USD-per-token strings) | Implemented by a few gateways |
quota multiplier-priced gateway |
/api/pricing (compatible with legacy map form) |
multiplier × $2.0 × group multiplier | Common quota pricing system in relay gateways |
flag capability-flag proxy |
/model/info (falls back to /v1/model/info on 404) |
per-token USD numbers | Returns capability booleans and prices |
ollama |
/api/tags |
none → fallback chain | Local service; /api/show provides capabilities and context |
vllm |
/v1/models + /version |
none → fallback chain | Local inference service, no key required |
All per-token prices in the catalog are normalized to USD per million tokens (USD/1M); per-call prices are marked separately:
| Input form | Conversion |
|---|---|
USD-per-token string (e.g. "0.00000056", "$0.00003") |
×1e6, rounded to 6 decimal places |
USD-per-token number (e.g. 1.5e-7) |
×1e6 |
Multiplier (quota system, model_ratio) |
input = model_ratio × 2.0 × group_ratio; output = model_ratio × completion_ratio × 2.0 × group_ratio (completion_ratio/group_ratio default 1; group_ratio uses the default group when it is a map) |
Per-call (quota_type=1) |
per-call USD = model_price × group_ratio, billing: "per-call" |
augmented pricing field mapping: prompt → input, completion → output, input_cache_read → cacheRead, input_cache_write → cacheWrite, internal_reasoning → internalReasoning.
1. Host endpoint (full trust: if the host provides some prices, no other sources are consulted)
2. User override config data/overrides.json (replacement semantics: override only the fields configured)
3. External price mirror --external-url (only fills fully-missing pricing; result cached 1h)
4. Built-in default table data/builtin-table.json (only fills gaps; includes DeepSeek official model facts)
5. None of the above → pricing: null, marked "unknown" in the report with a warning
Capability fields, context and max output follow the same "host > override > mirror > built-in table" priority (override is replacement; the rest only fill gaps).
The DeepSeek official API has billed by peak/off-peak time-of-day since 2026-08-16 (peak: 01:00–04:00 and 06:00–10:00 UTC; half price at other times). In the catalog:
pricing.dynamic: true;pricing.amounts holds the baseline tier (first off-peak tier) prices;pricing.tiers carries all tiers (label, UTC window, per-tier prices);data/builtin-table.json.For capabilities missing from metadata (tool calling / structured output / streaming), sends minimal probe requests (max_tokens tiny, message very short) to live-test host support:
tools + forced tool_choice;response_format: {type: "json_object"} (message contains the word "json" to dodge the classic JSON-mode rejection trap);stream: true; the response must actually be SSE (has data: events and a [DONE] terminator); a plain JSON body is judged unsupported.Interpretation: 2xx = supported; 400/404/405/422 = unsupported (error-body summary kept as evidence); 401/403 = abort all probing with a warning (avoid wasting quota); 5xx/network/timeout = stays unknown with a short-lived error cache.
auto (default; probes only with a key or a local host) / never / always;(baseUrl, model, capability) for 24h (errors 30m);var/ (vault.json): host classification (1h), probe results (24h/30m), external mirror (1h);var/.lock): stale locks (>5 minutes) are taken over automatically; wait timeout (10s) raises an error;cache --clear wipes everything in one command.Config file catalog.config.json (in the plugin root; overridable with --config FILE; all fields optional):
{
"baseUrl": "https://api.deepseek.com",
"apiKeyEnv": "DEEPSEEK_API_KEY",
"probe": "auto",
"externalUrl": "https://example.com/mirror.json",
"outputDir": "out",
"cacheDir": "var",
"httpTimeoutMs": 10000
}
| Field | Default | Description |
|---|---|---|
baseUrl |
none | Host address; also --base-url on the CLI |
apiKeyEnv |
auto | Key environment variable name; auto-detects MODELCAT_API_KEY / DEEPSEEK_API_KEY / OPENAI_API_KEY |
kindHint |
none | Force host type (bare/augmented/quota/flag/ollama/vllm) |
probe |
auto |
Capability probe mode |
catalogTtlSec |
900 | Catalog freshness (reused by the plugin list tool) |
probeTtlSec |
86400 | Probe result cache TTL |
detectTtlSec |
3600 | Host classification cache TTL |
externalUrl |
none | External price mirror URL (structure in data/mirror.example.json) |
outputDir / cacheDir |
out / var |
Output and cache directories |
concurrency |
4 | Fetch concurrency (e.g. Ollama /api/show) |
httpTimeoutMs |
10000 | HTTP timeout |
Keys are only passed via environment variables (--api-key is for transient CLI use only); no artifact file ever contains a plaintext key.
| File | Purpose |
|---|---|
data/builtin-table.json |
Built-in default table (fallback): DeepSeek official model facts and time-of-day pricing |
data/overrides.example.json → copy to data/overrides.json |
Manual overrides: per-field replacement |
data/aliases.example.json → copy to data/aliases.json |
Alias mapping: old names/aliases → canonical ids |
data/mirror.example.json |
External mirror format example (self-hostable isomorphic JSON) |
| File | Content |
|---|---|
out/catalog.json |
Full catalog (schema model-catalog/v1): metadata, warnings, all normalized entries |
out/dsh-models.json |
dsh config fragment (schema dsh/models/v1): directly consumable by the harness |
out/report.md |
Human-readable: catalog tables, unknown-pricing list, dynamic pricing, warnings |
model-catalog discover [args] discover and output the model catalog (default command)
model-catalog pick [args] interactively pick models and generate a dsh config fragment
model-catalog probe --model ID [args] run capability probing for a single model
model-catalog cache --clear clear the cache
model-catalog config show effective config
--base-url URL --api-key-env NAME --api-key KEY
--kind KIND --probe MODE --out DIR
--cache DIR --external-url URL --config FILE
--model ID --help
The plugin is self-contained: manifest.json declares the entry and interfaces, and dist/src/plugin.js exports a createPlugin() factory registering 5 tools (catalog.discover/list/refresh/select/probe) and 2 events (catalog.updated/catalog.failed). It is also installable via the dsh bundle (package.json → dsh.bundle → cordis.patch.yml): the Cordis entry dist/src/dsh.js exports name/inject/apply and registers the same 5 tools on the harness. Harness loading, tool parameters and returns, event payloads, and how config fragments are consumed are all covered in docs/integration.md.
group_ratio is a map without a default group, it counts as 1 — actual group multipliers can be corrected in the override config;auto mode;npm run build # compile TypeScript
npm test # compile + run all tests (node:test, no external test deps)
Test coverage: unit conversion, host detection, per-type fetching, normalization priority chain, probe interpretation and caching, cache store (TTL/locking/corruption recovery), output artifacts, and an end-to-end pipeline (local mock host).
MIT — see LICENSE. Copyright (c) 2026 JohnXu22786.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。