provider-concurrency.ts limits concurrent task tool calls per model provider inside the current OpenCode process. It is intended to keep delegated subagents from overloading a local model server or a paid remote provider.
This directory is the global OpenCode plugin directory for this machine. OpenCode auto-discovers *.ts and *.js files under ~/.config/opencode/plugins/, so plugins/provider-concurrency.ts does not need an opencode.json plugin entry.
Restart OpenCode after changing this plugin or opencode.concurrency.json. Plugin and config files are loaded at startup.
The plugin reads opencode.concurrency.json from the same config directory:
{
"enabled": true,
"debug": false,
"mode": "reject",
"providerLimits": {
"openrouter": null,
"ollama": 1
},
"agentProviderOverrides": {},
"agentModelOverrides": {},
"queueTimeoutMs": null,
"staleLeaseMs": 600000
}Fields:
enabled: disables all limits when set tofalse.debug: logs missing or stale lease details withconsole.warn.mode:rejectthrows immediately when a provider is full;queuewaits for a slot.providerLimits: provider to max concurrenttaskcalls. Set a provider value tonullto make that provider explicitly unlimited, for example{ "openrouter": null }.agentProviderOverrides: agent name to provider, for example{ "worker-md": "ollama" }.agentModelOverrides: agent name to model string with provider prefix, for example{ "worker-md": "ollama/worker-md-local" }.queueTimeoutMs: max queue wait before throwing inqueuemode. Set tonullfor no queue timeout.staleLeaseMs: age after which a lease can be cleaned up before another same-provider acquire. Set to0to disable stale cleanup.
The plugin only intercepts OpenCode's task tool. Provider resolution order is:
args.modelorargs.subagent_modelwhen it has aprovider/modelprefix.- The task agent name from
subagent_type,agent,subagent, oragentName. agentModelOverrides[agent], parsed asprovider/model.agentProviderOverrides[agent].
If no provider is found, the provider has no configured limit, or the provider limit is null, the task runs without throttling.
Current configured text worker in this config:
worker-md:ollama/worker-md-local, so it resolves toollama.
Equivalent explicit override:
{
"agentModelOverrides": {
"worker-md": "ollama/worker-md-local"
}
}- Limits are process-local. They do not coordinate across multiple OpenCode processes or terminals.
- This does not intercept direct provider API calls; it only gates OpenCode
tasktool execution. - OpenCode currently exposes
tool.execute.beforeandtool.execute.afterfor this use. If a task starts but noafterhook runs,staleLeaseMsis the recovery mechanism. - This is a concurrency guard, not a token, billing, health-check, or provider rate-limit scheduler. Provider limits are defense-in-depth; they complement orchestrator-level lifecycle policies like one-worker-at-a-time execution but do not replace them.