DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

dsh-llm-quota-retry

Llm Quota Retry

在账户配额耗尽的情况下保持 DeepSeek Harness 代理步骤运行:基础提供商重试策略因 QUOTA 失败而放弃后,每小时重试相同请求一次,不设尝试次数限制,并向其他插件发布该长期重试的进入、退出和当前状态。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:windwhiterain/dsh-llm-quota-retry#a69732d70b0fc4d55c269c452edde2d21d8a81af
README兼容性版本

兼容性与来源证明

Llm Quota Retry 以 dsh-llm-quota-retry 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/29

版本

0.2.0stable
2026/9/29

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

README

dsh-llm-quota-retry

A DeepSeek Harness host plugin that keeps an agent step alive through an exhausted account quota or balance.

When a model request fails because the account is out of allowance, the ordinary recovery policy gives up once its retry budget is spent and the turn ends. This plugin takes over at that point and retries the same request inside the same open turn once per configured interval — one hour by default, with no attempt limit — until a request succeeds or the turn is cancelled. It is on by default for every session: turn it off per session through the composer chip or /quota-retry, or for the whole deployment with defaultEnabled: false.

That covers three shapes of the same condition: the canonical QUOTA code, and an AUTH or RATE_LIMIT failure whose text names a spent usage limit. The other two are how metered providers answer — a 403 permission error from one that meters a rolling window, a 429 rate limit from one that meters a Token Plan (已达到 Token Plan 用量上限:…, in Chinese) — and a plugin that keyed on QUOTA alone would miss exactly the cases it exists for.

Install

The package is a Cordis bundle with a Web composer half:

From the directory that contains your checkout of this repository:

dsh plugin --profile web add ./dsh-llm-quota-retry

Installation links the package into the profile and records it in dsh.profile.bundles, so the bundle layer is read on every later start. The host row applies without a restart: the profile patch reloads live, the row activates, and the bundle reports enabled with an active fiber.

The composer chip needs one host restart the first time. The dsh.client manifest is read by the client-module scan, which caches its verdict per package for the lifetime of the host — a package first scanned before it declared dsh.client stays cached as "not a client package", and no later rescan clears that entry. Restart dsh web once after installing, or after adding dsh.client to an already-installed package, and the chip appears.

Composition order

Compose the llm-quota-retry row after @deepseek-ai/dsh-llm-retry.

That order is the contract, not a preference. dsh-llm-retry runs earlier in the agent/request-error waterfall, spends its own retry budget first, and calls the next listener once that budget is exhausted. By the time a quota failure reaches this plugin, every earlier recovery policy has already declined it — which is exactly what "after the base quick retries" means. The bundle's own cordis.patch.yml appends the row to the composition root, so a bundle install lands in the right place automatically.

What this plugin does not touch

The plugin is strictly additive for every failure except an exhausted allowance, and for that too in every session whose switch is off:

  • Every other failure delegates unchanged — rate limits, server errors, timeouts, transports, and context overflows keep their ordinary handling, including compaction's own recovery. So does a credential the provider will keep rejecting, and so does ordinary throttling: an AUTH or RATE_LIMIT failure is read as a spent allowance only when its text names one, so a wrong or revoked API key still fails fast and a burst of concurrent requests still keeps its sub-minute retries, instead of either waiting an hour between attempts that cannot succeed.
  • A session whose switch is off delegates an exhausted allowance unchanged. Turning the switch off is the opt-out; every session starts on.
  • The native quick retry is never removed. dsh-llm-retry still runs first and its configured retryPolicy still governs. Note that QUOTA is not in the default retryableCodes, so by default an exhausted allowance triggers no native retry at all and this plugin is the only thing that answers it; a provider that lists QUOTA (or runs mode: always) keeps its own retries, and this plugin wakes up only after they are spent.
  • One configuration is superseded rather than merely left alone. retryPolicy.mode: always has no eligible-code list and no budget, and it asks downstream first, so for an exhausted allowance the hourly schedule replaces its own sub-minute backoff. Every other configuration is untouched.

The per-session switch

Long-term retry is on until the switch is turned off. Three paths move the same switch:

  • Composer chip — beside the model, permission, and compaction chips, with a menu offering On, Off, and Default.
  • /quota-retry <on|off|default|status> — the one write path the chip also uses, so a typed line and a click can never disagree.
  • The setting is per session and durable through the llm_quota_retry storage domain, so it survives a host restart. Without a usable storage domain it degrades to a process-local value instead of failing the switch.

A session with no record of its own follows defaultEnabled, which is true unless the row sets it to false. A forked or delegated session takes its nearest ancestor's explicit setting once, as a snapshot: the value applies to that session from then on, and default clears it back to the deployment default rather than re-inheriting.

Turning the switch off while a session is waiting ends the entry immediately — the pending timer is aborted rather than left to wake an hour later — and reports left with reason disabled.

Configuration

KeyDefaultMeaning
longTermDelayMs3600000Interval between long-term attempts, in milliseconds. Must be a positive finite number no greater than 2147483647.
defaultEnabledtrueThe switch a session starts from before it owns a setting of its own. false makes long-term retry opt-in.

Unknown keys and invalid values throw at activation, so a misconfigured row fails loudly instead of silently retrying on a wrong schedule.

A row that turns the default off makes long-term retry opt-in for the whole deployment; the row below also shortens the interval.

- id: llm-quota-retry
  name: 'dsh-llm-quota-retry'
  config:
    longTermDelayMs: 1800000
    defaultEnabled: false

Reading the state from another plugin

Two read paths are published.

The live retry state, as the service ctx.llmQuotaRetry:

export const inject = ['llmQuotaRetry']

export function apply(ctx) {
  ctx.on('session/event', (session) => {
    if (!ctx.llmQuotaRetry.isRetrying(session)) return
    const state = ctx.llmQuotaRetry.stateOf(session)
    // state.pending       — an hourly wait is armed right now
    // state.attempts      — long-term attempts scheduled for this entry
    // state.enteredAt     — epoch ms the entry opened
    // state.nextAttemptAt — epoch ms of the armed attempt, while pending
    // state.provider, state.turn, state.step — the failing request
  })
}

isRetrying(session) answers whether the session is in long-term retry. stateOf(session) returns a frozen snapshot, or undefined when the session is not in long-term retry. Both accept the Harness Session. This state is in-memory: it exists only while a wait is live.

The per-session switch, as the quotaRetry Session projection:

const facts = ctx.sessionProjections.stateOf(session, 'quotaRetry')
// facts.enabled        — the effective switch
// facts.defaultEnabled — the row's configured default
// facts.source         — 'default' | 'session' | 'inherited'

The projection is the client-visible path, so it is also what the composer chip reads.

Subscribing to the transitions

Two Cordis events carry the timing of every transition.

llm-quota-retry/entered

Emitted once per entry, when the first quota failure takes the session over and its first hourly wait is armed.

FieldMeaning
session, agentThe session and agent whose request failed.
failureThe LlmFailure that opened the entry.
provider, turn, stepLocation of the failing request.
enteredAtEpoch ms the entry opened.
nextAttemptAtEpoch ms of the first long-term attempt.
attempts1 on entry.
pendingtrue — the wait is armed.
retryingtrue.

llm-quota-retry/left

Emitted when an entry ends: a model request in the session succeeded, or the switch was turned off.

FieldMeaning
sessionThe session whose entry ended.
reasonrecovered or disabled.
provider, turn, stepLocation of the last failed request.
enteredAtEpoch ms the entry opened.
leftAtEpoch ms the entry ended.
durationMsleftAt - enteredAt.
attemptsLong-term attempts scheduled during the entry.
export function apply(ctx) {
  ctx.on('llm-quota-retry/entered', ({ session, nextAttemptAt }) => {
    // ...
  })
  ctx.on('llm-quota-retry/left', ({ session, reason, durationMs }) => {
    // ...
  })
}

Behavior and limits

  • The trigger is an exhausted allowance. The canonical QUOTA code always counts; an AUTH or RATE_LIMIT failure counts only when its text names a spent usage limit, quota, balance, or credits, in English or Chinese. Everything else reaches the next listener untouched.
  • The session stays busy. A long-term wait holds the open step, so the turn does not reach quiescence and the session reports as running until a request succeeds or the turn is cancelled.
  • Each attempt is a billed provider request. The schedule is unbounded by design: nothing but a successful request, cancellation, the switch going off, or unloading the plugin stops it.
  • Cancelling a turn keeps the entry. The pending wait aborts, pending becomes false, and no left is announced; the entry and its enteredAt survive, and the next quota failure in that session re-arms the schedule. Only success or turning the switch off ends an entry.
  • The composer chip shows the switch, not live progress. Session projections recompute on session events, and the retry state changes between them, so a live "retrying now" badge would be up to an hour stale. Use the service or the two events for live progress.
  • The wording checks compensate for the harness. A Harness release that classifies a spent allowance as QUOTA — which @deepseek-ai/dsh-llm does as of the fix(llm): classify a spent usage allowance as quota, not auth change, for a rolling window a provider reports as a 403 — needs no wording check at all. A Token Plan provider still arrives as RATE_LIMIT: that harness classifier reads English wording only, so a Chinese body keeps its 429 code and would take its turn down here. The checks keep this plugin correct against both hosts.
  • It consumes no model-visible context. Nothing here reaches the model, and the plugin writes no session events, so it adds no log vocabulary that another build would have to know.

Hot reload

Listing index.js, client.js, and lib/policy.js in the profile's hmr roots makes an edit to either host file replace the module generation in a running host: the plugin is disposed and re-imported, and apply() re-runs. The in-memory retry state does not survive that — a reload drops a pending wait and its entry, exactly as a restart does. The durable per-session switch does survive, because it lives in the storage domain. Editing client.js of an already-registered client row is picked up as a new artifact generation; only adding or changing the dsh.client manifest itself needs a restart, because the client-module scan caches that verdict per package.

Client bundle scope

The shell concatenates every dynamic client bundle of a batch into one classic script, so a top-level declaration in client.js joins the same lexical scope as every other bundle's. A name two bundles both declare is a SyntaxError that fails the whole batch, which takes down every composer contribution in it — not just this one.

client.js therefore declares nothing at the top level: a single IIFE owns every name and only the window.__ModuleLoader__.load(...) call inside it reaches the shell. probe/client-probe.mjs enforces this by evaluating the bundle twice into one scope, which is exactly what a batch does.

Probe

probe/probe.mjs drives apply() against a fake Cordis context and checks every decision, event, state transition, command outcome, inherited setting, and projection value without a Harness:

node probe/probe.mjs

probe/client-probe.mjs loads the composer half through a stub module loader and checks its slot registration, dictionary, menu contents, selected option, and the exact /quota-retry line it submits:

node probe/client-probe.mjs

Neither probe can produce a provider response that reports an exhausted quota. Confirming the composed behavior against a real provider requires either an account that actually runs out of balance or an OpenAI-compatible endpoint that answers 402 with insufficient-balance wording.

License

MIT

相关插件

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

Whale Widgetdsh-whale-widgetDSH Web 界面右下角的 DeepSeek 余额小鲸鱼挂件:余额/今日已用/峰谷定价、自定义泡泡点击序列(文本/余额/今日/峰谷/图片/随机语句与并列加权选择)、逐行样式与字体、悬浮快捷编辑、音效与每轮消耗、自定义角色/动图/音效、吸附与翻转自定义Usage@linxin666/dsh-usage用于 dsh Web GUI 的使用统计插件:检测各提供商的余额和编程套餐配额,并实时记录令牌使用情况;侧边栏 Settings 行上方显示紧凑的价格概览卡片Client Ui Model Capabilities@linxin666/dsh-client-ui-model-capabilities为自定义 pi-ai 提供商声明每个模型的能力(图像输入和推理力度),可直接在 Models 设置卡片中编辑;写入官方 llm-pi-ai 设置命名空间,不更改 DSH 源代码。Connect Workbuddydsh-connect-workbuddy把本机登录的 WorkBuddy 模型接入 DeepSeek Harness,并提供只读的积分概览与模型管理。