UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

177 lines (176 loc) • 7.53 kB
/** * Timeout utilities for NeuroLink * * Provides flexible timeout parsing and error handling for AI operations. * Supports multiple time formats: milliseconds, seconds, minutes, hours. */ import type { TimeoutConfig, TimeoutResult } from "../types/index.js"; import { TimeoutError as BaseTimeoutError } from "./async/withTimeout.js"; /** * Custom error class for timeout operations. * * Extends the base {@link BaseTimeoutError} (from `./async/withTimeout.js`) * rather than `Error` directly, merging what were two independent internal * `TimeoutError` classes onto one prototype chain — an `instanceof` check * against either module's `TimeoutError` now recognizes errors thrown by * this class. Constructor signature, `.name`, and the extra * `timeout`/`provider`/`operation` fields are unchanged so all 15 existing * `instanceof TimeoutError` call sites keep working exactly as before; * `super(message, timeout)` additionally populates the base class's * `timeoutMs` field (equal to `timeout`) as a byproduct. */ export declare class TimeoutError extends BaseTimeoutError { readonly timeout: number; readonly provider?: string | undefined; readonly operation?: "generate" | "stream" | undefined; constructor(message: string, timeout: number, provider?: string | undefined, operation?: "generate" | "stream" | undefined); } /** * Parse timeout value from various formats * @param timeout - Can be number (ms), string with unit, or undefined * @returns Parsed timeout in milliseconds or undefined * @throws Error if format is invalid * * Examples: * - parseTimeout(5000) => 5000 * - parseTimeout('30s') => 30000 * - parseTimeout('2m') => 120000 * - parseTimeout('1.5h') => 5400000 * - parseTimeout(undefined) => undefined */ export declare function parseTimeout(timeout: number | string | undefined): number | undefined; /** * Default timeout configurations for different providers and operations */ export declare const DEFAULT_TIMEOUTS: { global: string; streaming: string; providers: { openai: string; bedrock: string; vertex: string; anthropic: string; azure: string; "google-ai": string; huggingface: string; ollama: string; mistral: string; litellm: string; }; tools: { default: string; filesystem: string; network: string; computation: string; }; }; /** * Get default timeout for a specific provider * @param provider - Provider name * @param operation - Operation type (generate or stream) * @returns Default timeout string */ export declare function getDefaultTimeout(provider: string, operation?: "generate" | "stream"): string; /** * Create a timeout promise that rejects after specified duration * @param timeout - Timeout duration * @param provider - Provider name for error message * @param operation - Operation type for error message * @returns Promise that rejects with TimeoutError */ export declare function createTimeoutPromise(timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): Promise<never> | null; /** * Enhanced timeout manager with proper cleanup and abort controller integration * Consolidated from timeout-manager.ts */ export declare class TimeoutManager { private activeTimeouts; /** * Execute operation with timeout and proper cleanup */ executeWithTimeout<T>(operation: () => Promise<T>, config: TimeoutConfig): Promise<TimeoutResult<T>>; private performSingleOperation; private getTimeoutMs; private generateOperationId; private createTimeoutPromise; private registerTimeout; cleanup(operationId: string): void; gracefulShutdown(): void; } /** * Wrapper functions consolidated from timeout-wrapper.ts */ /** * Wrap a promise with timeout * @param promise - The promise to wrap * @param timeout - Timeout duration (number in ms or string with unit) * @param provider - Provider name for error messages * @param operation - Operation type (generate or stream) * @returns The result of the promise or throws TimeoutError */ export declare function withTimeout<T>(promise: Promise<T>, timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): Promise<T>; /** * Wrap a streaming async generator with timeout * @param generator - The async generator to wrap * @param timeout - Timeout duration for the entire stream * @param provider - Provider name for error messages * @returns Wrapped async generator that respects timeout */ export declare function withStreamingTimeout<T>(generator: AsyncGenerator<T>, timeout: number | string | undefined, provider: string): AsyncGenerator<T>; /** * Create an abort controller with timeout * @param timeout - Timeout duration * @param provider - Provider name for error messages * @param operation - Operation type * @returns AbortController and cleanup function */ export declare function createTimeoutController(timeout: number | string | undefined, provider: string, operation: "generate" | "stream"): { controller: AbortController; cleanup: () => void; /** * Re-arm the timeout window from now. Streaming consumers call this on * every chunk so the timeout bounds *idle* time rather than total * duration — a slow-but-alive upstream is not killed mid-generation. * No-op once the controller has already aborted. */ reset: () => void; timeoutMs: number; } | null; /** * Compose an external abort signal with a timeout controller's signal. * Returns a single AbortSignal that fires when either signal aborts. * If only one signal is present, returns it directly without wrapping. * * @param externalSignal - User-provided AbortSignal (e.g., from options.abortSignal) * @param timeoutSignal - Timeout controller's signal * @returns Combined AbortSignal, or undefined if neither is present */ export declare function composeAbortSignals(externalSignal?: AbortSignal, timeoutSignal?: AbortSignal): AbortSignal | undefined; /** * Scoped variant of {@link composeAbortSignals} for per-step / per-request * composition against a LONG-LIVED external signal (e.g. the generate-call * signal inside a multi-step agent loop). `AbortSignal.any` keeps its source * registration alive until the derived signal is GC'd, so composing per step * accumulates listeners on the outer signal for the whole turn * (MaxListenersExceededWarning at 10+ steps). This helper registers plain * listeners instead and returns a `dispose()` that removes them the moment * the step settles. */ export declare function composeAbortSignalsScoped(externalSignal?: AbortSignal, timeoutSignal?: AbortSignal): { signal: AbortSignal | undefined; dispose: () => void; }; /** * Merge abort signals (for combining user abort with timeout) * * Implemented via `AbortSignal.any` with a single once-listener forward, so * no per-source listeners are left behind on long-lived input signals once * the merged controller becomes unreachable (registrations are released with * the derived signal). The previous implementation attached one permanent * listener per source per call — repeated stream calls sharing one caller * signal accumulated listeners for the life of that signal. * * @param signals - Array of abort signals to merge * @returns Combined abort controller */ export declare function mergeAbortSignals(signals: (AbortSignal | undefined)[]): AbortController;