export type IdentityType = 'user' | 'bot' | 'app' | 'unknown';
export interface IdentityRecord {
    openId: string;
    type: IdentityType;
    name?: string;
    source: 'sender' | 'mention' | 'contact_api' | 'bot_cross_ref' | 'bot_info';
    updatedAt: number;
}
/** Best-effort flush on shutdown — pairs with the debounce above. */
export declare function flushIdentityCacheSync(): void;
/**
 * Merge a partial identity record into the cache. Existing `name` is preserved
 * unless the incoming record carries a real name (no clobbering). Existing
 * `type` is only overridden when the incoming value is more specific
 * (anything other than `unknown`).
 */
export declare function recordIdentity(larkAppId: string, rec: {
    openId: string;
    type?: IdentityType;
    name?: string;
    source?: IdentityRecord['source'];
}): void;
/**
 * Learn (open_id, name) pairs from a parsed message's mentions. Free path —
 * no API call. Mentions don't carry sender_type, so we leave `type` as
 * `unknown` and let a subsequent sender event (or bot cross-ref lookup) tighten
 * it.
 */
export declare function learnFromMentions(larkAppId: string, mentions?: Array<{
    name: string;
    openId?: string;
}>): void;
export declare function getIdentity(larkAppId: string, openId: string): IdentityRecord | undefined;
/**
 * Best-effort name resolution. Returns the cached name on hit; on miss for a
 * user open_id, calls `contact.v3.user.get` with a budget and updates the
 * cache. Bots/apps skip the API (no public contact endpoint). Failures
 * (permission denied, network, timeout) degrade silently to `undefined`.
 *
 * When the bot lacks `contact:user.base:readonly`, the first 99991672 from
 * the API trips a per-app circuit breaker so subsequent calls short-circuit
 * without burning quota.
 */
export declare function resolveName(larkAppId: string, openId: string): Promise<string | undefined>;
export interface ResolvedSender {
    openId: string;
    type: 'user' | 'bot';
    name?: string;
}
/**
 * Resolve sender identity for prompt injection.
 *
 * Inputs are taken directly from the Lark event (`sender_id.open_id`,
 * `sender_type` ∈ {user, app, bot}). We normalize Lark's `app`/`bot` to our
 * prompt vocabulary (`bot`), record the sender event in the cache for future
 * lookups, and best-effort resolve the display name. Caller-supplied hints
 * (e.g. a known foreign-bot display name from `bot-openids-${appId}.json`)
 * win over cache.
 */
export declare function resolveSender(larkAppId: string, openId: string | undefined, senderType: string | undefined, hint?: {
    name?: string;
    type?: 'user' | 'bot';
}): Promise<ResolvedSender | undefined>;
//# sourceMappingURL=identity-cache.d.ts.map