import { AgentService } from '../agent/service.js'; import { MessageBus } from '../infra/bus/index.js'; import { AutomationService } from '../automations/index.js'; import { DiscussionLiveWorker, DiscussionOrganizerWorker, DiscussionSealer, DiscussionService } from '../discussions/index.js'; import { NotesService } from '../notes/index.js'; import { WorkflowRunService } from '../workflows/service/workflow-run-service.js'; import { ExtensionLoader } from '../extensions/index.js'; import { SessionIndex } from '../session/index.js'; import type { Config } from '../config/schema.js'; import { type ResolvedGatewayAuth } from './auth.js'; import { ModelCatalogSyncService } from '../providers/model-catalog-sync-service.js'; import { ProjectService } from '../projects/index.js'; import { LocalAppService } from '../local-apps/index.js'; import { type BrowserRecipeService } from '../browser/recipes/index.js'; import { listInsights, ProactiveEventService, ProactiveInboxService, ProactiveInboxWorker, ProactiveScenarioService, ProactiveTemporalWorker, ProactiveWorker } from '../proactive/index.js'; import { GatewaySessionsApi } from './service/sessions-api.js'; import { GatewayMarketplaceService } from './service/marketplace-service.js'; import { GatewayAgentRunner } from './service/agent-runner.js'; import { RealtimeRuntime } from '../realtime/runtime.js'; import type { GatewayServiceConfig } from './service/types.js'; import { type GatewayReadinessSnapshot } from './startup-readiness.js'; import { type ConnectorLearningCoordinator } from '../connectors/learning-coordinator.js'; import { type ProductLanguage } from '../voice/language-profile.js'; import { EndpointToolRuntime } from '../endpoint-tools/index.js'; export type { GatewayChannelStartupPhase1Metrics, GatewayChannelStartupPhase2Metrics, GatewayServiceConfig, } from './service/types.js'; export declare class GatewayService { private serviceConfig; private bus; private config; private configPath; private _agentService; private channelManager; private automationService; private browserRecipeService; private notesService; private extensionLoader; private extensionMetadataSnapshot; private browserExtensionProvider; private browserExtensionRelease; /** `${host}:${port}` when the gateway holds the extension bridge listener. */ private browserExtensionBindKey; private heartbeatService; private sessionIndex; private running; private startTime; private workspacePath; private readonly configCoordinator; private readonly modelCatalogSync; private auth; readonly endpointTools: EndpointToolRuntime; readonly realtime: RealtimeRuntime; getConfig(): Config; getModelCatalogSync(): ModelCatalogSyncService; get browserRecipes(): BrowserRecipeService; private stopGatewayUpdateCheck; /** When set (e.g. by `GatewayServer`), `triggerGatewayProcessRestart` can stop HTTP then exit. */ private gatewayShutdownForRestart; /** Snapshot for phase-2 metrics / logs (ids deferred at phase-1 `start()`). */ private lastDeferredChannelConnectIds; private lastChannelConnectDeferMode; private lastChannelConnectDeferSource; private readonly readiness; private startupTrace; private workflowSessionBridge; private workflowRunServiceInstance; private taskRunDispatcher; private taskRunDispatchTimer; private mobileNotifications; private connectorSupervisor; private connectorLearningCoordinator; private connectedSourceChangePublisher; private connectedKnowledgeCoordinator; private stopAutomationProductEventBridge; private stopSessionTranscriptAutomationEvents; private stopRealtimeLogBridge; /** * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`, * `submitClarifyResponse`, clarify-bridge dispatch). Owns the * `activeWebchatRunBySession` + `runAbortControllers` maps. */ readonly agentRunner: GatewayAgentRunner; /** * Session CRUD / search / compaction / tag-archive-pin / stats — the gateway * REST surface for sessions. Routes should depend on this narrow service * rather than the full GatewayService composition root. */ readonly sessions: GatewaySessionsApi; /** * Skills + extensions marketplace surface (browse / install / uninstall) plus * local-only managed-skill ops. Routes depend on this narrow service. */ readonly marketplace: GatewayMarketplaceService; /** First-class project grouping surface. */ readonly projects: ProjectService; readonly discussions: DiscussionService; readonly discussionWorker: DiscussionOrganizerWorker; readonly discussionLiveWorker: DiscussionLiveWorker; readonly discussionSealer: DiscussionSealer; /** Local user-created apps, their coder projects, previews, and installs. */ readonly localApps: LocalAppService; /** Unified durable event spine for proactive scenarios. */ readonly proactiveScenarios: ProactiveScenarioService; readonly proactive: ProactiveEventService; readonly proactiveInbox: ProactiveInboxService; readonly proactiveInsights: typeof listInsights; readonly proactiveWorker: ProactiveWorker; readonly proactiveTemporalWorker: ProactiveTemporalWorker; readonly proactiveInboxWorker: ProactiveInboxWorker; constructor(serviceConfig?: GatewayServiceConfig); /** Lazy AgentService — constructed on first use or during `start()`. */ get agentService(): AgentService; refreshActionTrustPolicy(): void; refreshUserProfileContext(): void; private ensureAgentService; private ensureHeartbeatService; private createTaskRunDispatcher; private createMobileNotificationService; dispatchTaskRuns(): void; runAgent(...args: Parameters): ReturnType; submitSessionInput(...args: Parameters): Promise<{ ok: true; effectiveDelivery: import("../storage/sqlite/session-input-repository.js").SessionInputDelivery; state: import("../storage/sqlite/session-input-repository.js").SessionInputState; } | { ok: false; code: "BAD_REQUEST" | "QUEUE_FULL"; }>; getSessionInputState(...args: Parameters): import("../storage/sqlite/session-input-repository.js").SessionInputState; updateSessionInput(...args: Parameters): Promise<{ ok: boolean; state: import("../storage/sqlite/session-input-repository.js").SessionInputState; }>; removeSessionInput(...args: Parameters): { ok: boolean; state: import("../storage/sqlite/session-input-repository.js").SessionInputState; }; abortAgentRun(runId: string): Promise<{ aborted: boolean; idle: boolean; }>; getActiveWebchatRunId(sessionKey: string): string | undefined; submitClarifyResponse(requestId: string, answer: string): boolean; private initializeExtensionLoader; private registerExtensionChannelPlugins; /** * Load extensions and register SDK / full ChannelPlugin instances with ChannelManager. */ private loadExtensionsAndRegisterChannels; private findChannelContributionExtension; ensureChannelRuntimePlugin(channelId: string): Promise>; private loadDeferredExtensions; private schedulePostReadySidecars; private runPostReadySidecars; start(): Promise; private ensureDefaultProactiveScenarioSubscriptions; /** Called when the HTTP listener is bound (before deferred channel work). */ markHttpListening(): void; isGatewayReady(): boolean; getGatewayReadiness(): GatewayReadinessSnapshot; private applyStartupReadyDelayForTesting; private markGatewayReady; /** After HTTP is listening: exposure auto-start (Tailscale, then FRP tunnel). */ private runExposureAutoStartIfConfigured; /** * Called by `GatewayServer` when the HTTP listener is bound. Starts channels that * opted into `meta.deferConnectUntilAfterListen`, then replays outbound queue. */ onHttpListening(): Promise; stop(): Promise; /** Start the browser extension WS server when backend is 'extension'. */ private startBrowserExtensionServerIfNeeded; /** Release the gateway's hold on the shared extension bridge (does not restart). */ releaseBrowserExtensionBridge(): Promise; /** * Start/stop/rebind the Chrome extension bridge. * PATCH saves update config in memory without re-running gateway startup, so this must run on save too. */ reconcileBrowserExtensionServer(): Promise; /** * Start processing outbound messages and send through channels */ private startOutboundProcessor; reloadHeartbeatFromCurrentConfig(): void; reloadConfig(): Promise<{ reloaded: boolean; error?: string; }>; afterWeixinCredentialsPersisted(): Promise; afterFeishuCredentialsPersisted(): Promise; saveConfig(config: Config): Promise<{ saved: boolean; error?: string; }>; syncVoiceLanguage(language: ProductLanguage): Promise<{ applied: boolean; language: ProductLanguage; mode: 'auto' | 'manual'; error?: string; }>; setBundledExtensionActivationTarget(extensionId: string, wanted: boolean): Promise<{ ok: boolean; error?: string; requiresGatewayRestart: boolean; }>; updateConfig(updates: Partial): Promise<{ updated: boolean; error?: string; }>; /** * Send message through a channel */ sendMessage(channel: string, chatId: string, content: string): Promise<{ sent: boolean; messageId?: string; }>; /** * Get channel statuses */ getChannelsStatus(): Array<{ name: string; enabled: boolean; connected: boolean; }>; getRunningChannelIds(): string[]; getChannelRuntimePlugin(channelId: string): import("../channels/plugin-types.js").ChannelPlugin; restartChannel(channelId: string): Promise; /** * Hub metadata for gateway console (built-in registry + registered channel plugins). */ getChannelsHubMeta(): Array<{ id: string; label: string; description: string; manageable: boolean; order: number; }>; /** * Request an immediate heartbeat run (coalesced like interval/cron wakes). */ requestHeartbeatNow(opts?: { reason?: string; }): void; requestConnectorLearning(connectionId: string, request?: Parameters[1]): ReturnType; requestConnectorLearningForToolkit(toolkit: string): ReturnType; setConnectorLearningPaused(connectionId: string, paused: boolean): number; /** * Register graceful shutdown used after spawning a replacement gateway process (foreground CLI server). */ registerGatewayShutdownForRestart(handler: () => Promise): void; /** * Respawn the gateway process when supported (spawn + exit, supervisor exit, or disabled when XOPC_NO_RESPAWN). */ triggerGatewayProcessRestart(): { ok: boolean; mode: string; message?: string; }; /** * Get health status */ getHealth(): { status: string; service: string; version: string; uptime: number; ready: boolean; httpListening: boolean; startupDurationMs: number | null; channels: { running: number; total: number; }; configPath: string; logs?: { dir: string; errors24h: number; stats: Record; }; }; get isRunning(): boolean; /** * Get extension registry for external access (HTTP routes, gateway methods) */ getExtensionRegistry(): import("../extensions/extension-registry-impl.js").ExtensionRegistryImpl; /** Extension loader for discovery and frontend asset APIs (may be null if extensions failed to init). */ getExtensionLoader(): ExtensionLoader | null; /** * Get model registry for external access (HTTP routes) */ getModelRegistry(): any; /** * Invoke a gateway method registered by extensions */ invokeGatewayMethod(method: string, params: Record): Promise; get currentConfig(): Config; get currentWorkspacePath(): string; get messageBusInstance(): MessageBus; /** Effective HTTP listen port (CLI `--port` override or config default). */ getEffectiveListenPort(): number; get automationServiceInstance(): AutomationService; private reconcileDreamingAutomations; get notesServiceInstance(): NotesService; get sessionIndexInstance(): SessionIndex; /** Shared workflow run orchestrator + session bridge (one instance per gateway). */ createWorkflowRunService(): WorkflowRunService; private reconcileInterruptedWorkflowRuns; private collectWorkflowAgentIds; /** Process a message directly through the agent (for CLI mode). */ processDirect(content: string, sessionKey?: string): Promise; emit(type: string, payload: unknown): void; private handleAutomationRunCompleted; private startAutomationProductEventBridge; /** * Validate authentication token from request headers. * Returns true if auth is disabled (mode: 'none') or token is valid. */ validateAuth(headers?: Record): boolean; /** * Get current auth mode. */ getAuthMode(): 'none' | 'token' | 'password' | 'trusted-proxy'; /** Resolved gateway auth (mode, credentials, trusted-proxy config). */ getResolvedAuth(): ResolvedGatewayAuth; /** * Get current auth token (for CLI server integration). * Returns undefined if mode is not token. */ getAuthToken(): string | undefined; /** * Refresh (regenerate) the gateway auth token. * Returns the new token. */ refreshAuthToken(): Promise; }