/** * Default auto-extend policy for subagent budgets. * * The budget's soft-limit path (`SubagentBudget` → `budget.threshold_reached`) * only negotiates an extension when SOMETHING listens on the EventBus. Under a * `Director`, that listener is the director's own auto-extend handler. On the * plain coordinator path (e.g. a bare `/spawn` with no director) nothing * listens, so the budget falls back to a hard stop and the subagent dies the * moment it crosses a soft limit. * * `attachAutoExtend` is the additive fix: wire it to a subagent's EventBus and * budget overruns are auto-granted headroom instead of killing the run. It is * heartbeat-aware for the timeout kind — wall-clock time always advances, so a * naive "extend timeout forever" would let a wedged agent run indefinitely. * Instead, a timeout extension is granted only when the agent has executed a * new tool call or started a new iteration since the last timeout extension. * No progress since last time ⇒ the agent is genuinely stuck ⇒ deny and let it * fail. The non-timeout kinds (iterations/tool_calls/tokens/cost) extend up to * a per-kind cap, then deny — those ceilings are the real runaway guard. */ import type { EventBus } from '../kernel/events.js'; export interface AutoExtendCeiling { maxIterations?: number | undefined; maxToolCalls?: number | undefined; maxTokens?: number | undefined; maxCostUsd?: number | undefined; timeoutMs?: number | undefined; } export interface AutoExtendPolicy { /** Multiplier applied to the tripped limit when extending. Default 0.5 (+50%). */ factor?: number | undefined; /** * Max extensions per NON-timeout kind before denying. Timeout is governed by * the heartbeat check, not this cap, so it can extend indefinitely while the * agent makes progress. Default 8. */ maxExtensionsPerKind?: number | undefined; /** Absolute ceilings — an extension never pushes a limit past these. */ ceiling?: AutoExtendCeiling | undefined; } /** * Attach an auto-extend policy to a subagent's EventBus. Returns an unsubscribe * function that detaches all listeners — call it when the subagent task ends. */ export declare function attachAutoExtend(events: EventBus, policy?: AutoExtendPolicy): () => void; //# sourceMappingURL=auto-extend.d.ts.map