UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

1,190 lines (1,189 loc) 33.8 kB
/** * Server Adapter Types * Comprehensive type system for NeuroLink server adapters */ import type { ExternalServerManager } from "../mcp/externalServerManager.js"; import type { MCPToolRegistry } from "../mcp/toolRegistry.js"; import type { NeuroLink } from "../neurolink.js"; import type { JsonObject, JsonValue } from "./common.js"; import type { ExternalMCPServerStatus } from "./externalMcp.js"; /** * Server adapter configuration */ export type ServerAdapterConfig = { /** Server port (default: 3000) */ port?: number; /** Server host (default: "0.0.0.0") */ host?: string; /** Base path for all routes (default: "/api") */ basePath?: string; /** CORS configuration */ cors?: CORSConfig; /** Rate limiting configuration */ rateLimit?: RateLimitConfig; /** Body parser configuration */ bodyParser?: BodyParserConfig; /** Logging configuration */ logging?: LoggingConfig; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; /** Enable metrics endpoint (default: true) */ enableMetrics?: boolean; /** Enable Swagger/OpenAPI documentation (default: false) */ enableSwagger?: boolean; /** Disable built-in health routes (use when registering healthRoutes separately) */ disableBuiltInHealth?: boolean; /** Stream redaction configuration (disabled by default) */ redaction?: RedactionConfig; /** Shutdown configuration for graceful shutdown behavior */ shutdown?: ShutdownConfig; }; /** * Required server adapter configuration (with defaults applied) */ export type RequiredServerAdapterConfig = { port: number; host: string; basePath: string; cors: RequiredCORSConfig; rateLimit: RequiredRateLimitConfig; bodyParser: RequiredBodyParserConfig; logging: RequiredLoggingConfig; timeout: number; enableMetrics: boolean; enableSwagger: boolean; disableBuiltInHealth: boolean; redaction?: RequiredRedactionConfig; shutdown: RequiredShutdownConfig; }; /** * CORS configuration */ export type CORSConfig = { /** Enable CORS (default: true) */ enabled?: boolean; /** Allowed origins (default: ["*"]) */ origins?: string[]; /** Allowed HTTP methods */ methods?: string[]; /** Allowed headers */ headers?: string[]; /** Allow credentials */ credentials?: boolean; /** Preflight cache max age in seconds */ maxAge?: number; }; /** * Required CORS configuration */ export type RequiredCORSConfig = { enabled: boolean; origins: string[]; methods: string[]; headers: string[]; credentials: boolean; maxAge: number; }; /** * Rate limiting configuration */ export type RateLimitConfig = { /** Enable rate limiting (default: true) */ enabled?: boolean; /** Time window in milliseconds (default: 15 minutes) */ windowMs?: number; /** Maximum requests per window (default: 100) */ maxRequests?: number; /** Custom error message */ message?: string; /** Skip rate limiting for certain paths */ skipPaths?: string[]; /** Custom key generator function */ keyGenerator?: (ctx: ServerContext) => string; }; /** * Required rate limit configuration */ export type RequiredRateLimitConfig = { enabled: boolean; windowMs: number; maxRequests: number; message: string; skipPaths?: string[]; keyGenerator?: (ctx: ServerContext) => string; }; /** * Body parser configuration */ export type BodyParserConfig = { /** Enable body parsing (default: true) */ enabled?: boolean; /** Maximum body size (default: "10mb") */ maxSize?: string; /** JSON body limit (default: "10mb") */ jsonLimit?: string; /** Enable URL-encoded body parsing */ urlEncoded?: boolean; }; /** * Required body parser configuration */ export type RequiredBodyParserConfig = { enabled: boolean; maxSize: string; jsonLimit: string; urlEncoded: boolean; }; /** * Logging configuration */ export type LoggingConfig = { /** Enable request logging (default: true) */ enabled?: boolean; /** Log level */ level?: "debug" | "info" | "warn" | "error"; /** Include request body in logs */ includeBody?: boolean; /** Include response body in logs */ includeResponse?: boolean; }; /** * Required logging configuration */ export type RequiredLoggingConfig = { enabled: boolean; level: "debug" | "info" | "warn" | "error"; includeBody: boolean; includeResponse: boolean; }; /** * Configuration for stream redaction * * IMPORTANT: Redaction is DISABLED by default (enabled: false) * This is an opt-in security feature to prevent accidental data exposure. */ export type RedactionConfig = { /** * Enable stream redaction (default: false) * * When false, redactStreamChunk() returns chunks unchanged. * Must be explicitly set to true to enable redaction. */ enabled?: boolean; /** Additional field names to redact (case-insensitive) */ additionalFields?: string[]; /** Field names to preserve (not redact) */ preserveFields?: string[]; /** Whether to redact tool arguments when enabled (default: true) */ redactToolArgs?: boolean; /** Whether to redact tool results when enabled (default: true) */ redactToolResults?: boolean; /** Custom redaction placeholder (default: "[REDACTED]") */ placeholder?: string; }; /** * Required redaction configuration (with defaults applied) */ export type RequiredRedactionConfig = { enabled: boolean; additionalFields: string[]; preserveFields: string[]; redactToolArgs: boolean; redactToolResults: boolean; placeholder: string; }; /** * Server request context * Passed to all route handlers and middleware */ export type ServerContext = { /** Unique request ID */ requestId: string; /** HTTP method */ method: string; /** Request path */ path: string; /** Request headers */ headers: Record<string, string>; /** Query parameters */ query: Record<string, string>; /** Path parameters */ params: Record<string, string>; /** Request body (parsed) */ body?: unknown; /** NeuroLink SDK instance */ neurolink: NeuroLink; /** Tool registry instance */ toolRegistry: MCPToolRegistry; /** External server manager (optional) */ externalServerManager?: ExternalServerManager; /** Request timestamp */ timestamp: number; /** Additional metadata */ metadata: Record<string, unknown>; /** User information (if authenticated) */ user?: AuthenticatedUser; /** Session information */ session?: { id: string; data?: Record<string, JsonValue>; }; /** Abort signal for cancellation (set by abort signal middleware) */ abortSignal?: AbortSignal; /** Abort controller for manual cancellation (set by abort signal middleware) */ abortController?: AbortController; /** Raw framework response object (for framework-specific operations) */ rawResponse?: unknown; /** Raw framework request object (for framework-specific operations) */ rawRequest?: unknown; /** Response headers to be set (used by middleware to add headers) */ responseHeaders?: Record<string, string>; /** Redaction configuration (for stream redaction support) */ redaction?: RedactionConfig; }; /** * Server response object */ export type ServerResponse<T = unknown> = { /** Response data */ data?: T; /** Error information */ error?: { code: string; message: string; details?: Record<string, unknown>; }; /** Response metadata */ metadata?: { requestId: string; timestamp: string; duration?: number; }; }; /** * Streaming response configuration */ export type StreamingConfig = { /** Enable streaming response */ enabled: boolean; /** Content type for streaming */ contentType?: "text/event-stream" | "application/x-ndjson"; /** Keep-alive interval in milliseconds */ keepAliveInterval?: number; }; /** * HTTP methods supported by server adapters */ export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS"; /** * Route deprecation information */ export type RouteDeprecation = { /** Whether the route is deprecated */ enabled: boolean; /** Version when deprecated */ since?: string; /** Version when route will be removed */ removeIn?: string; /** Alternative route to use */ alternative?: string; /** Deprecation message */ message?: string; }; /** * Route definition */ export type RouteDefinition = { /** HTTP method */ method: HttpMethod; /** Route path (supports parameters like :id) */ path: string; /** Route handler function */ handler: RouteHandler; /** Route description (for documentation) */ description?: string; /** Request schema (for validation) */ requestSchema?: JsonObject; /** Response schema (for documentation) */ responseSchema?: JsonObject; /** Authentication required */ auth?: boolean; /** Required roles */ roles?: string[]; /** Rate limit override for this route */ rateLimit?: RateLimitConfig; /** Streaming configuration */ streaming?: StreamingConfig; /** Route tags (for documentation) */ tags?: string[]; /** Route deprecation information */ deprecated?: RouteDeprecation; }; /** * Route handler function */ export type RouteHandler<T = unknown> = (ctx: ServerContext) => Promise<T | ServerResponse<T> | AsyncIterable<unknown>>; /** * Route group for organizing related routes */ export type RouteGroup = { /** Group prefix */ prefix: string; /** Routes in this group */ routes: RouteDefinition[]; /** Middleware specific to this group */ middleware?: MiddlewareDefinition[]; /** Group-level authentication */ auth?: boolean; /** Group-level roles */ roles?: string[]; }; /** * Middleware definition */ export type MiddlewareDefinition = { /** Middleware name */ name: string; /** Execution order (lower = earlier) */ order?: number; /** Middleware handler */ handler: MiddlewareHandler; /** Paths to apply middleware to (default: all) */ paths?: string[]; /** Paths to exclude from middleware */ excludePaths?: string[]; }; /** * Middleware handler function */ export type MiddlewareHandler = (ctx: ServerContext, next: () => Promise<unknown>) => Promise<unknown>; /** * Server adapter events */ export type ServerAdapterEvents = { /** Server initialized */ initialized: { config: ServerAdapterConfig; routeCount: number; middlewareCount: number; }; /** Server started */ started: { port: number; host: string; timestamp: Date; }; /** Server stopped */ stopped: { uptime: number; timestamp: Date; }; /** Request received */ request: { requestId: string; method: string; path: string; timestamp: Date; }; /** Response sent */ response: { requestId: string; statusCode: number; duration: number; timestamp: Date; }; /** Error occurred */ error: { requestId?: string; error: Error; timestamp: Date; }; }; /** * Agent execution request */ export type AgentExecuteRequest = { /** Input prompt or message */ input: string | { text: string; images?: string[]; files?: string[]; }; /** Provider to use (optional) */ provider?: string; /** Model to use (optional) */ model?: string; /** System prompt (optional) */ systemPrompt?: string; /** Temperature (0-1) */ temperature?: number; /** Maximum tokens */ maxTokens?: number; /** Tools to enable */ tools?: string[]; /** Enable streaming */ stream?: boolean; /** Session ID for conversation memory */ sessionId?: string; /** User ID for context */ userId?: string; }; /** * Agent execution response */ export type AgentExecuteResponse = { /** Generated content */ content: string; /** Provider used */ provider: string; /** Model used */ model: string; /** Token usage */ usage?: { /** Input tokens (also known as prompt tokens) */ input: number; /** Output tokens (also known as completion tokens) */ output: number; /** Total tokens used */ total: number; /** Cache creation tokens (if applicable) */ cacheCreationTokens?: number; /** Cache read tokens (if applicable) */ cacheReadTokens?: number; /** Reasoning tokens (if applicable) */ reasoning?: number; /** Cache savings percentage */ cacheSavingsPercent?: number; }; /** Tool calls made */ toolCalls?: Array<{ name: string; arguments: Record<string, unknown>; result?: unknown; }>; /** Finish reason */ finishReason?: string; /** Response metadata */ metadata?: Record<string, JsonValue>; }; /** * Embed request (single text) */ export type EmbedRequest = { /** Text to embed */ text: string; /** Provider to use (optional) */ provider?: string; /** Embedding model to use (optional) */ model?: string; }; /** * Embed response (single text) */ export type EmbedResponse = { /** The embedding vector */ embedding: number[]; /** Provider used */ provider: string; /** Model used */ model: string; /** Embedding dimension */ dimension: number; }; /** * Embed many request (batch texts) */ export type EmbedManyRequest = { /** Texts to embed */ texts: string[]; /** Provider to use (optional) */ provider?: string; /** Embedding model to use (optional) */ model?: string; }; /** * Embed many response (batch texts) */ export type EmbedManyResponse = { /** The embedding vectors */ embeddings: number[][]; /** Provider used */ provider: string; /** Model used */ model: string; /** Number of embeddings */ count: number; /** Embedding dimension */ dimension: number; }; /** * Tool execution request */ export type ToolExecuteRequest = { /** Tool name */ name: string; /** Tool arguments */ arguments: Record<string, unknown>; /** Session context */ sessionId?: string; /** User context */ userId?: string; }; /** * Tool execution response */ export type ToolExecuteResponse = { /** Whether execution was successful */ success: boolean; /** Result data */ data?: unknown; /** Error message if failed */ error?: string; /** Execution duration in ms */ duration: number; /** Tool metadata */ metadata?: Record<string, JsonValue>; }; /** * MCP server status response */ export type MCPServerStatusResponse = { /** Server ID */ serverId: string; /** Server name */ name: string; /** Connection status */ status: ExternalMCPServerStatus; /** Available tools count */ toolCount: number; /** Last health check time */ lastHealthCheck?: string; /** Error message if failed */ error?: string; }; /** * Health check response */ export type HealthResponse = { /** Health status */ status: "ok" | "degraded" | "unhealthy"; /** Timestamp */ timestamp: string; /** Server uptime in milliseconds */ uptime: number; /** Version information */ version: string; }; /** * Ready check response */ export type ReadyResponse = { /** Ready status */ ready: boolean; /** Timestamp */ timestamp: string; /** Service status */ services: { neurolink: boolean; tools: boolean; externalServers: boolean; }; }; /** * Supported server frameworks */ export type ServerFramework = "hono" | "express" | "fastify" | "koa"; /** * Server adapter factory options */ export type ServerAdapterFactoryOptions = { /** Framework to use */ framework: ServerFramework; /** NeuroLink instance */ neurolink: NeuroLink; /** Server configuration */ config?: ServerAdapterConfig; }; /** * Server status information */ export type ServerStatus = { /** Whether server is running */ running: boolean; /** Server port */ port: number; /** Server host */ host: string; /** Server uptime in milliseconds */ uptime: number; /** Number of registered routes */ routes: number; /** Number of registered middleware */ middlewares: number; /** Current lifecycle state */ lifecycleState?: ServerLifecycleState; /** Number of active connections */ activeConnections?: number; }; /** * SSE write options */ export type SSEWriteOptions = { /** Event name */ event?: string; /** Event data (will be JSON stringified if object) */ data: string | object; /** Event ID */ id?: string; /** Retry interval in milliseconds */ retry?: number; }; /** * Data stream writer interface */ export type DataStreamWriter = { /** Write text start event */ writeTextStart(id: string): Promise<void>; /** Write text delta event */ writeTextDelta(id: string, delta: string): Promise<void>; /** Write text end event */ writeTextEnd(id: string): Promise<void>; /** Write tool call event */ writeToolCall(toolCall: { id: string; name: string; arguments: Record<string, unknown>; }): Promise<void>; /** Write tool result event */ writeToolResult(toolResult: { id: string; name: string; result: unknown; }): Promise<void>; /** Write arbitrary data event */ writeData(data: unknown): Promise<void>; /** Write error event */ writeError(error: { message: string; code?: string; }): Promise<void>; /** Close the stream */ close(): Promise<void>; }; /** * WebSocket message types */ export type WebSocketMessageType = "text" | "binary" | "ping" | "pong" | "close"; /** * WebSocket message */ export type WebSocketMessage = { type: WebSocketMessageType; data: string | ArrayBuffer; timestamp: number; }; /** * Authenticated user information */ export type AuthenticatedUser = { id: string; email?: string; name?: string; roles?: string[]; permissions?: string[]; metadata?: Record<string, unknown>; }; /** * WebSocket connection */ export type WebSocketConnection = { id: string; socket: unknown; user?: AuthenticatedUser; metadata: Record<string, unknown>; createdAt: number; lastActivity: number; }; /** * Authentication strategy types */ export type AuthStrategy = "bearer" | "apiKey" | "basic" | "custom" | "none"; /** * Authentication configuration */ export type ServerAuthConfig = { strategy: AuthStrategy; required?: boolean; headerName?: string; queryParam?: string; validate?: (token: string) => Promise<AuthenticatedUser | null>; roles?: string[]; permissions?: string[]; }; /** * WebSocket handler interface */ export type WebSocketHandler = { onOpen?: (connection: WebSocketConnection) => void | Promise<void>; onMessage?: (connection: WebSocketConnection, message: WebSocketMessage) => void | Promise<void>; onClose?: (connection: WebSocketConnection, code: number, reason: string) => void | Promise<void>; onError?: (connection: WebSocketConnection, error: Error) => void | Promise<void>; }; /** * WebSocket server configuration */ export type WebSocketConfig = { path?: string; maxConnections?: number; pingInterval?: number; pongTimeout?: number; maxMessageSize?: number; auth?: ServerAuthConfig; }; /** * Server lifecycle states * Represents the current state of the server adapter */ export type ServerLifecycleState = "uninitialized" | "initializing" | "initialized" | "starting" | "running" | "draining" | "stopping" | "stopped" | "error"; /** * Configuration for graceful shutdown behavior */ export type ShutdownConfig = { /** * Maximum time to wait for graceful shutdown in milliseconds * Default: 30000 (30 seconds) */ gracefulShutdownTimeoutMs?: number; /** * Maximum time to wait for connections to drain in milliseconds * Default: 15000 (15 seconds) */ drainTimeoutMs?: number; /** * Whether to force close connections after timeout * Default: true */ forceClose?: boolean; }; /** * Required shutdown configuration (with defaults applied) */ export type RequiredShutdownConfig = { gracefulShutdownTimeoutMs: number; drainTimeoutMs: number; forceClose: boolean; }; /** * Tracked connection for graceful shutdown */ export type TrackedConnection = { /** Unique connection identifier */ id: string; /** Timestamp when connection was created */ createdAt: number; /** Underlying socket or connection object */ socket?: unknown; /** Request ID if associated with a request */ requestId?: string; /** Whether the connection is currently processing a request */ isActive?: boolean; }; /** * Error categories for server adapter errors */ export declare const ErrorCategory: { readonly CONFIG: "CONFIG"; readonly VALIDATION: "VALIDATION"; readonly EXECUTION: "EXECUTION"; readonly EXTERNAL: "EXTERNAL"; readonly RATE_LIMIT: "RATE_LIMIT"; readonly AUTHENTICATION: "AUTHENTICATION"; readonly AUTHORIZATION: "AUTHORIZATION"; readonly STREAMING: "STREAMING"; readonly WEBSOCKET: "WEBSOCKET"; }; export type ErrorCategoryType = (typeof ErrorCategory)[keyof typeof ErrorCategory]; /** * Error severity levels */ export declare const ErrorSeverity: { readonly LOW: "LOW"; readonly MEDIUM: "MEDIUM"; readonly HIGH: "HIGH"; readonly CRITICAL: "CRITICAL"; }; export type ErrorSeverityType = (typeof ErrorSeverity)[keyof typeof ErrorSeverity]; /** * Server adapter error codes */ export declare const ServerAdapterErrorCode: { readonly INVALID_CONFIG: "SERVER_ADAPTER_INVALID_CONFIG"; readonly MISSING_DEPENDENCY: "SERVER_ADAPTER_MISSING_DEPENDENCY"; readonly FRAMEWORK_INIT_FAILED: "SERVER_ADAPTER_FRAMEWORK_INIT_FAILED"; readonly ROUTE_NOT_FOUND: "SERVER_ADAPTER_ROUTE_NOT_FOUND"; readonly ROUTE_CONFLICT: "SERVER_ADAPTER_ROUTE_CONFLICT"; readonly INVALID_ROUTE: "SERVER_ADAPTER_INVALID_ROUTE"; readonly HANDLER_ERROR: "SERVER_ADAPTER_HANDLER_ERROR"; readonly TIMEOUT: "SERVER_ADAPTER_TIMEOUT"; readonly MIDDLEWARE_ERROR: "SERVER_ADAPTER_MIDDLEWARE_ERROR"; readonly RATE_LIMIT_EXCEEDED: "SERVER_ADAPTER_RATE_LIMIT_EXCEEDED"; readonly AUTH_REQUIRED: "SERVER_ADAPTER_AUTH_REQUIRED"; readonly AUTH_INVALID: "SERVER_ADAPTER_AUTH_INVALID"; readonly FORBIDDEN: "SERVER_ADAPTER_FORBIDDEN"; readonly STREAM_ERROR: "SERVER_ADAPTER_STREAM_ERROR"; readonly STREAM_ABORTED: "SERVER_ADAPTER_STREAM_ABORTED"; readonly WEBSOCKET_ERROR: "SERVER_ADAPTER_WEBSOCKET_ERROR"; readonly WEBSOCKET_CONNECTION_FAILED: "SERVER_ADAPTER_WEBSOCKET_CONNECTION_FAILED"; readonly VALIDATION_ERROR: "SERVER_ADAPTER_VALIDATION_ERROR"; readonly SCHEMA_ERROR: "SERVER_ADAPTER_SCHEMA_ERROR"; readonly START_FAILED: "SERVER_ADAPTER_START_FAILED"; readonly STOP_FAILED: "SERVER_ADAPTER_STOP_FAILED"; readonly ALREADY_RUNNING: "SERVER_ADAPTER_ALREADY_RUNNING"; readonly NOT_RUNNING: "SERVER_ADAPTER_NOT_RUNNING"; }; export type ServerAdapterErrorCodeType = (typeof ServerAdapterErrorCode)[keyof typeof ServerAdapterErrorCode]; /** * Error context for server adapter errors */ export type ServerAdapterErrorContext = { category: ErrorCategoryType; severity: ErrorSeverityType; retryable: boolean; retryAfterMs?: number; requestId?: string; path?: string; method?: string; details?: Record<string, unknown>; cause?: Error; }; export type Frame = { type: "audio"; data: Int16Array; } | { type: "vad_start"; } | { type: "vad_stop"; } | { type: "transcript"; text: string; final: boolean; } | { type: "llm_token"; text: string; } | { type: "tts_audio"; data: Buffer; } | { type: "interrupt"; }; /** * Standardized error response format */ export type ErrorResponse = { error: { code: string; message: string; details?: unknown; }; metadata?: { timestamp: string; requestId?: string; }; httpStatus?: number; }; /** * Generic validation result with type-safe data or error. * Named ServerValidationResult to avoid collision with tools.ts ValidationResult. */ export type ServerValidationResult<T> = { success: true; data: T; error?: undefined; } | { success: false; error: ErrorResponse; data?: undefined; }; /** * Authentication configuration */ export type ServerServerAuthConfig = { /** Authentication type */ type: "bearer" | "api-key" | "basic" | "custom"; /** * Token validation function * Returns user information if valid, throws or returns null if invalid */ validate: (token: string, ctx: ServerContext) => Promise<AuthResult | null>; /** Header name for token (default: "Authorization" for bearer, "X-API-Key" for api-key) */ headerName?: string; /** Skip authentication for certain paths */ skipPaths?: string[]; /** Custom error message */ errorMessage?: string; /** * Optional token extractor for custom authentication schemes * Only used when type is "custom" */ extractToken?: (ctx: ServerContext) => string | null; /** * Skip authentication for dev playground requests in non-production. * When true (default), requests with x-neurolink-dev-playground or * x-neurolink-playground header set to "true" will bypass authentication * and receive a default developer user context. * * Only applies when NODE_ENV is not "production". * * @default true */ skipDevPlayground?: boolean; }; /** * Cache configuration */ export type ServerCacheConfig = { /** Default TTL in milliseconds */ ttlMs: number; /** Maximum cache size (number of entries) */ maxSize?: number; /** * Custom key generator * Default: method + path + sorted query params */ keyGenerator?: (ctx: ServerContext) => string; /** * Methods to cache (default: GET only) */ methods?: string[]; /** * Paths to cache (default: all paths) */ paths?: string[]; /** * Paths to exclude from caching */ excludePaths?: string[]; /** * Custom cache store * Default: in-memory store */ store?: CacheStore; /** * Whether to include query params in cache key * Default: true */ includeQuery?: boolean; /** * Custom TTL per path pattern */ ttlByPath?: Record<string, number>; }; /** * Base data stream event */ export type DataStreamEvent = { type: DataStreamEventType; id?: string; timestamp: number; data: unknown; }; export type AuthResult = { /** User ID */ id: string; /** User email (optional) */ email?: string; /** User roles (optional) */ roles?: string[]; /** Additional user data */ metadata?: Record<string, unknown>; }; export type CacheStore = { get(key: string): Promise<CacheEntry | undefined>; set(key: string, entry: CacheEntry): Promise<void>; delete(key: string): Promise<void>; clear(): Promise<void>; }; export type DataStreamEventType = "text-start" | "text-delta" | "text-end" | "tool-call" | "tool-result" | "data" | "error" | "finish"; export type CacheEntry = { data: unknown; createdAt: number; ttlMs: number; headers?: Record<string, string>; }; /** Voice-server conversation turn — superset role set. */ export type Message = { role: "system" | "user" | "assistant"; content: string; }; /** Subset of Message that excludes the system role (assistant+user only). */ export type ConversationMessage = { role: "user" | "assistant"; content: string; }; /** Configuration passed to the OpenAPI spec generator. */ export type OpenAPIGeneratorConfig = { info?: { title?: string; version?: string; description?: string; }; servers?: Array<{ url: string; description?: string; }>; includeSecurity?: boolean; basePath?: string; additionalTags?: Array<{ name: string; description: string; }>; customSchemas?: Record<string, JsonObject>; routes?: RouteDefinition[]; }; /** Structured OpenAPI 3.1 specification object. */ export type OpenAPISpec = { openapi: "3.1.0"; info: JsonObject; servers: JsonObject[]; tags: JsonObject[]; paths: Record<string, JsonObject>; components: { schemas: Record<string, JsonObject>; securitySchemes?: Record<string, JsonObject>; parameters?: Record<string, JsonObject>; }; security?: JsonObject[]; }; /** Options for createAllRoutes / createRoutes. */ export type CreateRoutesOptions = { enableSwagger?: boolean; getRoutes?: () => RouteDefinition[]; claudeProxy?: boolean; }; /** Data stream finish event. */ export type FinishEvent = DataStreamEvent & { type: "finish"; data: { reason?: string; usage?: { input: number; output: number; total: number; }; }; }; /** Configuration for DataStreamWriter. */ export type DataStreamWriterConfig = { write: (chunk: string) => void | Promise<void>; close?: () => void | Promise<void>; format?: "sse" | "ndjson"; includeTimestamps?: boolean; }; /** Configuration for the DataStreamResponse wrapper. */ export type DataStreamResponseConfig = { contentType?: "text/event-stream" | "application/x-ndjson"; headers?: Record<string, string>; keepAliveInterval?: number; includeTimestamps?: boolean; }; /** Options for a single SSE message. */ export type SSEEventOptions = { event?: string; data: string; id?: string; retry?: number; }; /** Single token emitted by the Soniox STT stream. */ export type SonioxToken = { is_final?: boolean; text?: string; }; /** Envelope received from the Soniox STT WebSocket. */ export type SonioxMessage = { error?: string; status?: string; type?: string; tokens?: SonioxToken[]; }; /** Control message received from the voice client over WebSocket. */ export type ClientControlMessage = { type?: string; }; /** * Structural type for Picovoice Cobra VAD instance. * Defined here so the optional `@picovoice/cobra-node` package * is not required at typecheck time. */ export type CobraInstance = { frameLength: number; process: (pcm: Int16Array) => number; release: () => void; }; /** * Per-WebSocket-connection context object passed to the voice connection * handler. Holds shared singletons that all per-connection state derives from. * * (Server-prefixed per CLAUDE.md Rule 9 — server-tier type.) */ export type ServerVoiceConnectionCtx = { neurolink: NeuroLink; accessKey: string; }; /** * Per-session mutable state for one voice WebSocket connection. * * Threaded through the voice connection helper functions so each connection * has fully isolated turn / TTS / VAD / barge-in state. The class types * (`FrameBus`, `TurnManager`, `CartesiaStream`) are imported as types here so * that this file remains the single source of truth — consumers import this * type via the barrel and do not redefine it locally. * * (Server-prefixed per CLAUDE.md Rule 9 — server-tier type.) */ export type ServerVoiceSessionState = { cobra: CobraInstance | null; FRAME_LENGTH: number; FRAME_BYTES: number; bus: import("../server/voice/frameBus.js").FrameBus; turnManager: import("../server/voice/turnManager.js").TurnManager; sonioxWs: import("ws").WebSocket | null; keepAliveTimer: NodeJS.Timeout | null; sonioxReconnectTimer: ReturnType<typeof setTimeout> | null; sessionClosed: boolean; transcriptBuffer: string; activeTTS: import("../adapters/tts/cartesiaHandler.js").CartesiaStream | null; conversation: ConversationMessage[]; currentTurnId: number; activePipelineTurnId: number | null; turnAborters: Set<{ aborted: boolean; }>; playbackResetTimer: NodeJS.Timeout | null; bargeInLockedUntil: number; isSpeaking: boolean; silenceFrameCount: number; voiceFrameCount: number; frameRemainder: Buffer; }; /** * Options accepted by `setupWebSocket()` in `server/voice/voiceWebSocketHandler.ts`. * * (Server-prefixed per CLAUDE.md Rule 9 — server-tier type. Lives in * `server.ts` rather than `cli.ts` because it configures a server-side * WebSocket upgrade handler, not CLI argument parsing.) */ export type ServerVoiceWebSocketOptions = { /** * Optional shared-secret bearer token. When set, the WebSocket upgrade * handshake must include `Authorization: Bearer <token>` or * `?token=<token>` in the URL. Without this, anyone reachable on the * network can open a session and consume Soniox / Cartesia / LLM credits. */ authToken?: string; /** * Maximum WebSocket message size in bytes. Defaults to 1 MiB. Caps both * inbound audio frames and any client control messages — guards against * OOM via oversized uploads. */ maxPayload?: number; };