/** * Pure four-state resolution for `GET /api/sessions/:id/trigger-result` * (async dispatch design A). Kept free of daemon/registry imports so it can be * unit-tested directly; dashboard-ipc-server gathers the three inputs (live * session, on-disk session record, persisted async result) and calls this. * * State contract (see docs/developer/platform/botmux-async-dispatch-design.md): * - completed: final output captured (mem OR durable) → output.content + finishedAt * - running: live session in flight, or a session record still open * - failed: session record closed with no captured output (no_output; soft * terminal — may be a genuine failure OR a caller-initiated close) * - not_found: no session record anywhere (never existed / invalid id) * * Restart guarantee: as long as EITHER a session record OR a persisted result * exists, this never returns not_found — an already-completed turn resolves to * completed even after the in-memory Map is gone. */ import type { TriggerResponse } from './trigger-types.js'; /** Fail-closed / positive-proof cross-bot ownership gate for trigger-result. * * sessionStore.getSession() scans EVERY bot's sessions-*.json and the async * store is a machine-wide shared directory, so a request routed to daemon A * carrying a sessionId owned by bot B could read B's record / persisted output. * This decides which of the two shared-store sources daemon `owner` may trust. * * A source is kept ONLY with POSITIVE proof of ownership — "not known-foreign" * is deliberately insufficient, so a legacy unstamped persisted file with no * owned session (unprovable owner) is dropped rather than leaked. * * - live ds: always ours (in THIS daemon's registry) → caller passes liveDs. * - stored: keep iff there's a live ds OR its larkAppId == owner. * - persisted: keep iff stamped with owner, OR (unstamped legacy) corroborated * by an owned session context for the same id. * * Returns which sources survive, plus `foreignLeak` = raw data existed but none * of it is attributable to us (→ caller returns a clean not_found miss). */ export interface OwnershipInputs { owner: string; liveDs: boolean; storedOwner?: string; storedExists: boolean; persistedOwner?: string; persistedExists: boolean; } export interface OwnershipDecision { keepStored: boolean; keepPersisted: boolean; foreignLeak: boolean; } export declare function decideAsyncOwnership(inp: OwnershipInputs): OwnershipDecision; export interface TurnUsageBuckets { inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheCreateTokens: number; } export interface AsyncStateInputs { sessionId: string; /** Whether a live DaemonSession is currently registered for this id. */ liveActive: boolean; /** chatId from the live session or the stored record, if known. */ chatId?: string; /** In-memory async result for the resolved trigger, if the session is live. */ memResult?: { status: 'pending' | 'completed' | 'failed'; content?: string; completedAt?: number; failedAt?: number; errorCode?: 'trigger_failed'; terminalErrorCode?: string; usage?: TurnUsageBuckets; }; /** triggerId the in-memory result is keyed under (latest or explicit). */ memTriggerId?: string; /** Durable persisted result (survives restart), if any. */ persisted?: { triggerId: string; result: { status: 'pending' | 'completed' | 'failed'; content?: string; completedAt?: number; usage?: TurnUsageBuckets; /** Present when status==='failed' — the authoritative dispatch outcome * (e.g. `dispatch_unknown` for an at-most-once ambiguous crash). */ failedAt?: number; errorCode?: 'no_output' | 'trigger_failed'; reason?: 'dispatch_unknown' | 'turn_terminal'; terminalErrorCode?: string; }; }; /** On-disk session record status: 'open' (active), 'closed', or absent. */ storedStatus?: 'open' | 'closed'; /** closedAt ISO string from the stored record, for failed/finishedAt. */ closedAt?: string; /** triggerId from the request query, if the caller pinned one. */ requestedTriggerId?: string; } export declare function resolveAsyncTriggerState(inp: AsyncStateInputs): TriggerResponse; //# sourceMappingURL=async-trigger-state.d.ts.map