/** * AgentSession interface - the contract for agent communication. * * Consumers (cron, heartbeat, polling, API server) depend on this interface, * not the concrete LettaBot class. This enables multi-agent orchestration * via LettaGateway without changing consumer code. */ import type { ChannelAdapter } from '../channels/types.js'; import type { InboundMessage, TriggerContext } from './types.js'; import type { GroupBatcher } from './group-batcher.js'; import type { StreamMsg } from './types.js'; export interface AgentSession { /** Register a channel adapter */ registerChannel(adapter: ChannelAdapter): void; /** Configure group message batching */ setGroupBatcher(batcher: GroupBatcher, intervals: Map, instantGroupIds?: Set, listeningGroupIds?: Set): void; /** Process a batched group message */ processGroupBatch(msg: InboundMessage, adapter: ChannelAdapter): void; /** Start all registered channels */ start(): Promise; /** Stop all channels */ stop(): Promise; /** Send a message to the agent (used by cron, heartbeat, polling) */ sendToAgent(text: string, context?: TriggerContext): Promise; /** Stream a message to the agent, yielding chunks as they arrive */ streamToAgent(text: string, context?: TriggerContext): AsyncGenerator; /** Deliver a message/file to a specific channel */ deliverToChannel(channelId: string, chatId: string, options: { text?: string; filePath?: string; kind?: 'image' | 'file' | 'audio'; }): Promise; /** Get agent status */ getStatus(): { agentId: string | null; conversationId: string | null; channels: string[] }; /** Set agent ID (for container deploys) */ setAgentId(agentId: string): void; /** Reset agent state */ reset(): void; /** Get the last message target (for heartbeat delivery) */ getLastMessageTarget(): { channel: string; chatId: string } | null; /** Get the time of the last user message (for heartbeat skip logic) */ getLastUserMessageTime(): Date | null; /** Callback to trigger heartbeat */ onTriggerHeartbeat?: () => Promise; /** Invalidate a cached session, forcing fresh session on next message */ invalidateSession(key?: string): void; /** Callback for session invalidation requests (e.g., from !new command) */ onInvalidateSession?: (key?: string) => void; } /** * Minimal interface for message delivery. * Satisfied by both AgentSession and LettaGateway. */ export interface MessageDeliverer { deliverToChannel(channelId: string, chatId: string, options: { text?: string; filePath?: string; kind?: 'image' | 'file' | 'audio'; }): Promise; } /** * Extended interface for the API server. * Supports both outbound delivery (to channels) and inbound chat (to agents). * Satisfied by LettaGateway. */ export interface AgentRouter extends MessageDeliverer { /** Send a message to a named agent and return the response text */ sendToAgent(agentName: string | undefined, text: string, context?: TriggerContext): Promise; /** Stream a message to a named agent, yielding chunks as they arrive */ streamToAgent(agentName: string | undefined, text: string, context?: TriggerContext): AsyncGenerator; /** Get all registered agent names */ getAgentNames(): string[]; }