import type { ChannelId } from "./channels.js"; /** A real conversation the agent has handled, recovered from run artifacts. */ export interface SeenConversation { /** The base (de-bucketed) conversationId to use as a `notify` destination. */ readonly conversationId: string; readonly channelId: ChannelId; /** ISO timestamp of the most recent run on this conversation, if recorded. */ readonly lastSeen?: string; } export interface ListSeenOptions { /** Cap on the number of (newest-first) summary files read. Default 2000. */ readonly limit?: number; } export interface SeenNotifyDestinationCache { /** List destinations, sharing one fresh scan for repeated reads of the same directory. */ list(artifactDir: string): Promise; /** Fence any cached or in-flight result after a relevant artifact change. */ invalidate(): void; } interface SeenNotifyDestinationCacheOptions { readonly ttlMs?: number; readonly now?: () => number; /** Test seam for deterministic scan/race coverage. */ readonly scan?: (artifactDir: string) => Promise; } /** * App-lifetime, one-directory cache for {@link listSeenNotifyDestinations}. * * The cache retains at most one completed value. Concurrent readers of the same * directory and generation share one scan; different directories may scan in * parallel while their transient map entries are removed on settlement. At * most two generations scan one directory concurrently, so repeated * invalidations cannot multiply the scanner's bounded stat batch without bound. * Invalidation is a generation fence: callers whose scan crossed a relevant * artifact change retry the current generation, while a stale scan can neither * populate the cache nor clear a newer generation's in-flight scan. */ export declare function createSeenNotifyDestinationCache(options?: SeenNotifyDestinationCacheOptions): SeenNotifyDestinationCache; /** * Distinct Telegram/Slack conversationIds the agent has actually handled, read * from the run-artifact summaries in `artifactDir`. Other schemes (including * synthetic `cron:`/`webhook:` ids and WhatsApp) are dropped; daily-rollover * buckets are stripped to the base id (the form a `notify` destination uses) and * deduped to the most recent sighting. Sorted newest-first. A missing dir yields * an empty list. */ export declare function listSeenNotifyDestinations(artifactDir: string, options?: ListSeenOptions): Promise; export {}; //# sourceMappingURL=seen-conversations.d.ts.map