import { SqliteConnection } from "./connection.js"; import { SessionScope } from "@graphorin/core"; //#region src/consolidator-store.d.ts /** * Persisted state row mirrored byte-for-byte by * `@graphorin/memory`'s `ConsolidatorStateRow`. * * @stable */ interface ConsolidatorStateRow { readonly scope: SessionScope; readonly lastProcessedMessageId: string | null; readonly lastPhase: 'light' | 'standard' | 'deep' | null; readonly lastCompletedAt: number | null; readonly nextEligibleAt: number | null; readonly activeLockHeldBy: string | null; readonly activeLockAcquiredAt: number | null; /** * `ended_at` (epoch ms) of the newest episode the deep-phase reflection * pass has already reflected on. A later pass accumulates * importance only from strictly-newer episodes; `null` ⇒ nothing reflected * yet. */ readonly reflectionWatermark: number | null; } /** @stable */ interface ConsolidatorStatePatch { readonly lastProcessedMessageId?: string | null; readonly lastPhase?: 'light' | 'standard' | 'deep' | null; readonly lastCompletedAt?: number | null; readonly nextEligibleAt?: number | null; readonly activeLockHeldBy?: string | null; readonly activeLockAcquiredAt?: number | null; readonly reflectionWatermark?: number | null; } /** @stable */ interface ConsolidatorRunInput { readonly id: string; readonly scope: SessionScope; readonly triggerKind: 'turn' | 'idle' | 'cron' | 'event' | 'budget' | 'buffer' | 'manual'; readonly phase: 'light' | 'standard' | 'deep'; readonly startedAt: number; } /** @stable */ interface ConsolidatorRunFinish { readonly id: string; readonly finishedAt: number; readonly status: 'completed' | 'failed' | 'deferred' | 'partial'; readonly llmTokensUsed?: number; readonly llmCostUsd?: number | null; readonly factsCreated?: number; readonly factsUpdated?: number; readonly conflictsResolved?: number; readonly noiseFilteredCount?: number; readonly emptyExtractions?: number; /** Episodes auto-formed by the run. */ readonly episodesFormed?: number; /** Insights synthesized by the run's reflection pass. */ readonly insightsCreated?: number; readonly errorMessage?: string | null; readonly retryCount?: number; } /** @stable */ interface DlqBatchInput { readonly id: string; readonly consolidatorRunId: string | null; readonly scope: SessionScope; readonly messageIds: ReadonlyArray; readonly errorKind: string; readonly errorMessage: string; readonly failedAt: number; readonly nextRetryAt: number; readonly retryCount: number; /** Phase that failed; `null`/absent ⇒ legacy 'standard' replay. */ readonly phase?: 'light' | 'standard' | 'deep' | null; } /** @stable */ interface DlqBatchRow { readonly id: string; readonly consolidatorRunId: string | null; readonly scope: SessionScope; readonly messageIds: ReadonlyArray; readonly errorKind: string; readonly errorMessage: string; readonly failedAt: number; readonly nextRetryAt: number | null; readonly retryCount: number; /** Phase that failed; `null` ⇒ legacy row. */ readonly phase?: 'light' | 'standard' | 'deep' | null; } /** * SQLite-backed consolidator state store. Constructed by * {@link SqliteMemoryStore}; never instantiated directly by * application code. * * @stable */ declare class SqliteConsolidatorStateStore { #private; constructor(conn: SqliteConnection); getState(scope: SessionScope): Promise; upsertState(scope: SessionScope, patch: ConsolidatorStatePatch): Promise; acquireLock(scope: SessionScope, runId: string, now: number, maxAgeMs: number): Promise; releaseLock(scope: SessionScope, runId: string): Promise; recordRunStart(input: ConsolidatorRunInput): Promise; recordRunFinish(finish: ConsolidatorRunFinish): Promise; listRecentRuns(scope: SessionScope, limit?: number): Promise>; enqueueFailedBatch(input: DlqBatchInput): Promise; /** * Despite the name, this is a plain SELECT of due DLQ batches * WITHOUT any lease/claim semantics - two concurrent callers see the * same rows. Serializing concurrent drains is the CALLER's job via * the consolidator scope lock (the runtime always drains under * it); the worst case of a bypassed lock is duplicated LLM replay * spend, not corruption. The name is kept because the method sits on * the stable contract surface - renaming would be a breaking change * with no behavioural gain. */ claimReadyBatches(scope: SessionScope, now: number, limit?: number): Promise>; markBatchSucceeded(id: string): Promise; rescheduleBatch(id: string, retryCount: number, nextRetryAt: number): Promise; markBatchExhausted(id: string, errorMessage: string, retryCount?: number): Promise; /** * Retention for the per-tick run log. Deletes terminal runs * that started before the cutoff; in-flight rows * (`status = 'running'`) always survive. Returns rows deleted. * * @stable */ pruneRuns(beforeEpochMs: number): Promise; /** * Retention for the dead-letter queue. Deletes only EXHAUSTED * batches (`next_retry_at IS NULL` - parked forever by * `markBatchExhausted`) that failed before the cutoff; batches still * awaiting a retry are never touched (they belong to * `claimReadyBatches`). Returns rows deleted. * * @stable */ pruneExhaustedBatches(beforeEpochMs: number): Promise; listFailedBatches(scope: SessionScope, limit?: number): Promise>; } //#endregion export { ConsolidatorRunFinish, ConsolidatorRunInput, ConsolidatorStatePatch, ConsolidatorStateRow, DlqBatchInput, DlqBatchRow, SqliteConsolidatorStateStore }; //# sourceMappingURL=consolidator-store.d.ts.map