/** * InboundLoop — owns the bus-driven inbound pipeline. * * Replaces the previous `AgentService.start()` while-loop, `handleInboundMessage`, * and `handleSystemMessage` methods. Everything that "a message arrives, run the * agent turn, publish the reply" needs is concentrated here; the parent * `AgentService` now just constructs the loop with collaborators and forwards * start/stop to it. * * The constructor takes a fairly wide config because handling a single inbound * message touches almost every subsystem (router, command handler, lifecycle * manager, agent orchestrator, outbound coordinator, session state, etc.). All * dependencies are injected so this class is unit-testable and the inbound * pipeline can evolve without touching `AgentService`. */ import type { MessageBus } from '../../infra/bus/index.js'; import type { Config } from '../../config/schema.js'; import type { ChannelManager } from '../../channels/manager.js'; import type { ContextualLogger } from '../../utils/logger/types.js'; import type { AgentManager } from '../agent-manager.js'; import type { AgentOrchestrator } from '../orchestration/index.js'; import type { CommandHandler, OutboundCoordinator, StreamManager } from '../messaging/index.js'; import type { MessageRouter } from '../messaging/message-router.js'; import type { ModelManager } from '../models/index.js'; import type { SessionContextManager, SessionHydrator, SessionLifecycleManager, SessionStateBag } from '../session/index.js'; import type { HookHandler } from '../lifecycle/hook-handler.js'; import type { SessionStore } from '../../session/store.js'; import type { StreamHandle } from '../service.types.js'; export interface InboundLoopConfig { log: ContextualLogger; agentId: string; bus: MessageBus; hookHandler: HookHandler; messageRouter: MessageRouter; commandHandler: CommandHandler; sessionContextManager: SessionContextManager; agentManager: AgentManager; sessionLifecycleManager: SessionLifecycleManager; agentOrchestrator: AgentOrchestrator; outboundCoordinator: OutboundCoordinator; streamManager: StreamManager; sessionState: SessionStateBag; sessionStore: SessionStore; modelManager: ModelManager; /** Register a per-session agent-event subscription (idempotent). */ setupSessionEventHandling: (sessionKey: string) => void; /** Per-session config hydration (workspace + model override) before a turn runs. */ sessionHydrator: SessionHydrator; /** Returns the visible last assistant text used for outbound + persistent-goal hook. */ getLastAssistantPlainText: (sessionKey: string) => string; /** Pre-turn auto-compaction (only used by system messages). */ /** Fire-and-forget auto-title (no-ops for cron/heartbeat keys). */ enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void; /** Effective merged config snapshot. */ getConfig: () => Config | undefined; /** Archive transcript + new session id (freshness / reset trigger rollover). */ resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string; } | null>; /** Connect a channel stream handle for partial assistant text rendering. */ setStreamHandle: (handle: StreamHandle) => void; } export declare class InboundLoop { private readonly cfg; private readonly log; private running; private channelManagerRef; constructor(cfg: InboundLoopConfig); setChannelManager(channelManager: ChannelManager | null): void; isRunning(): boolean; /** Begin consuming inbound messages from the bus until {@link stop} or shutdown. */ start(): Promise; /** Cooperatively stop the loop; the current message (if any) is allowed to finish. */ stop(): void; private handleInboundMessage; private handleSystemMessage; }