import { Express } from 'express'; import { z } from 'zod'; /** * Configuration types for ludicrous-gateway * Defines the structure of YAML configuration files */ /** * Server configuration */ interface ServerConfig { /** Listen address in format "host:port" */ listen: string; /** Request timeout in milliseconds */ timeout_ms: number; } /** * Routing rule condition */ interface RoutingCondition { /** Keywords to match in request content */ keywords?: string[]; /** Regex patterns to match */ patterns?: string[]; /** Minimum estimated token count */ min_tokens?: number; /** Maximum estimated token count */ max_tokens?: number; /** Specific model names to match */ models?: string[]; /** Whether request contains tool definitions or tool use blocks */ has_tools?: boolean; } /** * Route destination */ interface RouteDestination { /** Provider name to route to */ provider: string; /** Optional model override */ model?: string; } /** * A routing rule definition */ interface RoutingRuleConfig { /** Rule name for identification */ name: string; /** Conditions that must match */ conditions: RoutingCondition; /** Where to route when conditions match */ route_to: RouteDestination; /** Priority (higher = evaluated first) */ priority: number; /** Whether rule is enabled */ enabled?: boolean; } /** * Routing configuration section */ interface RoutingConfig { /** Default provider when no rules match */ default_provider: string; /** Default model when no rules match */ default_model?: string; /** List of routing rules */ rules: RoutingRuleConfig[]; } /** * API key configuration */ interface ApiKeyConfig { /** The API key (supports ${ENV_VAR} syntax) */ key: string; /** Optional weight for load balancing */ weight?: number; } /** * Provider configuration */ interface ProviderConfig { /** Provider name (unique identifier) */ name: string; /** Provider type (anthropic, openai, gemini, zai, ollama, kimi, mistral, deepseek, grok) */ type: "anthropic" | "openai" | "gemini" | "zai" | "ollama" | "kimi" | "mistral" | "deepseek" | "grok"; /** Whether provider is enabled */ enabled: boolean; /** Base URL for API calls */ base_url?: string; /** API keys for this provider */ keys?: ApiKeyConfig[]; /** Whether to pass through subscription headers (for anthropic) */ subscription_passthrough?: boolean; /** Model name mappings */ model_aliases?: Record; /** Default model for this provider */ default_model?: string; } /** * Circuit breaker configuration */ interface CircuitBreakerConfig$1 { /** Number of failures before opening circuit */ failure_threshold: number; /** Seconds to wait before trying half-open */ recovery_timeout_seconds: number; } /** * Health check configuration */ interface HealthConfig { /** Interval between health checks in seconds */ check_interval_seconds: number; /** Circuit breaker settings */ circuit_breaker: CircuitBreakerConfig$1; } /** * Logging configuration */ interface LoggingConfig { /** Log level (debug, info, warn, error) */ level: "debug" | "info" | "warn" | "error"; /** Log format (text, json) */ format: "text" | "json"; } /** * Complete gateway configuration */ interface GatewayConfig { server: ServerConfig; routing: RoutingConfig; providers: ProviderConfig[]; health: HealthConfig; logging: LoggingConfig; } /** * Anthropic message types for the Claude API * These match the Anthropic API specification */ /** * Text content block */ interface TextContent { type: "text"; text: string; } /** * Image source (base64) */ interface Base64ImageSource { type: "base64"; media_type: "image/jpeg" | "image/png" | "image/gif" | "image/webp"; data: string; } /** * Image source (URL) */ interface UrlImageSource { type: "url"; url: string; } /** * Image content block */ interface ImageContent { type: "image"; source: Base64ImageSource | UrlImageSource; } /** * Tool use content block */ interface ToolUseContent { type: "tool_use"; id: string; name: string; input: Record; } /** * Tool result content block */ interface ToolResultContent { type: "tool_result"; tool_use_id: string; content: string | ContentBlock[]; is_error?: boolean; } /** * Content block union type */ type ContentBlock = TextContent | ImageContent | ToolUseContent | ToolResultContent; /** * A message in the conversation */ interface Message { role: "user" | "assistant"; content: string | ContentBlock[]; } /** * Tool definition */ interface Tool { name: string; description?: string; input_schema: { type: "object"; properties?: Record; required?: string[]; }; } /** * Tool choice options */ type ToolChoice = { type: "auto"; } | { type: "any"; } | { type: "none"; } | { type: "tool"; name: string; }; /** * Anthropic /v1/messages request body */ interface MessagesRequest { /** Model identifier */ model: string; /** Maximum tokens to generate */ max_tokens: number; /** Conversation messages */ messages: Message[]; /** System prompt */ system?: string | ContentBlock[]; /** Whether to stream the response */ stream?: boolean; /** Temperature for sampling */ temperature?: number; /** Top-p sampling */ top_p?: number; /** Top-k sampling */ top_k?: number; /** Stop sequences */ stop_sequences?: string[]; /** Tool definitions */ tools?: Tool[]; /** Tool choice preference */ tool_choice?: ToolChoice; /** Metadata for the request */ metadata?: { user_id?: string; }; } /** * Usage information in response */ interface Usage { input_tokens: number; output_tokens: number; } /** * Stop reason for response */ type StopReason = "end_turn" | "max_tokens" | "stop_sequence" | "tool_use"; /** * Anthropic /v1/messages response */ interface MessagesResponse { id: string; type: "message"; role: "assistant"; content: ContentBlock[]; model: string; stop_reason: StopReason | null; stop_sequence: string | null; usage: Usage; } /** * Provider types for ludicrous-gateway * Defines interfaces for provider adapters */ /** * Provider health status */ type ProviderHealthStatus = "healthy" | "degraded" | "unhealthy"; /** * Provider health information */ interface ProviderHealth { status: ProviderHealthStatus; lastCheck: Date; lastSuccess: Date | null; lastError: Date | null; consecutiveFailures: number; errorMessage?: string | undefined; } /** * Provider statistics */ interface ProviderStats { totalRequests: number; successfulRequests: number; failedRequests: number; totalLatencyMs: number; averageLatencyMs: number; lastRequestTime: Date | null; } /** * Provider information */ interface ProviderInfo { name: string; type: string; enabled: boolean; baseUrl?: string; health: ProviderHealth; stats: ProviderStats; } /** * Request context passed to providers */ interface ProviderRequestContext { /** Original request headers */ headers: Record; /** Resolved model name (after aliases) */ resolvedModel: string; /** Request timeout in milliseconds */ timeoutMs: number; /** Whether this is a streaming request */ isStreaming: boolean; } /** * Streaming response handler */ interface StreamHandler { /** Called for each SSE event */ onEvent: (event: string, data: string) => void; /** Called on stream completion */ onComplete: () => void; /** Called on stream error */ onError: (error: Error) => void; } /** * Provider interface that all adapters must implement */ interface Provider { /** Provider name */ readonly name: string; /** Provider type */ readonly type: string; /** Whether provider is enabled */ readonly enabled: boolean; /** * Send a non-streaming request * @param request - The messages request * @param context - Request context * @returns The messages response */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request * @param request - The messages request * @param context - Request context * @param handler - Streaming response handler */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; /** * Check provider health * @returns Whether provider is healthy */ healthCheck(): Promise; /** * Get provider information * @returns Provider info including health and stats */ getInfo(): ProviderInfo; /** * Resolve model name using aliases * @param model - Original model name * @returns Resolved model name */ resolveModel(model: string): string; } /** * Routing types for ludicrous-gateway * Defines interfaces for routing decisions */ /** * Analysis result from content analyzer */ interface ContentAnalysis { /** Estimated token count */ estimatedTokens: number; /** Keywords found in content */ matchedKeywords: string[]; /** Patterns matched in content */ matchedPatterns: string[]; /** Original model requested */ requestedModel: string; /** Whether request contains sensitive content */ hasSensitiveContent: boolean; /** Content length in characters */ contentLength: number; /** Whether request has tool definitions */ hasTools: boolean; /** Whether messages contain tool_use or tool_result blocks */ hasToolUseBlocks: boolean; } /** * Routing decision result */ interface RoutingDecision { /** Selected provider name */ provider: string; /** Selected model (may be aliased) */ model: string; /** Rule that matched (if any) */ matchedRule?: string; /** Reason for routing decision */ reason: string; /** Whether this was the default route */ isDefault: boolean; /** Content analysis used for decision */ analysis: ContentAnalysis; } /** * Compiled routing rule for efficient matching */ interface CompiledRoutingRule { /** Rule name */ name: string; /** Priority (higher = evaluated first) */ priority: number; /** Whether rule is enabled */ enabled: boolean; /** Destination provider */ destinationProvider: string; /** Destination model override */ destinationModel?: string | undefined; /** Compiled keyword set for fast lookup */ keywords: Set; /** Compiled regex patterns */ patterns: RegExp[]; /** Minimum tokens condition */ minTokens?: number | undefined; /** Maximum tokens condition */ maxTokens?: number | undefined; /** Model whitelist */ models: Set; /** Whether to match requests with tools */ hasTools?: boolean | undefined; } /** * Router interface */ interface Router { /** * Route a request to a provider * @param request - The incoming request * @param analysis - Content analysis result * @returns Routing decision */ route(request: MessagesRequest, analysis: ContentAnalysis): RoutingDecision; /** * Get all compiled rules * @returns List of compiled routing rules */ getRules(): CompiledRoutingRule[]; /** * Reload rules from configuration */ reloadRules(): void; } /** * Content analyzer interface */ interface ContentAnalyzer { /** * Analyze a request for routing * @param request - The incoming request * @returns Content analysis result */ analyze(request: MessagesRequest): ContentAnalysis; } /** * Main router for ludicrous-gateway * Routes requests to providers based on rules and analysis */ /** * Router configuration */ interface RouterConfig { /** Default provider when no rules match */ defaultProvider: string; /** Default model for the default provider */ defaultModel?: string | undefined; /** Routing rules */ rules: RoutingRuleConfig[]; } /** * Default router implementation */ declare class DefaultRouter implements Router { private config; private compiledRules; constructor(config: RouterConfig); /** * Route a request to a provider */ route(request: MessagesRequest, analysis: ContentAnalysis): RoutingDecision; /** * Get all compiled rules */ getRules(): CompiledRoutingRule[]; /** * Reload rules from new configuration */ reloadRules(): void; /** * Update rules from new configuration */ updateConfig(config: RouterConfig): void; /** * Debug routing decision (evaluate all rules) */ debugRoute(request: MessagesRequest, analysis: ContentAnalysis): { decision: RoutingDecision; ruleEvaluations: Array<{ ruleName: string; matched: boolean; matchedConditions: string[]; failedConditions: string[]; }>; }; } /** * Create a router from gateway routing config */ declare function createRouter(config: RoutingConfig): DefaultRouter; /** * Circuit breaker pattern implementation for ludicrous-gateway * Prevents cascading failures by temporarily stopping requests to unhealthy providers */ /** * Circuit breaker states */ type CircuitState = "CLOSED" | "OPEN" | "HALF_OPEN"; /** * Circuit breaker configuration */ interface CircuitBreakerConfig { /** Number of failures before opening circuit */ failureThreshold: number; /** Milliseconds to wait before trying half-open */ recoveryTimeoutMs: number; /** Number of successful requests in half-open to close circuit */ successThreshold?: number; } /** * Circuit breaker statistics */ interface CircuitStats { state: CircuitState; failures: number; successes: number; lastFailureTime: Date | null; lastSuccessTime: Date | null; lastStateChange: Date; totalTrips: number; } /** * Circuit breaker for a single provider */ declare class CircuitBreaker { private state; private failures; private successes; private lastFailureTime; private lastSuccessTime; private lastStateChange; private totalTrips; private config; private logger; readonly name: string; constructor(name: string, config: CircuitBreakerConfig); /** * Check if the circuit allows requests */ isAllowed(): boolean; /** * Record a successful request */ recordSuccess(): void; /** * Record a failed request */ recordFailure(): void; /** * Get current circuit state */ getState(): CircuitState; /** * Get circuit statistics */ getStats(): CircuitStats; /** * Force circuit to a specific state (for testing/admin) */ forceState(state: CircuitState): void; /** * Reset the circuit breaker */ reset(): void; /** * Check if state should transition based on time */ private checkStateTransition; /** * Transition to a new state */ private transitionTo; } /** * Circuit breaker manager for multiple providers */ declare class CircuitBreakerManager { private breakers; private defaultConfig; constructor(defaultConfig: CircuitBreakerConfig); /** * Get or create a circuit breaker for a provider */ getBreaker(providerName: string): CircuitBreaker; /** * Check if a provider is allowed */ isAllowed(providerName: string): boolean; /** * Record success for a provider */ recordSuccess(providerName: string): void; /** * Record failure for a provider */ recordFailure(providerName: string): void; /** * Get all circuit breaker stats */ getAllStats(): Map; /** * Reset all circuit breakers */ resetAll(): void; } /** * Health tracking for ludicrous-gateway providers * Monitors provider health and coordinates circuit breakers */ /** * Overall health status */ interface HealthStatus { status: "healthy" | "degraded" | "unhealthy"; providers: Map; circuits: Map; lastCheck: Date; } /** * Health tracker for monitoring provider health */ declare class HealthTracker { private providers; private circuitManager; private healthCheckInterval; private checkIntervalMs; private logger; private lastCheck; constructor(config: HealthConfig); /** * Register a provider for health tracking */ registerProvider(provider: Provider): void; /** * Unregister a provider */ unregisterProvider(name: string): void; /** * Start periodic health checks */ startHealthChecks(): void; /** * Stop periodic health checks */ stopHealthChecks(): void; /** * Run health checks for all providers */ runHealthChecks(): Promise; /** * Check if a provider is healthy and allowed */ isProviderHealthy(name: string): boolean; /** * Record a successful request to a provider */ recordSuccess(providerName: string): void; /** * Record a failed request to a provider */ recordFailure(providerName: string): void; /** * Get overall health status */ getHealthStatus(): HealthStatus; /** * Get list of healthy providers */ getHealthyProviders(): string[]; /** * Reset all health tracking state */ reset(): void; } /** * HTTP server for ludicrous-gateway * Express server setup and lifecycle management */ /** * Gateway server class */ declare class GatewayServer { private app; private server; private config; private providers; private router; private analyzer; private healthTracker; private logger; constructor(config: GatewayConfig); /** * Initialize provider instances */ private initializeProviders; /** * Create and configure Express app */ private createApp; /** * Start the server */ start(): Promise; /** * Stop the server */ stop(): Promise; /** * Get the Express app (for testing) */ getApp(): Express; /** * Get provider by name */ getProvider(name: string): Provider | undefined; /** * Get all providers */ getProviders(): Map; /** * Get router */ getRouter(): DefaultRouter; /** * Get health tracker */ getHealthTracker(): HealthTracker; /** * Reload configuration */ reloadConfig(config: GatewayConfig): void; } /** * Create and start a gateway server */ declare function createServer(config: GatewayConfig): Promise; /** * Zod schemas for configuration validation * Provides runtime validation for YAML configuration files */ /** * Complete gateway configuration schema */ declare const GatewayConfigSchema: z.ZodObject<{ server: z.ZodDefault; timeout_ms: z.ZodDefault; }, "strip", z.ZodTypeAny, { listen: string; timeout_ms: number; }, { listen?: string | undefined; timeout_ms?: number | undefined; }>>; routing: z.ZodObject<{ default_provider: z.ZodString; default_model: z.ZodOptional; rules: z.ZodDefault>; patterns: z.ZodOptional>; min_tokens: z.ZodOptional; max_tokens: z.ZodOptional; models: z.ZodOptional>; has_tools: z.ZodOptional; }, "strip", z.ZodTypeAny, { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }, { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }>; route_to: z.ZodObject<{ provider: z.ZodString; model: z.ZodOptional; }, "strip", z.ZodTypeAny, { provider: string; model?: string | undefined; }, { provider: string; model?: string | undefined; }>; priority: z.ZodDefault; enabled: z.ZodDefault; }, "strip", z.ZodTypeAny, { name: string; conditions: { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }; route_to: { provider: string; model?: string | undefined; }; priority: number; enabled: boolean; }, { name: string; conditions: { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }; route_to: { provider: string; model?: string | undefined; }; priority?: number | undefined; enabled?: boolean | undefined; }>, "many">>; }, "strip", z.ZodTypeAny, { rules: { name: string; conditions: { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }; route_to: { provider: string; model?: string | undefined; }; priority: number; enabled: boolean; }[]; default_provider: string; default_model?: string | undefined; }, { default_provider: string; rules?: { name: string; conditions: { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }; route_to: { provider: string; model?: string | undefined; }; priority?: number | undefined; enabled?: boolean | undefined; }[] | undefined; default_model?: string | undefined; }>; providers: z.ZodArray; enabled: z.ZodDefault; base_url: z.ZodOptional; keys: z.ZodOptional; }, "strip", z.ZodTypeAny, { key: string; weight?: number | undefined; }, { key: string; weight?: number | undefined; }>, "many">>; subscription_passthrough: z.ZodOptional; model_aliases: z.ZodOptional>; default_model: z.ZodOptional; }, "strip", z.ZodTypeAny, { name: string; type: "anthropic" | "zai" | "ollama" | "openai" | "gemini" | "grok" | "mistral" | "deepseek" | "kimi"; enabled: boolean; keys?: { key: string; weight?: number | undefined; }[] | undefined; default_model?: string | undefined; base_url?: string | undefined; subscription_passthrough?: boolean | undefined; model_aliases?: Record | undefined; }, { name: string; type: "anthropic" | "zai" | "ollama" | "openai" | "gemini" | "grok" | "mistral" | "deepseek" | "kimi"; keys?: { key: string; weight?: number | undefined; }[] | undefined; default_model?: string | undefined; enabled?: boolean | undefined; base_url?: string | undefined; subscription_passthrough?: boolean | undefined; model_aliases?: Record | undefined; }>, "many">; health: z.ZodDefault; circuit_breaker: z.ZodDefault; recovery_timeout_seconds: z.ZodDefault; }, "strip", z.ZodTypeAny, { failure_threshold: number; recovery_timeout_seconds: number; }, { failure_threshold?: number | undefined; recovery_timeout_seconds?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { check_interval_seconds: number; circuit_breaker: { failure_threshold: number; recovery_timeout_seconds: number; }; }, { check_interval_seconds?: number | undefined; circuit_breaker?: { failure_threshold?: number | undefined; recovery_timeout_seconds?: number | undefined; } | undefined; }>>; logging: z.ZodDefault>; format: z.ZodDefault>; }, "strip", z.ZodTypeAny, { level: "debug" | "info" | "warn" | "error"; format: "text" | "json"; }, { level?: "debug" | "info" | "warn" | "error" | undefined; format?: "text" | "json" | undefined; }>>; }, "strip", z.ZodTypeAny, { providers: { name: string; type: "anthropic" | "zai" | "ollama" | "openai" | "gemini" | "grok" | "mistral" | "deepseek" | "kimi"; enabled: boolean; keys?: { key: string; weight?: number | undefined; }[] | undefined; default_model?: string | undefined; base_url?: string | undefined; subscription_passthrough?: boolean | undefined; model_aliases?: Record | undefined; }[]; server: { listen: string; timeout_ms: number; }; routing: { rules: { name: string; conditions: { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }; route_to: { provider: string; model?: string | undefined; }; priority: number; enabled: boolean; }[]; default_provider: string; default_model?: string | undefined; }; health: { check_interval_seconds: number; circuit_breaker: { failure_threshold: number; recovery_timeout_seconds: number; }; }; logging: { level: "debug" | "info" | "warn" | "error"; format: "text" | "json"; }; }, { providers: { name: string; type: "anthropic" | "zai" | "ollama" | "openai" | "gemini" | "grok" | "mistral" | "deepseek" | "kimi"; keys?: { key: string; weight?: number | undefined; }[] | undefined; default_model?: string | undefined; enabled?: boolean | undefined; base_url?: string | undefined; subscription_passthrough?: boolean | undefined; model_aliases?: Record | undefined; }[]; routing: { default_provider: string; rules?: { name: string; conditions: { keywords?: string[] | undefined; patterns?: string[] | undefined; min_tokens?: number | undefined; max_tokens?: number | undefined; models?: string[] | undefined; has_tools?: boolean | undefined; }; route_to: { provider: string; model?: string | undefined; }; priority?: number | undefined; enabled?: boolean | undefined; }[] | undefined; default_model?: string | undefined; }; server?: { listen?: string | undefined; timeout_ms?: number | undefined; } | undefined; health?: { check_interval_seconds?: number | undefined; circuit_breaker?: { failure_threshold?: number | undefined; recovery_timeout_seconds?: number | undefined; } | undefined; } | undefined; logging?: { level?: "debug" | "info" | "warn" | "error" | undefined; format?: "text" | "json" | undefined; } | undefined; }>; /** * Inferred types from schemas */ type ValidatedGatewayConfig = z.infer; /** * Configuration loader for ludicrous-gateway * Loads and validates configuration from YAML files */ /** * Configuration loading options */ interface ConfigLoadOptions { /** Path to config file */ configPath?: string; /** Whether to use defaults if no config found */ useDefaults?: boolean; } /** * Load configuration from file or defaults */ declare function loadConfig(options?: ConfigLoadOptions): GatewayConfig; /** * Validate a configuration without loading */ declare function validateConfig(config: unknown): { valid: true; config: ValidatedGatewayConfig; } | { valid: false; errors: string[]; }; /** * Main content analyzer for ludicrous-gateway * Orchestrates token estimation and keyword detection */ /** * Content analyzer configuration */ interface ContentAnalyzerConfig { /** Custom keywords from routing rules */ ruleKeywords?: string[]; /** Custom patterns from routing rules */ rulePatterns?: string[]; /** Additional sensitive keywords */ additionalKeywords?: string[]; } /** * Default content analyzer implementation */ declare class DefaultContentAnalyzer implements ContentAnalyzer { private keywordDetector; constructor(config?: ContentAnalyzerConfig); /** * Analyze a request for routing decisions */ analyze(request: MessagesRequest): ContentAnalysis; /** * Detect if messages contain tool_use or tool_result blocks */ private detectToolUseBlocks; /** * Add keywords from routing rules */ addRuleKeywords(keywords: string[]): void; /** * Add patterns from routing rules */ addRulePatterns(patterns: string[]): void; } /** * Create a content analyzer from routing rules */ declare function createAnalyzerFromRules(rules: RoutingRuleConfig[]): DefaultContentAnalyzer; /** * Rate limiting for ludicrous-gateway * Implements per-provider rate limiting with token bucket algorithm */ /** * Rate limiter configuration */ interface RateLimiterConfig { /** Maximum requests per window */ maxRequests: number; /** Window size in milliseconds */ windowMs: number; /** Whether to queue requests when rate limited */ queueEnabled?: boolean; /** Maximum queue size */ maxQueueSize?: number; } /** * Rate limiter statistics */ interface RateLimiterStats { requests: number; windowStart: Date; remaining: number; queueSize: number; rejectedCount: number; } /** * Result of a rate limit check */ interface RateLimitResult { allowed: boolean; remaining: number; resetTime: Date; retryAfterMs?: number; } /** * Sliding window rate limiter */ declare class RateLimiter { readonly name: string; private requests; private rejectedCount; private config; private logger; constructor(name: string, config: RateLimiterConfig); /** * Check if a request is allowed */ checkLimit(): RateLimitResult; /** * Record a request (call after checkLimit returns allowed: true) */ recordRequest(): void; /** * Try to make a request (combines check and record) */ tryRequest(): RateLimitResult; /** * Get current statistics */ getStats(): RateLimiterStats; /** * Reset the rate limiter */ reset(): void; /** * Remove requests outside the current window */ private pruneOldRequests; } /** * Rate limiter manager for multiple providers */ declare class RateLimiterManager { private limiters; private defaultConfig; constructor(defaultConfig: RateLimiterConfig); /** * Get or create a rate limiter for a provider */ getLimiter(providerName: string): RateLimiter; /** * Set custom config for a specific provider */ setProviderConfig(providerName: string, config: RateLimiterConfig): void; /** * Check rate limit for a provider */ checkLimit(providerName: string): RateLimitResult; /** * Try a request for a provider */ tryRequest(providerName: string): RateLimitResult; /** * Get all rate limiter stats */ getAllStats(): Map; /** * Reset all rate limiters */ resetAll(): void; } /** * Structured logging utility for ludicrous-gateway * Provides consistent log formatting and levels */ type LogLevel = "debug" | "info" | "warn" | "error"; type LogFormat = "text" | "json"; /** * Logger configuration */ interface LoggerConfig { level: LogLevel; format: LogFormat; } /** * Logger class for structured logging */ declare class Logger { private level; private format; private context; constructor(config: LoggerConfig, context?: Record); /** * Create a child logger with additional context */ child(context: Record): Logger; /** * Check if a log level should be output */ private shouldLog; /** * Format and output a log entry */ private log; /** * Output log entry as JSON */ private outputJson; /** * Output log entry as formatted text */ private outputText; /** * Log a debug message */ debug(message: string, context?: Record): void; /** * Log an info message */ info(message: string, context?: Record): void; /** * Log a warning message */ warn(message: string, context?: Record): void; /** * Log an error message */ error(message: string, context?: Record): void; } /** * Initialize the default logger */ declare function initLogger(config: LoggerConfig): void; /** * Get the default logger */ declare function getLogger(): Logger; /** * Create a child logger with context */ declare function createLogger(context: Record): Logger; /** * Base provider abstract class for ludicrous-gateway * Defines common functionality for all provider adapters */ /** * Abstract base class for provider implementations */ declare abstract class BaseProvider implements Provider { readonly name: string; readonly type: string; readonly enabled: boolean; protected baseUrl: string; protected modelAliases: Map; protected defaultModel: string | undefined; protected logger: Logger; protected health: ProviderHealth; protected stats: ProviderStats; constructor(config: ProviderConfig); /** * Get the default base URL for this provider type * Must be implemented by subclasses */ protected abstract getDefaultBaseUrl(): string; /** * Send a non-streaming request * Must be implemented by subclasses */ abstract sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request * Must be implemented by subclasses */ abstract sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; /** * Check provider health * Can be overridden by subclasses for custom health checks */ healthCheck(): Promise; /** * Get provider information */ getInfo(): ProviderInfo; /** * Resolve model name using aliases */ resolveModel(model: string): string; /** * Record a health check result */ protected recordHealthCheck(success: boolean, errorMessage?: string): void; /** * Record a request result */ protected recordRequest(success: boolean, latencyMs: number): void; /** * Build headers for API request * Can be overridden by subclasses */ protected buildHeaders(_context: ProviderRequestContext): Record; /** * Transform request body if needed * Can be overridden by subclasses */ protected transformRequest(request: MessagesRequest): unknown; /** * Transform response if needed * Can be overridden by subclasses */ protected transformResponse(response: unknown): MessagesResponse; } /** * Anthropic provider adapter for ludicrous-gateway * Passes requests directly to Anthropic API with subscription passthrough */ /** * Anthropic API provider * Supports subscription passthrough for Claude Code clients */ declare class AnthropicProvider extends BaseProvider { private subscriptionPassthrough; constructor(config: ProviderConfig); protected getDefaultBaseUrl(): string; /** * Build headers for Anthropic API * Passes through subscription headers if enabled */ protected buildHeaders(context: ProviderRequestContext): Record; /** * Send a non-streaming request to Anthropic */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to Anthropic */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; /** * Health check for Anthropic API */ healthCheck(): Promise; } /** * Create an Anthropic provider from config */ declare function createAnthropicProvider(config: ProviderConfig): AnthropicProvider; /** * OpenAI provider adapter for ludicrous-gateway * Translates between Anthropic API format and OpenAI API format */ /** * Available OpenAI models */ declare const OPENAI_MODELS: { value: string; label: string; }[]; /** * Default model aliases mapping Claude models to OpenAI models */ declare const DEFAULT_OPENAI_ALIASES: Record; /** * OpenAI API provider */ declare class OpenAIProvider extends BaseProvider { private apiKeys; private currentKeyIndex; constructor(config: ProviderConfig); /** * Get the next API key (round-robin) */ private getNextApiKey; protected getDefaultBaseUrl(): string; /** * Build headers for OpenAI API request */ protected buildHeaders(_context: ProviderRequestContext): Record; /** * Convert Anthropic messages to OpenAI format */ private convertToOpenAIFormat; /** * Convert OpenAI response to Anthropic format */ private convertFromOpenAIFormat; /** * Map OpenAI finish_reason to Anthropic stop_reason */ private mapFinishReason; /** * Handle OpenAI API errors */ private handleError; /** * Send a non-streaming request to OpenAI */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to OpenAI */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; /** * Health check for OpenAI */ healthCheck(): Promise; } /** * Create an OpenAI provider from config */ declare function createOpenAIProvider(config: ProviderConfig): OpenAIProvider; /** * Z.AI GLM provider adapter for ludicrous-gateway * Connects to Z.AI's Anthropic-compatible API */ /** * Z.AI API provider * Uses Anthropic-compatible API format */ declare class ZaiProvider extends BaseProvider { private apiKeys; private currentKeyIndex; constructor(config: ProviderConfig); protected getDefaultBaseUrl(): string; /** * Get the next API key (round-robin) */ private getNextApiKey; /** * Build headers for Z.AI API * Z.AI accepts both ANTHROPIC_AUTH_TOKEN and x-api-key headers */ protected buildHeaders(context: ProviderRequestContext): Record; /** * Send a non-streaming request to Z.AI */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to Z.AI */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; } /** * Create a Z.AI provider from config */ declare function createZaiProvider(config: ProviderConfig): ZaiProvider; /** * Ollama provider adapter for ludicrous-gateway * Connects to local Ollama instance for private/local inference */ /** * Ollama API provider for local inference */ declare class OllamaProvider extends BaseProvider { constructor(config: ProviderConfig); protected getDefaultBaseUrl(): string; /** * Convert Anthropic messages to Ollama format */ private convertToOllamaFormat; /** * Convert Ollama response to Anthropic format */ private convertFromOllamaFormat; /** * Send a non-streaming request to Ollama */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to Ollama */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; /** * Health check for Ollama */ healthCheck(): Promise; } /** * Create an Ollama provider from config */ declare function createOllamaProvider(config: ProviderConfig): OllamaProvider; /** * Kimi K2 provider adapter for ludicrous-gateway * Connects to Moonshot AI's Kimi API */ /** * Kimi/Moonshot API provider */ declare class KimiProvider extends BaseProvider { private apiKeys; private currentKeyIndex; constructor(config: ProviderConfig); protected getDefaultBaseUrl(): string; /** * Get the next API key (round-robin) */ private getNextApiKey; /** * Build headers for Kimi API */ protected buildHeaders(_context: ProviderRequestContext): Record; /** * Convert Anthropic messages to Kimi format */ private convertToKimiFormat; /** * Convert Kimi response to Anthropic format */ private convertFromKimiFormat; /** * Send a non-streaming request to Kimi */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to Kimi */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; } /** * Create a Kimi provider from config */ declare function createKimiProvider(config: ProviderConfig): KimiProvider; /** * DeepSeek provider adapter for ludicrous-gateway * Connects to DeepSeek's OpenAI-compatible API */ /** * Available DeepSeek models */ declare const DEEPSEEK_MODELS: { value: string; label: string; }[]; /** * DeepSeek API provider */ declare class DeepSeekProvider extends BaseProvider { private apiKeys; private currentKeyIndex; constructor(config: ProviderConfig); protected getDefaultBaseUrl(): string; /** * Get the next API key (round-robin) */ private getNextApiKey; /** * Build headers for DeepSeek API */ protected buildHeaders(_context: ProviderRequestContext): Record; /** * Convert Anthropic messages to DeepSeek format */ private convertToDeepSeekFormat; /** * Convert DeepSeek response to Anthropic format */ private convertFromDeepSeekFormat; /** * Send a non-streaming request to DeepSeek */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to DeepSeek */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; } /** * Create a DeepSeek provider from config */ declare function createDeepSeekProvider(config: ProviderConfig): DeepSeekProvider; /** * Mistral AI provider adapter for ludicrous-gateway * Connects to Mistral AI's OpenAI-compatible API */ /** * Available Mistral models */ declare const MISTRAL_MODELS: readonly [{ readonly value: "mistral-large-latest"; readonly label: "Mistral Large (Best)"; }, { readonly value: "mistral-medium-latest"; readonly label: "Mistral Medium"; }, { readonly value: "mistral-small-latest"; readonly label: "Mistral Small (Fast)"; }, { readonly value: "codestral-latest"; readonly label: "Codestral (Code-focused)"; }, { readonly value: "ministral-8b-latest"; readonly label: "Ministral 8B (Cheapest)"; }]; /** * Default model aliases mapping Claude models to Mistral */ declare const DEFAULT_MISTRAL_ALIASES: Record; /** * Mistral AI provider */ declare class MistralProvider extends BaseProvider { private apiKeys; private currentKeyIndex; constructor(config: ProviderConfig); protected getDefaultBaseUrl(): string; /** * Get the next API key (round-robin) */ private getNextApiKey; /** * Build headers for Mistral API */ protected buildHeaders(_context: ProviderRequestContext): Record; /** * Convert Anthropic messages to Mistral format */ private convertToMistralFormat; /** * Convert Mistral response to Anthropic format */ private convertFromMistralFormat; /** * Send a non-streaming request to Mistral */ sendRequest(request: MessagesRequest, context: ProviderRequestContext): Promise; /** * Send a streaming request to Mistral */ sendStreamingRequest(request: MessagesRequest, context: ProviderRequestContext, handler: StreamHandler): Promise; /** * Health check for Mistral */ healthCheck(): Promise; } /** * Create a Mistral provider from config */ declare function createMistralProvider(config: ProviderConfig): MistralProvider; /** * Request and routing metrics for ludicrous-gateway * Tracks performance and usage statistics */ /** * Per-provider metrics */ interface ProviderMetrics { totalRequests: number; successfulRequests: number; failedRequests: number; totalLatencyMs: number; streamingRequests: number; tokensSent: number; tokensReceived: number; } /** * Per-rule metrics */ interface RuleMetrics { matchCount: number; lastMatchTime: Date | null; } /** * Overall gateway metrics */ interface GatewayMetrics { startTime: Date; totalRequests: number; activeRequests: number; providers: Map; rules: Map; } /** * Metrics collector class */ declare class MetricsCollector { private startTime; private totalRequests; private activeRequests; private providers; private rules; constructor(); /** * Get or create metrics for a provider */ private getProviderMetrics; /** * Get or create metrics for a rule */ private getRuleMetrics; /** * Record start of a request */ recordRequestStart(): void; /** * Record end of a request */ recordRequestEnd(provider: string, success: boolean, latencyMs: number, isStreaming: boolean): void; /** * Record a routing decision */ recordRoutingDecision(decision: RoutingDecision): void; /** * Record token usage */ recordTokenUsage(provider: string, inputTokens: number, outputTokens: number): void; /** * Get all metrics */ getMetrics(): GatewayMetrics; /** * Get metrics as a plain object for JSON serialization */ toJSON(): Record; /** * Reset all metrics */ reset(): void; } /** * Initialize the metrics collector */ declare function initMetrics(): void; /** * Get the metrics collector instance */ declare function getMetrics(): MetricsCollector; export { CircuitBreaker, CircuitBreakerManager, type CompiledRoutingRule, type ContentAnalysis, type ContentAnalyzer, type ContentBlock, DEEPSEEK_MODELS, DEFAULT_MISTRAL_ALIASES, DEFAULT_OPENAI_ALIASES, DefaultContentAnalyzer, DefaultRouter, type GatewayConfig, GatewayServer, type HealthConfig, HealthTracker, Logger, MISTRAL_MODELS, type Message, type MessagesRequest, type MessagesResponse, MetricsCollector, OPENAI_MODELS, type Provider, type ProviderConfig, type ProviderHealth, type ProviderInfo, type ProviderRequestContext, RateLimiter, RateLimiterManager, type Router, type RoutingConfig, type RoutingDecision, type RoutingRuleConfig, type StreamHandler, createAnalyzerFromRules, createAnthropicProvider, createDeepSeekProvider, createKimiProvider, createLogger, createMistralProvider, createOllamaProvider, createOpenAIProvider, createRouter, createServer, createZaiProvider, getLogger, getMetrics, initLogger, initMetrics, loadConfig, validateConfig };