/** * Message Router for unified messenger handling * * Routes messages from different platforms through a unified pipeline: * 1. Normalize message format * 2. Load/create session context * 3. Create AgentContext with role permissions * 4. Inject proactive context (related decisions) * 5. Call Agent Loop with context * 6. Update session context * 7. Return response */ import { SessionStore } from './session-store.js'; import { type MamaApiClient } from './context-injector.js'; import type { NormalizedMessage, MessageRouterConfig, Session, RelatedDecision, ContentBlock } from './types.js'; import type { AgentLoopOptions, StreamCallbacks } from '../agent/types.js'; import { type MemoryAuditAckLike } from '../memory/audit-task-queue.js'; import { EnvelopeAuthority } from '../envelope/index.js'; import { type ReactiveEnvelopeConfig } from '../envelope/reactive-config.js'; export type { AgentLoopOptions } from '../agent/types.js'; export type { ReactiveEnvelopeConfig } from '../envelope/reactive-config.js'; /** * Agent Loop interface for message processing */ export interface AgentLoopClient { /** * Run the agent loop with a prompt */ run(prompt: string, options?: AgentLoopOptions): Promise<{ response: string; modelRunId?: string | null; }>; /** * Run the agent loop with multimodal content */ runWithContent?(content: ContentBlock[], options?: AgentLoopOptions): Promise<{ response: string; modelRunId?: string | null; }>; } export interface MemoryAgentProcessLike { sendMessage(content: string, options?: { sourceTurnId?: string; sourceMessageRef?: string; parentModelRunId?: string; }): Promise<{ response?: string; ack?: MemoryAuditAckLike; } | { response?: string; }>; } export interface MemoryAgentProcessManagerLike { getSharedProcess(agentId: 'memory'): Promise; } export interface GatewayRegistry { sendMessage(source: string, channelId: string, text: string): Promise; } /** * Message processing result */ export interface ProcessingResult { /** Response text from agent */ response: string; /** Session ID used */ sessionId: string; /** Related decisions that were injected */ injectedDecisions: RelatedDecision[]; /** Processing duration in milliseconds */ duration: number; } /** * Message Router class * * Central hub for processing messages from all messenger platforms. */ export declare class MessageRouter { private sessionStore; private contextInjector; private mamaApi; private agentLoop; private config; private envelopeConfig?; private envelopeAuthority?; private roleManager; private promptEnhancer; private cachedGatewayToolsPrompt; private gatewayRegistry; private memoryAgentProcessManager?; private memoryAuditQueue?; private memoryNoticeQueue; private memoryAuditCooldowns; private memoryAgentStats; private sessionsDb; setSessionsDb(db: import('../sqlite.js').default): void; private uiCommandQueue; setUICommandQueue(queue: import('../api/ui-command-handler.js').UICommandQueue): void; private validationService; setValidationService(svc: import('../validation/session-service.js').ValidationSessionService): void; private getPageContextPrefix; setGatewayRegistry(registry: GatewayRegistry): void; setMemoryAgent(processManager: MemoryAgentProcessManagerLike): void; getMemoryAgentStats(): { turnsObserved: number; candidatesDetected: number; factsExtracted: number; factsSaved: number; acksApplied: number; acksSkipped: number; acksFailed: number; lastExtraction: number | null; recentExtractions: Array<{ topic: string; timestamp: number; channelKey?: string; status: "applied" | "skipped" | "failed"; }>; }; /** * Public API for auditing a conversation via the memory agent. * Used by the /api/mama/audit-conversation endpoint for benchmarking. * Bypasses cooldown and candidate detection — caller provides conversation + optional candidates. */ auditConversation(job: { conversation: string; scopes: Array<{ kind: string; id: string; }>; candidates?: Array<{ kind: string; topicHint?: string; confidence: number; summary: string; }>; }): Promise; constructor(sessionStore: SessionStore, agentLoop: AgentLoopClient, mamaApi: MamaApiClient, config?: MessageRouterConfig, envelopeConfig?: ReactiveEnvelopeConfig, envelopeAuthority?: EnvelopeAuthority); private buildReactiveEnvelope; /** * Create AgentContext for a message * Determines role based on message source and builds context */ private createAgentContext; /** * Check if message should trigger auto-translation * Returns true for short messages or image-related text */ private shouldAutoTranslate; /** * Process a normalized message and return response * @param message - The normalized message to process * @param processOptions - Optional callbacks for async notifications * @param processOptions.onQueued - Called immediately if session is busy (message queued) */ process(message: NormalizedMessage, processOptions?: { onQueued?: () => void; onStream?: StreamCallbacks; }): Promise; /** * Build system prompt with session context, injected decisions, and AgentContext * Note: With --no-session-persistence mode, history is ALWAYS injected * because CLI doesn't persist sessions between calls. */ private buildSystemPrompt; /** * Build minimal prompt for resumed CLI sessions. * CLI already has full system prompt from initial request. * Only inject per-message context (related decisions) to avoid context overflow. */ private buildMinimalResumePrompt; /** * Post-process agent response: detect image file paths and copy to outbound. * Rewrites paths to ~/.mama/workspace/media/outbound/filename so format.js renders them. */ private resolveMediaPaths; /** * List all sessions for a source */ listSessions(source: NormalizedMessage['source']): Session[]; /** * Get session for a channel */ getSession(source: NormalizedMessage['source'], channelId: string): Session | null; /** * Clear session context (start fresh conversation) */ clearSession(sessionId: string): boolean; /** * Delete a session entirely */ deleteSession(sessionId: string): boolean; /** * Update configuration */ setConfig(config: Partial): void; /** * Get current configuration */ getConfig(): Required; /** * Update channel name for a session (used to backfill channel names) */ updateChannelName(source: NormalizedMessage['source'], channelId: string, channelName: string): boolean; /** * Trigger memory agent to extract facts (fire-and-forget). * Uses AgentProcessManager persistent process. */ private static readonly EXTRACT_COOLDOWN_MS; private static readonly MIN_CONTENT_LENGTH; private static readonly MAX_CONTENT_LENGTH; private getRuntimeProjectId; private buildMemoryAuditPrompt; private classifyMemoryAuditResponse; private recordMemoryAuditAck; private getPerTurnMemoryPrefix; private triggerMemoryAgent; private resolveFrontdoorAgentId; private logFrontdoorActivity; private logAgentActivity; } /** * Create a mock agent loop for testing */ export declare function createMockAgentLoop(responseGenerator?: (prompt: string) => string): AgentLoopClient; //# sourceMappingURL=message-router.d.ts.map