DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

dsh-loop-brake

Loop Brake

DeepSeek Harness 插件:一种熔断器,通过对工具名称和规范化参数进行精确哈希,拒绝连续第 N 次相同的工具调用

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

npx -y @deepseek-ai/dsh plugin --profile web add github:jwilson411/dsh-loop-brake#08eb25770caa657530b326dbd7dc06e0c0b32a8e
README兼容性版本

兼容性与来源证明

Loop Brake 以 dsh-loop-brake 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/8/31

版本

0.1.0stable
2026/8/31

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

相关插件

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

Doctor@linxin666/dsh-doctorDSH 配置档案的事务性救援模式,配备受监督的启动器、隔离的恢复容器、确定性修复、健康监控以及本地 Web 恢复控制台Pocketdsh-pocket把 DeepSeek Harness 装进你的口袋:一个包、一个设置页,手机扫码即同步访问电脑上的 DSH(局域网 + 公网,实时同屏)。DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。Auto Reviewdsh-auto-review针对 DeepSeek Harness 审批请求的第二模型 AI 自动审查:只读审查子代理在审批应答链上决定允许或拒绝,并采用故障关闭回退机制和完整的会话日志审计。

README

dsh-loop-brake

A DeepSeek Harness function plugin: a circuit breaker for identical tool calls.

An agent gets stuck. It calls search with {"q":"weather"}, reads the result, decides it needs to call search with {"q":"weather"}, and does. Nothing is wrong with any single call, so nothing stops it, and the loop runs until a budget, a turn limit, or a human notices.

This plugin notices on the third one.

LoopBrakeError: loop brake: tool "search" called 3 times in a row with identical
arguments (call 9f2c1a7b3e04…, limit 3); the call was denied before it ran.
Change the arguments, call a different tool, or stop.

The tool body does not run. The error carries code: 'LOOP_BRAKE', the count, the limit, and twelve hex characters of the call hash, so the denial is legible in a log without the arguments themselves being copied into one.

What it is not

This is not an LLM similarity judge. It is not embeddings, not a fuzzy match, not a semantic "are these two calls basically the same" question put to a model, not a workflow engine, and not a second agent loop watching the first one. There is no model call anywhere in this package and no threshold to tune.

Exact hash match only. Two calls are the same call when

sha256(toolName + "\n" + canonicalJson(args))

produces the same digest, and are different calls otherwise. Canonicalization sorts object keys at every nesting level and nothing else — so {"a":1,"b":2} and {"b":2,"a":1} are one call, and {"q":"weather"} and {"q":"weather "} are two.

That boundary is worth stating plainly, because it decides what this catches:

  • An agent repeating a call byte for byte — caught, on the Nth try.
  • An agent looping while a timestamp, a nonce, a page cursor, or a retry counter changes in its arguments — not caught. Every call hashes differently, and this plugin has no opinion about whether they mean the same thing.
  • An agent alternating between two calls forever — not caught. The counter is a consecutive-repeat streak, so A, B, A, B never reaches three of anything.

A brake that fired on "these look similar" would need a model to decide what similar means, which is a model call in front of every tool call in the composition, with a false-positive rate and a bill. The exact-match version costs microseconds, cannot hallucinate, and is explainable to whoever reads the denial at three in the morning. It catches the single most common shape of a stuck agent and it is honest about the rest.

Install

dsh plugin --profile default add github:jwilson411/dsh-loop-brake

The installer reads dsh.bundle.patch from the package manifest and appends this package to the profile's ordered bundle list. Its cordis.patch.yml carries one insert row, id: loop-brake, with no config — the defaults.

Pin the tools package at 0.1.1-rc.2; that is the release candidate this plugin is developed and tested against.

Configure

One knob, in the plugin's row in the composed patch:

- id: loop-brake
  config:
    maxRepeats: 5
KeyDefaultMeaning
maxRepeats3Consecutive identical calls a session may make before the next one is denied. Counting includes the denied call, so at 3 two identical calls run and the third is refused.

Must be an integer of at least 1. An unusable value is rejected when the plugin applies, not at the first call: a brake with different teeth than the one a profile asked for is discovered, if ever, only when a loop is already burning tokens. 1 denies every repeat immediately, including the first call of any streak — a debugging setting rather than a deployment one.

The environment fallback DSH_LOOP_BRAKE_MAX_REPEATS is read only when the config key is absent. The patch row is the deployment's stated intent, so it wins over an ambient variable.

An id-targeted patch replaces the row's whole config rather than merging into it, so an override must restate every field it means to keep.

Counting

Counts are per session, and per session the plugin keeps one current hash and one count — a streak, not a histogram.

  • Call A, A → the streak is at 2.
  • Call B → the A streak is gone; B is at 1.
  • Call A → back to 1, not 3.

Two sessions never share a count: two agents legitimately making the same call are not one agent looping. A session is the explicit sessionId a caller passes, else the calling agent's id from the execution input, else default.

Memory does not grow with session length — one slot per session, not one entry per distinct call ever made.

The error

error.code       // 'LOOP_BRAKE'
error.toolName   // 'search'
error.count      // 3 — which consecutive repeat this was, counting this call
error.maxRepeats // 3
error.hashPrefix // '9f2c1a7b3e04' — the first 12 hex characters, and no more
error.sessionId  // the session whose streak tripped
error.plugin     // 'dsh-loop-brake'

LoopBrakeError is thrown, not returned. A brake a caller can drive past by ignoring a return value is not a brake, and the failure this exists to stop is precisely the case where nobody is reading return values carefully.

The arguments are never put in the error. They are the thing most likely to hold a path, a query, or a credential the caller passed in, and the error message is the thing most likely to be logged, shown, or handed back to a model.

How it attaches

apply patches the injected tool registry in two places and returns the LoopBrake instance, so a host that wants to inspect or reset it can.

  • ctx.tools.register is patched, so every definition registered for the lifetime of this fiber carries a braked execute. This is the mandatory path and the only one this plugin assumes exists.
  • ctx.tools.execute is patched when the runtime exposes it, which catches what the register patch cannot: a tool registered before this plugin applied.

One host call passing through both seams is counted once, keyed by its call id. A pair of wrappers that both counted would bite at half the configured limit.

Both patches are undone on dispose, so stopping or reloading the plugin leaves the registry exactly as it was found — and forgets every streak, which is the right default. A brake that remembered across a reload would deny the first call of a fresh run for something the previous run did.

No tool is registered. This plugin adds nothing to the model's tool surface. A brake the model can call is a brake it can be talked into arguing with, and there is nothing a status tool could report that the denial does not already say.

Using the library directly

The counting half is exported on its own for a host that owns its call sites:

import { LoopBrake, decorateTool, wrapExecute } from 'dsh-loop-brake/loop-brake'

const brake = new LoopBrake({ maxRepeats: 3 })

// Wrap one execute…
const guarded = wrapExecute(execute, brake, { tool: 'search', sessionId: 's1' })

// …or copy a whole definition with its execute braked.
const braked = decorateTool(definition, brake)

decorateTool returns a copy; the original definition is left alone. Also exported: callHash, canonicalJson, hashPrefix, sessionKey, normalizeMaxRepeats, resolveMaxRepeats, LoopBrakeError, InvalidMaxRepeatsError.

Dependencies

None at runtime. The shipped source imports node:crypto and nothing else — it opens no socket, reads no file, and spawns no process, all of which the test suite asserts rather than promises. @deepseek-ai/cordis and @deepseek-ai/dsh-tools are peer dependencies, provided by the harness.

Node >=22.14.0.

Tests

npm install
npm test

No network, no credentials, no model weights. CI runs the same suite on Node 22.x and 24.x.

License

MIT. Copyright (c) 2026 jwilson411.