export type ObservedBotSource = 'introduce';
export interface ObservedBot {
    openId: string;
    name: string;
    source: ObservedBotSource;
    firstSeenAt: number;
    lastSeenAt: number;
}
/**
 * Merge a batch of (openId, name) pairs into the observer's per-chat file.
 *
 * - Existing openIds: keep firstSeenAt, bump lastSeenAt, refresh name.
 * - New openIds: firstSeenAt = lastSeenAt = now.
 * - Entries with empty openId or empty name are silently skipped — callers
 *   pass through whatever Lark gave them, and we never want a half-known
 *   entry polluting the store.
 * - Empty input or all-filtered input is a no-op (no file write).
 *
 * `larkAppId` is the OBSERVING daemon's app id (i.e. whose perspective these
 * open_ids represent). Pass the receiving bot's `larkAppId`, not the sender's.
 */
export declare function recordObservedBots(dataDir: string, larkAppId: string, chatId: string, bots: ReadonlyArray<{
    openId: string;
    name: string;
}>, source?: ObservedBotSource, now?: number): void;
/**
 * Return non-expired entries for the (observer, chat) pair. `maxAgeMs`
 * defaults to 30 days; pass a custom value (or `Infinity`) to override.
 * Order is unspecified — callers needing a deterministic order should sort
 * on their side.
 */
export declare function listObservedBots(dataDir: string, larkAppId: string, chatId: string, maxAgeMs?: number, now?: number): ObservedBot[];
//# sourceMappingURL=observed-bots-store.d.ts.map