/** * Global concurrency gate around the local Ollama instance. * Local inference is bottlenecked on VRAM and compute; letting 20 calls * race into llama.cpp just thrashes. Default to 2 concurrent calls. * * When the semaphore has to make a caller wait, we want the operator * reading the log to see "yes this was slow because the queue was full, * and here's a rough wait estimate" — not the default "why is Ollama slow?" * shrug. See `observeWait` and the `semaphore:wait` LogEvent for that path. */ export declare class Semaphore { private permits; private maxPermits; private queue; /** * Start timestamps of in-flight holders, keyed by a monotonic ticket id. * A Map (not a FIFO array) is required so out-of-order release — which is * the common case once tier timeouts and heterogeneous call durations enter * the picture — deletes the correct entry. An earlier FIFO `shift()` would * drop the oldest marker regardless of which holder actually released, * corrupting the `expected_wait_ms` estimate in `snapshot()`. */ private inFlightStartedAt; private nextTicket; constructor(permits: number); acquire(signal?: AbortSignal): Promise<() => void>; private release; /** For tests. */ get pending(): number; /** True if a caller attempting to acquire right now would have to wait. */ get wouldBlock(): boolean; /** * Snapshot for observability: queue depth, in-flight count, and a rough * expected-wait estimate based on the oldest in-flight request's age * (clamped at 0). Not precise — inference latency varies wildly — but * it's grounded in real state, not a guess. */ snapshot(): { queue_depth: number; in_flight: number; expected_wait_ms: number; }; } /** * Parse INTERN_MAX_CONCURRENT with validation. `Number("abc")` silently * returns NaN, which produced a semaphore that blocked every acquire — the * operator saw "Ollama is slow" with no hint the concurrency cap was * misconfigured. Reject NaN, non-integers, and values < 1. */ declare function parseConcurrency(raw: string | undefined): number; /** * Exported proxy — forwards property access to the lazily-resolved singleton. * Lets existing `ollamaSemaphore.acquire()` / `.snapshot()` call sites keep * working without threading a resolver everywhere. */ export declare const ollamaSemaphore: Semaphore; /** Exported for tests. */ export { parseConcurrency }; //# sourceMappingURL=semaphore.d.ts.map