@@ -6,6 +6,10 @@ import {
|
6 | 6 | isSubagentSessionKey, |
7 | 7 | parseAgentSessionKey, |
8 | 8 | } from "../routing/session-key.js"; |
| 9 | +import { |
| 10 | +resolveIntegerOption, |
| 11 | +resolveNonNegativeIntegerOption, |
| 12 | +} from "../shared/number-coercion.js"; |
9 | 13 | import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; |
10 | 14 | import { |
11 | 15 | normalizeInheritedToolAllowlist, |
@@ -145,11 +149,12 @@ function resolveSubagentRoleForDepth(params: {
|
145 | 149 | depth: number; |
146 | 150 | maxSpawnDepth?: number; |
147 | 151 | }): SubagentSessionRole { |
148 | | -const depth = Number.isInteger(params.depth) ? Math.max(0, params.depth) : 0; |
149 | | -const maxSpawnDepth = |
150 | | -typeof params.maxSpawnDepth === "number" && Number.isFinite(params.maxSpawnDepth) |
151 | | - ? Math.max(1, Math.floor(params.maxSpawnDepth)) |
152 | | - : DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH; |
| 152 | +const depth = resolveNonNegativeIntegerOption(params.depth, 0); |
| 153 | +const maxSpawnDepth = resolveIntegerOption( |
| 154 | +params.maxSpawnDepth, |
| 155 | +DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH, |
| 156 | +{ min: 1 }, |
| 157 | +); |
153 | 158 | if (depth <= 0) { |
154 | 159 | return "main"; |
155 | 160 | } |
@@ -161,10 +166,11 @@ function resolveSubagentControlScopeForRole(role: SubagentSessionRole): Subagent
|
161 | 166 | } |
162 | 167 | |
163 | 168 | export function resolveSubagentCapabilities(params: { depth: number; maxSpawnDepth?: number }) { |
| 169 | +const depth = resolveNonNegativeIntegerOption(params.depth, 0); |
164 | 170 | const role = resolveSubagentRoleForDepth(params); |
165 | 171 | const controlScope = resolveSubagentControlScopeForRole(role); |
166 | 172 | return { |
167 | | -depth: Math.max(0, Math.floor(params.depth)), |
| 173 | + depth, |
168 | 174 | role, |
169 | 175 | controlScope, |
170 | 176 | canSpawn: role === "main" || role === "orchestrator", |
|