/** * Memory Bridge — Routes CLI memory operations through ControllerRegistry + AgentDB v3 * * Per ADR-053 Phases 1-6: Full controller activation pipeline. * CLI → ControllerRegistry → AgentDB v3 controllers. * * Phase 1: Core CRUD + embeddings + HNSW + controller access (complete) * Phase 2: BM25 hybrid search, TieredCache read/write, MutationGuard validation * Phase 3: ReasoningBank pattern store, recordFeedback, CausalMemoryGraph edges * Phase 4: SkillLibrary promotion, ExplainableRecall provenance, AttestationLog * Phase 5: ReflexionMemory session lifecycle, WitnessChain attestation * Phase 6: AgentDB MCP tools (separate file), COW branching * * Uses better-sqlite3 API (synchronous .all()/.get()/.run()) since that's * what AgentDB v3 uses internally. * * @module v3/cli/memory-bridge */ /** * #3024: AgentDB's optional native controller stack can abort the whole Node * process on Windows during registry initialization (a Rust allocation panic), * which cannot be caught by JavaScript. Keep the CLI/MCP server on the * sql.js + local-embedding path there until the native dependency is proven * safe. Advanced users and CI can opt back in explicitly for diagnosis. */ export declare function shouldDisableNativeBridge(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): boolean; /** * Should this init-time log line be swallowed? * * A DEGRADATION notice never is. AgentDB logs "[AgentDB] better-sqlite3 not * available, using sql.js WASM" when it falls back to WASM, and both the * '[AgentDB]' and 'better-sqlite3' entries above match it — so the one line * explaining why the native driver was not in use was being discarded as * noise. Suppress the banners, keep the bad news. */ export declare function shouldSuppressInitLog(msg: string): boolean; /** * Create/migrate the bridge's `memory_entries` table on `db`. * * Returns true when the schema is known-good, false when the database was not * writable (caller then leaves it un-ensured so a later writable call retries). * * Exported so the ADR-323 column migration can be tested directly: the bug it * fixes was invisible end-to-end, because the resulting error was swallowed and * reported as an unrelated WAL-sidecar refusal. */ export declare function ensureBridgeSchema(db: { exec: (sql: string) => unknown; }): boolean; /** * Store an entry via AgentDB v3. * Phase 2-5: Routes through MutationGuard → TieredCache → DB → AttestationLog. * Returns null to signal fallback to sql.js. */ export declare function bridgeStoreEntry(options: { key: string; value: string; namespace?: string; generateEmbeddingFlag?: boolean; tags?: string[]; ttl?: number; dbPath?: string; upsert?: boolean; /** ADR-323: defaults to 'unknown' when omitted. */ provenanceType?: string; }): Promise<{ success: boolean; id: string; embedding?: { dimensions: number; model: string; }; rawEmbedding?: number[]; guarded?: boolean; cached?: boolean; attested?: boolean; error?: string; /** #2968: set when the post-write checkpoint failed in a way that * indicates this connection may not durably persist writes at all * (the sql.js fallback driver, engaged when better-sqlite3's native * binding is missing). The write above still ran and `success` is * still true — this is advisory, not a failure — but callers should * surface it instead of only printing an unconditional success message. */ persistWarning?: string; } | null>; /** * Search entries via AgentDB v3. * Phase 2: BM25 hybrid scoring replaces naive String.includes() keyword fallback. * Combines cosine similarity (semantic) with BM25 (lexical) via reciprocal rank fusion. */ export declare function bridgeSearchEntries(options: { query: string; namespace?: string; limit?: number; threshold?: number; dbPath?: string; /** ADR-323: restrict results to these provenance types. */ provenanceFilter?: string[]; }): Promise<{ success: boolean; results: { id: string; key: string; content: string; score: number; namespace: string; provenance?: string; /** ADR-323 — NOT the same as `provenance` above (that's the * ExplainableRecall score breakdown). This is the entry's * user_claim/agent_output/... provenance type. */ provenanceType?: string; }[]; searchTime: number; searchMethod?: string; error?: string; } | null>; /** * List entries via AgentDB v3. */ export declare function bridgeListEntries(options: { namespace?: string; limit?: number; offset?: number; dbPath?: string; /** #2073: When true, include the entry's full `content` string in each result. */ includeContent?: boolean; /** ADR-323: restrict rows to these provenance types. */ provenanceFilter?: string[]; }): Promise<{ success: boolean; entries: { id: string; key: string; namespace: string; size: number; accessCount: number; createdAt: string; updatedAt: string; hasEmbedding: boolean; /** #2073: Present when `includeContent: true` was requested. */ content?: string; provenanceType?: string; }[]; total: number; error?: string; } | null>; /** * Get a specific entry via AgentDB v3. * Phase 2: TieredCache consulted before DB hit. */ export declare function bridgeGetEntry(options: { key: string; namespace?: string; dbPath?: string; }): Promise<{ success: boolean; found: boolean; entry?: { id: string; key: string; namespace: string; content: string; accessCount: number; createdAt: string; updatedAt: string; hasEmbedding: boolean; tags: string[]; }; cacheHit?: boolean; error?: string; } | null>; /** * Delete an entry via AgentDB v3. * Phase 5: MutationGuard validation, cache invalidation, attestation logging. */ export declare function bridgeDeleteEntry(options: { key: string; namespace?: string; dbPath?: string; }): Promise<{ success: boolean; deleted: boolean; key: string; namespace: string; remainingEntries: number; guarded?: boolean; error?: string; } | null>; export declare function bridgePurgeNamespace(options: { namespace: string; dbPath?: string; }): Promise<{ success: boolean; deletedCount: number; remainingEntries: number; guarded?: boolean; error?: string; } | null>; /** * Generate embedding via AgentDB v3's embedder. * Returns null if bridge unavailable — caller falls back to own ONNX/hash. */ export declare function bridgeGenerateEmbedding(text: string, dbPath?: string): Promise<{ embedding: number[]; dimensions: number; model: string; backend?: 'onnx' | 'mock'; } | null>; /** * Load embedding model via AgentDB v3 (it loads on init). * Returns null if unavailable. */ export declare function bridgeLoadEmbeddingModel(dbPath?: string): Promise<{ success: boolean; dimensions: number; modelName: string; loadTime?: number; } | null>; /** * Get vector search status from AgentDB v3's SQLite-backed store. * Returns null if unavailable. * * #2922: previously named `bridgeGetHNSWStatus` and unconditionally returned * `available: true` whenever a DB connection succeeded — but the search this * status describes (`bridgeSearchBruteForceCosine`, below) is a full-table * SELECT + brute-force cosine scan, not an HNSW index lookup. Renamed and * given an explicit `algorithm` field so callers can't mistake "vector * search works" for "vector search is HNSW-accelerated". */ export declare function bridgeGetVectorSearchStatus(dbPath?: string): Promise<{ available: boolean; initialized: boolean; entryCount: number; dimensions: number; algorithm: 'brute-force-cosine'; } | null>; /** * Search AgentDB v3's embedder + SQLite entries via a full-table scan and * brute-force cosine similarity. NOT HNSW-accelerated — see #2922. Returns * null if unavailable. */ export declare function bridgeSearchBruteForceCosine(queryEmbedding: number[], options?: { k?: number; namespace?: string; threshold?: number; }, dbPath?: string): Promise | null>; /** * Add entry to the bridge's database with embedding. No HNSW index is built * or updated here — see #2922; the embedding is only stored for a later * brute-force scan. Returns null if unavailable. */ export declare function bridgeAddEmbedding(id: string, embedding: number[], entry: { id: string; key: string; namespace: string; content: string; }, dbPath?: string): Promise; /** * Get a named controller from AgentDB v3 via ControllerRegistry. * Returns null if unavailable. */ export declare function bridgeGetController(name: string, dbPath?: string): Promise; /** * Check if a controller is available. */ export declare function bridgeHasController(name: string, dbPath?: string): Promise; /** * List all controllers and their status. */ export declare function bridgeListControllers(dbPath?: string): Promise | null>; /** * Check if the AgentDB v3 bridge is available. */ export declare function isBridgeAvailable(dbPath?: string): Promise; /** * Get the ControllerRegistry instance (for advanced consumers). */ export declare function getControllerRegistry(dbPath?: string): Promise; /** * Why the bridge last declined a write, or null when it has not. * * Deliberately NOT gated on `bridgeAvailable === false`. A bridge that * initialised fine can still fail every write — a schema mismatch throws * per-operation while the registry stays healthy — and that case is exactly * the one worth reporting, since the caller then demotes to a fallback whose * error message describes something else entirely. * * Callers that surface a degraded-path error should include this so the * operator learns the cause instead of only the symptom. */ export declare function getBridgeFailureReason(): string | null; /** * Install a pre-initialized registry for deterministic bridge tests. * * The CLI test runner intentionally externalizes the optional * `@claude-flow/memory` package so an unbuilt workspace can still exercise * fallback paths. That also makes module-level mocking of ControllerRegistry * environment-dependent. This narrow seam keeps native SQL regression tests * independent of package build order without changing production startup. */ export declare function __setMemoryBridgeRegistryForTests(registry: any | null): void; /** * Shutdown the bridge and release resources. * * The cached state is cleared unconditionally. Previously the reset lived * inside `if (registryInstance)`, so it could not clear a FAILED init — the * one state that actually needs clearing, since `registryInstance` is null * precisely when init failed. A process that latched `bridgeAvailable = false` * therefore had no recovery path short of a restart. */ export declare function shutdownBridge(): Promise; /** * Store a pattern via ReasoningBank controller. * Falls back to raw SQL if ReasoningBank unavailable. */ export declare function bridgeStorePattern(options: { pattern: string; type: string; confidence: number; metadata?: Record; dbPath?: string; }): Promise<{ success: boolean; patternId: string; controller: string; } | null>; /** * Search patterns via ReasoningBank controller. */ export declare function bridgeSearchPatterns(options: { query: string; topK?: number; minConfidence?: number; dbPath?: string; }): Promise<{ results: Array<{ id: string; content: string; score: number; }>; controller: string; } | null>; /** * Record task feedback for learning via ReasoningBank or LearningSystem. * Wired into hooks_post-task handler. */ export declare function bridgeRecordFeedback(options: { taskId: string; /** Human-readable task text used as the semantic learning signal. */ task?: string; success: boolean; quality: number; agent?: string; duration?: number; patterns?: string[]; dbPath?: string; parentAgentId?: string; depth?: number; }): Promise<{ success: boolean; controller: string; updated: number; } | null>; /** * Record a causal edge between two entries (e.g., task → result). */ export declare function bridgeRecordCausalEdge(options: { sourceId: string; targetId: string; relation: string; weight?: number; dbPath?: string; }): Promise<{ success: boolean; controller: string; } | null>; /** * Delete a hierarchical-memory entry by key (#1784). * * Reality check: agentdb's HierarchicalMemory class doesn't expose a public * delete API today, so the real-backend path falls back to direct SQL on * the underlying SQLite tables (status flip to 'deleted' + AttestationLog * audit). The bridge-fallback path that bridgeHierarchicalStore uses when * HierarchicalMemory isn't loaded writes plain memory_entries rows that * `bridgeDeleteEntry` already handles. * * Returns { controller: 'native-unsupported' } when the real HM is loaded * and the SQL fallback can't reach its private tables — surfacing the * limitation honestly instead of silently returning success. */ export declare function bridgeDeleteHierarchical(options: { key: string; tier?: string; dbPath?: string; }): Promise<{ success: boolean; deleted: boolean; key: string; tier?: string; controller: string; guarded?: boolean; error?: string; } | null>; /** * Delete a causal edge between two memory entries (#1784). * * The bridge stores fallback edges in namespace='causal-edges' with key * '{sourceId}→{targetId}'. Those CAN be soft-deleted. The native graph-node * backend has no delete API (createNode/createEdge/createHyperedge only), * so an edge that landed in graph-node native storage stays there. We * surface that explicitly via controller: 'native-unsupported'. */ export declare function bridgeDeleteCausalEdge(options: { sourceId: string; targetId: string; relation?: string; dbPath?: string; }): Promise<{ success: boolean; deleted: boolean; sourceId: string; targetId: string; controller: string; guarded?: boolean; error?: string; } | null>; /** * Cascade-delete a causal node and all its incident edges (#1784). * * Same constraint as bridgeDeleteCausalEdge — native graph-node lacks a * delete API. SQL fallback path soft-deletes the node (if stored as a * memory_entries row) and every edge whose key contains the nodeId. */ export declare function bridgeDeleteCausalNode(options: { nodeId: string; dbPath?: string; }): Promise<{ success: boolean; deletedNode: boolean; deletedEdges: number; nodeId: string; controller: string; guarded?: boolean; error?: string; } | null>; /** * Start a session with ReflexionMemory episodic replay. * Loads relevant past session patterns for the new session. */ export declare function bridgeSessionStart(options: { sessionId: string; context?: string; dbPath?: string; }): Promise<{ success: boolean; controller: string; restoredPatterns: number; sessionId: string; } | null>; /** * End a session and persist episodic summary to ReflexionMemory. */ export declare function bridgeSessionEnd(options: { sessionId: string; summary?: string; tasksCompleted?: number; patternsLearned?: number; dbPath?: string; }): Promise<{ success: boolean; controller: string; persisted: boolean; } | null>; /** * Route a task via AgentDB's SemanticRouter. * Returns null to fall back to local ruvector router. */ export declare function bridgeRouteTask(options: { task: string; context?: string; dbPath?: string; }): Promise<{ route: string; confidence: number; agents: string[]; controller: string; } | null>; /** * Get comprehensive bridge health including all controller statuses. */ export declare function bridgeHealthCheck(dbPath?: string): Promise<{ available: boolean; controllers: Array<{ name: string; enabled: boolean; level: number; }>; attestationCount?: number; cacheStats?: { size: number; hits: number; misses: number; }; hierarchicalMemory?: { controller: string; durable: boolean; persistence: string; /** Real row count in the backing table — null when nothing is on disk. */ persistedRows: number | null; fallbackFrom?: string; }; } | null>; /** * Store to hierarchical memory with tier. * Valid tiers: working, episodic, semantic * * Real HierarchicalMemory API (agentdb alpha.10+): * store(content, importance?, tier?, options?) → Promise * Fallback API (@claude-flow/memory TieredMemoryStore): * store(key, value, tier, temporalOptions?) — synchronous, returns * { id, key, tier, superseded? } * * Temporal validity (Zep/Graphiti-style, impl/memory-sota): * - validFrom / validUntil (ISO) travel with the entry. * - supersedes= INVALIDATES the old entry (validUntil=now + * supersededBy=newId) instead of deleting it. Natively supported by the * TieredMemoryStore fallback; on the real agentdb HierarchicalMemory the * temporal fields are stored in metadata, and supersede is reported as * unsupported (no public update API) rather than silently dropped. */ /** * Describe which store `agentdb_hierarchical-*` actually landed on and * whether its writes survive the process (#2887). * * agentdb removed its `HierarchicalMemory` export at 3.0.0-alpha.17, so the * @claude-flow/memory TieredMemoryStore fallback is the live path. It is only * durable when it was handed a SQLite connection — callers must not report a * volatile write as a success. */ export declare function describeHierarchicalStore(hm: any, fallback: { reason: string; } | null): { controller: string; fallbackFrom?: string; durable: boolean; persistence: string; }; export declare function bridgeHierarchicalStore(params: { key: string; value: string; tier?: string; importance?: number; validFrom?: string; validUntil?: string; supersedes?: string; }): Promise; /** * Recall from hierarchical memory. * * Real HierarchicalMemory API (agentdb alpha.10+): * recall(query: MemoryQuery) → Promise * where MemoryQuery = { query, tier?, k?, threshold?, context?, includeDecayed? } * Stub API (fallback): * recall(query: string, topK: number) → synchronous array */ export declare function bridgeHierarchicalRecall(params: { query: string; tier?: string; topK?: number; includeExpired?: boolean; }): Promise; /** * Run memory consolidation. * * Real MemoryConsolidation API (agentdb alpha.10+): * consolidate() → Promise * ConsolidationReport = { episodicProcessed, semanticCreated, memoriesForgotten, ... } * Stub API (fallback): * consolidate() → { promoted, pruned, timestamp } */ export declare function bridgeConsolidate(params: { minAge?: number; maxEntries?: number; }): Promise; /** * Batch operations (insert, update, delete). * - insert: calls insertEpisodes(entries) where entries are {content, metadata?} * - delete: calls bulkDelete(table, conditions) on episodes table * - update: calls bulkUpdate(table, updates, conditions) on episodes table */ export declare function bridgeBatchOperation(params: { operation: string; entries: any[]; }): Promise; /** * Synthesize context from memories. * ContextSynthesizer.synthesize is a static method that takes MemoryPattern[] (not a string). */ export declare function bridgeContextSynthesize(params: { query: string; maxEntries?: number; }): Promise; /** * Route via SemanticRouter. * Available since agentdb 3.0.0-alpha.10 — uses @ruvector/router for * semantic matching with keyword fallback. */ export declare function bridgeSemanticRoute(params: { input: string; }): Promise; /** * Export all embeddings from the bridge's better-sqlite3 connection. * Used by RaBitQ to build its index from the same data that memory_store writes. * Returns null if bridge is unavailable (caller falls back to sql.js). */ export declare function bridgeGetAllEmbeddings(options?: { dimensions?: number; limit?: number; dbPath?: string; }): Promise | null>; /** * Public helper for the unified learning-stats aggregator: counts of entries * per namespace + the top-level total. Best-effort — if the bridge isn't * available it returns zeros so the aggregator can still report the other * stores honestly. (#2245 follow-up.) */ export declare function getMemoryBridgeStats(options?: { namespaces?: string[]; dbPath?: string; }): Promise<{ totalEntries: number; perNamespace: Record; source: string; reachable: boolean; }>; //# sourceMappingURL=memory-bridge.d.ts.map