You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c156f3b
Browse filesBrowse the repository at this point in the historyBrowse files
feat(opencode): make subagent tree limit configurable (nested-agents Issue 2)
Promote the SUBAGENT_TREE_LIMIT=200 lifetime cap to a configurable
experimental key (experimental.subagent_tree_limit, PositiveInt). Add a
single-source-of-truth clamp helper treeLimit(cfg) in subagent-limits.ts,
exactly analogous to maxDepth(cfg): the __testHooks.treeLimit seam keeps
top precedence, then the config key (clamped to 1..HARD_MAX_TREE_LIMIT=10000,
truncated), else the 200 default. task.ts consumes the helper exclusively
instead of the bare constant/seam.
The in-memory per-process counter is unchanged (safety ceiling, no DB
priming). Clamp bounds: min 1 (at least one spawn must remain possible),
max 10000 (keeps the ceiling a sane order of magnitude, guards against
typos/overflow making it effectively unlimited).
Tests: config-parse round-trip + non-positive rejection; treeLimit clamp
(0/negative/too-large/undefined->default, NaN/Infinity->default, fractional
truncation, seam override). Docs updated in config.mdx and agents.mdx.
Co-Authored-By: Claude Fable 5 <[email protected]>
Copy file name to clipboardExpand all lines: packages/core/src/v1/config/config.ts
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -218,6 +218,10 @@ export const Info = Schema.Struct({
218
218
description:
219
219
"Maximum subagent nesting depth (the root session is depth 1; clamped to 1..10). Default 5. Set 2 to restore the previous spawn behavior (the root spawns, subagents do not) — additionally the workflow tool is removed at the limit (security fix) and custom agents that previously nested without limit are bounded; 1 is the kill switch that removes the task and workflow tools entirely.",
"In-memory lifetime cap on subagents started per session tree, a per-process safety ceiling against runaway delegation (clamped to 1..10000). Default 200. Resumes and workflow dispatches do not count against it; the counter is not persisted, so it resets each process run.",
| Maximum nesting depth |`5` (root session = depth 1), configurable via `experimental.subagent_max_depth`, clamped to 1–10 | The `task` and `workflow` tools are removed at the last level; any remaining spawn attempt fails with a typed `SubagentDepthError`|
155
-
| Subagents per session tree |`200` started subagents per tree, counted **per OpenCode process** (the counter resets on restart) | Further spawns fail with `SubagentTreeLimitError`|
155
+
| Subagents per session tree |`200` started subagents per tree, configurable via `experimental.subagent_tree_limit` (clamped to 1–10000), counted **per OpenCode process** (the counter resets on restart) | Further spawns fail with `SubagentTreeLimitError`|
156
156
|`task_id` resume | Only tasks the session started itself (direct children) | Other session IDs fail with `SubagentResumeError`; unknown IDs still start a fresh session |
157
157
| Permission prompts | Raised anywhere in the tree, answered on the **root session** of the tree | — see [permissions in nested trees](#permissions-in-nested-trees)|
158
158
@@ -179,6 +179,23 @@ Values are clamped to the range 1–10.
179
179
180
180
---
181
181
182
+
### Configure the tree limit
183
+
184
+
Set the per-tree lifetime cap with `experimental.subagent_tree_limit`:
The default is `200`. This is an in-memory safety ceiling counted per OpenCode process: resumed subagents and workflow dispatches do not count against it, and the counter resets on restart. Values are clamped to the range 1–10000; reaching the cap fails further spawns with `SubagentTreeLimitError`.
196
+
197
+
---
198
+
182
199
### Permissions in nested trees
183
200
184
201
- Whether an agent below the depth limit can spawn is governed by its regular [task permissions](#task-permissions). The default wildcard `"*": "allow"` is enough — an exact `task` rule is no longer required.
Copy file name to clipboardExpand all lines: packages/web/src/content/docs/config.mdx
+15Lines changed: 15 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -880,6 +880,21 @@ Use `experimental.subagent_max_depth` to control how deep subagents can [nest](/
880
880
881
881
The default is `5`. Setting it to `2` restores the previous spawn behavior (the main session spawns subagents, subagents do not); additionally, the `workflow` tool is removed at the limit (a security fix), and custom agents that previously nested without limit are now bounded. Setting it to `1` is the kill switch: the `task` and `workflow` tools are removed everywhere, including from the main session.
882
882
883
+
#### Subagent tree limit
884
+
885
+
Use `experimental.subagent_tree_limit` to control how many subagents a single session tree may start over its lifetime. The cap is an in-memory, per-process safety ceiling against runaway delegation; values are clamped to 1–10000.
The default is `200`. Resumed subagents and workflow dispatches do not count against it, and the counter is not persisted — it resets on each OpenCode process restart. Reaching the limit fails further spawns with a typed `SubagentTreeLimitError`.
0 commit comments