A DSH Agent may issue multiple tool calls in parallel within a step, and may repeatedly retry the same tool. This plugin checks quotas by registered name before a tool is actually executed: if quota remains, the call is allowed; if the quota is exceeded, it is denied — it only throttles call volume, without changing the tool’s own behavior.
Plugin Overview¶
- Plugin name:
@zhourenke/dsh-tool-call-limit - Maintainer:
zhourenke - Core functionality: Adds a tool call quota to each step of DSH; limits the number of tool calls within each step; synchronously pre-reserves quotas to prevent parallel quota over-consumption; parent Agent and child Agent each have independent quotas.
Installation and Activation¶
The installation command is as follows:
dsh plugin --profile web add "github:zhourenke/dsh-tool-call-limit"
Note: After installation, you must restart DSH. The bundle collection is a snapshot taken at process startup; before restart, new plugins are not loaded, and refreshing the page has no effect.
Uninstall command:
dsh plugin --profile web remove @zhourenke/dsh-tool-call-limit
Configuration Method¶
This plugin does not limit any tools by default (limits: {}). To enable limits, override the plugin entry line in the profile patch.
# ~/.dsh/profiles/web/cordis.patch.yml
- id: tool-call-limit
name: '@zhourenke/dsh-tool-call-limit'
config:
limits:
web_search: 1
Important constraints:
* You must use - id: to override: Do not use - insert:. The plugin’s built-in bundle patch already uses insert to insert this line; inserting it again in the profile will not cause an error, but will create an additional instance with the same id — the plugin runs twice and the quota is counted twice.
* Configuration replaces the whole object: It is not merged field by field. Specify the complete limits and onExceeded values if needed.
Confirm that the configuration has been loaded:
dsh --profile web --dump-config
If you see tool-call-limit and the expected limits in the output, the configuration has taken effect.
Quota Rules and Dimensions¶
Quotas are calculated separately along four dimensions; if any dimension differs, it constitutes an independent quota:
- Agent: The parent Agent and child Agent created by
subagentare different live Agent objects, each counted independently. - turn: Multiple steps within a turn are each counted separately.
- step: The quota reset unit — the count is reset when entering a new step.
- Tool name: Each tool is counted separately and does not consume quota from other tools.
Other rules:
* Once a call passes the quota check, the quota is consumed and not refunded. Even if the tool fails, is cancelled, or times out, the quota slot is not returned.
* Wildcard * is not supported; you must configure each tool name individually.
* After the quota is exhausted, do not retry the same tool within the current step until you enter the next step.
Denial Modes¶
The configuration item onExceeded controls behavior when the quota is exhausted. The default value is "deny".
deny: The call is directly denied. Upon denial, three stable English reason messages are returned, the first being quota exhaustion.ask: Every over-quota call must request authorization again. It uses DSH 0.2.0’s approval channel. At this time you may seethe user rejected tool "<name>"; first check the session’s approval policy (read-only/workspace-writeareask, anddanger-full-accessisnever) instead of looking for the user who rejected it. After configuringask, you need to run/permission <preset>once to reapply the policy.
Limitation Boundaries¶
This plugin limits the number of calls entering DSH ToolRuntime, not the number of operations occurring inside the tool implementation.
It does not limit:
* multiple queries issued inside a single web_search call.
* HTTP requests inside a Web provider.
* multiple shell commands executed inside a single bash call.
* API requests initiated internally by MCP or other custom tools.
To limit these internal operations, you need to configure the corresponding tool parameters separately (such as searchMaxQueries for Web tools).