/** * @license * Copyright 2025 Qwen Team * SPDX-License-Identifier: Apache-2.0 */ import type { CLIControlRequest, CLIControlResponse, ControlRequestPayload, ControlResponse } from '../types.js'; import type { IControlContext } from './ControlContext.js'; import type { IPendingRequestRegistry } from './controllers/baseController.js'; import { PermissionController } from './controllers/permissionController.js'; import { SdkMcpController } from './controllers/sdkMcpController.js'; import { SystemController } from './controllers/systemController.js'; /** * Central coordinator for control plane communication. * Routes requests to controllers and manages request lifecycle. */ export declare class ControlDispatcher implements IPendingRequestRegistry { private context; readonly systemController: SystemController; readonly permissionController: PermissionController; readonly sdkMcpController: SdkMcpController; private pendingIncomingRequests; private pendingOutgoingRequests; private abortHandler; constructor(context: IControlContext); /** * Routes an incoming request to the appropriate controller and sends response */ dispatch(request: CLIControlRequest): Promise; /** * Processes response from SDK for an outgoing request */ handleControlResponse(response: CLIControlResponse): void; /** * Sends a control request to SDK and waits for response */ sendControlRequest(payload: ControlRequestPayload, timeoutMs?: number): Promise; /** * Cancels a specific request or all pending requests */ handleCancel(requestId?: string): void; /** * Marks stdin as closed and rejects all pending outgoing requests. * After this is called, new outgoing requests will be rejected immediately. * This should be called when stdin closes to avoid waiting for responses. */ markInputClosed(): void; /** * Stops all pending requests and cleans up all controllers */ shutdown(): void; /** * Registers an incoming request in the pending registry. */ registerIncomingRequest(requestId: string, controller: string, abortController: AbortController, timeoutId: NodeJS.Timeout): void; /** * Removes an incoming request from the pending registry */ deregisterIncomingRequest(requestId: string): void; /** * Registers an outgoing request in the pending registry */ registerOutgoingRequest(requestId: string, controller: string, resolve: (response: ControlResponse) => void, reject: (error: Error) => void, timeoutId: NodeJS.Timeout): void; /** * Removes an outgoing request from the pending registry */ deregisterOutgoingRequest(requestId: string): void; /** * Get count of pending incoming requests (for debugging) */ getPendingIncomingRequestCount(): number; /** * Wait for all incoming request handlers to complete. * * Uses polling since we don't have direct Promise references to handlers. * The pendingIncomingRequests map is managed by BaseController: * - Registered when handler starts (in handleRequest) * - Deregistered when handler completes (success or error) * * @param pollIntervalMs - How often to check (default 50ms) * @param timeoutMs - Maximum wait time (default 30s) */ waitForPendingIncomingRequests(pollIntervalMs?: number, timeoutMs?: number): Promise; /** * Returns the controller that handles the given request subtype */ private getControllerForRequest; /** * Sends a success response back to SDK */ private sendSuccessResponse; /** * Sends an error response back to SDK */ private sendErrorResponse; }