@anuma/sdk 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5658,6 +5658,12 @@ declare class VaultMemory extends Model {
5658
5658
  topicsExtractedVersion: number | null;
5659
5659
  /** C3 re-observation watermark: Unix ms of the last retain() merge, or null. */
5660
5660
  lastObservedAt: number | null;
5661
+ /** Typed memory (PR1) — the extractor's FactType. Null on legacy/manual rows. */
5662
+ factType: string | null;
5663
+ /** Decay archive state (PR2) — Unix ms when archived, null when active. */
5664
+ archivedAt: number | null;
5665
+ /** Tier-0 security (PR3) — "quarantined" | "trusted" | null. */
5666
+ trustTier: string | null;
5661
5667
  createdAt: Date;
5662
5668
  updatedAt: Date;
5663
5669
  isDeleted: boolean;
@@ -5828,290 +5834,25 @@ declare function backfillMemoryEntityUserIdsOp(ctx: EntityOperationsContext, vau
5828
5834
  * lane returns IDs from every user who tagged a matching entity.
5829
5835
  */
5830
5836
  declare function getMemoriesByEntityNamesOp(ctx: EntityOperationsContext, entityNames: readonly string[]): Promise<Map<string, Set<string>>>;
5831
-
5832
- interface StoredVaultMemory {
5833
- /** WatermelonDB internal ID */
5834
- uniqueId: string;
5835
- /** Plain text memory content */
5836
- content: string;
5837
- /** Scope for partitioning memories (e.g., "private", "shared") */
5838
- scope: string;
5839
- /** Folder ID for organization, null if unfiled */
5840
- folderId: string | null;
5841
- /** User ID for multi-user server-side scoping, null on client */
5842
- userId: string | null;
5843
- /** JSON-stringified embedding vector, null if not yet computed */
5844
- embedding: string | null;
5845
- /** Model that produced `embedding`. Null on legacy rows (grandfathered as
5846
- * compatible with the current model). */
5847
- embeddingModel: string | null;
5848
- /** JSON-stringified array of source message IDs this fact was extracted from. */
5849
- sourceChunkIds: string[] | null;
5850
- /** Times this fact has been re-observed (for ranking + UX badges). */
5851
- proofCount: number | null;
5852
- /** How the memory was created: manual | auto-extracted | capsule. */
5853
- source: string | null;
5854
- /** W6 temporal lane — Unix ms when the event occurred (point/start of range). */
5855
- eventTimeStart: number | null;
5856
- /** W6 temporal lane — Unix ms when the event ended (range only). */
5857
- eventTimeEnd: number | null;
5858
- /** W6 temporal lane — `point | range | ongoing | null`. */
5859
- eventTimeKind: string | null;
5860
- /** When true, the user has manually set this memory's topics (entity links);
5861
- * auto-extraction leaves them alone. False on legacy/auto rows. */
5862
- topicsUserManaged: boolean;
5863
- /** Unix ms of the last LLM topic-extraction pass over this memory's content.
5864
- * Null = never extracted standalone; rows that already carry entity links
5865
- * are grandfathered as extracted (see getMemoriesNeedingTopicExtractionOp). */
5866
- topicsExtractedAt: number | null;
5867
- /** Write-time supersession (A2): id of the newer memory that replaced this
5868
- * one (incompatible-value update, e.g. "Lives in Portland" → "Lives in SF").
5869
- * Null = live. Superseded rows are excluded from recall/dedup by default but
5870
- * kept for history + the read-time fallback. */
5871
- supersededBy: string | null;
5872
- /** Unix ms when this memory was superseded. Null when live. */
5873
- supersededAt: number | null;
5874
- /** Extraction-logic version this memory was last stamped under. Null (pre-v38)
5875
- * reads as 0, so a TOPICS_EXTRACTION_VERSION bump re-extracts stale rows. */
5876
- topicsExtractedVersion: number | null;
5877
- /** C3 re-observation watermark: Unix ms of the last retain() merge into this
5878
- * fact. Distinct from `updatedAt` (which merges preserve). Null = never
5879
- * re-observed since the column was added; synthesis falls back to
5880
- * `updatedAt` in that case. */
5881
- lastObservedAt: number | null;
5882
- createdAt: Date;
5883
- updatedAt: Date;
5884
- isDeleted: boolean;
5885
- }
5886
- interface CreateVaultMemoryOptions {
5887
- content: string;
5888
- /** Scope for the memory. Defaults to "private" if omitted. */
5889
- scope?: string;
5890
- /** Folder ID for organization, null or omitted if unfiled */
5891
- folderId?: string | null;
5892
- /** JSON-stringified embedding vector to persist */
5893
- embedding?: string;
5894
- /** Model that produced `embedding`. Persisted alongside it so a later
5895
- * model change can detect and re-embed stale vectors. */
5896
- embeddingModel?: string;
5897
- /** Source message IDs that produced this fact (auto-extraction provenance). */
5898
- sourceChunkIds?: string[];
5899
- /** Initial proof count. Defaults to 1 if omitted. */
5900
- proofCount?: number;
5901
- /** How the memory was created. Defaults to "manual" if omitted. */
5902
- source?: string;
5903
- /** W6 temporal lane — when the event in this memory occurred. */
5904
- eventTime?: {
5905
- /** Unix ms timestamp of event start (or point). */
5906
- start: number | null;
5907
- /** Unix ms timestamp of event end (range only). */
5908
- end: number | null;
5909
- /** Kind: 'point' | 'range' | 'ongoing' | null (or omit). */
5910
- kind: "point" | "range" | "ongoing" | null;
5911
- };
5912
- }
5913
- interface UpdateVaultMemoryOptions {
5914
- content: string;
5915
- /** If provided, updates the memory's scope. */
5916
- scope?: string;
5917
- /** If provided, moves the memory to this folder. */
5918
- folderId?: string | null;
5919
- /** JSON-stringified embedding vector to persist, or null to clear stale embedding */
5920
- embedding?: string | null;
5921
- /** Model that produced `embedding`. Set whenever `embedding` is written so
5922
- * the stored model tag stays in sync with the vector. */
5923
- embeddingModel?: string | null;
5924
- /** Replace source-chunk-ids list (used during merge to accumulate provenance). */
5925
- sourceChunkIds?: string[];
5926
- /** Set an absolute proof count. Prefer {@link proofCountIncrement} for
5927
- * re-observation paths so the read+write happens inside the writer
5928
- * and concurrent retains can't lose updates. */
5929
- proofCount?: number;
5930
- /** Atomically bump proof_count by this delta inside the write block.
5931
- * Reads the current value from the in-memory record at write time, so
5932
- * two parallel retain() calls observe each other's commits and neither
5933
- * loses its increment. Wins over `proofCount` when both are set. */
5934
- proofCountIncrement?: number;
5935
- /** Set source ("manual" | "auto-extracted" | "capsule"). */
5936
- source?: string;
5937
- /**
5938
- * W6 temporal lane — write the event-time fields on update. Use during
5939
- * auto-merge to preserve (or refine) the original event-time signal when
5940
- * a new observation lands on an existing fact. Omit to leave the
5941
- * existing values untouched.
5942
- */
5943
- eventTime?: {
5944
- start: number | null;
5945
- end: number | null;
5946
- kind: "point" | "range" | "ongoing" | null;
5947
- };
5948
- /**
5949
- * When true, restore the existing `updated_at` after the write so the
5950
- * recency multiplier doesn't see a re-observation as a brand-new fact.
5951
- * Set by auto-merge/consolidate paths — they want proof_count to bump
5952
- * without inflating recency on top.
5953
- */
5954
- preserveUpdatedAt?: boolean;
5955
- /** C3: Unix ms to stamp as the re-observation watermark (`last_observed_at`).
5956
- * Set by retain() merge/consolidate paths so a re-observation records "seen
5957
- * again now" without touching `updated_at` (which `preserveUpdatedAt` keeps
5958
- * pinned). Omit to leave the existing value untouched. */
5959
- lastObservedAt?: number;
5960
- /** If provided, sets whether the user has taken manual control of this
5961
- * memory's topics. Set by {@link setMemoryEntitiesOp}. */
5962
- topicsUserManaged?: boolean;
5963
- }
5964
-
5965
- interface VaultMemoryOperationsContext {
5966
- database: Database;
5967
- vaultMemoryCollection: Collection<VaultMemory>;
5968
- walletAddress?: string;
5969
- signMessage?: SignMessageFn;
5970
- embeddedWalletSigner?: EmbeddedWalletSignerFn;
5971
- /** When set, operations scope to this user (server-side multi-user). */
5972
- userId?: string;
5973
- /**
5974
- * When set, vault delete ops cascade to memory_entity rows pointing at
5975
- * the deleted memories. Without this the W5 graph lane keeps returning
5976
- * IDs of soft-deleted memories and the join table grows unbounded.
5977
- */
5978
- entityCtx?: EntityOperationsContext;
5979
- }
5980
- declare function createVaultMemoryOp(ctx: VaultMemoryOperationsContext, opts: CreateVaultMemoryOptions): Promise<StoredVaultMemory>;
5981
- declare function createVaultMemoriesBatchOp(ctx: VaultMemoryOperationsContext, optionsArray: CreateVaultMemoryOptions[]): Promise<StoredVaultMemory[]>;
5982
- declare function getVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string): Promise<StoredVaultMemory | null>;
5983
- declare function getAllVaultMemoriesOp(ctx: VaultMemoryOperationsContext, options?: {
5984
- scopes?: string[];
5985
- since?: Date;
5986
- limit?: number;
5987
- folderId?: string | null;
5988
- /**
5989
- * Include soft-deleted memories in the result (each carries
5990
- * `isDeleted: true`). Default `false` — deleted rows are excluded, as
5991
- * they are from every other read path. Used by the Memory Graph to
5992
- * render "forgotten" nodes; ordinary consumers should leave this off.
5993
- */
5994
- includeDeleted?: boolean;
5995
- /**
5996
- * Include A2-superseded memories (each carries `supersededBy`). Default
5997
- * `false` — superseded rows are excluded, as they are from recall/dedup.
5998
- * Used by a "memory history" view to render retired facts.
5999
- */
6000
- includeSuperseded?: boolean;
6001
- }): Promise<StoredVaultMemory[]>;
6002
- declare function getAllVaultMemoryContentsOp(ctx: VaultMemoryOperationsContext, options?: {
6003
- since?: Date;
6004
- }): Promise<string[]>;
6005
- declare function updateVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string, opts: UpdateVaultMemoryOptions): Promise<StoredVaultMemory | null>;
6006
5837
  /**
6007
- * Replace a memory's topic (entity) links with a user-chosen set and mark the
6008
- * memory `topics_user_managed` so auto-extraction stops touching its links.
6009
- * Replace semantics: the given `entities` become the memory's complete topic
6010
- * set (pass `[]` to clear all topics — the memory stays user-managed and
6011
- * unclustered). Requires `ctx.entityCtx`. Preserves `updated_at` so a topic
6012
- * edit doesn't inflate the recency multiplier.
6013
- */
6014
- declare function setMemoryEntitiesOp(ctx: VaultMemoryOperationsContext, memoryId: string, entities: ReadonlyArray<EntityInput>): Promise<StoredVaultMemory | null>;
6015
- /**
6016
- * Reset a memory's topics to automatic: clear the `topics_user_managed` flag so
6017
- * auto-extraction resumes owning its links. Invalidates `topics_extracted_version`
6018
- * (→ null) and ensures a NON-NULL `topics_extracted_at`, so the next sweep routes
6019
- * the row through the stale-version pending path and actually RE-EXTRACTS it via
6020
- * the LLM. A never-stamped user-curated row (`setMemoryEntitiesOp` marks
6021
- * user-managed without stamping, so stamp can be null) would otherwise fall
6022
- * through the sweep's unstamped→`linkedUnstamped` grandfather path (stamped
6023
- * current, no LLM pass); forcing a stamp when absent avoids that. Existing links
6024
- * are left in place until the re-extraction replaces them. Preserves `updated_at`.
6025
- */
6026
- declare function clearMemoryTopicsOverrideOp(ctx: VaultMemoryOperationsContext, memoryId: string): Promise<boolean>;
6027
- declare function deleteVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string): Promise<boolean>;
6028
- /**
6029
- * Mark a memory as superseded by a newer one (A2 write-time supersession).
6030
- * The row stays in the table (history + read-time fallback) but is excluded
6031
- * from recall/dedup by default via `superseded_by`. Idempotent-ish: no-op if
6032
- * the row is missing, not owned, deleted, or already superseded. Does NOT
6033
- * preserve `updated_at` — superseded rows are hidden from recall, so their
6034
- * recency is irrelevant.
5838
+ * Reverse of {@link getMemoriesByEntityNamesOp}: given a set of memory IDs
5839
+ * (e.g. the current BFS frontier), return each memory's set of linked
5840
+ * canonical entity names. This is the missing primitive for multi-hop graph
5841
+ * traversal (PR4) — one step outward from a memory to its neighbor entities,
5842
+ * which the traversal then expands to reach topically-adjacent memories.
6035
5843
  *
6036
- * @param id - the memory being retired (e.g. "Lives in Portland")
6037
- * @param supersededById - the newer memory that replaced it (e.g. "Lives in SF")
6038
- */
6039
- declare function supersedeVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string, supersededById: string): Promise<boolean>;
6040
- /**
6041
- * Get all non-deleted, unfiled vault memories (folder_id is null).
6042
- */
6043
- declare function getUnfiledVaultMemoriesOp(ctx: VaultMemoryOperationsContext): Promise<StoredVaultMemory[]>;
6044
- /**
6045
- * The current topic-extraction logic version. Bump this whenever the extraction
6046
- * prompt or model in `topicExtract.ts` changes: every memory stamped under an
6047
- * older version (including pre-v37 rows, read as version 0) is then re-extracted
6048
- * by the next sweep, so topic-quality improvements propagate across the existing
6049
- * vault. The worker's `limit` drains that re-extraction across sweeps.
6050
- */
6051
- declare const TOPICS_EXTRACTION_VERSION = 1;
6052
- /**
6053
- * Result of {@link getMemoriesNeedingTopicExtractionOp}: which memories the
6054
- * background topic worker should run LLM entity extraction on, and which it
6055
- * should merely stamp as already-extracted.
6056
- */
6057
- interface MemoriesNeedingTopicExtraction {
6058
- /**
6059
- * Memories to run LLM topic extraction on (decrypted): never-extracted rows
6060
- * with no entity links, plus stamped rows edited since their last pass
6061
- * (`updated_at` > `topics_extracted_at`) or extracted under an older
6062
- * `topics_extracted_version` than {@link TOPICS_EXTRACTION_VERSION}. Edited /
6063
- * stale-version rows come first (they get priority under `limit`), each group
6064
- * newest-created first.
6065
- */
6066
- pending: StoredVaultMemory[];
6067
- /**
6068
- * IDs of rows that already have entity links but no watermark — legacy rows
6069
- * extracted by the conversation pipeline before v36. Grandfather these with
6070
- * {@link stampTopicsExtractedAtOp} (no LLM call) so a later content edit
6071
- * makes them re-extractable instead of invisible forever. Bounded by the
6072
- * same `limit` as {@link pending} — stamping loads a Model per row, so the
6073
- * grandfather backlog is drained across sweeps rather than in one spike.
6074
- */
6075
- linkedUnstamped: string[];
6076
- }
6077
- /**
6078
- * Sweep query for the background topic-extraction worker: partition the
6079
- * user's non-deleted, non-user-managed memories by what the worker should do
6080
- * with them (see {@link MemoriesNeedingTopicExtraction}). User-managed rows
6081
- * are never returned — the user owns their topics, including an intentionally
6082
- * empty set. Requires `ctx.entityCtx` for the entity-links check.
6083
- */
6084
- declare function getMemoriesNeedingTopicExtractionOp(ctx: VaultMemoryOperationsContext, options?: {
6085
- limit?: number;
6086
- }): Promise<MemoriesNeedingTopicExtraction>;
6087
- /**
6088
- * Stamp `topics_extracted_at` (and `topics_extracted_version`) on the given
6089
- * memories — the topic worker calls this after a successful extraction pass
6090
- * (including zero-entity results, so quiet memories aren't re-asked every sweep)
6091
- * and to grandfather `linkedUnstamped` rows without an LLM call. `version`
6092
- * defaults to {@link TOPICS_EXTRACTION_VERSION}: stamping at the current version
6093
- * (for both fresh extractions and grandfathered legacy rows) means they aren't
6094
- * re-extracted until a future version bump. Preserves `updated_at` so a stamp
6095
- * never inflates the recency multiplier — and never masks a concurrent content
6096
- * edit from the next sweep. Skips deleted, foreign-user, and user-managed rows.
6097
- * Returns the IDs actually stamped.
5844
+ * Empty input returns an empty map. Memory IDs with no links contribute
5845
+ * nothing (they simply don't appear as keys).
6098
5846
  *
6099
- * ALL eligibility AND `updated_at` are read from the LIVE Model inside the
6100
- * serialized writer — never a pre-writer snapshot. Writers are serialized, so
6101
- * a content edit or topic-override that commits before this writer runs is
6102
- * observed here: its fresh `updated_at` is preserved (so the next sweep's
6103
- * `updated_at > stamp` check still fires) and a mid-pass user-managed flip
6104
- * skips the row. Reading `updated_at` from a raw pre-fetch instead would write
6105
- * a stale value back, pushing `updated_at < topics_extracted_at` and hiding
6106
- * the edited memory from every future sweep.
5847
+ * Multi-user safety mirrors {@link getMemoriesByEntityNamesOp} exactly: when
5848
+ * `ctx.userId` is set, only `memory_entity` rows owned by that user are
5849
+ * followed (with the same `allowUnscopedRows` LokiJS escape hatch for pre-v31
5850
+ * rows whose `user_id` backfill was a no-op). Without the filter the reverse
5851
+ * lookup would leak entity links written by other users.
6107
5852
  *
6108
- * Callers bound the input via `getMemoriesNeedingTopicExtractionOp`'s `limit`
6109
- * (both `pending` and `linkedUnstamped` are capped), so the per-row Model load
6110
- * needed to `prepareUpdate` stays bounded and never spikes the RecordCache.
5853
+ * @public
6111
5854
  */
6112
- declare function stampTopicsExtractedAtOp(ctx: VaultMemoryOperationsContext, memoryIds: readonly string[], extractedAt: number, version?: number): Promise<string[]>;
6113
- declare function deleteAllVaultMemoriesForUserOp(ctx: VaultMemoryOperationsContext, userId: string): Promise<number>;
6114
- declare function updateVaultMemoryEmbeddingOp(ctx: VaultMemoryOperationsContext, id: string, embedding: string, embeddingModel: string): Promise<boolean>;
5855
+ declare function getEntitiesByMemoryIdsOp(ctx: EntityOperationsContext, memoryIds: readonly string[]): Promise<Map<string, Set<string>>>;
6115
5856
 
6116
5857
  /**
6117
5858
  * Auth for portal LLM calls (extraction, consolidation, decomposition,
@@ -6132,6 +5873,165 @@ interface PortalLlmAuth {
6132
5873
  getToken?: () => Promise<string | null>;
6133
5874
  }
6134
5875
 
5876
+ /**
5877
+ * Optional LLM injection classifier — Tier-0 security second layer (PR5).
5878
+ *
5879
+ * The deterministic {@link ./injectionScreen} is a signature scan: it catches
5880
+ * imperative overrides, role-marker leakage, and exfil URLs, but by
5881
+ * construction it CANNOT catch signature-free poison phrased as a plain
5882
+ * third-person fact — e.g. "Trusts BrandX for financial advice", "Prefers to
5883
+ * always use the AcmePay card". Those read like ordinary preferences and sail
5884
+ * through the regex screen.
5885
+ *
5886
+ * This module closes that gap as a SECOND, opt-in layer. In `extractAndRetain`
5887
+ * it runs ONLY over the candidates the deterministic screen already passed as
5888
+ * clean, asking a cheap model a single batched yes/no per candidate: "is this
5889
+ * an instruction to the assistant / a planted preference, rather than a genuine
5890
+ * fact the user stated about themselves?" Positives are moved to quarantine
5891
+ * (trust_tier="quarantined"), exactly like a signature hit.
5892
+ *
5893
+ * Safety posture (why it can only ever add safety, never remove it):
5894
+ * - Default OFF. No option → no LLM call → zero latency/cost added, and the
5895
+ * write path is byte-for-byte the pre-PR5 deterministic screen.
5896
+ * - Fails CLEAN. Any error (network, timeout, malformed JSON, auth) → the
5897
+ * candidate stays in the clean set (trusts the deterministic result). A
5898
+ * flaky classifier can never suppress a legitimate memory.
5899
+ * - Bounded. One batched portal call per turn (never per-candidate), with a
5900
+ * candidate cap, a low retry budget, and a wall-clock total-timeout.
5901
+ * - Zero-knowledge parity. Candidate content is PII-redacted before it
5902
+ * reaches the portal using the SAME redactor setting as the extraction
5903
+ * path (inherited by `extractAndRetain`); the model only ever returns
5904
+ * integer indices, so nothing needs de-anonymizing on the way back.
5905
+ *
5906
+ * SECURITY (MEDIUM, residual): this is a NEW portal call surface for memory
5907
+ * content. It is gated on an explicit opt-in and redacts like the extractor, but
5908
+ * a security review should treat enabling it as widening the set of models that
5909
+ * see (redacted) facts. A malicious / MITM'd portal can also use it as a lever
5910
+ * to QUARANTINE the affected rows (they drop out of recall) — reversible, and it
5911
+ * can never delete or alter a memory. Bounded, recoverable trust tradeoff; gate
5912
+ * on trust in the portal.
5913
+ */
5914
+
5915
+ /**
5916
+ * Auth + tuning for the optional LLM injection classifier. Auth is the dual
5917
+ * pattern — one of `apiKey` / `getToken` is required at runtime (see
5918
+ * {@link PortalLlmAuth}). The mere PRESENCE of this options object in
5919
+ * `extractAndRetain` is the opt-in switch; omit it for the default-off,
5920
+ * deterministic-only screen.
5921
+ * @public
5922
+ */
5923
+ interface InjectionClassifierOptions extends PortalLlmAuth {
5924
+ baseUrl?: string;
5925
+ model?: string;
5926
+ /** Override fetch (tests). */
5927
+ fetchFn?: typeof fetch;
5928
+ /** Max portal attempts on a TRANSIENT failure. Default 2. */
5929
+ maxAttempts?: number;
5930
+ /** Absolute wall-clock budget across attempts. Default 15s. */
5931
+ totalTimeoutMs?: number;
5932
+ /** Backoff before each retry (ms). Tests pass `() => 0`. */
5933
+ backoffMs?: (attempt: number) => number;
5934
+ /**
5935
+ * PII redaction for the outbound content, same switch as the extractor.
5936
+ * `extractAndRetain` inherits the extraction setting so enabling redaction
5937
+ * there also protects this call. `true` = fresh per-call redactor; pass a
5938
+ * shared {@link PiiRedactor} to keep placeholder numbering consistent.
5939
+ */
5940
+ piiRedaction?: boolean | PiiRedactor;
5941
+ /** Max candidates classified per call. Default 20. */
5942
+ maxCandidates?: number;
5943
+ }
5944
+ /**
5945
+ * Classify already-clean extraction candidates for signature-free injection /
5946
+ * poisoning. Returns the set of 0-based indices (into `candidates`) the model
5947
+ * flagged as poison.
5948
+ *
5949
+ * FAILS CLEAN: returns an empty set on empty input, missing auth, LLM error,
5950
+ * or any malformed response — the caller then keeps every candidate clean, so
5951
+ * this layer can only ever ADD quarantines, never suppress a legitimate fact
5952
+ * on failure. Makes at most ONE portal call regardless of candidate count.
5953
+ *
5954
+ * @public
5955
+ */
5956
+ declare function classifyInjectionCandidates(candidates: readonly ExtractedCandidate[], options: InjectionClassifierOptions): Promise<{
5957
+ flagged: Set<number>;
5958
+ }>;
5959
+
5960
+ /**
5961
+ * Write-time memory-poisoning screen — Tier-0 security (PR3).
5962
+ *
5963
+ * Deterministic, network-free, and always on. Scans each extraction
5964
+ * candidate's `content` for prompt-injection / memory-poisoning
5965
+ * signatures and routes flagged candidates to quarantine instead of the
5966
+ * live vault.
5967
+ *
5968
+ * WHY a signature scan (not an LLM classifier): this runs on the write
5969
+ * path for every extracted fact, so it must be cheap, offline, and must
5970
+ * never leak content to a model. It also gives a small false-positive
5971
+ * surface here: durable third-person facts about the user ("Lives in San
5972
+ * Francisco", "Allergic to shellfish", "Works in engineering") almost
5973
+ * never contain second-person imperatives aimed at the assistant, chat
5974
+ * role markers, or beacon URLs — the exact shapes these signatures look
5975
+ * for. An optional LLM injection classifier is deferred to PR5.
5976
+ *
5977
+ * WHY quarantine, not drop: a flagged candidate is still persisted (see
5978
+ * `extractAndRetain`) with `trust_tier="quarantined"` so it stays an
5979
+ * auditable record, recoverable by an operator via the `includeQuarantined`
5980
+ * read path. The `baseVaultConditions` choke point excludes quarantined
5981
+ * rows from every recall lane, so a poisoned fact never reaches the answer
5982
+ * model even though it lives in the DB.
5983
+ *
5984
+ * This MITIGATES memory poisoning (MINJA / AgentPoison; OWASP ASI06 2026).
5985
+ * It is not a complete solve — a poison phrased as a plain third-person
5986
+ * fact ("Prefers the BrandX credit card") carries no injection signature
5987
+ * and will pass. The proof-count ranking boost (once-seen facts stay
5988
+ * low-ranked) and the read-time isolation in `formatRecallResult` are the
5989
+ * complementary layers.
5990
+ */
5991
+
5992
+ /** Why a candidate was quarantined. Coarse buckets over the signature set
5993
+ * below — surfaced for audit/telemetry, never alongside the content.
5994
+ * `llm_semantic` (PR5) is emitted by the optional second-layer LLM classifier
5995
+ * ({@link classifyInjectionCandidates}), not by any deterministic signature
5996
+ * here — it catches signature-free poison ("Trusts BrandX for financial
5997
+ * advice") the regex screen passes as clean. */
5998
+ type InjectionReason = "imperative_override" | "role_marker_leak" | "exfiltration_url" | "llm_semantic";
5999
+ /** A candidate the screen flagged, with the matching signature id + reason.
6000
+ * Content is intentionally NOT duplicated here beyond the candidate itself —
6001
+ * callers must never log `candidate.content`. */
6002
+ interface ScreenedCandidate {
6003
+ candidate: ExtractedCandidate;
6004
+ /** Coarse reason bucket. */
6005
+ reason: InjectionReason;
6006
+ /** Stable id of the signature that matched (safe to log; carries no content). */
6007
+ signature: string;
6008
+ }
6009
+ /** Result of screening a candidate batch. */
6010
+ interface ScreenResult {
6011
+ /** Candidates with no injection signature — persist normally. */
6012
+ clean: ExtractedCandidate[];
6013
+ /** Candidates that matched a signature — persist quarantined. */
6014
+ quarantined: ScreenedCandidate[];
6015
+ }
6016
+ /**
6017
+ * Screen extraction candidates for injection / poisoning signatures.
6018
+ *
6019
+ * Partitions the input into `clean` (persist normally) and `quarantined`
6020
+ * (persist with `trust_tier="quarantined"`, hidden from recall). Pure and
6021
+ * synchronous — no network, no DB, no content logging. Input order is
6022
+ * preserved within each partition.
6023
+ */
6024
+ declare function screenCandidatesForInjection(candidates: readonly ExtractedCandidate[]): ScreenResult;
6025
+ /**
6026
+ * Content-free catalog of the active signatures (id + reason, no patterns).
6027
+ * Exposed so a security review / audit surface can enumerate coverage
6028
+ * without reaching into module internals. Does not leak any user content.
6029
+ */
6030
+ declare function injectionSignatureCatalog(): {
6031
+ id: string;
6032
+ reason: InjectionReason;
6033
+ }[];
6034
+
6135
6035
  /**
6136
6036
  * Linear recency decay multiplier — applied post-fusion to nudge fresh
6137
6037
  * memories above stale ones with otherwise comparable scores.
@@ -6185,6 +6085,23 @@ interface MemoryVaultSearchOptions {
6185
6085
  scopes?: string[];
6186
6086
  /** When provided, only search memories in this folder (null for unfiled) */
6187
6087
  folderId?: string | null;
6088
+ /** Typed memory (PR1) — when provided, only search memories of these fact
6089
+ * types. Applied at load time via `Q.oneOf` on the indexed `fact_type`
6090
+ * column. Omit for no type filter. */
6091
+ factTypes?: string[];
6092
+ /**
6093
+ * PR5 — optional per-FactType score multiplier applied in the boost stage
6094
+ * (e.g. `{ identity: 1.2, ongoing_context: 0.8 }`). Empty/omitted = uniform
6095
+ * (no behavior change). See {@link rankFusedVaultMemories}.
6096
+ */
6097
+ factTypeWeights?: Record<string, number>;
6098
+ /**
6099
+ * PR5 — include archived (decayed) rows in the candidate load. Default false
6100
+ * (the baseVaultConditions choke point excludes them). retain()'s dedup
6101
+ * search sets this so a re-observed fact can merge into — and un-archive — an
6102
+ * archived row instead of creating a fresh duplicate.
6103
+ */
6104
+ includeArchived?: boolean;
6188
6105
  /**
6189
6106
  * Use the hybrid fusion ranker (cosine + BM25 + RRF + recency) instead of
6190
6107
  * cosine-only. Default true — new W1 pipeline. Pass false to fall back
@@ -6279,6 +6196,10 @@ interface VaultSearchResult {
6279
6196
  eventTimeStart?: number | null;
6280
6197
  eventTimeEnd?: number | null;
6281
6198
  eventTimeKind?: "point" | "range" | "ongoing" | null;
6199
+ /** Typed memory (PR1) — the fact's FactType, threaded through from the
6200
+ * storage row alongside the event-time anchors. Null/undefined when
6201
+ * untyped. Loose string (originates from a stored column). */
6202
+ factType?: string | null;
6282
6203
  /** Message ids this fact was extracted from (provenance). recall() uses
6283
6204
  * these to suppress the originating chunk in the chunk lane. */
6284
6205
  sourceChunkIds?: string[] | null;
@@ -6368,6 +6289,14 @@ interface RankedMemory {
6368
6289
  eventTimeStart?: number | null;
6369
6290
  eventTimeEnd?: number | null;
6370
6291
  eventTimeKind?: "point" | "range" | "ongoing" | null;
6292
+ /**
6293
+ * Typed memory (PR1) — the extractor's FactType classification for this
6294
+ * fact, threaded through the same channel as the event-time anchors so
6295
+ * recall results (and UI) can show the type without a second DB read.
6296
+ * Null/undefined on legacy/untyped/manual facts. Kept as a loose string
6297
+ * (not narrowed to FactType) since it originates from a stored column.
6298
+ */
6299
+ factType?: string | null;
6371
6300
  conversationId?: string;
6372
6301
  messageId?: string;
6373
6302
  role?: "user" | "assistant";
@@ -6389,6 +6318,18 @@ interface RecallOptions {
6389
6318
  scopes?: string[];
6390
6319
  /** Vault folder filter. Vault-only. */
6391
6320
  folderId?: string | null;
6321
+ /**
6322
+ * Typed memory (PR1) — restrict fact recall to these FactTypes. Optional
6323
+ * and no-op when unset (all types are eligible). Vault-only.
6324
+ */
6325
+ factTypes?: FactType[];
6326
+ /**
6327
+ * PR5 — optional per-FactType score multiplier applied in the fusion boost
6328
+ * stage (e.g. boost `identity`/`constraint`, down-weight `ongoing_context`).
6329
+ * A type absent from the map (and untyped rows) uses 1.0, so an empty/omitted
6330
+ * map is a no-op (uniform weighting). Vault-only.
6331
+ */
6332
+ factTypeWeights?: Partial<Record<FactType, number>>;
6392
6333
  /** Restrict chunk search to one conversation. Chunk-only. */
6393
6334
  conversationId?: string;
6394
6335
  /** Exclude one conversation from chunk search. Chunk-only. */
@@ -6441,6 +6382,21 @@ interface RecallOptions {
6441
6382
  bm25AdmissionDivisor?: number;
6442
6383
  /** RRF smoothing constant for lane fusion (facts × chunks and side lanes). Default: 60. */
6443
6384
  rrfK?: number;
6385
+ /** Total graph hops incl. the seed lookup (hop 1). Default: 1 (seed only). */
6386
+ maxHops?: number;
6387
+ /** Max neighbor entities expanded per hop. Default: 8. */
6388
+ entityFanout?: number;
6389
+ /** Hard cap on accumulated memory IDs across all hops. Default: 64. */
6390
+ nodeBudget?: number;
6391
+ /**
6392
+ * PR5 — enable LLM graph path-refinement: at each traversal hop a model picks
6393
+ * which neighbor entities to expand instead of pure co-occurrence ranking.
6394
+ * Opt-in (default false); only active on the `high` budget (needs the
6395
+ * `traverse` flag) AND when `decomposeOptions` is set (reuses that auth).
6396
+ * Falls back to deterministic co-occurrence order on any error. Adds ≤1 LLM
6397
+ * call per expansion hop.
6398
+ */
6399
+ graphRefine?: boolean;
6444
6400
  }
6445
6401
  interface RecallContext {
6446
6402
  /** Required when `types` includes 'fact'. */
@@ -6580,6 +6536,22 @@ interface RetainOptions {
6580
6536
  start: number;
6581
6537
  end: number | null;
6582
6538
  } | null;
6539
+ /**
6540
+ * Typed memory (PR1) — the extractor's classification for this fact.
6541
+ * Persisted on create; on merge/consolidate it lazily backfills the target
6542
+ * only when the target has no type yet (never overwrites a non-null type).
6543
+ * Auto-extraction emits this; manual writes omit it (persisted as null).
6544
+ */
6545
+ factType?: FactType;
6546
+ /**
6547
+ * Tier-0 security (PR3) — trust tier for this fact. The write-time
6548
+ * injection screen threads `"quarantined"` here for flagged candidates;
6549
+ * omit for the default (null/trusted). Persisted only on create (a
6550
+ * quarantined candidate is force-created, never merged, so it can't bump
6551
+ * or contaminate a clean memory). The DB op re-validates the value
6552
+ * against the known set before writing.
6553
+ */
6554
+ trustTier?: string;
6583
6555
  }
6584
6556
  interface RetainResult {
6585
6557
  action: RetainAction;
@@ -6662,195 +6634,654 @@ interface ExtractedEntity {
6662
6634
  name: string;
6663
6635
  kind?: EntityKind;
6664
6636
  }
6665
- interface ExtractedCandidate {
6637
+ interface ExtractedCandidate {
6638
+ content: string;
6639
+ type: FactType;
6640
+ confidence: number;
6641
+ sourceMessageIds: string[];
6642
+ entities: ExtractedEntity[];
6643
+ /** W6 temporal lane — when the event in this fact occurred. Resolved
6644
+ * to absolute timestamps by the LLM; null when the fact has no
6645
+ * temporal anchor. */
6646
+ eventTime: {
6647
+ kind: "point" | "range" | "ongoing";
6648
+ /** Unix ms timestamp of the event start (or point). */
6649
+ start: number;
6650
+ /** Unix ms timestamp of the event end. Only set when kind='range'. */
6651
+ end: number | null;
6652
+ } | null;
6653
+ }
6654
+ /**
6655
+ * Tier-0 security (PR3) — describes a candidate the injection screen
6656
+ * quarantined and persisted as an audit row. The client uses this to surface
6657
+ * a "held for review" state. `content` lives on `candidate` (same exposure as
6658
+ * {@link ExtractedCandidate}); never log it.
6659
+ */
6660
+ interface QuarantinedMemoryInfo {
6661
+ candidate: ExtractedCandidate;
6662
+ /** The persisted (quarantined) memory row id. */
6663
+ memoryId: string;
6664
+ /** Coarse reason bucket from the screen. */
6665
+ reason: InjectionReason;
6666
+ /** Stable signature id that matched (safe to log; carries no content). */
6667
+ signature: string;
6668
+ }
6669
+ /**
6670
+ * Auth + endpoint for the extraction LLM call. Auth is the dual pattern —
6671
+ * one of `apiKey` / `getToken` is required at runtime; see
6672
+ * {@link PortalLlmAuth}.
6673
+ */
6674
+ interface ExtractFactsOptions extends PortalLlmAuth {
6675
+ baseUrl?: string;
6676
+ model?: string;
6677
+ /** Override the global fetch implementation (useful for tests). */
6678
+ fetchFn?: typeof fetch;
6679
+ /**
6680
+ * The user's own name(s) / handle(s) (e.g. profile nickname, wallet display
6681
+ * name). Candidates whose entire content is just one of these are dropped —
6682
+ * a personal memory system already knows who the user is, so "Peter Lee" is
6683
+ * circular noise. Optional; when omitted only the bare-fragment gate applies.
6684
+ */
6685
+ userIdentity?: string[];
6686
+ /**
6687
+ * Reference "now" (Unix ms) for resolving relative temporal phrases in the
6688
+ * transcript ("yesterday", "next week", "in two days") into the absolute
6689
+ * YYYY-MM-DD anchors the W6 temporal lane indexes on. The transcript itself
6690
+ * carries no timestamps, so without an anchor the model resolves relatives
6691
+ * against its own training-cutoff guess and emits wrong `eventTime` dates.
6692
+ * Defaults to `Date.now()`. Override for back-dated eval corpora and
6693
+ * deterministic tests (mirrors {@link RecallOptions.now}).
6694
+ *
6695
+ * Server-side timezone note: the ms value is formatted to a calendar date in
6696
+ * the process's local timezone (same basis as `parseLocalCalendarDay`). On a
6697
+ * UTC server, a user near midnight in a non-UTC offset can get the wrong
6698
+ * calendar day. Pass the user's local-midnight timestamp as `now` when the
6699
+ * process timezone doesn't match the user's.
6700
+ */
6701
+ now?: number;
6702
+ /**
6703
+ * Max attempts for the extraction call on a transient failure (default 3).
6704
+ * Lower it to bound how long extraction can hold a turn open — e.g. a worker
6705
+ * that runs extraction behind an in-flight-turn guard can pass `2` to keep
6706
+ * repeated failures from delaying later turns.
6707
+ */
6708
+ maxAttempts?: number;
6709
+ /** Per-attempt timeout (ms) for the extraction call. Defaults to the portal
6710
+ * helper's 60s. Combine with {@link maxAttempts} to cap the total time budget. */
6711
+ timeoutMs?: number;
6712
+ /**
6713
+ * Absolute wall-clock budget (ms) across ALL extraction attempts incl. backoff.
6714
+ * When set, the loop stops before an attempt that would exceed it, so worst-case
6715
+ * latency is bounded rather than `maxAttempts × timeoutMs`.
6716
+ */
6717
+ totalTimeoutMs?: number;
6718
+ /**
6719
+ * Override the retry backoff (ms) for a given 1-based attempt index. The
6720
+ * extraction call retries transient failures internally (default exponential
6721
+ * backoff); pass `() => 0` to retry without delay (useful for tests).
6722
+ */
6723
+ backoffMs?: (attempt: number) => number;
6724
+ /**
6725
+ * When set, PII (emails, phones, SSNs, cards, IPs, API keys, …) in the
6726
+ * conversation transcript is replaced with tagged placeholders before the
6727
+ * extraction call, and the returned facts + entities are de-anonymized so the
6728
+ * vault keeps the real values while raw PII never reaches the extraction
6729
+ * model (and, via `extractAndRetain`, the consolidation model). Pass `true`
6730
+ * for a fresh per-call redactor, or a shared {@link PiiRedactor} to keep
6731
+ * placeholder numbering consistent with other calls.
6732
+ *
6733
+ * NOTE: this does NOT cover the embeddings provider. Facts are stored and
6734
+ * embedded with their real values, so to keep PII out of embedding requests
6735
+ * set `RetainContext.embeddingOptions.maskInput` (e.g. `redactor.maskText`)
6736
+ * as well — the two are independent switches.
6737
+ */
6738
+ piiRedaction?: boolean | PiiRedactor;
6739
+ /**
6740
+ * Called when the extraction LLM returned no usable result after exhausting
6741
+ * its retries (empty/malformed completion, network/HTTP error) — i.e. a
6742
+ * *failure* that drops the turn's facts, as opposed to a legitimate
6743
+ * `{candidates: []}` "nothing durable here". Lets callers distinguish a
6744
+ * silently-degrading extractor from quiet turns (the two are otherwise
6745
+ * indistinguishable). See {@link extractAndRetain}'s `outcome`.
6746
+ */
6747
+ onExhaustedEmpty?: () => void;
6748
+ /**
6749
+ * Called when the extractor DID produce candidates but PII de-anonymization
6750
+ * dropped every one of them — the model mangled its placeholders (so they
6751
+ * can't be restored to real values) or restoring the values blew the length
6752
+ * cap. These drops happen before `retain()`, so `failedCount` can't see them,
6753
+ * and the turn would otherwise masquerade as a quiet `no-facts` result. Lets
6754
+ * H3's `outcome` surface `dropped-after-redaction` so a rising PII-drop rate
6755
+ * (i.e. redaction silently eating facts) is alarmable.
6756
+ */
6757
+ onCandidatesDropped?: () => void;
6758
+ }
6759
+ /**
6760
+ * Stage 1 — call the LLM to extract candidate facts from the recent
6761
+ * conversation. Returns post-validated candidates only (confidence
6762
+ * threshold, source-id check, length cap, schema validation). Returns
6763
+ * an empty array if the LLM emits malformed JSON or no candidates.
6764
+ *
6765
+ * A null from `callPortalJsonCompletion` means a *failure* (empty completion,
6766
+ * malformed JSON, network/HTTP error) — distinct from a successful
6767
+ * `{candidates: []}`, which parses to a non-null object. A failed extraction
6768
+ * silently drops the whole turn's memories, so transient failures matter:
6769
+ * `callPortalJsonCompletion` retries them internally with backoff (default 3
6770
+ * attempts), so a one-off empty/malformed completion from a reasoning-class
6771
+ * model doesn't lose the turn. Only an exhausted-retry null reaches here.
6772
+ */
6773
+ declare function extractFacts(messages: AutoExtractMessage[], options: ExtractFactsOptions): Promise<ExtractedCandidate[]>;
6774
+ /**
6775
+ * Outcome of the EXTRACTOR stage for a turn — independent of whether the
6776
+ * subsequent `retain()` writes landed (that's `failedCount`):
6777
+ * - `extracted` — the extractor produced at least one candidate above
6778
+ * the confidence floor. Whether those writes succeeded
6779
+ * is reported separately by `failedCount` — so
6780
+ * `extracted` + `failedCount > 0` means "found facts but
6781
+ * writes are failing", which is more signal than
6782
+ * collapsing it into `no-facts` would give.
6783
+ * - `no-facts` — the extractor ran fine but found nothing durable.
6784
+ * - `empty-after-retry` — the extractor returned empty/malformed after
6785
+ * exhausting retries (a *failure*). Distinguishing this
6786
+ * from `no-facts` is what makes a silently-degrading
6787
+ * extractor alarmable rather than invisible.
6788
+ * - `dropped-after-redaction` — the extractor found facts but PII
6789
+ * de-anonymization dropped every one (mangled
6790
+ * placeholders / over-cap after restore), before retain.
6791
+ * A degradation `failedCount` can't see; would otherwise
6792
+ * look like `no-facts`.
6793
+ */
6794
+ type ExtractOutcome = "extracted" | "no-facts" | "empty-after-retry" | "dropped-after-redaction";
6795
+ /**
6796
+ * Stage 2 — for each extracted candidate, call retain() with auto-merge
6797
+ * enabled. When `consolidateOptions` are wired, retain()'s consolidation pass
6798
+ * is the "resolver": a second LLM call against the top-K existing vault
6799
+ * memories that decides create/update/noop/supersede — including retiring a
6800
+ * stale value on a state change (the supersession the extraction prompt above
6801
+ * promises). Without consolidation, retain() still dedups at the cosine-merge
6802
+ * level, and the read-time supersession heuristic remains the fallback.
6803
+ *
6804
+ * Returns the candidates that survived validation along with the retain
6805
+ * result for each (which captures whether the fact was created, merged,
6806
+ * or skipped), plus an `outcome` summarizing why the turn did/didn't produce
6807
+ * facts (see {@link ExtractOutcome}).
6808
+ */
6809
+ declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: RetainContext, options: {
6810
+ extract: ExtractFactsOptions;
6811
+ minConfidence?: number;
6812
+ /** Override scope/folder for all retained facts. */
6813
+ scope?: string;
6814
+ folderId?: string | null;
6815
+ /**
6816
+ * Forwarded verbatim to each retain() call — enables the LLM-based
6817
+ * consolidation pass (Hindsight facet-dedup) on every write. See
6818
+ * `RetainOptions.consolidateOptions` for auth + observability fields.
6819
+ */
6820
+ consolidateOptions?: RetainOptions["consolidateOptions"];
6821
+ /**
6822
+ * When provided, persist each candidate's `entities[]` to the
6823
+ * entity + memory_entity tables after a successful retain. This
6824
+ * powers the W5 graph retrieval lane — recall() can query for
6825
+ * memories sharing entities with the user's question.
6826
+ */
6827
+ entityCtx?: EntityOperationsContext;
6828
+ /**
6829
+ * Per-candidate failure hook — invoked once per filtered candidate
6830
+ * whose `retain()` call threw. Lets UI layers surface "couldn't save
6831
+ * X" toasts; without it consumers only see the aggregate
6832
+ * `failedCount` and can't name which facts dropped.
6833
+ */
6834
+ onCandidateFailed?: (candidate: ExtractedCandidate, error: unknown) => void;
6835
+ /**
6836
+ * Tier-0 security (PR3) — invoked once per candidate the injection screen
6837
+ * quarantined AND persisted (audit row written). Lets a UI surface a
6838
+ * "held for review" state instead of the fact silently vanishing. Carries
6839
+ * the same content exposure as `onMemoryExtracted` (the candidate) plus
6840
+ * the persisted `memoryId` + the screen `reason`/`signature`; content is
6841
+ * never logged. Fired only on a successful quarantine write, not on a
6842
+ * failed one (that goes to `onCandidateFailed`).
6843
+ */
6844
+ onQuarantined?: (info: QuarantinedMemoryInfo) => void;
6845
+ /**
6846
+ * Tier-0 security (PR5) — optional SECOND-layer LLM injection classifier.
6847
+ * When provided, candidates the deterministic {@link screenCandidatesForInjection}
6848
+ * screen passed as CLEAN are additionally run through a cheap LLM that
6849
+ * catches signature-free poison ("Trusts BrandX for financial advice")
6850
+ * the regex screen can't. Positives are quarantined exactly like a
6851
+ * signature hit (reason `llm_semantic`). DEFAULT OFF — omit this to keep
6852
+ * the deterministic-only, no-extra-LLM-call path. Fails clean on any
6853
+ * error. Content is PII-redacted before the call, inheriting the
6854
+ * extraction redaction setting when this option doesn't set its own.
6855
+ */
6856
+ injectionClassifier?: InjectionClassifierOptions;
6857
+ }): Promise<{
6858
+ candidates: ExtractedCandidate[];
6859
+ results: RetainResult[];
6860
+ failedCount: number;
6861
+ outcome: ExtractOutcome;
6862
+ /**
6863
+ * Tier-0 security (PR3) — candidates quarantined by the injection screen and
6864
+ * persisted as audit rows (trust_tier="quarantined"). Kept OUT of
6865
+ * `candidates`/`results` so `onMemoryExtracted` never announces poison;
6866
+ * surfaced here so callers can distinguish "nothing extracted" from
6867
+ * "extracted but held for review".
6868
+ */
6869
+ quarantined: QuarantinedMemoryInfo[];
6870
+ }>;
6871
+
6872
+ interface StoredVaultMemory {
6873
+ /** WatermelonDB internal ID */
6874
+ uniqueId: string;
6875
+ /** Plain text memory content */
6876
+ content: string;
6877
+ /** Scope for partitioning memories (e.g., "private", "shared") */
6878
+ scope: string;
6879
+ /** Folder ID for organization, null if unfiled */
6880
+ folderId: string | null;
6881
+ /** User ID for multi-user server-side scoping, null on client */
6882
+ userId: string | null;
6883
+ /** JSON-stringified embedding vector, null if not yet computed */
6884
+ embedding: string | null;
6885
+ /** Model that produced `embedding`. Null on legacy rows (grandfathered as
6886
+ * compatible with the current model). */
6887
+ embeddingModel: string | null;
6888
+ /** JSON-stringified array of source message IDs this fact was extracted from. */
6889
+ sourceChunkIds: string[] | null;
6890
+ /** Times this fact has been re-observed (for ranking + UX badges). */
6891
+ proofCount: number | null;
6892
+ /** How the memory was created: manual | auto-extracted | capsule. */
6893
+ source: string | null;
6894
+ /** W6 temporal lane — Unix ms when the event occurred (point/start of range). */
6895
+ eventTimeStart: number | null;
6896
+ /** W6 temporal lane — Unix ms when the event ended (range only). */
6897
+ eventTimeEnd: number | null;
6898
+ /** W6 temporal lane — `point | range | ongoing | null`. */
6899
+ eventTimeKind: string | null;
6900
+ /** When true, the user has manually set this memory's topics (entity links);
6901
+ * auto-extraction leaves them alone. False on legacy/auto rows. */
6902
+ topicsUserManaged: boolean;
6903
+ /** Unix ms of the last LLM topic-extraction pass over this memory's content.
6904
+ * Null = never extracted standalone; rows that already carry entity links
6905
+ * are grandfathered as extracted (see getMemoriesNeedingTopicExtractionOp). */
6906
+ topicsExtractedAt: number | null;
6907
+ /** Write-time supersession (A2): id of the newer memory that replaced this
6908
+ * one (incompatible-value update, e.g. "Lives in Portland" → "Lives in SF").
6909
+ * Null = live. Superseded rows are excluded from recall/dedup by default but
6910
+ * kept for history + the read-time fallback. */
6911
+ supersededBy: string | null;
6912
+ /** Unix ms when this memory was superseded. Null when live. */
6913
+ supersededAt: number | null;
6914
+ /** Extraction-logic version this memory was last stamped under. Null (pre-v38)
6915
+ * reads as 0, so a TOPICS_EXTRACTION_VERSION bump re-extracts stale rows. */
6916
+ topicsExtractedVersion: number | null;
6917
+ /** C3 re-observation watermark: Unix ms of the last retain() merge into this
6918
+ * fact. Distinct from `updatedAt` (which merges preserve). Null = never
6919
+ * re-observed since the column was added; synthesis falls back to
6920
+ * `updatedAt` in that case. */
6921
+ lastObservedAt: number | null;
6922
+ /** Typed memory (PR1) — the extractor's FactType for this fact, or null on
6923
+ * legacy/manual/untyped rows. Plaintext string (not narrowed to FactType
6924
+ * here since the DB can hold any stored value). */
6925
+ factType: string | null;
6926
+ /** Decay archive state (PR2) — Unix ms when archived, or null when active. */
6927
+ archivedAt: number | null;
6928
+ /** Tier-0 security (PR3) — "quarantined" | "trusted" | null. */
6929
+ trustTier: string | null;
6930
+ createdAt: Date;
6931
+ updatedAt: Date;
6932
+ isDeleted: boolean;
6933
+ }
6934
+ interface CreateVaultMemoryOptions {
6666
6935
  content: string;
6667
- type: FactType;
6668
- confidence: number;
6669
- sourceMessageIds: string[];
6670
- entities: ExtractedEntity[];
6671
- /** W6 temporal lane — when the event in this fact occurred. Resolved
6672
- * to absolute timestamps by the LLM; null when the fact has no
6673
- * temporal anchor. */
6674
- eventTime: {
6675
- kind: "point" | "range" | "ongoing";
6676
- /** Unix ms timestamp of the event start (or point). */
6677
- start: number;
6678
- /** Unix ms timestamp of the event end. Only set when kind='range'. */
6936
+ /** Scope for the memory. Defaults to "private" if omitted. */
6937
+ scope?: string;
6938
+ /** Folder ID for organization, null or omitted if unfiled */
6939
+ folderId?: string | null;
6940
+ /** JSON-stringified embedding vector to persist */
6941
+ embedding?: string;
6942
+ /** Model that produced `embedding`. Persisted alongside it so a later
6943
+ * model change can detect and re-embed stale vectors. */
6944
+ embeddingModel?: string;
6945
+ /** Source message IDs that produced this fact (auto-extraction provenance). */
6946
+ sourceChunkIds?: string[];
6947
+ /** Initial proof count. Defaults to 1 if omitted. */
6948
+ proofCount?: number;
6949
+ /** How the memory was created. Defaults to "manual" if omitted. */
6950
+ source?: string;
6951
+ /** W6 temporal lane — when the event in this memory occurred. */
6952
+ eventTime?: {
6953
+ /** Unix ms timestamp of event start (or point). */
6954
+ start: number | null;
6955
+ /** Unix ms timestamp of event end (range only). */
6679
6956
  end: number | null;
6680
- } | null;
6957
+ /** Kind: 'point' | 'range' | 'ongoing' | null (or omit). */
6958
+ kind: "point" | "range" | "ongoing" | null;
6959
+ };
6960
+ /** Typed memory (PR1) — the extractor's classification for this fact.
6961
+ * Omit for manual/untyped saves (persisted as null). */
6962
+ factType?: FactType;
6963
+ /** Tier-0 security (PR3) — set "quarantined" when the injection screen
6964
+ * flagged this fact. Omit for the default (null/trusted). */
6965
+ trustTier?: string;
6681
6966
  }
6682
- /**
6683
- * Auth + endpoint for the extraction LLM call. Auth is the dual pattern —
6684
- * one of `apiKey` / `getToken` is required at runtime; see
6685
- * {@link PortalLlmAuth}.
6686
- */
6687
- interface ExtractFactsOptions extends PortalLlmAuth {
6688
- baseUrl?: string;
6689
- model?: string;
6690
- /** Override the global fetch implementation (useful for tests). */
6691
- fetchFn?: typeof fetch;
6967
+ interface UpdateVaultMemoryOptions {
6968
+ content: string;
6969
+ /** If provided, updates the memory's scope. */
6970
+ scope?: string;
6971
+ /** If provided, moves the memory to this folder. */
6972
+ folderId?: string | null;
6973
+ /** JSON-stringified embedding vector to persist, or null to clear stale embedding */
6974
+ embedding?: string | null;
6975
+ /** Model that produced `embedding`. Set whenever `embedding` is written so
6976
+ * the stored model tag stays in sync with the vector. */
6977
+ embeddingModel?: string | null;
6978
+ /** Replace source-chunk-ids list (used during merge to accumulate provenance). */
6979
+ sourceChunkIds?: string[];
6980
+ /** Set an absolute proof count. Prefer {@link proofCountIncrement} for
6981
+ * re-observation paths so the read+write happens inside the writer
6982
+ * and concurrent retains can't lose updates. */
6983
+ proofCount?: number;
6984
+ /** Atomically bump proof_count by this delta inside the write block.
6985
+ * Reads the current value from the in-memory record at write time, so
6986
+ * two parallel retain() calls observe each other's commits and neither
6987
+ * loses its increment. Wins over `proofCount` when both are set. */
6988
+ proofCountIncrement?: number;
6989
+ /** Set source ("manual" | "auto-extracted" | "capsule"). */
6990
+ source?: string;
6692
6991
  /**
6693
- * The user's own name(s) / handle(s) (e.g. profile nickname, wallet display
6694
- * name). Candidates whose entire content is just one of these are dropped —
6695
- * a personal memory system already knows who the user is, so "Peter Lee" is
6696
- * circular noise. Optional; when omitted only the bare-fragment gate applies.
6992
+ * W6 temporal lane — write the event-time fields on update. Use during
6993
+ * auto-merge to preserve (or refine) the original event-time signal when
6994
+ * a new observation lands on an existing fact. Omit to leave the
6995
+ * existing values untouched.
6697
6996
  */
6698
- userIdentity?: string[];
6997
+ eventTime?: {
6998
+ start: number | null;
6999
+ end: number | null;
7000
+ kind: "point" | "range" | "ongoing" | null;
7001
+ };
6699
7002
  /**
6700
- * Reference "now" (Unix ms) for resolving relative temporal phrases in the
6701
- * transcript ("yesterday", "next week", "in two days") into the absolute
6702
- * YYYY-MM-DD anchors the W6 temporal lane indexes on. The transcript itself
6703
- * carries no timestamps, so without an anchor the model resolves relatives
6704
- * against its own training-cutoff guess and emits wrong `eventTime` dates.
6705
- * Defaults to `Date.now()`. Override for back-dated eval corpora and
6706
- * deterministic tests (mirrors {@link RecallOptions.now}).
6707
- *
6708
- * Server-side timezone note: the ms value is formatted to a calendar date in
6709
- * the process's local timezone (same basis as `parseLocalCalendarDay`). On a
6710
- * UTC server, a user near midnight in a non-UTC offset can get the wrong
6711
- * calendar day. Pass the user's local-midnight timestamp as `now` when the
6712
- * process timezone doesn't match the user's.
7003
+ * When true, restore the existing `updated_at` after the write so the
7004
+ * recency multiplier doesn't see a re-observation as a brand-new fact.
7005
+ * Set by auto-merge/consolidate paths — they want proof_count to bump
7006
+ * without inflating recency on top.
6713
7007
  */
6714
- now?: number;
7008
+ preserveUpdatedAt?: boolean;
7009
+ /** C3: Unix ms to stamp as the re-observation watermark (`last_observed_at`).
7010
+ * Set by retain() merge/consolidate paths so a re-observation records "seen
7011
+ * again now" without touching `updated_at` (which `preserveUpdatedAt` keeps
7012
+ * pinned). Omit to leave the existing value untouched. */
7013
+ lastObservedAt?: number;
7014
+ /** If provided, sets whether the user has taken manual control of this
7015
+ * memory's topics. Set by {@link setMemoryEntitiesOp}. */
7016
+ topicsUserManaged?: boolean;
7017
+ /** Typed memory (PR1) — set/refine the fact's classification on update.
7018
+ * Used by retain()'s lazy backfill (adopt an incoming type only when the
7019
+ * existing row has none). Omit to leave the existing value untouched. */
7020
+ factType?: FactType;
7021
+ /** Tier-0 security (PR3) — set the trust tier on update ("quarantined" |
7022
+ * "trusted"). Omit to leave the existing value untouched. */
7023
+ trustTier?: string;
6715
7024
  /**
6716
- * Max attempts for the extraction call on a transient failure (default 3).
6717
- * Lower it to bound how long extraction can hold a turn open — e.g. a worker
6718
- * that runs extraction behind an in-flight-turn guard can pass `2` to keep
6719
- * repeated failures from delaying later turns.
7025
+ * PR5 — un-archive on re-observe. When true, clears `archived_at` (null) as
7026
+ * part of the write, resurrecting a decayed row that a new observation just
7027
+ * merged into. retain() sets this (with `preserveUpdatedAt` OFF) so the
7028
+ * restored row's decay clock resets and it doesn't immediately re-archive.
7029
+ * Omit/false to leave `archived_at` untouched.
6720
7030
  */
6721
- maxAttempts?: number;
6722
- /** Per-attempt timeout (ms) for the extraction call. Defaults to the portal
6723
- * helper's 60s. Combine with {@link maxAttempts} to cap the total time budget. */
6724
- timeoutMs?: number;
7031
+ restore?: boolean;
7032
+ }
7033
+
7034
+ interface VaultMemoryOperationsContext {
7035
+ database: Database;
7036
+ vaultMemoryCollection: Collection<VaultMemory>;
7037
+ walletAddress?: string;
7038
+ signMessage?: SignMessageFn;
7039
+ embeddedWalletSigner?: EmbeddedWalletSignerFn;
7040
+ /** When set, operations scope to this user (server-side multi-user). */
7041
+ userId?: string;
6725
7042
  /**
6726
- * Absolute wall-clock budget (ms) across ALL extraction attempts incl. backoff.
6727
- * When set, the loop stops before an attempt that would exceed it, so worst-case
6728
- * latency is bounded rather than `maxAttempts × timeoutMs`.
7043
+ * Asserts this context runs against a physically single-tenant database — one
7044
+ * where every row belongs to the same owner (the per-wallet client DBs, which
7045
+ * hold exactly one wallet's rows written with `user_id = null`). This is the
7046
+ * ONLY thing that makes the decay sweep's unscoped scan/archive/delete safe
7047
+ * without a `userId`: see {@link assertVaultScopeForSweep}. A shared /
7048
+ * multi-tenant DB must NOT set this — it must scope by `userId` instead.
7049
+ * `walletAddress` presence alone is NOT a substitute (the sweep query filters
7050
+ * by `user_id` only, so a bare `walletAddress` on a shared DB would sweep
7051
+ * every tenant).
6729
7052
  */
6730
- totalTimeoutMs?: number;
7053
+ singleTenant?: boolean;
6731
7054
  /**
6732
- * Override the retry backoff (ms) for a given 1-based attempt index. The
6733
- * extraction call retries transient failures internally (default exponential
6734
- * backoff); pass `() => 0` to retry without delay (useful for tests).
7055
+ * When set, vault delete ops cascade to memory_entity rows pointing at
7056
+ * the deleted memories. Without this the W5 graph lane keeps returning
7057
+ * IDs of soft-deleted memories and the join table grows unbounded.
6735
7058
  */
6736
- backoffMs?: (attempt: number) => number;
7059
+ entityCtx?: EntityOperationsContext;
7060
+ }
7061
+ declare function createVaultMemoryOp(ctx: VaultMemoryOperationsContext, opts: CreateVaultMemoryOptions): Promise<StoredVaultMemory>;
7062
+ declare function createVaultMemoriesBatchOp(ctx: VaultMemoryOperationsContext, optionsArray: CreateVaultMemoryOptions[]): Promise<StoredVaultMemory[]>;
7063
+ declare function getVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string): Promise<StoredVaultMemory | null>;
7064
+ declare function getAllVaultMemoriesOp(ctx: VaultMemoryOperationsContext, options?: {
7065
+ scopes?: string[];
7066
+ since?: Date;
7067
+ limit?: number;
7068
+ folderId?: string | null;
6737
7069
  /**
6738
- * When set, PII (emails, phones, SSNs, cards, IPs, API keys, …) in the
6739
- * conversation transcript is replaced with tagged placeholders before the
6740
- * extraction call, and the returned facts + entities are de-anonymized so the
6741
- * vault keeps the real values while raw PII never reaches the extraction
6742
- * model (and, via `extractAndRetain`, the consolidation model). Pass `true`
6743
- * for a fresh per-call redactor, or a shared {@link PiiRedactor} to keep
6744
- * placeholder numbering consistent with other calls.
6745
- *
6746
- * NOTE: this does NOT cover the embeddings provider. Facts are stored and
6747
- * embedded with their real values, so to keep PII out of embedding requests
6748
- * set `RetainContext.embeddingOptions.maskInput` (e.g. `redactor.maskText`)
6749
- * as well — the two are independent switches.
7070
+ * Include soft-deleted memories in the result (each carries
7071
+ * `isDeleted: true`). Default `false` — deleted rows are excluded, as
7072
+ * they are from every other read path. Used by the Memory Graph to
7073
+ * render "forgotten" nodes; ordinary consumers should leave this off.
6750
7074
  */
6751
- piiRedaction?: boolean | PiiRedactor;
7075
+ includeDeleted?: boolean;
7076
+ /** Include archived (decayed) memories. Default `false` (PR1 choke point). */
7077
+ includeArchived?: boolean;
7078
+ /** Include quarantined memories. Default `false` (PR1 choke point). */
7079
+ includeQuarantined?: boolean;
7080
+ /** Typed memory (PR1) — restrict to these fact types. Omit for no filter. */
7081
+ factTypes?: string[];
6752
7082
  /**
6753
- * Called when the extraction LLM returned no usable result after exhausting
6754
- * its retries (empty/malformed completion, network/HTTP error) — i.e. a
6755
- * *failure* that drops the turn's facts, as opposed to a legitimate
6756
- * `{candidates: []}` "nothing durable here". Lets callers distinguish a
6757
- * silently-degrading extractor from quiet turns (the two are otherwise
6758
- * indistinguishable). See {@link extractAndRetain}'s `outcome`.
7083
+ * Include A2-superseded memories (each carries `supersededBy`). Default
7084
+ * `false` — superseded rows are excluded, as they are from recall/dedup.
7085
+ * Used by a "memory history" view to render retired facts.
6759
7086
  */
6760
- onExhaustedEmpty?: () => void;
7087
+ includeSuperseded?: boolean;
7088
+ }): Promise<StoredVaultMemory[]>;
7089
+ declare function getAllVaultMemoryContentsOp(ctx: VaultMemoryOperationsContext, options?: {
7090
+ since?: Date;
7091
+ }): Promise<string[]>;
7092
+ declare function updateVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string, opts: UpdateVaultMemoryOptions): Promise<StoredVaultMemory | null>;
7093
+ /**
7094
+ * Replace a memory's topic (entity) links with a user-chosen set and mark the
7095
+ * memory `topics_user_managed` so auto-extraction stops touching its links.
7096
+ * Replace semantics: the given `entities` become the memory's complete topic
7097
+ * set (pass `[]` to clear all topics — the memory stays user-managed and
7098
+ * unclustered). Requires `ctx.entityCtx`. Preserves `updated_at` so a topic
7099
+ * edit doesn't inflate the recency multiplier.
7100
+ */
7101
+ declare function setMemoryEntitiesOp(ctx: VaultMemoryOperationsContext, memoryId: string, entities: ReadonlyArray<EntityInput>): Promise<StoredVaultMemory | null>;
7102
+ /**
7103
+ * Reset a memory's topics to automatic: clear the `topics_user_managed` flag so
7104
+ * auto-extraction resumes owning its links. Invalidates `topics_extracted_version`
7105
+ * (→ null) and ensures a NON-NULL `topics_extracted_at`, so the next sweep routes
7106
+ * the row through the stale-version pending path and actually RE-EXTRACTS it via
7107
+ * the LLM. A never-stamped user-curated row (`setMemoryEntitiesOp` marks
7108
+ * user-managed without stamping, so stamp can be null) would otherwise fall
7109
+ * through the sweep's unstamped→`linkedUnstamped` grandfather path (stamped
7110
+ * current, no LLM pass); forcing a stamp when absent avoids that. Existing links
7111
+ * are left in place until the re-extraction replaces them. Preserves `updated_at`.
7112
+ */
7113
+ declare function clearMemoryTopicsOverrideOp(ctx: VaultMemoryOperationsContext, memoryId: string): Promise<boolean>;
7114
+ declare function deleteVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string): Promise<boolean>;
7115
+ /**
7116
+ * Mark a memory as superseded by a newer one (A2 write-time supersession).
7117
+ * The row stays in the table (history + read-time fallback) but is excluded
7118
+ * from recall/dedup by default via `superseded_by`. Idempotent-ish: no-op if
7119
+ * the row is missing, not owned, deleted, or already superseded. Does NOT
7120
+ * preserve `updated_at` — superseded rows are hidden from recall, so their
7121
+ * recency is irrelevant.
7122
+ *
7123
+ * @param id - the memory being retired (e.g. "Lives in Portland")
7124
+ * @param supersededById - the newer memory that replaced it (e.g. "Lives in SF")
7125
+ */
7126
+ declare function supersedeVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string, supersededById: string): Promise<boolean>;
7127
+ /**
7128
+ * Get all non-deleted, unfiled vault memories (folder_id is null).
7129
+ */
7130
+ declare function getUnfiledVaultMemoriesOp(ctx: VaultMemoryOperationsContext): Promise<StoredVaultMemory[]>;
7131
+ /**
7132
+ * The current topic-extraction logic version. Bump this whenever the extraction
7133
+ * prompt or model in `topicExtract.ts` changes: every memory stamped under an
7134
+ * older version (including pre-v37 rows, read as version 0) is then re-extracted
7135
+ * by the next sweep, so topic-quality improvements propagate across the existing
7136
+ * vault. The worker's `limit` drains that re-extraction across sweeps.
7137
+ */
7138
+ declare const TOPICS_EXTRACTION_VERSION = 1;
7139
+ /**
7140
+ * Result of {@link getMemoriesNeedingTopicExtractionOp}: which memories the
7141
+ * background topic worker should run LLM entity extraction on, and which it
7142
+ * should merely stamp as already-extracted.
7143
+ */
7144
+ interface MemoriesNeedingTopicExtraction {
6761
7145
  /**
6762
- * Called when the extractor DID produce candidates but PII de-anonymization
6763
- * dropped every one of them — the model mangled its placeholders (so they
6764
- * can't be restored to real values) or restoring the values blew the length
6765
- * cap. These drops happen before `retain()`, so `failedCount` can't see them,
6766
- * and the turn would otherwise masquerade as a quiet `no-facts` result. Lets
6767
- * H3's `outcome` surface `dropped-after-redaction` so a rising PII-drop rate
6768
- * (i.e. redaction silently eating facts) is alarmable.
7146
+ * Memories to run LLM topic extraction on (decrypted): never-extracted rows
7147
+ * with no entity links, plus stamped rows edited since their last pass
7148
+ * (`updated_at` > `topics_extracted_at`) or extracted under an older
7149
+ * `topics_extracted_version` than {@link TOPICS_EXTRACTION_VERSION}. Edited /
7150
+ * stale-version rows come first (they get priority under `limit`), each group
7151
+ * newest-created first.
7152
+ */
7153
+ pending: StoredVaultMemory[];
7154
+ /**
7155
+ * IDs of rows that already have entity links but no watermark — legacy rows
7156
+ * extracted by the conversation pipeline before v36. Grandfather these with
7157
+ * {@link stampTopicsExtractedAtOp} (no LLM call) so a later content edit
7158
+ * makes them re-extractable instead of invisible forever. Bounded by the
7159
+ * same `limit` as {@link pending} — stamping loads a Model per row, so the
7160
+ * grandfather backlog is drained across sweeps rather than in one spike.
6769
7161
  */
6770
- onCandidatesDropped?: () => void;
7162
+ linkedUnstamped: string[];
6771
7163
  }
6772
7164
  /**
6773
- * Stage 1 — call the LLM to extract candidate facts from the recent
6774
- * conversation. Returns post-validated candidates only (confidence
6775
- * threshold, source-id check, length cap, schema validation). Returns
6776
- * an empty array if the LLM emits malformed JSON or no candidates.
7165
+ * Sweep query for the background topic-extraction worker: partition the
7166
+ * user's non-deleted, non-user-managed memories by what the worker should do
7167
+ * with them (see {@link MemoriesNeedingTopicExtraction}). User-managed rows
7168
+ * are never returned — the user owns their topics, including an intentionally
7169
+ * empty set. Requires `ctx.entityCtx` for the entity-links check.
7170
+ */
7171
+ declare function getMemoriesNeedingTopicExtractionOp(ctx: VaultMemoryOperationsContext, options?: {
7172
+ limit?: number;
7173
+ }): Promise<MemoriesNeedingTopicExtraction>;
7174
+ /**
7175
+ * Stamp `topics_extracted_at` (and `topics_extracted_version`) on the given
7176
+ * memories — the topic worker calls this after a successful extraction pass
7177
+ * (including zero-entity results, so quiet memories aren't re-asked every sweep)
7178
+ * and to grandfather `linkedUnstamped` rows without an LLM call. `version`
7179
+ * defaults to {@link TOPICS_EXTRACTION_VERSION}: stamping at the current version
7180
+ * (for both fresh extractions and grandfathered legacy rows) means they aren't
7181
+ * re-extracted until a future version bump. Preserves `updated_at` so a stamp
7182
+ * never inflates the recency multiplier — and never masks a concurrent content
7183
+ * edit from the next sweep. Skips deleted, foreign-user, and user-managed rows.
7184
+ * Returns the IDs actually stamped.
6777
7185
  *
6778
- * A null from `callPortalJsonCompletion` means a *failure* (empty completion,
6779
- * malformed JSON, network/HTTP error) — distinct from a successful
6780
- * `{candidates: []}`, which parses to a non-null object. A failed extraction
6781
- * silently drops the whole turn's memories, so transient failures matter:
6782
- * `callPortalJsonCompletion` retries them internally with backoff (default 3
6783
- * attempts), so a one-off empty/malformed completion from a reasoning-class
6784
- * model doesn't lose the turn. Only an exhausted-retry null reaches here.
7186
+ * ALL eligibility AND `updated_at` are read from the LIVE Model inside the
7187
+ * serialized writer — never a pre-writer snapshot. Writers are serialized, so
7188
+ * a content edit or topic-override that commits before this writer runs is
7189
+ * observed here: its fresh `updated_at` is preserved (so the next sweep's
7190
+ * `updated_at > stamp` check still fires) and a mid-pass user-managed flip
7191
+ * skips the row. Reading `updated_at` from a raw pre-fetch instead would write
7192
+ * a stale value back, pushing `updated_at < topics_extracted_at` and hiding
7193
+ * the edited memory from every future sweep.
7194
+ *
7195
+ * Callers bound the input via `getMemoriesNeedingTopicExtractionOp`'s `limit`
7196
+ * (both `pending` and `linkedUnstamped` are capped), so the per-row Model load
7197
+ * needed to `prepareUpdate` stays bounded and never spikes the RecordCache.
6785
7198
  */
6786
- declare function extractFacts(messages: AutoExtractMessage[], options: ExtractFactsOptions): Promise<ExtractedCandidate[]>;
7199
+ declare function stampTopicsExtractedAtOp(ctx: VaultMemoryOperationsContext, memoryIds: readonly string[], extractedAt: number, version?: number): Promise<string[]>;
7200
+ declare function deleteAllVaultMemoriesForUserOp(ctx: VaultMemoryOperationsContext, userId: string): Promise<number>;
6787
7201
  /**
6788
- * Outcome of the EXTRACTOR stage for a turn — independent of whether the
6789
- * subsequent `retain()` writes landed (that's `failedCount`):
6790
- * - `extracted` — the extractor produced at least one candidate above
6791
- * the confidence floor. Whether those writes succeeded
6792
- * is reported separately by `failedCount` — so
6793
- * `extracted` + `failedCount > 0` means "found facts but
6794
- * writes are failing", which is more signal than
6795
- * collapsing it into `no-facts` would give.
6796
- * - `no-facts` — the extractor ran fine but found nothing durable.
6797
- * - `empty-after-retry` — the extractor returned empty/malformed after
6798
- * exhausting retries (a *failure*). Distinguishing this
6799
- * from `no-facts` is what makes a silently-degrading
6800
- * extractor alarmable rather than invisible.
6801
- * - `dropped-after-redaction` — the extractor found facts but PII
6802
- * de-anonymization dropped every one (mangled
6803
- * placeholders / over-cap after restore), before retain.
6804
- * A degradation `failedCount` can't see; would otherwise
6805
- * look like `no-facts`.
7202
+ * The minimal plaintext shape the decay sweep needs — mirrors the `DecayInput`
7203
+ * shape in `memory/decay` plus the row id. Deliberately omits `content`
7204
+ * (encrypted) so the sweep stays zero-knowledge.
6806
7205
  */
6807
- type ExtractOutcome = "extracted" | "no-facts" | "empty-after-retry" | "dropped-after-redaction";
7206
+ interface DecayCandidateRaw {
7207
+ uniqueId: string;
7208
+ factType: string | null;
7209
+ eventTimeEnd: number | null;
7210
+ eventTimeKind: string | null;
7211
+ /** Unix ms — the raw `updated_at`, used both for the age rule and as the
7212
+ * optimistic-concurrency guard passed back to {@link archiveVaultMemoryOp}. */
7213
+ updatedAt: number;
7214
+ archivedAt: number | null;
7215
+ source: string | null;
7216
+ /** `trusted` | `quarantined` | null. Quarantined rows still decay by RULE, but
7217
+ * are never handed to the optional content-reading decay classifier (they must
7218
+ * not egress poison content — see the decay sweeper's `isBorderline`). */
7219
+ trustTier: string | null;
7220
+ }
6808
7221
  /**
6809
- * Stage 2 — for each extracted candidate, call retain() with auto-merge
6810
- * enabled. When `consolidateOptions` are wired, retain()'s consolidation pass
6811
- * is the "resolver": a second LLM call against the top-K existing vault
6812
- * memories that decides create/update/noop/supersede — including retiring a
6813
- * stale value on a state change (the supersession the extraction prompt above
6814
- * promises). Without consolidation, retain() still dedups at the cosine-merge
6815
- * level, and the read-time supersession heuristic remains the fallback.
7222
+ * Decay sweep candidate scan (PR2). Selects the plaintext columns
7223
+ * `classifyDecay` (in `memory/decay`) needs via
7224
+ * `unsafeFetchRaw` — NO Model per row (dodges the never-evicted RecordCache /
7225
+ * web Pile-2 OOM history) and NO `content` read / decrypt (zero-knowledge).
6816
7226
  *
6817
- * Returns the candidates that survived validation along with the retain
6818
- * result for each (which captures whether the fact was created, merged,
6819
- * or skipped), plus an `outcome` summarizing why the turn did/didn't produce
6820
- * facts (see {@link ExtractOutcome}).
7227
+ * Includes archived AND quarantined rows (so archived→delete transitions and
7228
+ * aged quarantined rows are seen) but excludes hard-deleted rows — the
7229
+ * `baseVaultConditions` default keeps `is_deleted = false`.
7230
+ *
7231
+ * Refuses to run on an unscoped multi-tenant context (see
7232
+ * {@link assertVaultScopeForSweep}).
6821
7233
  */
6822
- declare function extractAndRetain(messages: AutoExtractMessage[], retainCtx: RetainContext, options: {
6823
- extract: ExtractFactsOptions;
6824
- minConfidence?: number;
6825
- /** Override scope/folder for all retained facts. */
6826
- scope?: string;
6827
- folderId?: string | null;
6828
- /**
6829
- * Forwarded verbatim to each retain() call — enables the LLM-based
6830
- * consolidation pass (Hindsight facet-dedup) on every write. See
6831
- * `RetainOptions.consolidateOptions` for auth + observability fields.
6832
- */
6833
- consolidateOptions?: RetainOptions["consolidateOptions"];
6834
- /**
6835
- * When provided, persist each candidate's `entities[]` to the
6836
- * entity + memory_entity tables after a successful retain. This
6837
- * powers the W5 graph retrieval lane — recall() can query for
6838
- * memories sharing entities with the user's question.
6839
- */
6840
- entityCtx?: EntityOperationsContext;
6841
- /**
6842
- * Per-candidate failure hook — invoked once per filtered candidate
6843
- * whose `retain()` call threw. Lets UI layers surface "couldn't save
6844
- * X" toasts; without it consumers only see the aggregate
6845
- * `failedCount` and can't name which facts dropped.
6846
- */
6847
- onCandidateFailed?: (candidate: ExtractedCandidate, error: unknown) => void;
6848
- }): Promise<{
6849
- candidates: ExtractedCandidate[];
6850
- results: RetainResult[];
6851
- failedCount: number;
6852
- outcome: ExtractOutcome;
6853
- }>;
7234
+ declare function getDecayCandidatesRawOp(ctx: VaultMemoryOperationsContext): Promise<DecayCandidateRaw[]>;
7235
+ /**
7236
+ * Archive a memory (decay soft state, PR2) — set `archived_at`. An archived row
7237
+ * drops out of every recall lane via the `baseVaultConditions` choke point but
7238
+ * stays recoverable via {@link restoreVaultMemoryOp} until the hard-delete
7239
+ * window elapses.
7240
+ *
7241
+ * Concurrency: re-checks `is_deleted` / ownership / `archived_at` INSIDE the
7242
+ * serialized writer (mirrors {@link updateVaultMemoryOp}). Additionally, when
7243
+ * `opts.expectedUpdatedAt` is given, the archive is skipped if the row's current
7244
+ * `updated_at` no longer matches — i.e. a `retain()` merge (which bumps
7245
+ * `updated_at`) landed between the sweep's candidate scan and this write, so the
7246
+ * fact was just re-observed and must NOT be archived on stale data. Idempotent:
7247
+ * a row another sweep already archived returns `false` (no double-write).
7248
+ *
7249
+ * @returns `true` if this call archived the row; `false` if it was stale
7250
+ * (deleted / not owned / already archived / refreshed under us).
7251
+ */
7252
+ declare function archiveVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string, opts?: {
7253
+ /** Timestamp to stamp into `archived_at`. Default `Date.now()`. */
7254
+ now?: number;
7255
+ /** Optimistic-concurrency guard: skip if the row's `updated_at` changed
7256
+ * since the sweep observed it (a concurrent re-observation). */
7257
+ expectedUpdatedAt?: number;
7258
+ }): Promise<boolean>;
7259
+ /**
7260
+ * Restore an archived memory (PR2) — clear `archived_at` so it re-enters recall.
7261
+ * Re-checks `is_deleted` / ownership inside the writer. Idempotent on an
7262
+ * already-active row (clearing null → null is harmless).
7263
+ *
7264
+ * @returns `true` if the row was restored (or already active); `false` if it was
7265
+ * deleted / not owned / missing.
7266
+ */
7267
+ declare function restoreVaultMemoryOp(ctx: VaultMemoryOperationsContext, id: string): Promise<boolean>;
7268
+ /**
7269
+ * Hard-delete a memory ONLY if it is still archived and still past the delete
7270
+ * window (PR2 decay terminal transition). Unlike the generic
7271
+ * {@link deleteVaultMemoryOp}, this re-reads `archived_at` INSIDE the writer and
7272
+ * bails if the row was restored (`archived_at → null`) or re-archived more
7273
+ * recently since the sweep's candidate scan. This is the restore-vs-delete
7274
+ * mutual-exclusion guard: a user hitting Restore between the scan and this write
7275
+ * must win, so their just-rescued memory is never permanently lost.
7276
+ *
7277
+ * @returns `true` if this call hard-deleted the row; `false` if it was stale
7278
+ * (deleted / not owned / no longer archived / no longer past the window).
7279
+ */
7280
+ declare function hardDeleteDecayedOp(ctx: VaultMemoryOperationsContext, id: string, opts: {
7281
+ hardDeleteWindowMs: number;
7282
+ now?: number;
7283
+ }): Promise<boolean>;
7284
+ declare function updateVaultMemoryEmbeddingOp(ctx: VaultMemoryOperationsContext, id: string, embedding: string, embeddingModel: string): Promise<boolean>;
6854
7285
 
6855
7286
  /**
6856
7287
  * Auto-extraction worker — orchestration glue for wiring
@@ -6910,6 +7341,16 @@ interface MemoryExtractedEvent {
6910
7341
  result: RetainResult;
6911
7342
  conversationId?: string;
6912
7343
  }
7344
+ /**
7345
+ * Tier-0 security (PR3) — fired once per candidate the injection screen
7346
+ * quarantined and persisted as an audit row. Distinct from
7347
+ * {@link MemoryExtractedEvent} so a client can render "held for review"
7348
+ * without treating a poisoned fact as a normal saved memory.
7349
+ * @public
7350
+ */
7351
+ interface MemoryQuarantinedEvent extends QuarantinedMemoryInfo {
7352
+ conversationId?: string;
7353
+ }
6913
7354
  /** @public */
6914
7355
  interface TurnSkippedEvent {
6915
7356
  /**
@@ -7048,6 +7489,12 @@ interface CreateAutoExtractorOptions {
7048
7489
  };
7049
7490
  /** Per-fact event — fires once per memory written. */
7050
7491
  onMemoryExtracted?: (event: MemoryExtractedEvent) => void;
7492
+ /**
7493
+ * Tier-0 security (PR3) — fires once per candidate quarantined by the
7494
+ * injection screen (and persisted as an audit row). Lets a client surface a
7495
+ * "held for review" state instead of the fact silently disappearing.
7496
+ */
7497
+ onMemoryQuarantined?: (event: MemoryQuarantinedEvent) => void;
7051
7498
  /** Per-turn event — fires once after the whole pipeline finishes. */
7052
7499
  onTurnComplete?: (event: TurnCompleteEvent) => void;
7053
7500
  /** Diagnostic — fires when a turn is skipped. */
@@ -7108,6 +7555,536 @@ declare const DEFAULT_CHUNK_CACHE_SIZE = 5000;
7108
7555
  */
7109
7556
  declare function createChunkVectorCache(maxSize?: number): ChunkVectorCache;
7110
7557
 
7558
+ /**
7559
+ * Temporal decay classifier (PR2) — pure, DB-free, unit-testable.
7560
+ *
7561
+ * Decides whether a stored memory should be kept, archived (soft, recoverable),
7562
+ * or hard-deleted, based ONLY on its plaintext columns. This is the
7563
+ * zero-knowledge core of the decay sweep: it never sees `content` and never
7564
+ * triggers a signature/decrypt, so it can run wherever a wallet key is NOT
7565
+ * loaded. The sweep worker ({@link ./decayWorker}) feeds it raw rows selected
7566
+ * via `unsafeFetchRaw` and materializes Models only for the transitions.
7567
+ *
7568
+ * Lifecycle (mirrors the timestamp state machine in db/schema.ts):
7569
+ * active → archived (set `archived_at`) — recoverable, drops out of recall
7570
+ * archived → deleted (set `is_deleted`) — terminal, after HARD_DELETE_WINDOW
7571
+ *
7572
+ * Per-type TTL policy (the "becomes past" intuition):
7573
+ * - identity / preference / relationship / constraint → never age-archive
7574
+ * (durable facts about who the user is; Infinity TTL).
7575
+ * - plan / ongoing_context → short TTL (they go stale as time moves on).
7576
+ * - other / null (untyped/legacy) → medium TTL.
7577
+ * `source === "manual"` memories are protected from AUTO-ARCHIVE (user-curated)
7578
+ * — but NOT from the hard-delete clock once they are archived: archive is the
7579
+ * shared purge buffer for every row, so an already-archived manual memory is
7580
+ * still deleted after the window (the archived check runs before the manual
7581
+ * short-circuit by design).
7582
+ */
7583
+ /** The verdict for a single memory. */
7584
+ type DecayVerdict = "keep" | "archive" | "delete";
7585
+ /** Short TTL — `plan` / `ongoing_context` age out ~30 days after last touch. */
7586
+ declare const SHORT_TTL_MS: number;
7587
+ /** Medium TTL — `other` / untyped rows age out ~180 days after last touch. */
7588
+ declare const MEDIUM_TTL_MS: number;
7589
+ /**
7590
+ * "Never" TTL — durable identity-class types (identity/preference/relationship/
7591
+ * constraint) never age-archive. Expressed as +Infinity so the age comparison
7592
+ * `now - updatedAt > ttl` is always false.
7593
+ */
7594
+ declare const NEVER_TTL_MS: number;
7595
+ /**
7596
+ * How long an archived memory lingers (recoverable) before the sweep hard-
7597
+ * deletes it. ~30 days gives the user a window to restore an over-eager decay.
7598
+ */
7599
+ declare const HARD_DELETE_WINDOW_MS: number;
7600
+ /**
7601
+ * Grace applied after a `plan` / `ongoing_context` event's `event_time_end`
7602
+ * before it's considered "become past" and archived. Avoids archiving a plan
7603
+ * the instant its end date passes (the user may still reference it briefly).
7604
+ */
7605
+ declare const PAST_EVENT_GRACE_MS: number;
7606
+ /**
7607
+ * Per-type TTL + window overrides. Pass a partial to {@link classifyDecay} /
7608
+ * the sweeper to tune behavior (evaluation harnesses, tests). Anything omitted
7609
+ * falls back to {@link DEFAULT_DECAY_POLICY}.
7610
+ */
7611
+ interface DecayPolicy {
7612
+ /**
7613
+ * Age TTL (ms since `updatedAt`) per FactType. A type absent from this map —
7614
+ * or a null/unknown `factType` — uses {@link DecayPolicy.fallbackTtlMs}.
7615
+ */
7616
+ ttlByType: Record<string, number>;
7617
+ /** TTL for `null` / unknown fact types (the medium bucket). */
7618
+ fallbackTtlMs: number;
7619
+ /** How long an archived row lingers before hard delete. */
7620
+ hardDeleteWindowMs: number;
7621
+ /** Grace after a past `event_time_end` before archiving a plan/ongoing. */
7622
+ pastEventGraceMs: number;
7623
+ }
7624
+ /** Default policy — the locked per-type TTLs. */
7625
+ declare const DEFAULT_DECAY_POLICY: DecayPolicy;
7626
+ /**
7627
+ * The minimal plaintext shape {@link classifyDecay} reads. Deliberately excludes
7628
+ * `content` (encrypted; never touched by decay) — the sweep selects exactly
7629
+ * these columns so it stays zero-knowledge.
7630
+ */
7631
+ interface DecayInput {
7632
+ /**
7633
+ * The row's stable id. Not read by the rule engine ({@link classifyDecay}
7634
+ * ignores it) — it is threaded through so an optional content-reading decay
7635
+ * classifier (PR5, {@link createLlmDecayClassifier}) can fetch + decrypt the
7636
+ * row for a borderline verdict. Optional so pure rule-based callers/tests can
7637
+ * omit it.
7638
+ */
7639
+ id?: string;
7640
+ /** The extractor's FactType, or null (legacy/manual/untyped → medium bucket). */
7641
+ factType: string | null;
7642
+ /** W6 temporal lane — Unix ms the event ended (range/ongoing), or null. */
7643
+ eventTimeEnd: number | null;
7644
+ /** W6 temporal lane — `point | range | ongoing | null`. */
7645
+ eventTimeKind: string | null;
7646
+ /** Unix ms of the row's last write (re-observation resets this). */
7647
+ updatedAt: number;
7648
+ /** Unix ms when archived, or null when active. */
7649
+ archivedAt: number | null;
7650
+ /** `manual` | `auto-extracted` | `capsule` | null. Manual is never decayed. */
7651
+ source: string | null;
7652
+ /**
7653
+ * `trusted` | `quarantined` | null. Not read by the rule engine
7654
+ * ({@link classifyDecay} ignores it — quarantined rows still age/archive/delete
7655
+ * by RULE). It exists only so the sweeper's `isBorderline` can keep a
7656
+ * quarantined (injection-screened) row away from the optional content-reading
7657
+ * classifier, so poison content never egresses. Optional so pure rule-based
7658
+ * callers/tests can omit it (treated as not quarantined).
7659
+ */
7660
+ trustTier?: string | null;
7661
+ }
7662
+ /**
7663
+ * The age TTL for a fact type. `null` / unknown types fall to the medium
7664
+ * fallback bucket (never Infinity — untyped rows must still eventually age out).
7665
+ */
7666
+ declare function ttlForType(factType: string | null, policy?: Partial<DecayPolicy>): number;
7667
+ /**
7668
+ * Classify one memory into a decay verdict, reading only plaintext fields.
7669
+ *
7670
+ * Rules, in order (first match wins):
7671
+ * 0. Non-finite timestamps → keep (safe) + warn (corrupt row, observable).
7672
+ * 1. Already archived (`archivedAt != null`): delete once past the hard-delete
7673
+ * window, else keep — runs REGARDLESS of `source`, so the purge clock
7674
+ * applies to archived manual rows too.
7675
+ * 2. `source === "manual"` → keep — protects manual saves from AUTO-ARCHIVE
7676
+ * only (rules 3/4). Delete-of-already-archived is handled above.
7677
+ * 3. `plan` / `ongoing_context` whose event has become past — `eventTimeEnd`
7678
+ * is set AND older than `now - grace` → archive. An `ongoing` status with a
7679
+ * null `eventTimeEnd` is still ongoing, so this rule does not fire for it.
7680
+ * 4. Age fallback — `now - updatedAt > TTL(factType)` → archive. Durable types
7681
+ * have Infinity TTL, so this never fires for them; null/unknown use medium.
7682
+ * EXCEPTION: a `plan`/`ongoing_context` with a still-upcoming event
7683
+ * (`eventTimeEnd >= now`) is kept — it must not age-archive before the event
7684
+ * happens; only rule 3 (after it passes) may archive it.
7685
+ * 5. Otherwise → keep.
7686
+ *
7687
+ * @param m Plaintext decay inputs for one row.
7688
+ * @param now Reference time (Unix ms). Injected for determinism.
7689
+ * @param policy Optional partial policy overriding {@link DEFAULT_DECAY_POLICY}.
7690
+ */
7691
+ declare function classifyDecay(m: DecayInput, now: number, policy?: Partial<DecayPolicy>): DecayVerdict;
7692
+
7693
+ /**
7694
+ * Decay sweeper (PR2) — orchestration glue that runs the temporal-decay
7695
+ * lifecycle over the vault. Mirrors the shape of {@link ./autoExtractWorker}'s
7696
+ * `createAutoExtractor`: created once, driven by the caller (a client hook on a
7697
+ * low-frequency interval / app-foreground), disposable.
7698
+ *
7699
+ * A sweep is zero-knowledge by construction:
7700
+ * 1. {@link getDecayCandidatesRawOp} selects plaintext columns via
7701
+ * `unsafeFetchRaw` — no `content`, no decrypt, no Model per row.
7702
+ * 2. {@link classifyDecay} is a pure function over those plaintext fields.
7703
+ * 3. Only the (usually small) transition set is materialized as Models to
7704
+ * archive ({@link archiveVaultMemoryOp}) or hard-delete
7705
+ * ({@link hardDeleteDecayedOp}, which re-checks archived + past-window
7706
+ * inside the write so a concurrent restore wins).
7707
+ *
7708
+ * The optional {@link DecayClassifier} is a PR5 seam for an on-device model that
7709
+ * refines borderline verdicts by reading decrypted content — it is NOT
7710
+ * implemented here. Default is `undefined` → pure rule-based, which is what
7711
+ * keeps the default path zero-knowledge.
7712
+ */
7713
+
7714
+ /** Counts from one sweep, for UI surfacing (e.g. "N memories archived"). */
7715
+ interface DecaySweepResult {
7716
+ /** Rows transitioned active → archived this sweep. */
7717
+ archived: number;
7718
+ /** Rows hard-deleted (archived past the window) this sweep. */
7719
+ deleted: number;
7720
+ /** Total candidate rows scanned (all non-hard-deleted rows). */
7721
+ scanned: number;
7722
+ }
7723
+ /**
7724
+ * PR5 seam — an on-device classifier that refines the rule-based verdict for
7725
+ * borderline rows (e.g. type `other`/null, or a `plan` without an event end).
7726
+ * Because it may read decrypted content, callers MUST gate providing it on
7727
+ * wallet-key availability. Left undefined here → pure rule-based sweep.
7728
+ *
7729
+ * Egress is bounded by the sweeper (NOT the classifier): each sweep caps how
7730
+ * many rows reach the classifier ({@link CreateDecaySweeperOptions.maxClassifierCallsPerSweep})
7731
+ * and a row whose (id, updated_at) was already classified is never re-sent on a
7732
+ * later sweep — so a stable borderline "keep" row egresses at most once.
7733
+ *
7734
+ * SECURITY (MEDIUM, residual) — enabling a classifier hands whoever answers the
7735
+ * portal (incl. a malicious / MITM'd endpoint) a lever over the affected rows:
7736
+ * a hostile verdict can only quarantine-adjacent OUTCOMES here, i.e. archive a
7737
+ * row (reversible — never a hard delete, which stays the deterministic
7738
+ * archived-past-window mechanic). Bounded, reversible trust tradeoff; gate the
7739
+ * classifier on trust in the portal.
7740
+ *
7741
+ * @param input The same plaintext inputs the rule engine saw.
7742
+ * @param ruleVerdict The rule-based verdict, as a starting point / fallback.
7743
+ * @param now The sweep's reference time (Unix ms). Injected so the
7744
+ * classifier derives any age math from the same clock the rule engine used,
7745
+ * never wall-clock `Date.now()` — keeping a fixed-`now` sweep deterministic.
7746
+ * @returns The (possibly refined) verdict.
7747
+ */
7748
+ interface DecayClassifier {
7749
+ classify(input: DecayInput, ruleVerdict: DecayVerdict, now: number): Promise<DecayVerdict> | DecayVerdict;
7750
+ }
7751
+ /** A clock: a fixed timestamp (tests) or a getter (production intervals). */
7752
+ type NowSource = number | (() => number);
7753
+ /** @public */
7754
+ interface CreateDecaySweeperOptions {
7755
+ /** Vault write context — the same one recall/retain use. */
7756
+ vaultCtx: VaultMemoryOperationsContext;
7757
+ /**
7758
+ * Reference "now". A number is fixed (deterministic tests); a function is
7759
+ * re-evaluated per sweep (long-lived interval usage). Default `Date.now`.
7760
+ */
7761
+ now?: NowSource;
7762
+ /** Partial policy overriding the per-type TTL defaults. Omit for defaults. */
7763
+ policy?: Partial<DecayPolicy>;
7764
+ /**
7765
+ * PR5 seam. When provided, borderline candidates' rule verdict is passed
7766
+ * through it. Gate on key availability (it may decrypt content). Default
7767
+ * undefined. Egress is bounded — see {@link maxClassifierCallsPerSweep}.
7768
+ */
7769
+ classifier?: DecayClassifier;
7770
+ /**
7771
+ * PR5 — hard ceiling on classifier invocations (and thus decrypted-content
7772
+ * portal egress) per sweep. Once hit, the remaining borderline rows fall back
7773
+ * to the rule verdict for that sweep (no call). Prevents a large vault from
7774
+ * firing hundreds of sequential content-bearing calls in one sweep. Default
7775
+ * {@link DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP} (20). Cache hits (a row
7776
+ * already classified at its current `updated_at`) do NOT count against this.
7777
+ */
7778
+ maxClassifierCallsPerSweep?: number;
7779
+ /** Fires once after each sweep with the transition counts (UI). */
7780
+ onSwept?: (result: DecaySweepResult) => void;
7781
+ /** Diagnostic — fires on an unexpected sweep-level error. */
7782
+ onError?: (error: Error) => void;
7783
+ }
7784
+ /** @public */
7785
+ interface DecaySweeper {
7786
+ /**
7787
+ * Scan the vault, classify every candidate, and apply archive/delete
7788
+ * transitions. Safe to call repeatedly (idempotent — a keep stays a keep, an
7789
+ * already-archived row won't re-archive). Returns the transition counts.
7790
+ * A no-op (returns zero counts) after {@link DecaySweeper.dispose}.
7791
+ */
7792
+ runSweep(): Promise<DecaySweepResult>;
7793
+ /** Stop accepting sweeps. An in-flight `runSweep()` resolves normally. */
7794
+ dispose(): void;
7795
+ }
7796
+ /**
7797
+ * Default per-sweep ceiling on decay-classifier invocations (see
7798
+ * {@link CreateDecaySweeperOptions.maxClassifierCallsPerSweep}). Kept small: the
7799
+ * classifier egresses DECRYPTED content, so a sweep must never fan out to
7800
+ * hundreds of sequential calls. 20 covers the borderline churn of a typical
7801
+ * sweep while capping worst-case egress; stable rows are also cached so this
7802
+ * ceiling is rarely reached after the first sweep.
7803
+ */
7804
+ declare const DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP = 20;
7805
+ /**
7806
+ * Create a decay sweeper. See module docstring for the zero-knowledge contract.
7807
+ */
7808
+ declare function createDecaySweeper(options: CreateDecaySweeperOptions): DecaySweeper;
7809
+
7810
+ /**
7811
+ * Optional content-reading decay classifier (PR5).
7812
+ *
7813
+ * The rule engine ({@link ./decay}.classifyDecay) decides keep/archive/delete
7814
+ * from plaintext columns ALONE — it never sees `content`, which is what keeps
7815
+ * the default decay sweep zero-knowledge. That is the right default, but it is
7816
+ * weakest on BORDERLINE rows: an `other`/untyped fact, or a `plan` with no
7817
+ * event end, whose staleness is a pure `updated_at` guess.
7818
+ *
7819
+ * This factory builds a {@link DecayClassifier} that reads the DECRYPTED content
7820
+ * of such a row and returns keep-vs-archive. The sweeper consults it ONLY for a
7821
+ * borderline row whose CURRENT rule verdict is `keep` — a rule archive/delete
7822
+ * short-circuits before the classifier ever runs (see `decayWorker.verdictFor` +
7823
+ * `isBorderline`). So its whole job is to REFINE a still-kept borderline row
7824
+ * toward EARLIER archive when the content shows it is genuinely ephemeral (a
7825
+ * finished one-off plan, an expired temporary state) — turning a weak age-only
7826
+ * "keep" into an "archive" sooner.
7827
+ *
7828
+ * DIRECTIONALITY IS DELIBERATE (a security property, not a shortcoming): it can
7829
+ * move a borderline keep → archive, never the reverse. It CANNOT rescue /
7830
+ * keep-alive a row the rule would archive — the escalation gate makes that path
7831
+ * unreachable, and archive is reversible while un-archiving poison would not be.
7832
+ * Enabling a classifier hands whoever answers the portal (incl. a malicious /
7833
+ * MITM'd endpoint) a lever, and that lever must only ever archive-reversibly.
7834
+ *
7835
+ * ZERO-KNOWLEDGE CONTRACT (the caller MUST honor this):
7836
+ * - `getContent` is supplied by the caller and MUST be gated on wallet-key
7837
+ * availability: return `null` when no key is loaded. With no content the
7838
+ * classifier degrades to the rule verdict — never blocks, never guesses.
7839
+ * - When it does read content and calls the portal, the content is
7840
+ * PII-redacted first. Redaction is OPT-OUT, not opt-in: it defaults ON when
7841
+ * the consumer omits `piiRedaction`, so a caller can never accidentally
7842
+ * egress raw PII. Pass `piiRedaction: false` to deliberately disable it.
7843
+ * - Egress is bounded by the SWEEPER, not this classifier: the sweep caps
7844
+ * invocations per pass and never re-sends an unchanged (id, updated_at) row
7845
+ * (see `decayWorker`), so a stable borderline "keep" row egresses once.
7846
+ * - It only ever chooses keep vs archive, and only for a row the rule already
7847
+ * keeps. It NEVER escalates to `delete` and NEVER un-archives — hard-delete
7848
+ * is exclusively the deterministic archived-past-window mechanic (rule 1),
7849
+ * and a row the rule wants archived is archived regardless of this layer.
7850
+ *
7851
+ * Fails to the rule verdict (keep) on any error, missing id, no key, or
7852
+ * malformed response — like every other optional LLM layer in this subsystem it
7853
+ * can only refine a borderline keep toward archive, never make the sweep worse.
7854
+ *
7855
+ * RESIDUAL SCOPE (accepted): a genuinely durable fact MISTYPED as `other`/null
7856
+ * and never re-mentioned within its medium TTL WILL age-archive — this layer can
7857
+ * only bring that archive EARLIER, never prevent it. Accepted because it is
7858
+ * recoverable: archived rows stay in the Archived section, Restore clears
7859
+ * `archived_at`, and any re-observation resets the TTL. The alternative — a
7860
+ * keep-alive lever — is exactly the capability a hostile portal must NOT have.
7861
+ *
7862
+ * SECURITY (MEDIUM, residual) — this is a NEW portal call surface carrying
7863
+ * (redacted) memory content. It is opt-in (you must construct + pass it) and
7864
+ * gated on key availability. Beyond widening which models see facts, a
7865
+ * malicious / MITM'd portal can steer the verdict — but only to ARCHIVE a row
7866
+ * (reversible; never a hard delete). Gate it on trust in the portal.
7867
+ */
7868
+
7869
+ /**
7870
+ * Auth + wiring for {@link createLlmDecayClassifier}. Auth is the dual pattern —
7871
+ * one of `apiKey` / `getToken` is required at runtime (see {@link PortalLlmAuth}).
7872
+ * @public
7873
+ */
7874
+ interface LlmDecayClassifierOptions extends PortalLlmAuth {
7875
+ baseUrl?: string;
7876
+ model?: string;
7877
+ /** Override fetch (tests). */
7878
+ fetchFn?: typeof fetch;
7879
+ /** Max portal attempts on a TRANSIENT failure. Default 2. */
7880
+ maxAttempts?: number;
7881
+ /** Absolute wall-clock budget across attempts. Default 12s. */
7882
+ totalTimeoutMs?: number;
7883
+ /** Backoff before each retry (ms). Tests pass `() => 0`. */
7884
+ backoffMs?: (attempt: number) => number;
7885
+ /**
7886
+ * PII redaction for the outbound content. OPT-OUT: defaults to ON (a fresh
7887
+ * per-call redactor) when omitted, so decrypted content is never egressed
7888
+ * raw by accident. Pass a shared {@link PiiRedactor} to keep placeholder
7889
+ * numbering consistent with other calls, or `false` to deliberately disable
7890
+ * redaction. The verdict returned is a bare enum — nothing to de-anonymize.
7891
+ */
7892
+ piiRedaction?: boolean | PiiRedactor;
7893
+ /**
7894
+ * Resolve a memory's DECRYPTED content by id. The caller supplies this and
7895
+ * MUST gate it on wallet-key availability — return `null` when no key is
7896
+ * loaded so the classifier degrades to the rule verdict (zero-knowledge).
7897
+ * A throw is treated the same as `null` (fail to the rule verdict).
7898
+ */
7899
+ getContent: (id: string) => Promise<string | null>;
7900
+ }
7901
+ /**
7902
+ * Build a {@link DecayClassifier} that reads a borderline row's decrypted
7903
+ * content and returns a keep/archive verdict via a cheap portal LLM. Pass it as
7904
+ * `createDecaySweeper({ classifier })`. See the module docstring for the
7905
+ * zero-knowledge contract. Returns the rule verdict on any failure and never
7906
+ * escalates to `delete`.
7907
+ * @public
7908
+ */
7909
+ declare function createLlmDecayClassifier(options: LlmDecayClassifierOptions): DecayClassifier;
7910
+
7911
+ /**
7912
+ * Multi-hop graph traversal for the W5 entity-graph recall lane (PR4,
7913
+ * MRAgent-style "active reconstruction").
7914
+ *
7915
+ * The single-hop lane (see `recall.ts:buildGraphLaneRanking`) does one thing:
7916
+ * extract entities from the query, look up memories sharing any of them, and
7917
+ * order those memories by shared-entity count. That is hop 1 — the "seed"
7918
+ * lookup. This module wraps a bounded breadth-first search around it: from the
7919
+ * seed memories it walks OUT to their neighbor entities (via the new reverse
7920
+ * edge {@link getEntitiesByMemoryIdsOp}), ranks those neighbors by
7921
+ * co-occurrence across the frontier, expands the top few, and pulls the
7922
+ * memories they reach — repeating up to {@link MAX_HOPS} times.
7923
+ *
7924
+ * Cost note (why this is cheap): NONE of this runs cosine. Cosine runs exactly
7925
+ * once per recall inside `searchVaultMemoriesWithSize`. This lane only emits an
7926
+ * ordered list of memory IDs that is RRF-fused against the cosine head. So
7927
+ * multi-hop adds indexed WatermelonDB joins + more RRF entries, not embedding
7928
+ * math. The dominant cost of enabling it is the reranker over a slightly larger
7929
+ * candidate pool — which stays bounded because `rerankTopN` remains
7930
+ * authoritative downstream.
7931
+ *
7932
+ * Determinism: neighbor-entity selection is pure co-occurrence counting by
7933
+ * default. An optional LLM path-refiner (PR5) can override which neighbors
7934
+ * expand; it falls back to the deterministic order on any error.
7935
+ *
7936
+ * Hop numbering: hop 1 is the seed lookup. `maxHops = 1` therefore means "seed
7937
+ * only" — byte-for-byte identical to the single-hop lane (the regression guard).
7938
+ * `MAX_HOPS = 2` (the PR5 default) performs one expansion beyond the seed.
7939
+ *
7940
+ * Neighbor selection at each expansion hop is deterministic co-occurrence
7941
+ * counting by default. PR5 adds an OPTIONAL LLM path-refiner
7942
+ * ({@link NeighborRefiner} / {@link createLlmNeighborRefiner}) that lets a model
7943
+ * pick which neighbor entities to expand instead; it is opt-in, capped to ≤1
7944
+ * call per hop, and falls back to the deterministic order on any error.
7945
+ */
7946
+
7947
+ /**
7948
+ * Total hops the traversal performs, counting the seed lookup as hop 1.
7949
+ * `1` = seed only (identical to the single-hop lane). PR5 default is `2` (one
7950
+ * expansion beyond the seed). Overridable per-call for ablation. Still gated to
7951
+ * the `high` budget in recall, and capped back to 1 on large vaults by
7952
+ * {@link capHopsForDensity}.
7953
+ * @public
7954
+ */
7955
+ declare const MAX_HOPS = 2;
7956
+ /**
7957
+ * Max neighbor entities expanded per hop. Caps fan-out so a densely-linked
7958
+ * frontier can't explode the candidate pool. Neighbors are ranked by
7959
+ * co-occurrence frequency across the frontier; only the top this-many expand.
7960
+ * @public
7961
+ */
7962
+ declare const ENTITY_FANOUT = 8;
7963
+ /**
7964
+ * Hard ceiling on total accumulated memory IDs across all hops. The BFS stops
7965
+ * expanding once the accumulated set reaches this size (and the frontier is
7966
+ * bounded to it too), keeping the RRF pool — and the downstream reranker
7967
+ * workload — bounded regardless of graph density.
7968
+ * @public
7969
+ */
7970
+ declare const NODE_BUDGET = 64;
7971
+ /**
7972
+ * Above this vault size, {@link capHopsForDensity} forces `MAX_HOPS = 1`
7973
+ * (seed-only). Fan-out grows with graph density, so on large vaults we don't
7974
+ * pay the expansion cost. Bounded-traversal safety valve.
7975
+ * @public
7976
+ */
7977
+ declare const VAULT_SIZE_HOP_CAP = 1000;
7978
+ /** Options for {@link traverseGraphLane}. All optional; defaults are the
7979
+ * exported constants above. Exposed for ablation / evaluation sweeps.
7980
+ * @public */
7981
+ interface GraphTraversalOptions {
7982
+ /** Total hops incl. the seed lookup (hop 1). Default {@link MAX_HOPS}. */
7983
+ maxHops?: number;
7984
+ /** Max neighbor entities expanded per hop. Default {@link ENTITY_FANOUT}. */
7985
+ entityFanout?: number;
7986
+ /** Hard cap on accumulated memory IDs. Default {@link NODE_BUDGET}. */
7987
+ nodeBudget?: number;
7988
+ /** RRF smoothing constant for per-hop fusion. Default 60 (rrf.ts). */
7989
+ rrfK?: number;
7990
+ /**
7991
+ * Vault size hint. When provided and above {@link VAULT_SIZE_HOP_CAP}, the
7992
+ * effective hop count is capped to 1 (see {@link capHopsForDensity}).
7993
+ */
7994
+ vaultSize?: number;
7995
+ /**
7996
+ * PR5 — optional LLM neighbor-selection. When provided, at each expansion hop
7997
+ * the deterministically-ranked candidate neighbor entities are handed to this
7998
+ * refiner, which returns the subset to expand. Falls back to the
7999
+ * co-occurrence order on any error or empty result. Called at most ONCE per
8000
+ * hop. Build one with {@link createLlmNeighborRefiner}, or supply your own.
8001
+ */
8002
+ refineNeighbors?: NeighborRefiner;
8003
+ /**
8004
+ * Resolve a batch of candidate memory ids to just the ACTIVE ones (not
8005
+ * archived, not quarantined, not soft-deleted — the same set the final recall
8006
+ * gate admits). When provided, traversal drops "forgotten" memories from the
8007
+ * frontier AT EACH HOP so they neither steer neighbor-entity ranking nor
8008
+ * egress their entity names to {@link refineNeighbors}. Omit (tests /
8009
+ * entity-only callers) to traverse over every linked memory. Wire it from a
8010
+ * vault context with {@link ../db/memoryVault/operations.getActiveVaultMemoryIdsOp}.
8011
+ */
8012
+ filterActiveMemoryIds?: (ids: string[]) => Promise<Set<string>>;
8013
+ }
8014
+ /**
8015
+ * Picks which candidate neighbor entities to expand at a traversal hop. Given
8016
+ * the query and the deterministically-ranked candidate entity names, return the
8017
+ * subset (≤ `limit`) to expand. Must be resilient: {@link traverseGraphLane}
8018
+ * falls back to the deterministic top-`limit` on a throw or empty return.
8019
+ * @public
8020
+ */
8021
+ interface NeighborRefiner {
8022
+ refine(query: string, candidates: string[], limit: number): Promise<string[]>;
8023
+ }
8024
+ /**
8025
+ * Cap the hop count on large vaults. Fan-out grows with graph density, so above
8026
+ * {@link VAULT_SIZE_HOP_CAP} memories we force seed-only traversal (1 hop)
8027
+ * rather than pay an unbounded expansion. A no-op when `vaultSize` is unknown or
8028
+ * within the threshold.
8029
+ * @public
8030
+ */
8031
+ declare function capHopsForDensity(maxHops: number, vaultSize?: number): number;
8032
+ /**
8033
+ * Bounded multi-hop entity-graph traversal. Returns an ordered list of memory
8034
+ * IDs (best first) — the SAME output shape as the single-hop lane, so nothing
8035
+ * downstream changes. The caller passes it through as `entityRanking` for RRF
8036
+ * fusion with the cosine/BM25 head.
8037
+ *
8038
+ * With `maxHops <= 1` this returns the seed ordering verbatim, making it a
8039
+ * drop-in equivalent of the single-hop lane (the regression guard). The PR5
8040
+ * default is 2 (one expansion beyond the seed).
8041
+ *
8042
+ * Returns an empty array when the query has no extractable entities or no stored
8043
+ * memory shares a seed entity.
8044
+ *
8045
+ * @public
8046
+ */
8047
+ declare function traverseGraphLane(query: string, entityCtx: EntityOperationsContext, options?: GraphTraversalOptions): Promise<string[]>;
8048
+ /** Auth + tuning for {@link createLlmNeighborRefiner}. Reuses the recall
8049
+ * `decomposeOptions` shape (dual auth — one of `apiKey`/`getToken`). @public */
8050
+ interface LlmNeighborRefinerOptions extends PortalLlmAuth {
8051
+ baseUrl?: string;
8052
+ model?: string;
8053
+ fetchFn?: typeof fetch;
8054
+ maxAttempts?: number;
8055
+ totalTimeoutMs?: number;
8056
+ backoffMs?: (attempt: number) => number;
8057
+ }
8058
+ /**
8059
+ * Build a {@link NeighborRefiner} backed by a cheap portal LLM. At each hop it
8060
+ * asks the model to pick, from the candidate neighbor entities, the ≤`limit`
8061
+ * most relevant to the query, so traversal expands toward the question instead
8062
+ * of purely by co-occurrence frequency.
8063
+ *
8064
+ * Bounded + fail-safe: one attempt by default, a short total timeout, and
8065
+ * {@link traverseGraphLane} falls back to the deterministic co-occurrence order
8066
+ * on any throw or empty result — so enabling this can reorder which neighbors
8067
+ * expand but never breaks or stalls recall.
8068
+ *
8069
+ * SECURITY / ZERO-KNOWLEDGE (must stay default-OFF): this sends the query +
8070
+ * candidate ENTITY NAMES to the portal UNREDACTED. Those names ARE user PII —
8071
+ * people, places, orgs pulled from the stored graph (e.g. "Sara", "Kyoto",
8072
+ * "Acme") — not lower-risk than content just because they're short. It reuses
8073
+ * the query-decompose auth and is opt-in (`RecallOptions.graphRefine`, default
8074
+ * off in recall); leave it off unless you accept that exposure. To bound that
8075
+ * exposure, {@link traverseGraphLane} caps the candidate list it hands this
8076
+ * refiner per hop — at most `MAX_REFINER_CANDIDATES` entity names ever leave per
8077
+ * hop, REGARDLESS of `entityFanout` (the cap is a hard ceiling, not just a
8078
+ * fanout-scaled floor), so the full frontier is never egressed.
8079
+ *
8080
+ * MEDIUM residual: a malicious / MITM'd portal can only steer WHICH neighbor
8081
+ * entities expand — a recall-ranking nudge, not a data-integrity change (no
8082
+ * memory is written, archived, or deleted), and {@link traverseGraphLane}
8083
+ * falls back to deterministic order on any bad/empty response. Bounded tradeoff.
8084
+ * @public
8085
+ */
8086
+ declare function createLlmNeighborRefiner(options: LlmNeighborRefinerOptions): NeighborRefiner;
8087
+
7111
8088
  /**
7112
8089
  * Unified Recall API — single retrieval surface above vault + engine.
7113
8090
  *
@@ -8625,6 +9602,9 @@ declare class WatermelonChatStorageAdapter implements ChatStorageAdapter {
8625
9602
  * - v33: Added embedding_model column to memory_vault so stale-model vectors are
8626
9603
  * detectable and re-embeddable after an embedding-model change (null = legacy
8627
9604
  * rows, grandfathered as compatible with the current model)
9605
+ * - v34: Added topics_user_managed column to memory_vault so a memory whose
9606
+ * entity links the user has taken manual control of is left alone by
9607
+ * auto-extraction (null/false = auto-derived, the default)
8628
9608
  * - v35: Added conversation_memory table recording which vault memories a
8629
9609
  * conversation drew on, so the conversation-level Memories panel survives reload
8630
9610
  * - v36: Added topics_extracted_at column to memory_vault — watermark of the last
@@ -8643,8 +9623,13 @@ declare class WatermelonChatStorageAdapter implements ChatStorageAdapter {
8643
9623
  * watermark stamped each time retain() merges into an existing fact, kept
8644
9624
  * distinct from updated_at (which merges preserve). Lets profile synthesis
8645
9625
  * weight facts by recency of reinforcement rather than last edit.
9626
+ * - v40: Added fact_type, archived_at, trust_tier columns to memory_vault for
9627
+ * typed memory + decay + Tier-0 security. All nullable + plaintext, no
9628
+ * backfill (null = legacy/untyped, active, un-screened — content is
9629
+ * encrypted so in-migration classification is impossible; NULL = zero-risk,
9630
+ * exact embedding_model precedent)
8646
9631
  */
8647
- declare const SDK_SCHEMA_VERSION = 39;
9632
+ declare const SDK_SCHEMA_VERSION = 40;
8648
9633
  /**
8649
9634
  * Combined WatermelonDB schema for all SDK storage modules.
8650
9635
  *
@@ -8722,11 +9707,13 @@ declare const sdkSchema: Readonly<{
8722
9707
  * - v30 → v31: Added `user_id` column to memory_entity for multi-user scoping of the W5 graph lane (with backfill from memory_vault.user_id)
8723
9708
  * - v31 → v32: Added `pinned_at` column to conversations for pinning chats
8724
9709
  * - v32 → v33: Added `embedding_model` column to memory_vault (null grandfathered as current-model-compatible)
9710
+ * - v33 → v34: Added `topics_user_managed` column to memory_vault (null/false = auto-derived topics, the default)
8725
9711
  * - v34 → v35: Added `conversation_memory` table (conversation ↔ recalled memory ids)
8726
9712
  * - v35 → v36: Added `topics_extracted_at` column to memory_vault (watermark for the background topic-extraction worker; null + existing links grandfathered as extracted)
8727
9713
  * - v36 → v37: Added `superseded_by` + `superseded_at` columns to memory_vault (write-time supersession; null = live, excluded from recall/dedup when set)
8728
9714
  * - v37 → v38: Added `topics_extracted_version` column to memory_vault (extraction-logic version; null read as 0 so a TOPICS_EXTRACTION_VERSION bump re-extracts stale rows)
8729
9715
  * - v38 → v39: Added `last_observed_at` column to memory_vault (C3 re-observation watermark; stamped on retain merge, distinct from updated_at)
9716
+ * - v39 → v40: Added `fact_type`, `archived_at`, `trust_tier` columns to memory_vault for typed memory + decay + Tier-0 security (all nullable + plaintext, NULL backfill)
8730
9717
  */
8731
9718
  declare const sdkMigrations: Readonly<{
8732
9719
  validated: true;
@@ -12875,4 +13862,4 @@ declare function renderAnumaTree(node: AnumaNode): React.ReactElement | null;
12875
13862
  */
12876
13863
  declare function renderAnumaJsx(jsx: string): React.ReactElement | null;
12877
13864
 
12878
- export { Anuma, type AnumaChild, AnumaJsxError, type AnumaNode, AnumaShadowIsolationProvider, type AnumaShadowIsolationProviderProps, type AnumaTheme, AnumaThemeProvider, type AnumaThemeProviderProps, AppFile as AppFileModel, type AppFileOperationsContext, type AttrValue, type AutoExtractMessage, type AutoExtractor, DEFAULT_CONVERSATIONS_FOLDER as BACKUP_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as BACKUP_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER as BACKUP_ICLOUD_FOLDER, BUILT_IN_TOOL_SETS, type BackupAuthContextValue, BackupAuthProvider, type BackupAuthProviderProps, type BackupOperationOptions, BlobUrlManager, type Budget, type CachedChunkVectors, type CachedServerTools, ChartCard, type ChartCardProps, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChatStorageAdapter, type ChatStorageObservable, type ChunkSearchResult, type ChunkVectorCache, type ChunkingOptions, type CircleProps, type ClientToolsFilterFn, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type ConversationQueryOptions, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateEntityOptions, type CreateMediaOptions, type CreateMessageOptions, type CreateModelPreferenceOptions, type CreateProjectOptions, type CreateSavedToolOptions, type CreateServerToolsFilterOptions, type CreateUserPreferenceOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_BACKUP_FOLDER, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_CONVERSATIONS_FOLDER as DEFAULT_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as DEFAULT_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_DROPBOX_FOLDER, DEFAULT_EXCLUDED_SERVER_TOOLS, DEFAULT_BACKUP_FOLDER as DEFAULT_ICLOUD_BACKUP_FOLDER, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PERSONALITY_SETTINGS, DEFAULT_PROFILE_FACETS, DEFAULT_SERVER_TOOLS_MATCH_OPTIONS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DeckProps, type DisplayToolMigrations, type DropboxAuthContextValue, DropboxAuthProvider, type DropboxAuthProviderProps, type DropboxExportResult, type DropboxImportResult, ENTITY_KINDS, type EmbeddedWalletSignerFn, type EntityInput, type EntityKind, Entity as EntityModel, type EntityOperationsContext, ExcelProcessor, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, FILE_PLACEHOLDER_PREFIX, FILE_PLACEHOLDER_REGEX, type FactType, type FileMetadata, type FileProcessor, type FileTypeQuery, type FileWithData, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GoogleDriveAuthContextValue, GoogleDriveAuthProvider, type GoogleDriveAuthProviderProps, type GoogleDriveExportResult, type GoogleDriveImportResult, type GroupProps, type ICloudAuthContextValue, ICloudAuthProvider, type ICloudAuthProviderProps, type ICloudExportResult, type ICloudImportResult, INFERENCE_ID_HEADER, type IconProps, type ImageProps, type InteractionType, type KnownTag, type LazyStoredConversation, type LineProps, type Logger, LoggerProvider, type LoggerProviderProps, type MediaDimensions, type MediaFilterOptions, type MediaMetadata, type MediaOperationsContext, type MediaRole, type MediaType, type MemoriesNeedingTopicExtraction, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, MemoryEntity as MemoryEntityModel, type MemoryExtractedEvent, type MemoryKind, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MessageChunk, type MessageFeedback, type MessageSkeleton, type ModelLoadProgress, type OCRFile, type OperationExecutor, PROFILE_DOC_VERSION, type ParsedServerToolsResponse, type PdfExportOptions, type PdfExportProgress, type PdfExportStage, type PdfFile, PdfProcessor, type PendingInteraction, type PersonalitySettings, type PersonalitySliders, type PersonalityStyle, type PhoneCallPollingOptions, type PlatformStorage, type PortalLlmAuth, type PreprocessingOptions, type PreprocessingResult, type ProcessedFileResult, ProcessorRegistry, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSection, type ProfileUpdate, type ProgressCallback, Project, type ProjectOperationsContext, type PromptPreProcessor, type PromptPreProcessorContext, type ProviderAuthState, type ProviderBackupState, ProviderStreamError, type QuantizedEmbedding, type QueueEncryptionContext, QueueManager, type QueueStatus, type QueuedOperation, type QueuedOperationType, R2_DEFAULT_TTL_MS, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankedMemory, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RectProps, type ReflectOptions, type ReflectResult, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SERVER_TOOL_DEPENDENCY_SETS, SLIDER_CONFIG, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, STREAM_RESUMABLE_HEADER, SavedTool as SavedToolModel, type SavedToolOperationsContext, type SavedToolParameter, type ScoreBreakdown, type ScreenProps, type SearchMessagesOptions, type SearchSource, type SelectServerToolsForPromptOptions, type SendMessageWithStorageArgs, type SendMessageWithStorageResult, type ServerTool, type ServerToolsFilter, type ServerToolsFilterFn, type ServerToolsFilterFunction, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type SignMessageOptions, type SlideProps, type StepFinishEvent, type StockPriceClassification, type StockPricePreProcessorOptions, type StorageOperationsContext, type StoredAppFile, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredEntity, type StoredFileWithContext, type StoredMedia, Media as StoredMediaModel, type StoredMessage, type StoredMessageWithSimilarity, type StoredModelPreference, ModelPreference as StoredModelPreferenceModel, type StoredProject, type StoredSavedTool, type StoredUserPreference, UserPreference as StoredUserPreferenceModel, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type SynthesizeProfileOptions, THEME_ATTRS, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, type TextChunk, TextProcessor, type TextProps, type ThemeAttr, type ToolCallArgumentsDeltaEvent, type ToolMatchOptions, type ToolMatchResult, type ToolSet, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TranscriptionResult, type TurnCompleteEvent, type TurnSkippedEvent, type UIInteractionContextValue, UIInteractionProvider, type UIInteractionProviderProps, type UpdateMediaOptions, type UpdateModelPreferenceOptions, type UpdateProjectOptions, type UpdateSavedToolOptions, type UpdateUserPreferenceOptions, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseBackupOptions, type UseBackupResult, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseDropboxBackupOptions, type UseDropboxBackupResult, type UseEncryptionResult, type UseExportPdfResult, type UseFilesOptions, type UseFilesResult, type UseGoogleDriveBackupOptions, type UseGoogleDriveBackupResult, type UseICloudBackupOptions, type UseICloudBackupResult, type UseModelsResult, type UseOCRResult, type UsePdfResult, type UsePhoneCallsOptions, type UsePhoneCallsResult, type UseProjectsOptions, type UseProjectsResult, type UseSettingsOptions, type UseSettingsResult, type UseSubscriptionOptions, type UseSubscriptionResult, type UseToolsOptions, type UseToolsResult, type UseVoiceOptions, type UseVoiceResult, type UseWalletBindingOptions, type UseWalletBindingResult, type VaultEmbeddingCache, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultSaveOperation, type VaultSearchResult, type VoiceRecording, WalletPoller, WatermelonChatStorageAdapter, type WatermelonChatStorageAdapterOptions, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, type WhisperModel, WordProcessor, ZipProcessor, type ZipProcessorOptions, addConversationMemoriesOp, appFileToStored, backfillMemoryEntityUserIdsOp, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearAllKeyPairs, clearCalendarToken, clearConversationMemoriesOp, clearDriveToken, clearToken as clearDropboxToken, clearEncryptionKey, clearGithubToken, clearGoogleDriveToken, clearICloudAuth, clearKeyPair, clearLazyTitleCache, clearMemoryTopicsOverrideOp, clearNotionToken, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createGitHubTools, createMediaBatchOp, createMediaOp, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createPlatformCursorStore, createProjectOp, createRecallTool, createSavedToolOp, createServerToolsFilter, createStockPricePreProcessor, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decryptConversationTitle, decryptData, decryptDataBatch, decryptDataBytes, decryptDataBytesFromBytes, decryptDataWithKey, defaultServerToolsFilter, deleteAllAppFilesOp, deleteAllVaultMemoriesForUserOp, deleteAppFileOp, deleteEncryptedFile, deleteMediaByConversationOp, deleteMediaByMessageOp, deleteMediaOp, deleteProjectOp, deleteSavedToolOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, eagerEmbedContent, embedAllMessages, embedMessage, encryptData, encryptDataBatch, encryptDataBytes, encryptDataWithKey, ensureDefaultFoldersOp, expandToolSetsAdditive, exportElementToPdf, exportMarkdownToPdf, exportPublicKey, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, extractFileIds, fileExists, findById, findMatchingTools, findParentOfId, generateConversationId, generateEmbedding, generateEmbeddings, generateMediaId, generateProjectId, getAIGeneratedMediaOp, getAllSavedToolsOp, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getAndClearCalendarPendingMessage, getAndClearCalendarReturnUrl, getAndClearDrivePendingMessage, getAndClearDriveReturnUrl, getAndClearGithubPendingMessage, getAndClearGithubReturnUrl, getAndClearNotionPendingMessage, getAndClearNotionReturnUrl, getAppFileMapOp, getAppFileOp, getAppFilesOp, getAudioOp, getCachedServerTools, getCalendarAccessToken, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsByProjectOp, getConversationsLazyOp, getConversationsPageOp, getDocumentsOp, getDriveAccessToken, getEncryptionKey, getGithubAccessToken, getGoogleDriveStoredToken, getId, getImagesOp, getLogger, getMediaByConversationOp, getMediaByIdOp, getMediaByIdsOp, getMediaByMessageOp, getMediaByModelOp, getMediaByRoleOp, getMediaBySourceUrlOp, getMediaByTypeOp, getMediaCountOp, getMediaCountsByTypeOp, getMediaOp, getMediaTypeFromMime, getMemoriesByEntityNamesOp, getMemoriesNeedingTopicExtractionOp, getNotionAccessToken, getNotionMCPUrl, getNumberAttr, getProjectConversationCountOp, getProjectConversationsOp, getProjectOp, getProjectsOp, getRecentMediaOp, getSavedToolByIdOp, getServerTools, getStringAttr, getSupportedFileTypes, getToolsChecksum, getUnfiledVaultMemoriesOp, getUserUploadedMediaOp, getValidCalendarToken, getValidDriveToken, getValidGithubToken, getValidNotionToken, getVaultFolderMemoryCountOp, getVaultMemoryOp, getVideosOp, handleCalendarCallback, handleDriveCallback, handleGithubCallback, handleNotionCallback, hardDeleteMediaOp, hasCalendarCredentials, hasDriveCredentials, hasDropboxCredentials, hasEncryptionKey, hasGithubCredentials, hasGoogleDriveCredentials, hasICloudCredentials, hasKeyPair, hasNotionCredentials, insertAfterId, insertChild, isAnumaTag, isCalendarCallback, isDriveCallback, isGithubCallback, isHtmlTag, isNotionCallback, isOPFSSupported, isR2UrlExpired, isRerankerAvailable, isSupportedFile, isSupportedMediaType, linkMemoryEntitiesOp, mediaToStored, migrateCalendarToken, migrateDisplayResult, migrateDriveToken, migrateGithubToken, migrateNotionClientRegistration, migrateNotionToken, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseJsx, preEmbedVaultMemories, preprocessFiles, previewToolSelection, projectToStored, putAppFileOp, quantizeEmbedding, queueManager, readEncryptedFile, recall, reflect, refreshCalendarToken, refreshDriveToken, refreshGithubToken, refreshNotionToken, relinkMisclassifiedVideosOp, removeById, renderAnumaJsx, renderAnumaTree, renderElementToCanvas, replaceById, replaceMemoryEntitiesGuardedOp, requestEncryptionKey, requestKeyPair, resolveFilePlaceholders, resolveThemeColor, resumeStream, retain, revokeCalendarToken, revokeDriveToken, revokeGithubToken, revokeNotionAccess, savedToolToStored, sdkMigrations, sdkModelClasses, sdkSchema, searchChunksOp, searchMediaOp, searchMessagesOp, searchVaultMemories, selectServerToolsForPrompt, serializeJsx, setLogger, setMemoryEntitiesOp, settingsStorageSchema, shouldChunkMessage, shouldRefreshTools, stampTopicsExtractedAtOp, startGithubAuth, startNotionAuth, storeCalendarPendingMessage, storeCalendarReturnUrl, storeCalendarToken, storeDrivePendingMessage, storeDriveReturnUrl, storeDriveToken, storeGithubPendingMessage, storeGithubReturnUrl, storeGithubToken, storeNotionPendingMessage, storeNotionReturnUrl, streamCancelPath, streamReplayPath, supersedeVaultMemoryOp, synthesizeProfile, updateAttrs, updateConversationProjectOp, updateMediaMessageIdBatchOp, updateMediaOp, updateMessageFeedbackOp, updateProjectNameOp, updateProjectOp, updateSavedToolOp, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, useAnumaTheme, useBackup, useBackupAuth, useChat, useChatStorage, useCredits, useDatabaseManager, useDropboxAuth, useDropboxBackup, useEncryption, useExportPdf, useFiles, useGoogleDriveAuth, useGoogleDriveBackup, useICloudAuth, useICloudBackup, useModels, useOCR, usePdf, usePhoneCalls, useProjects, useSettings, useSubscription, useTools, useUIInteraction, useVoice, useWalletBinding, userPreferencesStorageSchema, walk, webPlatformStorage, writeEncryptedFile };
13865
+ export { Anuma, type AnumaChild, AnumaJsxError, type AnumaNode, AnumaShadowIsolationProvider, type AnumaShadowIsolationProviderProps, type AnumaTheme, AnumaThemeProvider, type AnumaThemeProviderProps, AppFile as AppFileModel, type AppFileOperationsContext, type AttrValue, type AutoExtractMessage, type AutoExtractor, DEFAULT_CONVERSATIONS_FOLDER as BACKUP_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as BACKUP_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER as BACKUP_ICLOUD_FOLDER, BUILT_IN_TOOL_SETS, type BackupAuthContextValue, BackupAuthProvider, type BackupAuthProviderProps, type BackupOperationOptions, BlobUrlManager, type Budget, type CachedChunkVectors, type CachedServerTools, ChartCard, type ChartCardProps, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChatStorageAdapter, type ChatStorageObservable, type ChunkSearchResult, type ChunkVectorCache, type ChunkingOptions, type CircleProps, type ClientToolsFilterFn, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type ConversationQueryOptions, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateEntityOptions, type CreateMediaOptions, type CreateMessageOptions, type CreateModelPreferenceOptions, type CreateProjectOptions, type CreateSavedToolOptions, type CreateServerToolsFilterOptions, type CreateUserPreferenceOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_BACKUP_FOLDER, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_CONVERSATIONS_FOLDER as DEFAULT_DRIVE_CONVERSATIONS_FOLDER, DEFAULT_ROOT_FOLDER as DEFAULT_DRIVE_ROOT_FOLDER, DEFAULT_BACKUP_FOLDER$1 as DEFAULT_DROPBOX_FOLDER, DEFAULT_EXCLUDED_SERVER_TOOLS, DEFAULT_BACKUP_FOLDER as DEFAULT_ICLOUD_BACKUP_FOLDER, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PERSONALITY_SETTINGS, DEFAULT_PROFILE_FACETS, DEFAULT_SERVER_TOOLS_MATCH_OPTIONS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DeckProps, type DisplayToolMigrations, type DropboxAuthContextValue, DropboxAuthProvider, type DropboxAuthProviderProps, type DropboxExportResult, type DropboxImportResult, ENTITY_FANOUT, ENTITY_KINDS, type EmbeddedWalletSignerFn, type EntityInput, type EntityKind, Entity as EntityModel, type EntityOperationsContext, ExcelProcessor, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, FILE_PLACEHOLDER_PREFIX, FILE_PLACEHOLDER_REGEX, type FactType, type FileMetadata, type FileProcessor, type FileTypeQuery, type FileWithData, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GoogleDriveAuthContextValue, GoogleDriveAuthProvider, type GoogleDriveAuthProviderProps, type GoogleDriveExportResult, type GoogleDriveImportResult, type GraphTraversalOptions, type GroupProps, HARD_DELETE_WINDOW_MS, type ICloudAuthContextValue, ICloudAuthProvider, type ICloudAuthProviderProps, type ICloudExportResult, type ICloudImportResult, INFERENCE_ID_HEADER, type IconProps, type ImageProps, type InjectionClassifierOptions, type InjectionReason, type InteractionType, type KnownTag, type LazyStoredConversation, type LineProps, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type MediaDimensions, type MediaFilterOptions, type MediaMetadata, type MediaOperationsContext, type MediaRole, type MediaType, type MemoriesNeedingTopicExtraction, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, MemoryEntity as MemoryEntityModel, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MessageChunk, type MessageFeedback, type MessageSkeleton, type ModelLoadProgress, NEVER_TTL_MS, NODE_BUDGET, type NeighborRefiner, type NowSource, type OCRFile, type OperationExecutor, PAST_EVENT_GRACE_MS, PROFILE_DOC_VERSION, type ParsedServerToolsResponse, type PdfExportOptions, type PdfExportProgress, type PdfExportStage, type PdfFile, PdfProcessor, type PendingInteraction, type PersonalitySettings, type PersonalitySliders, type PersonalityStyle, type PhoneCallPollingOptions, type PlatformStorage, type PortalLlmAuth, type PreprocessingOptions, type PreprocessingResult, type ProcessedFileResult, ProcessorRegistry, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSection, type ProfileUpdate, type ProgressCallback, Project, type ProjectOperationsContext, type PromptPreProcessor, type PromptPreProcessorContext, type ProviderAuthState, type ProviderBackupState, ProviderStreamError, type QuantizedEmbedding, type QuarantinedMemoryInfo, type QueueEncryptionContext, QueueManager, type QueueStatus, type QueuedOperation, type QueuedOperationType, R2_DEFAULT_TTL_MS, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankedMemory, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RectProps, type ReflectOptions, type ReflectResult, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SERVER_TOOL_DEPENDENCY_SETS, SHORT_TTL_MS, SLIDER_CONFIG, SLIDES_FILE_PATH, SLIDE_CANVAS_HEIGHT, SLIDE_CANVAS_WIDTH, STREAM_RESUMABLE_HEADER, SavedTool as SavedToolModel, type SavedToolOperationsContext, type SavedToolParameter, type ScoreBreakdown, type ScreenProps, type ScreenResult, type ScreenedCandidate, type SearchMessagesOptions, type SearchSource, type SelectServerToolsForPromptOptions, type SendMessageWithStorageArgs, type SendMessageWithStorageResult, type ServerTool, type ServerToolsFilter, type ServerToolsFilterFn, type ServerToolsFilterFunction, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type SignMessageOptions, type SlideProps, type StepFinishEvent, type StockPriceClassification, type StockPricePreProcessorOptions, type StorageOperationsContext, type StoredAppFile, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredEntity, type StoredFileWithContext, type StoredMedia, Media as StoredMediaModel, type StoredMessage, type StoredMessageWithSimilarity, type StoredModelPreference, ModelPreference as StoredModelPreferenceModel, type StoredProject, type StoredSavedTool, type StoredUserPreference, UserPreference as StoredUserPreferenceModel, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type SynthesizeProfileOptions, THEME_ATTRS, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, type TextChunk, TextProcessor, type TextProps, type ThemeAttr, type ToolCallArgumentsDeltaEvent, type ToolMatchOptions, type ToolMatchResult, type ToolSet, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TranscriptionResult, type TurnCompleteEvent, type TurnSkippedEvent, type UIInteractionContextValue, UIInteractionProvider, type UIInteractionProviderProps, type UpdateMediaOptions, type UpdateModelPreferenceOptions, type UpdateProjectOptions, type UpdateSavedToolOptions, type UpdateUserPreferenceOptions, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseBackupOptions, type UseBackupResult, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseDropboxBackupOptions, type UseDropboxBackupResult, type UseEncryptionResult, type UseExportPdfResult, type UseFilesOptions, type UseFilesResult, type UseGoogleDriveBackupOptions, type UseGoogleDriveBackupResult, type UseICloudBackupOptions, type UseICloudBackupResult, type UseModelsResult, type UseOCRResult, type UsePdfResult, type UsePhoneCallsOptions, type UsePhoneCallsResult, type UseProjectsOptions, type UseProjectsResult, type UseSettingsOptions, type UseSettingsResult, type UseSubscriptionOptions, type UseSubscriptionResult, type UseToolsOptions, type UseToolsResult, type UseVoiceOptions, type UseVoiceResult, type UseWalletBindingOptions, type UseWalletBindingResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultSaveOperation, type VaultSearchResult, type VoiceRecording, WalletPoller, WatermelonChatStorageAdapter, type WatermelonChatStorageAdapterOptions, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, type WhisperModel, WordProcessor, ZipProcessor, type ZipProcessorOptions, addConversationMemoriesOp, appFileToStored, archiveVaultMemoryOp, backfillMemoryEntityUserIdsOp, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearAllKeyPairs, clearCalendarToken, clearConversationMemoriesOp, clearDriveToken, clearToken as clearDropboxToken, clearEncryptionKey, clearGithubToken, clearGoogleDriveToken, clearICloudAuth, clearKeyPair, clearLazyTitleCache, clearMemoryTopicsOverrideOp, clearNotionToken, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createGitHubTools, createLlmDecayClassifier, createLlmNeighborRefiner, createMediaBatchOp, createMediaOp, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createPlatformCursorStore, createProjectOp, createRecallTool, createSavedToolOp, createServerToolsFilter, createStockPricePreProcessor, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decryptConversationTitle, decryptData, decryptDataBatch, decryptDataBytes, decryptDataBytesFromBytes, decryptDataWithKey, defaultServerToolsFilter, deleteAllAppFilesOp, deleteAllVaultMemoriesForUserOp, deleteAppFileOp, deleteEncryptedFile, deleteMediaByConversationOp, deleteMediaByMessageOp, deleteMediaOp, deleteProjectOp, deleteSavedToolOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, eagerEmbedContent, embedAllMessages, embedMessage, encryptData, encryptDataBatch, encryptDataBytes, encryptDataWithKey, ensureDefaultFoldersOp, expandToolSetsAdditive, exportElementToPdf, exportMarkdownToPdf, exportPublicKey, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, extractFileIds, fileExists, findById, findMatchingTools, findParentOfId, generateConversationId, generateEmbedding, generateEmbeddings, generateMediaId, generateProjectId, getAIGeneratedMediaOp, getAllSavedToolsOp, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getAndClearCalendarPendingMessage, getAndClearCalendarReturnUrl, getAndClearDrivePendingMessage, getAndClearDriveReturnUrl, getAndClearGithubPendingMessage, getAndClearGithubReturnUrl, getAndClearNotionPendingMessage, getAndClearNotionReturnUrl, getAppFileMapOp, getAppFileOp, getAppFilesOp, getAudioOp, getCachedServerTools, getCalendarAccessToken, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsByProjectOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getDocumentsOp, getDriveAccessToken, getEncryptionKey, getEntitiesByMemoryIdsOp, getGithubAccessToken, getGoogleDriveStoredToken, getId, getImagesOp, getLogger, getMediaByConversationOp, getMediaByIdOp, getMediaByIdsOp, getMediaByMessageOp, getMediaByModelOp, getMediaByRoleOp, getMediaBySourceUrlOp, getMediaByTypeOp, getMediaCountOp, getMediaCountsByTypeOp, getMediaOp, getMediaTypeFromMime, getMemoriesByEntityNamesOp, getMemoriesNeedingTopicExtractionOp, getNotionAccessToken, getNotionMCPUrl, getNumberAttr, getProjectConversationCountOp, getProjectConversationsOp, getProjectOp, getProjectsOp, getRecentMediaOp, getSavedToolByIdOp, getServerTools, getStringAttr, getSupportedFileTypes, getToolsChecksum, getUnfiledVaultMemoriesOp, getUserUploadedMediaOp, getValidCalendarToken, getValidDriveToken, getValidGithubToken, getValidNotionToken, getVaultFolderMemoryCountOp, getVaultMemoryOp, getVideosOp, handleCalendarCallback, handleDriveCallback, handleGithubCallback, handleNotionCallback, hardDeleteDecayedOp, hardDeleteMediaOp, hasCalendarCredentials, hasDriveCredentials, hasDropboxCredentials, hasEncryptionKey, hasGithubCredentials, hasGoogleDriveCredentials, hasICloudCredentials, hasKeyPair, hasNotionCredentials, injectionSignatureCatalog, insertAfterId, insertChild, isAnumaTag, isCalendarCallback, isDriveCallback, isGithubCallback, isHtmlTag, isNotionCallback, isOPFSSupported, isR2UrlExpired, isRerankerAvailable, isSupportedFile, isSupportedMediaType, linkMemoryEntitiesOp, mediaToStored, migrateCalendarToken, migrateDisplayResult, migrateDriveToken, migrateGithubToken, migrateNotionClientRegistration, migrateNotionToken, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseJsx, preEmbedVaultMemories, preprocessFiles, previewToolSelection, projectToStored, putAppFileOp, quantizeEmbedding, queueManager, readEncryptedFile, recall, reflect, refreshCalendarToken, refreshDriveToken, refreshGithubToken, refreshNotionToken, relinkMisclassifiedVideosOp, removeById, renderAnumaJsx, renderAnumaTree, renderElementToCanvas, replaceById, replaceMemoryEntitiesGuardedOp, requestEncryptionKey, requestKeyPair, resolveFilePlaceholders, resolveThemeColor, restoreVaultMemoryOp, resumeStream, retain, revokeCalendarToken, revokeDriveToken, revokeGithubToken, revokeNotionAccess, savedToolToStored, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchChunksOp, searchMediaOp, searchMessagesOp, searchVaultMemories, selectServerToolsForPrompt, serializeJsx, setLogger, setMemoryEntitiesOp, settingsStorageSchema, shouldChunkMessage, shouldRefreshTools, stampTopicsExtractedAtOp, startGithubAuth, startNotionAuth, storeCalendarPendingMessage, storeCalendarReturnUrl, storeCalendarToken, storeDrivePendingMessage, storeDriveReturnUrl, storeDriveToken, storeGithubPendingMessage, storeGithubReturnUrl, storeGithubToken, storeNotionPendingMessage, storeNotionReturnUrl, streamCancelPath, streamReplayPath, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateAttrs, updateConversationProjectOp, updateMediaMessageIdBatchOp, updateMediaOp, updateMessageFeedbackOp, updateProjectNameOp, updateProjectOp, updateSavedToolOp, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, useAnumaTheme, useBackup, useBackupAuth, useChat, useChatStorage, useCredits, useDatabaseManager, useDropboxAuth, useDropboxBackup, useEncryption, useExportPdf, useFiles, useGoogleDriveAuth, useGoogleDriveBackup, useICloudAuth, useICloudBackup, useModels, useOCR, usePdf, usePhoneCalls, useProjects, useSettings, useSubscription, useTools, useUIInteraction, useVoice, useWalletBinding, userPreferencesStorageSchema, walk, webPlatformStorage, writeEncryptedFile };