import type { MemoryHistoryAppendRow } from "./memory-sync-store-pg.js"; import type { PgEmbedder } from "./pg-query.js"; import type { MemoryBackend, MemoryEntry, MemoryEntryHeader, NotePatch, PatchReport, ScoredMemoryEntry } from "@sema-agent/core"; import type { Pool } from "mysql2/promise"; /** Table names (single source) — SAME names as PG_MEMORY_ENGINE_TABLES (the two dialects never share * one database), deliberately DISJOINT from the legacy `agent_memory*` MemoryStore plane. */ export declare const TIDB_MEMORY_ENGINE_TABLES: { readonly entry: "agent_memory_engine_entry"; readonly cursor: "agent_memory_engine_cursor"; }; /** Idempotent DDL for the entry plane (TiDB dialect). Call once at startup. * Key lengths: utf8mb4 = 4 bytes/char and the default index-key cap is 3072 bytes, so the * (scope, slug) unique key budget is scope 190 + slug 512 = 702 chars ⇒ 2808 bytes ≤ 3072. */ export declare function ensureTiDBMemoryEngineSchema(pool: Pool): Promise; /** Options for {@link TiDBMemoryEngineBackend}. Signature-parity with the Pg twin, but v1 is * LEXICAL ONLY — there is no TiDB vector rung yet; passing an embedder is refused loudly * (no-stopgap: never silently ignore a caller's recall-quality expectation). */ export interface TiDBMemoryEngineBackendOptions { /** NOT SUPPORTED in v1 (lexical only) — present for signature parity; a value throws at construction. */ embedder?: PgEmbedder; /** Clock injection (file-backend precedent) — drives `mtime_ms`. Default `Date.now`. */ now?: () => number; /** 142-S5.1 history write point — OPTIONAL audit sink, one history row per APPLIED patch, appended * AFTER the entry write. Absent → byte-equal legacy behavior (additive). 同事务诚实记档(Pg 版同注, * posture 对称保持):this backend does hold a Pool (a getConnection+txn wrap IS possible), but the * entry plane itself is deliberately NON-transactional (single-statement CAS is the correctness * mechanism), and the Pg twin's bare-PgQueryFn seam cannot cheaply transact — wrapping only the * TiDB side would fork the twins' semantics. Chosen trade-off on BOTH dialects: entry write commits * first, history append is BEST-EFFORT (failure = swallow + console.warn) — history is the AUDIT * face, not the correctness face: a lost history row loses an audit line, never data. */ history?: { appendHistory(rows: readonly MemoryHistoryAppendRow[]): Promise; }; } export declare class TiDBMemoryEngineBackend implements MemoryBackend { private readonly pool; private readonly clock; private readonly history?; /** Cumulative lost-row count — audit-line breakage must itself be auditable. */ private historyRowsLost; /** [ref] rung indicator — TiDB v1 sits on the lexical floor (Pg twin parity surface). */ get vectorMode(): "lexical"; constructor(pool: Pool, opts?: TiDBMemoryEngineBackendOptions); private selectRows; private write; /** The search haystack — BYTE-EQUAL to the File/Pg backends' lexical haystack (contract equivalence). */ private haystackOf; private headerFromRow; private entryFromRow; listHeaders(scopes: readonly string[]): Promise; getByIds(ids: readonly string[]): Promise; search(query: string, scopes: readonly string[], opts?: { limit?: number; exposureBands?: boolean; }): Promise; applyPatches(patches: readonly NotePatch[]): Promise; private applyOne; /** The row's rev NOW, or undefined if the row is gone. The existence distinction is the whole point * (codex lens-3): a concurrent delete must not be mistaken for an idempotent already-at-target write. */ private freshRevOrMissing; /** When the conditional write reports zero rows (a write landed inside the SELECT→write window), the * report's `currentRev` must be the rev NOW — re-reporting the pre-race SELECT value could claim * `baseRev === currentRev` alongside a "rev mismatch" reason. Row gone ⇒ fallback (Pg parity). */ private freshRev; getConsolidationCursor(scope: string): Promise; setConsolidationCursor(scope: string, cursor: string): Promise; } //# sourceMappingURL=memory-engine-tidb.d.ts.map