1
/**2
* Delegation-depth accounting: the recursion budget a parent passes to its3
* children. Kept apart from the service so composition helpers can read it4
* without importing the registry.5
*6
* @module @deepseek-ai/dsh-subagent/depth7
*/9
import type { Agent } from '@deepseek-ai/dsh-agent'11
declare module '@deepseek-ai/dsh-agent' {12
interface AgentOptions {13
/** Delegation depth: zero for a top-level agent and parent depth + 1 for a child. */14
subagentDepth?: number15
}16
}18
/**19
* Read an agent's delegation depth, treating absence as top-level depth zero.20
* The persisted session header is authoritative and monotone: runtime21
* `AgentOptions.subagentDepth` may DEEPEN the count but can never lower it —22
* a resumed child arrives with fresh options, and counting it from zero would23
* let it delegate as if it were top-level.24
* @param agent - the agent whose header and options carry the depth.25
* @returns its non-negative safe-integer depth.26
* @throws if the runtime `AgentOptions.subagentDepth` is not a non-negative safe integer.27
*/28
export function delegationDepthOf(agent: Agent): number {29
const runtime = agent.options.subagentDepth30
if (runtime !== undefined && (!Number.isSafeInteger(runtime) || runtime < 0 || Object.is(runtime, -0))) {31
throw new TypeError('agent subagentDepth must be a non-negative safe integer')32
}33
// The header value was validated at the session boundary (creation and34
// persistence load both construct through the store).35
return Math.max(agent.session.header.delegationDepth ?? 0, runtime ?? 0)36
}38
/**39
* Reject a recursion cap that cannot represent an exact delegation depth.40
* @param maxDepth - the optional runtime value to validate.41
*/42
export function assertSubagentMaxDepth(maxDepth: unknown): void {43
if (maxDepth !== undefined && (44
typeof maxDepth !== 'number'45
|| !Number.isSafeInteger(maxDepth)46
|| maxDepth < 047
|| Object.is(maxDepth, -0)48
)) {49
throw new TypeError('subagent maxDepth must be a non-negative safe integer')50
}51
}