export interface SessionGroupEntry { /** The DM user this group was born for (open_id in the bot's app scope). */ ownerOpenId: string; /** Most recent session anchored in this group; same-group resume target. */ lastSessionId: string; /** Epoch ms the group was created. */ createdAt: number; /** Epoch ms of the last observed activity (birth, resume, new session). */ lastActiveAt: number; /** * Provenance of the authorization that birthed this group — the DM-side * `evaluateTalk` verdict, captured at birth. * * A session group is minted for ONE user off ONE authorization, so every * later message in it must keep charging that SAME authorization instead of * being re-judged against the brand-new chat id (which no chatGrant, no * quota counter and no expiry has ever seen). Without this, the auto-written * oncall binding — created only to carry the working dir — became the group's * talk source: unlimited when no `messageQuota.defaultLimit` is configured, * a FRESH per-group allowance when one is, and `restrictGrantCommands` * silently defeated because the reason was no longer `chatGrant`/`globalGrant`. * * Typed as a plain string (not `TalkReason`) on purpose: importing the type * from `im/lark/event-dispatcher` would close an import cycle, since the * dispatcher reads this registry. */ originReason?: string; /** quotaKey of that authorization; absent = the source carried no quota. */ originQuotaKey?: string; /** Chat the source authorization lives on (the DM). Revoke / expiry cleanup * must target it — the session group itself holds no grant record. */ originChatId?: string; /** True once the async AI title has been applied to the chat name. */ titled?: boolean; /** Failed scheduling rounds (each round contains the service's bounded * in-call retry). Persisted so later messages cannot spawn unbounded CLIs. */ titleAttempts?: number; /** Earliest epoch-ms at which another healing round may start. */ titleRetryAt?: number; } export declare function initSessionGroups(appId: string): void; /** Register a freshly-born session group (or overwrite after a re-birth). */ export declare function registerSessionGroup(chatId: string, entry: Omit & { createdAt?: number; }): void; /** Typing check — the ONLY sanctioned way to tell a session group apart. */ export declare function isSessionGroup(chatId: string): boolean; export declare function getSessionGroup(chatId: string): SessionGroupEntry | undefined; /** Point the registry at the session currently living in this group. */ export declare function touchSessionGroup(chatId: string, lastSessionId?: string): void; /** Mark the async AI title as applied (idempotent). */ export declare function markSessionGroupTitled(chatId: string): void; /** Record a failed title round and its next backoff boundary. */ export declare function markSessionGroupTitleFailed(chatId: string, failedAt?: number): SessionGroupEntry | undefined; /** Remove a registry entry (group disbanded / bot removed / gc). */ export declare function removeSessionGroup(chatId: string): void; export declare function listSessionGroups(): Array<{ chatId: string; } & SessionGroupEntry>; //# sourceMappingURL=session-groups-store.d.ts.map