/** * **LLM-queue admit gate** — the Node-side gate for the supervisor's LLM-queue * priority scheduler + per-provider rate governor (T11630 · AC1-AC4). * * The contended priority + rate state lives in the Rust arbiter * (`crates/cleo-supervisor/src/llm_queue.rs`), exposed over `lease-ipc` v1.1 as * the `queue_admit` → `queue_admit_result` verb. THIS module is the thin Node * gate every outbound LLM call passes through immediately before it hits the * wire: it asks the supervisor "may I admit this call?" and, on a `deferred` * answer, backs off `retry_after_ms` and re-asks — a structured deferral, never * a silent drop (AC4). * * ## Modes ({@link resolveLlmQueueMode}) * * `CLEO_LLM_QUEUE_MODE` ∈ `{ supervisor | off }`, **default `off`** — mirrors * {@link ../store/writer-lease.ts}'s `resolveLeaseMode()` shape: * * - `off` — pure pass-through: {@link llmQueueAdmit} returns `{ admitted: true }` * without touching the supervisor. The daemon is OFF by default in production, * so this is the shipping config: EVERY LLM call works with no supervisor. * - `supervisor` — prefer the supervisor arbiter over the IPC socket; a * `deferred` result is honoured with a back-off + re-request. When the socket * is absent / refused / errors, the gate logs the demotion ONCE and degrades * to direct execution (`{ admitted: true }`) — a dead/absent arbiter must * NEVER block an LLM call. * * ## CRITICAL degrade-to-direct (headline correctness — AC4 inverse) * * Because the daemon stays OFF by default, the load-bearing path is the degrade: * mode `off`, no socket, `E_LEASE_UNAVAILABLE`, or a connect-refused all resolve * to `{ admitted: true }` and the caller executes the LLM call DIRECTLY. The * supervisor is a pure OPTIMISATION; its absence is never an error. * * @module llm/llm-queue-admit * @task T11630 * @epic T11625 * @see ../store/writer-lease.ts — the `resolveLeaseMode()` + log-once demotion this mirrors * @see ../../../runtime/src/daemon/lease-ipc-client.ts — the v1.1 codec this mirrors (boundary: core cannot import runtime) */ import { type QueuePriorityClass } from '@cleocode/contracts'; /** The LLM-queue admit gate mode. Resolved once per process; default `off`. */ export type LlmQueueMode = 'supervisor' | 'off'; /** * The structured result of an admit gate decision. `admitted: true` means * execute the LLM call now; the gate NEVER returns a "dropped" — an over-budget * request is internally retried (with back-off) until admitted or the supervisor * is found unavailable (then degrades to admitted-direct). AC4. */ export interface LlmAdmitResult { /** Whether the LLM call may proceed (always `true` once this resolves). */ readonly admitted: true; /** * How the admission was decided — `direct` when no supervisor arbitrated * (off-mode / degrade), `supervisor` when the arbiter granted it. Diagnostic * only; both mean "go". */ readonly via: 'direct' | 'supervisor'; } /** Options for {@link llmQueueAdmit}. */ export interface LlmQueueAdmitOptions { /** * Override the supervisor socket path. Defaults to * `/cleo-supervisor.sock` (or `$CLEO_SUPERVISOR_SOCKET`). */ socketPath?: string; /** * Max wall-clock (ms) the gate will spend re-requesting a deferred admit * before degrading to direct. Bounds the worst-case latency a starved call * adds; on timeout the call proceeds (the supervisor budget is advisory, never * a hard block on a real call). Default {@link DEFAULT_ADMIT_DEADLINE_MS}. */ deadlineMs?: number; } /** Max wall-clock a deferred admit will be re-requested before degrading. */ export declare const DEFAULT_ADMIT_DEADLINE_MS = 30000; /** * Resolve the LLM-queue mode from `CLEO_LLM_QUEUE_MODE`, once per process. * * Unknown / unset values resolve to `'off'` — the production-safe default while * the supervisor daemon is disabled. Mirrors `resolveLeaseMode()`. * * @returns The resolved {@link LlmQueueMode}. * @task T11630 */ export declare function resolveLlmQueueMode(): LlmQueueMode; /** * Reset cached process-global state (mode + demotion flag). Tests only. * * @internal */ export declare function _resetLlmQueueStateForTest(): void; /** * Gate an outbound LLM call through the supervisor's priority scheduler + * per-provider rate governor (T11630). Call this immediately BEFORE executing * the LLM request. * * - mode `off` (default) → returns `{ admitted: true, via: 'direct' }` with no * IPC. The shipping config. * - mode `supervisor`, arbiter reachable → sends `queue_admit`; on `admitted` * returns immediately; on `deferred` awaits `retry_after_ms` and re-requests * until admitted or the deadline elapses (then degrades to direct — the budget * is advisory). AC4: a deferral is a structured wait, never a dropped call. * - mode `supervisor`, arbiter UNreachable (no socket / connect-refused / * `E_LEASE_UNAVAILABLE` / any transport error) → logs the demotion once and * returns `{ admitted: true, via: 'direct' }`. A dead/absent supervisor MUST * NEVER block an LLM call. * * @param provider - The provider id the call targets (rate budget is per-provider). * @param priorityClass - The caller's priority class (lead > worker > background). * @param estTokens - The caller's estimate of the request's token cost. * @param childId - The child the call belongs to (in-flight tracking seam). * @param opts - Socket path + deadline overrides. * @returns Always resolves to an `{ admitted: true }` result — never throws, never drops. * * @task T11630 */ export declare function llmQueueAdmit(provider: string, priorityClass: QueuePriorityClass, estTokens: number, childId: string, opts?: LlmQueueAdmitOptions): Promise; //# sourceMappingURL=llm-queue-admit.d.ts.map