/** * ConcurrencyGuard — Per-Tool Semaphore with Backpressure Queue * * Implements the Semaphore pattern to prevent thundering-herd scenarios * where an LLM fires N concurrent tool calls in the same millisecond. * * Architecture: * ┌─────────────────────────────────────────────────┐ * │ Incoming tool call │ * │ │ * │ ┌───────────┐ slot free? ┌──────────────┐ │ * │ │ acquire() ├────YES────► │ run handler │ │ * │ │ │ └──────────────┘ │ * │ │ │ queue has ┌──────────────┐ │ * │ │ ├──space?──YES─►│ enqueue() │ │ * │ │ │ └──────────────┘ │ * │ │ │ both full ┌──────────────┐ │ * │ │ ├──────NO──────►│ load shedding│ │ * │ └───────────┘ └──────────────┘ │ * └─────────────────────────────────────────────────┘ * * Properties: * - Zero overhead when not configured (guard is `undefined`) * - O(1) acquire/release with deque-based pending queue * - Cooperative with AbortSignal: queued waiters are rejected on abort * - Pure module: no side effects, no dependencies * * @module * @internal */ /** * Concurrency configuration for a tool builder. * * @example * ```typescript * createTool('billing') * .concurrency({ maxActive: 5, maxQueue: 20 }) * .action({ name: 'process_invoice', handler: ... }); * ``` */ export interface ConcurrencyConfig { /** * Maximum number of concurrent executions allowed. * When all slots are occupied, new calls enter the queue. * * @minimum 1 */ readonly maxActive: number; /** * Maximum number of calls waiting in the backpressure queue. * When the queue is full, new calls are immediately rejected * with a load-shedding error. * * @minimum 0 * @default 0 */ readonly maxQueue?: number; } /** * A concurrency guard that limits simultaneous tool executions. * * Created once per builder via `createConcurrencyGuard()`. * Used by `GroupedToolBuilder.execute()` to gate entry. */ export declare class ConcurrencyGuard { private readonly _maxActive; private readonly _maxQueue; private _active; private readonly _pending; constructor(config: ConcurrencyConfig); /** * Attempt to acquire an execution slot. * * - If a slot is free: increments active count, resolves immediately. * - If queue has space: enqueues and returns a promise that resolves when a slot opens. * - If both full: returns `null` (load shedding signal). * * @param signal - Optional AbortSignal for cooperative cancellation of queued waiters. * @returns A release function (call when execution completes) or `null` for load shedding. */ acquire(signal?: AbortSignal): Promise<(() => void)> | null; /** * Current number of active (in-flight) executions. */ get active(): number; /** * Current number of waiters in the backpressure queue. */ get queued(): number; private _createRelease; private _drainNext; private _removePending; } /** * Create a ConcurrencyGuard from configuration. * * Returns `undefined` when no configuration is provided, * ensuring zero overhead on the fast path. * * @internal */ export declare function createConcurrencyGuard(config?: ConcurrencyConfig): ConcurrencyGuard | undefined; //# sourceMappingURL=ConcurrencyGuard.d.ts.map