dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
🇬🇧 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. |
In DeepSeek Harness, session projections aggregate cumulative token usage across four core buckets:
uncachedInputTokens: usage.inputTokens, // No safety fallback in DSH core!
outputTokens: usage.outputTokens, // No safety fallback in DSH core!
cacheReadTokens: usage.cacheReadTokens ?? 0,
cacheWriteTokens: usage.cacheWriteTokens ?? 0,
While DSH core guards cacheReadTokens and cacheWriteTokens with ?? 0, it takes inputTokens and outputTokens as raw numbers without safety checks.
When third-party providers, local inference servers, custom proxy gateways, or community routers return non-standard payloads, missing fields, or NaN, standard JavaScript arithmetic (total += NaN) instantly converts the session's cumulative token sum into NaN.
Subsequently, DSH schema validation fatally rejects the entire session digest:
history unavailable for session "<session-id>": expected number, received NaN
Because session history in DSH is computed dynamically by replaying the event log, a single malformed token packet permanently bricks the entire conversation history from being opened ever again.
graph LR
subgraph Malformed [Upstream Provider Stream]
API[LLM Output Stream] -->|Returns prompt_tokens / NaN / null| Event[Session Event Chunk]
end
subgraph Unprotected [Without dsh-usage-guard]
Event --> DSHMath[DSH Cumulative Arithmetic]
DSHMath -->|total += NaN| Poison[🚨 Cumulative Total becomes NaN]
Poison --> SchemaFail[Schema Validation Rejection]
SchemaFail --> DeadHistory[💥 Session History Permanently Unreadable]
end
subgraph Guarded [With dsh-usage-guard Active]
Event --> Patch[sessionProjections Interceptor]
Patch --> AliasCheck{Alias Borrowing Layer}
AliasCheck -->|Maps prompt_tokens -> inputTokens| Restored[Restored Number]
AliasCheck -->|If missing / NaN| ZeroFallback[Safe 0 Fallback]
Restored --> SafeMath[Clean Arithmetic Execution]
ZeroFallback --> SafeMath
SafeMath --> ValidHistory[✅ 100% Intact & Recovered Session History]
end
style Malformed fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
style Unprotected fill:#311b1b,stroke:#f38ba8,stroke-width:2px,color:#cdd6f4
style Guarded fill:#181825,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
The plugin does not alter or rewrite log files on disk. Instead, it hooks the projection fold at runtime. Because session replay passes through this exact interception point, all previously broken or locked sessions are instantly restored and readable immediately upon installing the plugin.
borrowed)Before substituting zero, dsh-usage-guard scans an extensive dictionary of industry-standard field aliases:
| Target DSH Field | Recognized Vendor Aliases |
|---|---|
inputTokens | input_tokens, input, promptTokens, prompt_tokens, promptTokenCount, prompt_eval_count |
outputTokens | output_tokens, output, completionTokens, completion_tokens, candidatesTokenCount, eval_count |
cacheReadTokens | cache_read_tokens, cachedTokens, cached_tokens, cache_read_input_tokens, cachedContentTokenCount, prompt_tokens_details.cached_tokens |
cacheWriteTokens | cache_write_tokens, cacheCreationTokens, cache_creation_input_tokens |
sound)Strictly validates typeof value === 'number' && Number.isFinite(value) && value >= 0 && Number.isInteger(value) to filter out NaN, Infinity, null, undefined, negative error codes (e.g. -1), non-integer floats, and malformed strings.
repaired)If a counter cannot be resolved from aliases, it is safely initialized to 0. Fractional tokens or decimal strings are safely rounded via Math.round(), strictly satisfying the core DSH contract z.number().int().nonnegative().
lib/patch.js).apply methods currently registered in sessionProjections.registrations while preserving full this context.map.set wrapping, guaranteeing 100% coverage regardless of plugin loading order.WeakMap cache ensures single execution across all 10–15 parallel DSH projections.told)Logs informative diagnostic warnings naming the exact session, turn, step, raw payload, and recovery action (e.g. inputTokens borrowed from alias vs inputTokens zeroed). Incidents are deduplicated in memory so logs are not flooded during replays, and the cache is bounded to 1,000 entries with O(1) FIFO eviction.
lib/client.js)Settings → Plugins → Plugin Settings (settings.plugin.item) with real-time status badge, auto-dismissing save feedback, and full English / Chinese localization.maxStepTokens)0 to disable./api/dsh-usage-guard/telemetry)/api/dsh-usage-guard/update)same-origin checks, and x-dsh-plugin-update: 1 security token. Allows updating the plugin directly from the settings interface.z.natural()):
z.number().int().nonnegative() in Config with Cordis Schemastery's native z.natural().TypeError: z.number(...).int is not a function preventing Cordis loader crash upon importing dsh-usage-guard.test/config.test.mjs.lib/client.js now strictly provides canonical en (English fallback) and zh (Simplified Chinese) dictionaries.@goodandready/dsh-russian-lang (Issue #196)./api/dsh-usage-guard/telemetry):
rescuedEvents, fixedTokens, clampedSpikes, and a FIFO circular buffer of recent incidents.TelemetrySection in the Settings Card displaying 3 metric cards and latest incident context./api/dsh-usage-guard/update):
isTrustedUpdateRequest: loopback IP check, sec-fetch-site: same-origin, matching host/origin, and x-dsh-plugin-update: 1 header.maxStepTokens):
Config and UI to clamp abnormally large step metrics (> 1,000,000) before projection calculation.dsh-clinebot (#6):
ensureCss() outside component render with <style id="dsh-usage-guard-full-css" data-dsh-plugin="dsh-usage-guard">.ErrorBoundary to gracefully contain render errors and offer a "Retry" mechanism without breaking DSH Settings..ug-section-card, .ug-field-card, .ug-stat-box, .ug-badge-ok, .ug-badge-warn, .ug-btn-primary).makeT(dict, fallback) supporting Russian and English locales with template interpolation.refreshMirrorUntilVisible(ctx) with an unref timer to guarantee host settings scope visibility.prompt_tokens_details.cachedTokens, prompt_tokens_details.cacheCreationTokens).Infinity, -Infinity, NaN, and malformed strings.settings.plugin.item Registration (#3):
Completely removed the deprecated fallback registration into settings.section. In compliance with DSH Plugin Authoring guidelines, settings are rendered exclusively in the "Settings → Plugins" tab (settings.plugin.item) with key dsh-usage-guard without cluttering the global sidebar.data-dsh-plugin:
Dynamic <style> element is explicitly tagged with data-dsh-plugin="dsh-usage-guard", preventing style purging during neighbor plugin reloads or HMR.ctx.slots.register('settings.plugin.item', ...).Config() initialization with try...catch and migrated diagnostic log messages to English.@deepseek-ai/dsh-token-meter projection schema enforces strict integers (z.number().int().nonnegative()). Fractional tokens (e.g. 42.5 or "1540.2" produced by routing proxies or weighted estimators) previously broke Zod schema validation.sound() now strictly validates Number.isInteger(value).Math.round() (42.6 $\rightarrow$ 43), protecting session history from schema rejections.guard):
WeakMap<event, guardedEvent> cache sanitizes each incoming event exactly once on the first projection, returning the cached normalized reference to all subsequent projections in $O(1)$ without re-parsing or memory leak risks.told Warning Cache:
told.clear() with individual oldest key eviction told.delete(oldest) at 1,000 entries, maintaining continuous deduplication without sudden re-logging storms.htmlFor/id and tagged the chevron icon with aria-hidden="true".settings.plugin.item):
lib/client.js registering a native configuration card under Settings → Plugins → Plugin Settings bound to namespace dsh-usage-guard (Issue #2).repair (automatic token counter repair) and report (diagnostic warning console logging).ACTIVE when auto-repair is enabled, REPORT ONLY when passive audit is selected).IconChevronDownOutline14, 12px border radius, and aria-expanded accessibility.en, ru, zh).settings.section for legacy core versions without the plugin settings tab.docs/design/DESIGN.md complying with project-design-contract and dsh-ui-design.nonnegative):
In v0.1.0, negative counters like -1 (sometimes returned by proxy gateways during rate limits or faults) passed finite-number checks and crashed DSH schema validation (z.number().int().nonnegative()). In v0.1.1, sound() strictly requires value >= 0. Any negative number is treated as corrupted and safely zeroed out.inputTokens: "1540"), v0.1.1 coerces them into true numbers rather than resetting them to zero.promptTokenCount, candidatesTokenCount, and cachedContentTokenCount.prompt_eval_count and eval_count.prompt_tokens_details.cached_tokens.this Context in Projections:
In lib/patch.js, wrapApply now dispatches via original.call(this, state, guard(event)), ensuring complete compatibility with class-based projection handlers.complaint(), object serialization is now safely protected with try...catch against circular structures and BigInt values.sessionId to avoid cross-session warning suppression. told cache size is bounded to 1,000 entries to prevent memory growth in long-running processes.dsh plugin --profile web add @goodandready/dsh-usage-guard
[!IMPORTANT] Restart DSH Web UI after installation (
systemctl --user restart dsh-web) to activate protection and instantly revive any previously locked sessions.
settings.yaml / Web UI)dsh-usage-guard:
repair: true
report: true
maxStepTokens: 1000000
| Parameter | Type | Default | Description |
|---|---|---|---|
repair | boolean | true | Replace missing or non-numeric token counters with zero before arithmetic accumulation |
report | boolean | true | Log diagnostic warning lines naming turn, step, and raw sample when damaged metrics arrive |
maxStepTokens | number | 0 | Clamp abnormally large step usage values (e.g. > 1,000,000) to prevent integer overflows. Set 0 to disable |
MIT © GooDAnDReaDY