import type { MessageBus } from '../infra/bus/index.js'; import { type Config } from '../config/schema.js'; import type { ChannelManager } from '../channels/manager.js'; import { SessionStore } from '../session/index.js'; import { OutboundCoordinator } from './messaging/index.js'; import { TurnDispatcher } from './inbound/turn-dispatcher.js'; import { SessionConfigService, SessionHydrator, SessionInspector } from './session/index.js'; import { type AgentSkillAvailabilityPayload, type SkillCatalogEntry, type SkillCatalogSnapshot } from './agent-manager.js'; import type { SkillMarkdownPreviewPayload } from './skills/types.js'; import type { AgentCapabilityCatalogEntry } from './capabilities/index.js'; import type { AgentServiceConfig, StreamHandle } from './service.types.js'; import { TaskJudgeService } from './tasks/task-judge-service.js'; import type { SkillInstallToolOptions, SkillInstallToolResult, MarketplaceSkillInstallToolOptions, MarketplaceSkillInstallToolResult } from './tools/skill-install-tool.js'; import { type InboundAttachmentInput, type MediaRef } from '../channels/attachments/inbound-persist.js'; export type { AgentServiceConfig, AgentContext, StreamHandle } from './service.types.js'; export declare class AgentService { /** * Persistent transcript + session-metadata store. Public so the gateway/TUI * can read sessions, delete them, etc. without forcing every CRUD-style * operation through a delegation method on `AgentService`. */ readonly sessionStore: SessionStore; private sessionConfigStore; private hookRunner?; private agentId; private workspaceDir; private config; private sessionTracker; private modelManager; private hookHandler; private lifecycleManager; private errorTracker; private requestLimiter; private systemReminder; private toolUsageAnalyzer; private toolChainTracker; private errorPatternMatcher; private selfVerifyMiddleware; private turnDiffTracker; private contextMiddleware; private messageRouter; private commandHandler; private streamManager; /** * Outbound pipeline: typing controller, silence guard, final response publish, * extension `message_sending`/`message_sent` hooks, post-turn `webchat_turn_complete` * event. Public so the gateway / channels can drive it directly. */ readonly outboundCoordinator: OutboundCoordinator; private inboundLoop; /** * Direct-turn entry points: `processDirect` (one-shot), `processDirectStreaming` * (event generator), webchat steering and live event injection. Public so the gateway, * TUI, CLI, and automations do not need to thread every call through `AgentService`. */ readonly turnDispatcher: TurnDispatcher; /** Independent acceptance review for the active Task after an agent turn. */ readonly taskJudge: TaskJudgeService; /** * Per-session config writes (model / thinking / reasoning / working directory). * Public so REST endpoints and CLI flows can hit it without going through a * monolithic patch entrypoint on `AgentService`. */ readonly sessionConfig: SessionConfigService; /** * Hydration — read persisted per-session config and apply it to the runtime * (AgentManager / ModelManager). The mirror image of `sessionConfig`: writes * go through `sessionConfig`, reads-into-runtime go through `sessionHydrator`. */ readonly sessionHydrator: SessionHydrator; /** * Read-only introspection (compaction, /context report, /btw, contextUsage, * agentConfig view). Public so REST endpoints and CLI flows can query a * session's view without going through delegating methods on `AgentService`. */ readonly sessionInspector: SessionInspector; private sessionContextManager; private sessionLifecycleManager; private agentOrchestrator; private agentEventHandler; private workflowProgressBrokerHandle; private agentManager; /** * Unified per-session state container (replaces six ad-hoc Maps). Owns webchat * publishers, last assistant text, embedded stream buffer, Task review stream * tasks, concurrent-turn depth, and event-listener unsubscribers; runs a TTL * sweep for slots that have no explicit owner. */ private sessionState; /** Gateway: notify UI after direct `SessionStore.updateMetadata` (no SessionManager emit). */ private onSessionMetadataUpdated?; private onSessionTranscriptUpdated?; private effectiveAppConfig; constructor(bus: MessageBus, config: AgentServiceConfig); private createSessionStore; private createHookRunner; private initializeReliabilityModules; setChannelManager(channelManager: ChannelManager): void; /** * Apply config after save or hot reload so the default model updates without restarting the gateway. */ applyAgentDefaultsFromConfig(config: Config): void; getSkillCatalog(): SkillCatalogEntry[]; getSkillCatalogSnapshot(): SkillCatalogSnapshot; getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload; getCapabilityCatalog(sessionKey?: string): AgentCapabilityCatalogEntry[]; getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null; refreshSkillsAfterDiskChange(): void; refreshSkillsAfterTrustChange(): void; installSkillFromSource(opts: SkillInstallToolOptions): Promise; installSkillFromMarketplace(opts: MarketplaceSkillInstallToolOptions): Promise; refreshSkillsAfterSkillConfigChange(): void; refreshActionTrustPolicy(): void; refreshUserProfileContext(): void; getMemoryManager(): import("./memory/manager.js").MemoryManager; getModelForSession(sessionKey: string): string; switchModelForSession(sessionKey: string, modelId: string): Promise; /** * Clears per-session model override so the next turn uses the configured agent default * (e.g. cron isolated job with no explicit model). */ resetSessionModelToAgentDefault(sessionKey: string): Promise; setStreamHandle(handle: StreamHandle): void; clearStreamHandle(): void; /** Last assistant visible plain text for a session (e.g. after a webchat stream). */ getLastAssistantPlainText(sessionKey: string): string; beginInboundTurn(sessionKey: string): void; endInboundTurn(sessionKey: string): void; getInboundTurnDepth(sessionKey: string): number; takeTaskReviewStreamHint(sessionKey: string): import("./session/session-state-bag.js").TaskReviewStreamHint; start(): Promise; stop(): Promise; /** * Persist agent messages with the same sanitizer + transcript hygiene as AgentOrchestrator. * Uses persistence hygiene so `thinking` blocks remain on disk for the web UI (LLM load path still drops them). */ private notifySessionTitleUpdated; /** Fire-and-forget provisional title from first user text (webchat sidebar). */ enqueueProvisionalSessionTitle(sessionKey: string, userText: string): void; /** * Fire-and-forget LLM refine after turn persist; skips user-locked and finalized LLM titles. */ private enqueueMaybeAutoTitleAfterPersist; private resolveSessionEndpoint; private initSessionContext; /** * Persist inbound file attachments to the global media store. */ prepareInboundAttachments(_sessionKey: string, attachments?: InboundAttachmentInput[]): Promise; private endDirectRequestContext; /** * Reset a session's transcript and drop the in-memory agent so the next turn * reloads from disk. Combines two collaborators (sessionStore + agentManager) * so it stays on `AgentService`; pure sessionStore reads should use * `agentService.sessionStore.*` directly. */ clearSessionMessages(key: string): Promise; /** * Reset session transcript (archive + new session id) and evict in-memory agent state. * Preserves the session key and persisted per-session overrides. */ resetSession(key: string): Promise<{ sessionId: string; previousSessionId: string; } | null>; /** * Drop in-memory agent so the next turn reloads transcript from disk (e.g. after checkpoint restore). */ evictSessionAgent(sessionKey: string): void; /** * Load session working directory override into AgentManager, ensure directory exists. * Call before AgentManager.getOrCreateAgent for this session. */ /** Workspace root for UI file tree / editor (same as agent tools after hydration). */ getEffectiveWorkspacePathForSession(sessionKey: string): Promise; /** * Best-effort timezone resolution for webchat envelope timestamps. * Reads the structured global user profile. */ resolveUserTimezoneForSession(sessionKey: string): string | undefined; /** * Setup event handling for a specific session */ private setupSessionEventHandling; /** * Handle events from a specific session's agent */ private handleSessionEvent; private getContextWindowForSession; private dispose; }