deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
🇬🇧 English • 🇷🇺 Русский • 🇨🇳 中文说明
|
⭐ If you like this plugin, please star it on GitHub — it shows me that the plugin is useful to you and motivates me to keep developing it.
🐛 If you find a bug or would like to request a feature, open a GitHub issue in any language — I will review your proposal and implement useful suggestions in a future plugin version. |
#307).catch (#315).#311, #314).#308).try ... finally block, preventing key starvation during clean finishes or client stream aborts.PROBE_RETRY_DELAY_MS) in SandboxRunner.probeModels before marking keys as broken.x-ratelimit-remaining-* and Retry-After headers before hitting 429 errors./models endpoint to automatically revive broken keys without token burn.round-robin, least-loaded (concurrency), and lowest-latency (p95 latency).dsh-clinebot Style: Sequential batch "Test All Keys" runner with live progress, Live Event Stream drawer, and Quota Reset countdown badge.en) and Chinese (zh) UI dictionaries.CIRCUIT_OPEN) until a cool-down; half-open probes recover automatically.circuit plus meta.expectedClones / meta.notifyQueue.test/smoke-rotation-080.test.mjs.resolveBaseUrl to map key credential refs to owning provider pools, restoring live probeModels testing.canaryTimer and selfHealTimer in Cordis effect scopes, eliminating background orphaned intervals on hot reload.pickLeastLoaded for uninterrupted least-connections routing.dsh-clinebot baseline: modular section cards, live pool telemetry stat boxes, pill badges, and complete semantic theme token styling (#281).props.t). Active locale: host snapshot → first navigator.languages entry → en (#277).All, Ready, In Cooldown, and With Errors quick filter chips.High-throughput autonomous agent workflows, parallel subagent swarms, and multi-turn tool loops inevitably hit upstream API rate limits (HTTP 429, RPM/TPM exhaustion, daily quotas, or sudden provider outages). In standard DeepSeek Harness deployments, a single exhausted API key breaks the entire agent execution chain, requiring manual intervention and destroying the session's replay state.
dsh-key-rotation provides a seamless, enterprise-ready transparent API key pooling, pre-emptive rate-limiting, and cross-provider failover engine built natively on the Cordis microkernel architecture.
Unlike naive routing proxies that alter provider identifiers, dsh-key-rotation hooks into ctx.credentials.resolve and intercepts llm/stream at runtime:
graph LR
subgraph ClientLayer ["Client & Agent Turn"]
UserMsg["User / Subagent Message"] --> Adapter["pi-ai Model Adapter"]
end
subgraph RotationEngine ["dsh-key-rotation Core Engine"]
Adapter --> StreamHook["llm/stream Interceptor"]
StreamHook --> BucketCheck{"Token Bucket\nRPM / TPM Check"}
BucketCheck -->|Under Limit| ConcurrencyCheck{"Concurrency Tracker\nLeast-Connections"}
BucketCheck -->|Exceeded| NextKey1["Pick Next Healthy Key"]
ConcurrencyCheck -->|Slot Available| KeyResolver["ctx.credentials.resolve"]
ConcurrencyCheck -->|Saturated| NextKey1
KeyResolver --> ActiveKey["Active Key (In Use)"]
ActiveKey -.->|HTTP 429 / Quota / Error| Failover["Instant Failover Handler"]
Failover --> BackoffCalc["Exponential Backoff & Quarantine"]
Failover --> NextKey2["Retry Next Key (Zero Token Loss)"]
Failover -.->|All Pool Keys Exhausted| CascadeEngine["Cross-Provider Cascade"]
BackoffCalc --> QuotaWindow["Calendar Reset / Midnight Window"]
BackoffCalc --> SelfHeal["Self-Heal Idle Sweep"]
SelfHeal -->|Cooldown Expired| PoolReady["Restored to Ready Pool"]
end
subgraph UpstreamLayer ["Model Provider Endpoints"]
ActiveKey --> UpstreamAPI["Primary Provider API"]
CascadeEngine --> FallbackAPI["Backup Provider API"]
end
style ClientLayer fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
style RotationEngine fill:#181825,stroke:#cba6f7,stroke-width:2px,color:#cdd6f4
style UpstreamLayer fill:#11111b,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
INVALID_REPLAY_STATE crashes in pi-ai multi-turn sessions.QUOTA, RATE_LIMIT, SERVER, TIMEOUT, TRANSPORT, EMPTY_RESPONSE, UNKNOWN_MODEL, AUTH, and INVALID error codes.SWITCHABLE_MESSAGE_PATTERN) identifies text-based quota/rate-limit errors thrown as generic exceptions by upstream SDKs.agent/request-error lifecycle hook.lib/bucket.js): Sliding-window tracking of Requests Per Minute (rpmLimit) and Tokens Per Minute (tpmLimit). Quarantines saturated keys before dispatching network requests, preventing 429 roundtrips.lib/concurrency.js): Tracks active in-flight streams per key (inFlight). Distributes concurrent requests evenly across available credentials and enforces maxConcurrency limits.lib/cascade.js): If all keys for a selected provider are in cooldown, requests automatically cascade to an alternative fallback provider pool (e.g., primary provider → fallback proxy / secondary provider).lib/sandbox.js): On-demand /models probes validate a key before returning it to rotation; idle cooldowns are lifted by the self-heal sweep.lib/quota-window.js): Supports scheduled quota reset alignments (midnight_utc, midnight_pst, and rolling_24h) so daily free/tier quotas unfreeze exactly when upstream resets them.lib/pool.js): Successive failures on a key double its quarantine duration (base → ×2 → ×4 → cap ×8). Successful requests gradually restore healthy status.lib/pool.js): Configure dedicated key pools for specific model tiers (e.g. reasoning/heavy models vs fast/cheap utility models).production, background, eval) to match key usage with workload priorities.lib/webhook.js): Dispatches rich notifications with HMAC-signed action buttons for Telegram (Inline Keyboards), Discord (Action Rows), and Slack (Block Kit). Administrators can click buttons to reset cooldowns or pause providers directly from their mobile chat.lib/usage-report.js): Per-key daily request counters and estimated cost breakdown with one-click CSV/JSON export (GET /dsh-key-rotation/usage-report).lib/histogram.js): Tracks Time-To-First-Token (TTFT) and stream durations with health score degradation scoring (0..100).The settings card includes an Updater section:
GET /api/dsh-key-rotation/update returns currentVersion, latestVersion, updateAvailable, canAutoUpdate (version metadata only; no secrets).POST with the same path installs the exact latest npm version through the standard dsh plugin add flow. The request is accepted only from loopback with a matching same-origin Origin/Host (and the dedicated header). Cross-origin or missing-origin POST is rejected with 403.No --force, no raw shell, no install from worktree/DEV paths. Update runs only after an explicit click.
Access full visual management under Settings → Key Rotation or via the Header quick-widget.
| Interface Feature | Description |
|---|---|
| Header Status Widget | Compact live badge in DSH header: 🟢 All Healthy | 🟡 Cooldown Active | 🔴 Pool Exhausted with quick popover actions. |
| 1-Click Health Matrix | "Health Matrix" dashboard running parallel sandbox probes across all providers, keys, and models with TTFT latency and status badges. |
| Instant Key Provisioning | Add keys with auto-generated names (<PROVIDER>_API_KEY, _2, _3) and automatic key-tail disambiguation. |
| Live Status Badges | Visual states: In Use, Ready, Cooling Down (with live countdown timer), and Not Found. |
| Drag & Priority Ordering | Reorder keys with ↑ and ↓ buttons to fine-tune selection precedence. |
| Switch Code Toggles | Interactive checkboxes for switchable error conditions. |
| Secret Leak Detector | Real-time input sanitizer (lib/keycheck.js) catching accidental pastes of private keys, SSH keys, or misplaced tokens. |
Batch .env Import |
Parse standard .env key-value pairs directly into corresponding provider pools. |
| 5-Second Undo Bar | Non-destructive undo bar for accidental key or pool removals. |
| Usage Analytics Chart | Interactive breakdown of lifetime requests and daily trends per key. |
MY_PROVIDER_API_KEY).$DSH_HOME/.credentials.yaml managed by the DSH Credentials service.keyTail): Full secret values are never sent to the client browser; only the trailing 5 characters are exposed for visual identification.GET /status, PUT /key, POST /reset, POST /test-matrix) strictly enforce loopback origin checks (isTrustedBridgeRequest).# Install via DSH Plugin Manager (Web Profile):
dsh plugin --profile web add @goodandready/dsh-key-rotation
# Or directly from GitHub:
dsh plugin --profile web add github:GooDAnDReaDY/dsh-key-rotation
[!IMPORTANT] Restart DeepSeek Harness web service after installation and refresh your browser tab:
systemctl --user restart dsh-web
settings.yaml)dsh-key-rotation:
switchCodes:
- QUOTA
- RATE_LIMIT
- SERVER
- TIMEOUT
- TRANSPORT
- EMPTY_RESPONSE
- UNKNOWN_MODEL
- AUTH
cooldownMs: 60000
# v0.8.0 circuit breaker
circuitBreakerEnabled: true
circuitBreakerThreshold: 5
circuitBreakerOpenMs: 30000
circuitBreakerHalfOpenProbes: 1
concurrencyLimit: 5
quotaResetWindow:
type: midnight_utc
hour: 0
cascade:
- provider: backup-provider-id
model: your-backup-model-id
webhookUrl: "https://api.telegram.org/bot<TOKEN>/sendMessage?chat_id=<CHAT_ID>"
providers:
- provider: your-primary-provider
rpmLimit: 60
tpmLimit: 100000
keys:
- PRIMARY_API_KEY
- PRIMARY_API_KEY_2
- PRIMARY_API_KEY_BACKUP
- provider: secondary-provider
keys:
- SECONDARY_API_KEY
- SECONDARY_API_KEY_2
| Parameter | Type | Default | Description |
|---|---|---|---|
switchCodes |
string[] |
[QUOTA, RATE_LIMIT, ...] |
List of error codes that immediately trigger failover. |
cooldownMs |
number |
60000 (1 min) |
Base penalty duration (in ms) for quarantined keys. |
circuitBreakerEnabled |
boolean |
true |
Enable per-provider circuit breaker (v0.8.0). |
circuitBreakerThreshold |
number |
5 |
Consecutive failures before opening the circuit. |
circuitBreakerOpenMs |
number |
30000 |
How long the circuit stays open (ms). |
circuitBreakerHalfOpenProbes |
number |
1 |
Probe requests allowed in half-open state. |
verboseLogging |
boolean |
false |
Per-request rotation logs (noisy; off by default). |
concurrencyLimit |
number |
0 (disabled) |
Max concurrent in-flight streams per key (0 = unlimited). |
quotaResetWindow |
object |
null |
Calendar reset alignment (midnight_utc, midnight_pst, rolling_24h). |
cascade |
array |
[] |
Fallback provider chain when primary pool is completely exhausted. |
webhookUrl |
string |
"" |
Target URL for interactive Telegram, Discord, Slack, or generic alerts. |
providers |
array |
[] |
List of { provider, keys, rpmLimit, tpmLimit, modelPools } definitions. |
All management routes require loopback authentication (127.0.0.1 / ::1) with same-origin validation:
| Route | Method | Description |
|---|---|---|
/dsh-key-rotation/status |
GET |
Real-time health, keys, cooldowns. Since v0.8.0 also providers[].circuit and meta (expectedClones, notifyQueue). |
/dsh-key-rotation/config |
GET / PUT |
Read and update active key rotation settings and provider pools. |
/dsh-key-rotation/key |
PUT / DELETE |
Add, update, or remove credentials in host storage and pool. |
/dsh-key-rotation/reset |
POST |
Instantly resets all cooldowns and restores all keys to ready. |
/dsh-key-rotation/test-matrix |
POST |
Triggers parallel health check across all configured keys and models. |
/dsh-key-rotation/usage-report |
GET |
Returns aggregated usage metrics in JSON or CSV format (?format=csv). |
/dsh-key-rotation/webhook-callback |
POST |
Receives and executes interactive actions from Telegram/Slack callbacks. |
MIT © GooDAnDReaDY
healIdleCooldowns to read from the modern pool.state.lastUsedAt map (with backwards-compatible fallback). credentials.resolve now properly records each key invocation timestamp in lastUsedAt, surfacing accurate "last used" indicators in the status dashboard and enabling background idle cooldown restoration.buildRuntime() calls across periodic sweeps, provider exhaustion handling, and /status query processing.buildRuntime() calls inside the rotate() finish chunk handler by reusing the request-scoped runtime0 snapshot.extractRateLimit() with single-pass header inspection and length guards, completely removing dynamic lowercase/uppercase string allocations on every response chunk.todayIso string calculation once per finishing request instead of creating multiple Date instances for costDays and usageDays.[...values()].reduce() with iterative summation for totalUsage in the /dsh-key-rotation/status endpoint.budgetNotifiedAt, lowHealthNotifiedAt) when provider pools are deleted.pickedRef), start timestamps, and retry counts strictly to each async dispatch context using Node's node:async_hooks. Eliminates race conditions where concurrent streaming requests could penalize healthy keys.isSwitchableError and cascades seamlessly to the next key if no content tokens have been yielded.attemptList), eliminating shared mutations on pool.weightedRefs./dsh-key-rotation/test) automatically lift failedUntil and brokenUntil quarantine flags.compactUsage(pool, 30, now) into the periodic 30-second maintenance sweep to prevent memory growth on high-uptime servers.startMs for accurate p50/p95 latency metrics under concurrent load.shadow, incident, agent-budget, region, canary, maintenance) and dead route registrations.429, 401, 403, 5xx) and gRPC codes (RESOURCE_EXHAUSTED, UNAVAILABLE) alongside regex fallback.document.visibilityState).credentials.resolve patch and ctx.on event handlers (llm/stream, agent/request-error) in ctx.effect scopes with guaranteed unmount cleanup (#238, #239)..role('secret') to incidentGitHubToken and webhookActionToken in Config schema for automatic UI masking (#237).settingsScope snapshot reading/saving in settings card with graceful bridge fallback (#235).props.t with locale: NS; plugin registers only en; no settings.section fallback and no bundled ru/zh tables (#236, #275, #277).mountDashboard routine after header-chip migration (#240).CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。