@metaharness/kernel 0.1.4 → 0.1.5

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.
package/README.md CHANGED
@@ -49,6 +49,64 @@ const ranked = await rankWithDecay(hits, {
49
49
 
50
50
  Wraps `@ruvector/emergent-time` for HNSW decay scoring.
51
51
 
52
+ ### RVF memory backend (optional, persistent)
53
+
54
+ `@metaharness/kernel/memory-rvf` stores memory vectors on disk in
55
+ [`@ruvector/rvf`](https://www.npmjs.com/package/@ruvector/rvf) files and searches
56
+ them with RVF's HNSW index. RVF is an optional peer dependency. Install it to
57
+ enable the backend:
58
+
59
+ ```sh
60
+ npm install @metaharness/kernel @ruvector/rvf
61
+ ```
62
+
63
+ ```js
64
+ import { createRvfBackend } from '@metaharness/kernel/memory-rvf';
65
+
66
+ const mem = await createRvfBackend({ dimensions: 384, dir: './.harness/memory' });
67
+ if (!mem) {
68
+ // @ruvector/rvf is not installed: keep using the default in-process memory.
69
+ } else {
70
+ await mem.insertBatch([{ id: 'note-1', embedding }], 'notes'); // re-insert = replace
71
+ const hits = await mem.search(query, 10, 'notes'); // [{ id, score, distance, namespace }]
72
+ const exact = await mem.search(query, 10, 'notes', { exact: true }); // brute force
73
+ await mem.delete(['note-1'], 'notes');
74
+ await mem.close(); // releases the file lock; reopen the same dir later to continue
75
+ }
76
+ ```
77
+
78
+ - Each namespace is one file, `<dir>/<namespace>.rvf`, plus its `.rvf.idmap.json`
79
+ id map. Keep the two together. Writes are committed when their promise
80
+ resolves. `flush()` is a no-op.
81
+ - `createRvfBackend()` returns `null` only when `@ruvector/rvf` is not installed.
82
+ Errors after that are thrown, not swallowed: a missing native binding, a
83
+ dimension mismatch, or a second writer on the same file (RVF holds a
84
+ single-writer lock until `close()`).
85
+ - With the default `cosine` metric, `score` is cosine similarity
86
+ (`1 - distance`). With `l2` it is `1 / (1 + distance)`, which ranks the same
87
+ way but is not a cosine similarity.
88
+ - Not supported: RVF has no per-vector metadata yet (ruvector issue #704), so
89
+ hits carry no `storedAt`, and `rankWithDecay` treats them all as age 0.
90
+ `{ exact: true }` needs `@ruvector/rvf` 0.4.6 or later. Earlier versions ignore it.
91
+ - Supported range: `@ruvector/rvf` `^0.3.0 || ^0.4.6`. On 0.2.3, deletes did not
92
+ survive a reopen. In the 0.4 line the floor is 0.4.6, which adds `forceExact` and the
93
+ filtered-HNSW recall fallback.
94
+
95
+ Measured with `bench/memory-rvf-bench.mjs` on `@ruvector/rvf` 0.4.6 and Node 22.
96
+ The data was seeded uniform random vectors with cosine distance. Each run used
97
+ 200 queries at k = 10, scored against brute force after closing and reopening the
98
+ store. The figures are medians of 5 runs (10k) and 3 runs (1k) on a shared,
99
+ heavily loaded host, so the latencies are indicative only.
100
+
101
+ | Set | recall@10 (HNSW, unfiltered, efSearch 100) | recall p50 / p95 | exact scan p50 | `insert()` p50 / p95 | `insertBatch` per vector |
102
+ |---|---|---|---|---|---|
103
+ | 1k × 128 | 1.000 | 0.11 ms / – | – | – | – |
104
+ | 10k × 128 | 0.972 | 1.26 ms / 2.09 ms | 0.74 ms (recall 1.0) | 5.2 ms / 17.1 ms | 0.031 ms |
105
+ | 10k × 384 | 0.8745 | – | – | – | – |
106
+
107
+ At this scale the exact scan was as fast as HNSW or faster. Each `insert()` is
108
+ its own durable commit, so batch your writes.
109
+
52
110
  ## Subsystems
53
111
 
54
112
  | Subsystem | What it does |
@@ -1,22 +1,71 @@
1
1
  import type { MemoryHit } from './memory.js';
2
+ export type RvfMetric = 'cosine' | 'l2';
3
+ /** A memory hit from the RVF backend; carries RVF's raw distance as well. */
4
+ export interface RvfMemoryHit extends MemoryHit {
5
+ /**
6
+ * RVF distance (lower = closer). Cosine: `1 - cos_sim`. L2: squared
7
+ * Euclidean distance.
8
+ */
9
+ distance: number;
10
+ }
11
+ export interface RvfSearchOptions {
12
+ /** Exact brute-force scan instead of HNSW (@ruvector/rvf >= 0.4.6; ignored earlier). */
13
+ exact?: boolean;
14
+ /** HNSW ef_search beam width. RVF default: 100. */
15
+ efSearch?: number;
16
+ }
17
+ export interface RvfBackendOptions {
18
+ dimensions: number;
19
+ /**
20
+ * Distance metric. Default `'cosine'`, where `score = 1 - distance` is the
21
+ * cosine similarity. For `'l2'`, `score = 1 / (1 + distance)`: a monotone
22
+ * similarity in (0, 1], NOT a cosine similarity. The metric is fixed when a
23
+ * namespace file is created; reopening must use the same metric.
24
+ */
25
+ metric?: RvfMetric;
26
+ /**
27
+ * Directory holding one `.rvf` file per namespace. Created if missing.
28
+ * When omitted, a fresh temporary directory is used and deleted on
29
+ * `close()` — i.e. nothing persists.
30
+ */
31
+ dir?: string;
32
+ /** HNSW M (max edges per node per layer). RVF default: 16. */
33
+ m?: number;
34
+ /** HNSW ef_construction. RVF default: 200. */
35
+ efConstruction?: number;
36
+ }
37
+ export interface RvfBackendEntry {
38
+ id: string;
39
+ embedding: number[] | Float32Array;
40
+ }
2
41
  export interface RvfBackend {
3
- /** Insert a vector into the index. */
4
- insert(id: string, embedding: number[], namespace?: string): Promise<void>;
5
- /** Search by embedding similarity. */
6
- search(embedding: number[], k: number, namespace?: string): Promise<MemoryHit[]>;
7
- /** Total items currently indexed. */
8
- size(): Promise<number>;
9
- /** Persist + flush. */
42
+ /** Absolute directory holding the namespace files. */
43
+ readonly dir: string;
44
+ /** False when `dir` was not given (temporary directory, removed on close). */
45
+ readonly persistent: boolean;
46
+ /** Insert (or replace) one vector. */
47
+ insert(id: string, embedding: number[] | Float32Array, namespace?: string): Promise<void>;
48
+ /** Insert (or replace) many vectors in one RVF commit. */
49
+ insertBatch(entries: RvfBackendEntry[], namespace?: string): Promise<void>;
50
+ /** Top-k nearest neighbours, best first. Unknown namespace → []. */
51
+ search(embedding: number[] | Float32Array, k: number, namespace?: string, opts?: RvfSearchOptions): Promise<RvfMemoryHit[]>;
52
+ /** Delete ids; returns how many were live and removed. */
53
+ delete(ids: string[], namespace?: string): Promise<number>;
54
+ /** Live vectors in one namespace, or across all namespaces on disk. */
55
+ size(namespace?: string): Promise<number>;
56
+ /** Namespaces that exist on disk. */
57
+ namespaces(): string[];
58
+ /** No-op kept for the backend contract: writes are committed per call. */
10
59
  flush(): Promise<void>;
60
+ /** Close every open namespace file and release the writer locks. */
61
+ close(): Promise<void>;
11
62
  }
12
- /** Is the RVF package installed and importable in the current process? */
63
+ /** Is a usable @ruvector/rvf (with `RvfDatabase`) importable in this process? */
13
64
  export declare function isRvfAvailable(): Promise<boolean>;
14
65
  /**
15
- * Create an RVF-backed backend. Returns null if RVF isn't installed —
16
- * caller falls back to the in-process HNSW.
66
+ * Create an RVF-backed memory backend. Returns null only when
67
+ * @ruvector/rvf is not installed (or has no `RvfDatabase`), so the caller
68
+ * can fall back to its default memory. Namespace files are opened lazily.
17
69
  */
18
- export declare function createRvfBackend(opts: {
19
- dimensions: number;
20
- metric?: 'cosine' | 'l2';
21
- }): Promise<RvfBackend | null>;
70
+ export declare function createRvfBackend(opts: RvfBackendOptions): Promise<RvfBackend | null>;
22
71
  //# sourceMappingURL=memory-rvf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-rvf.d.ts","sourceRoot":"","sources":["../src/memory-rvf.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,sCAAsC;IACtC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACjF,qCAAqC;IACrC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,uBAAuB;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAiCD,0EAA0E;AAC1E,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAEvD;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA2C7B"}
1
+ {"version":3,"file":"memory-rvf.d.ts","sourceRoot":"","sources":["../src/memory-rvf.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC;AAExC,6EAA6E;AAC7E,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,0DAA0D;IAC1D,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,oEAAoE;IACpE,MAAM,CACJ,SAAS,EAAE,MAAM,EAAE,GAAG,YAAY,EAClC,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,gBAAgB,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3B,0DAA0D;IAC1D,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,uEAAuE;IACvE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,qCAAqC;IACrC,UAAU,IAAI,MAAM,EAAE,CAAC;IACvB,0EAA0E;IAC1E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAiDD,iFAAiF;AACjF,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAEvD;AAyBD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA+H1F"}
@@ -1,86 +1,226 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  //
3
- // memory-rvf — graceful-fallback wrapper over @ruvector/rvf
3
+ // memory-rvf — persistent kernel memory on @ruvector/rvf
4
4
  // (https://www.npmjs.com/package/@ruvector/rvf).
5
5
  //
6
- // RVF is "RuVector Format — unified TypeScript SDK for vector intelligence":
7
- // HNSW-indexed binary vector format with SIMD, dual-target (TypeScript
8
- // runtime + optional @ruvector/rvf-wasm). When the user has RVF installed
9
- // AND wants RVF-backed memory storage, the kernel uses it; otherwise the
10
- // memory subsystem keeps using its plain in-process HNSW.
6
+ // RVF ("RuVector Format") is an HNSW-indexed, single-file vector store with a
7
+ // native Node backend (@ruvector/rvf-node). This module maps the kernel's
8
+ // memory backend contract onto `RvfDatabase`:
11
9
  //
12
- // RVF is declared as an OPTIONAL peer dep so the kernel doesn't bloat
13
- // install size for users who don't need it. The pairing matters most
14
- // for RVM-deployed harnesses — RVM's wasm guest can run rvf-wasm
15
- // inside the partition for hardware-isolated vector storage.
10
+ // kernel @ruvector/rvf
11
+ // ------------------------ -------------------------------------------
12
+ // namespace one `<namespace>.rvf` file under `dir`
13
+ // (+ its `.rvf.idmap.json` string-id sidecar)
14
+ // insert / insertBatch RvfDatabase.ingestBatch (re-insert = upsert)
15
+ // search RvfDatabase.query(vec, k, { efSearch,
16
+ // forceExact })
17
+ // delete RvfDatabase.delete(ids)
18
+ // size RvfDatabase.status().totalVectors
19
+ // flush no-op: every ingest/delete is committed to
20
+ // the file when its promise resolves
21
+ // close RvfDatabase.close() (releases the writer lock)
22
+ //
23
+ // What RVF cannot do, and how this module handles it:
24
+ // - Per-vector metadata is not supported by @ruvector/rvf (issue #704:
25
+ // `ingestBatch` throws MetadataNotSupported). So `storedAt` is NOT
26
+ // persisted and hits come back without it; `rankWithDecay` then treats
27
+ // every hit as age 0, i.e. decay does not reorder RVF hits. Namespaces are
28
+ // separate files for the same reason (there is no metadata to filter on).
29
+ // - `forceExact` (exact brute-force search) is passed through by
30
+ // @ruvector/rvf >= 0.4.6 (rvf-node >= 0.4.1). Earlier versions ignore it
31
+ // and search stays on HNSW.
32
+ // - Each `.rvf` file has a single-writer lock. A second backend (in this or
33
+ // another process) opening the same namespace for writing fails with
34
+ // RVF LockHeld. Call `close()` to release it.
35
+ //
36
+ // RVF is an OPTIONAL peer dependency (^0.3.0 || ^0.4.6). When it is not
37
+ // installed, `createRvfBackend()` returns null and the caller keeps its
38
+ // default in-process memory. When it IS installed but fails at use time
39
+ // (native binding missing, lock held, dimension mismatch), the error is
40
+ // thrown rather than silently swallowed.
41
+ import { existsSync, mkdirSync, mkdtempSync, readdirSync, rmSync } from 'node:fs';
42
+ import { tmpdir } from 'node:os';
43
+ import { join, resolve } from 'node:path';
16
44
  let _rvf;
17
45
  async function loadRvf() {
18
46
  if (_rvf !== undefined)
19
47
  return _rvf;
20
48
  try {
21
- // @ts-ignore — @ruvector/rvf is declared as an OPTIONAL peer
22
- // dependency, so a fresh CI install without it must build cleanly.
23
- // The graceful-fallback path returns null when the package is absent.
24
- _rvf = await import('@ruvector/rvf');
25
- return _rvf;
49
+ // @ts-ignore — @ruvector/rvf is an OPTIONAL peer dependency, so a fresh
50
+ // install without it must still type-check and build.
51
+ const mod = (await import('@ruvector/rvf'));
52
+ const db = mod.RvfDatabase ?? mod.default?.RvfDatabase;
53
+ _rvf = db && typeof db.create === 'function' && typeof db.open === 'function' ? db : null;
26
54
  }
27
55
  catch {
28
56
  _rvf = null;
29
- return null;
30
57
  }
58
+ return _rvf;
31
59
  }
32
- /** Is the RVF package installed and importable in the current process? */
60
+ /** Is a usable @ruvector/rvf (with `RvfDatabase`) importable in this process? */
33
61
  export async function isRvfAvailable() {
34
62
  return (await loadRvf()) !== null;
35
63
  }
64
+ const NAMESPACE_RE = /^[A-Za-z0-9_-][A-Za-z0-9._-]{0,127}$/;
65
+ const FILE_SUFFIX = '.rvf';
66
+ function checkNamespace(ns) {
67
+ if (typeof ns !== 'string' || !NAMESPACE_RE.test(ns)) {
68
+ throw new Error(`memory-rvf: invalid namespace ${JSON.stringify(ns)} — use 1-128 chars of [A-Za-z0-9._-], not starting with '.'`);
69
+ }
70
+ return ns;
71
+ }
72
+ function toVector(embedding, dimensions) {
73
+ if (!embedding || embedding.length !== dimensions) {
74
+ throw new Error(`memory-rvf: embedding has ${embedding?.length} dims, backend expects ${dimensions}`);
75
+ }
76
+ const v = embedding instanceof Float32Array ? embedding : Float32Array.from(embedding);
77
+ for (let i = 0; i < v.length; i++) {
78
+ if (!Number.isFinite(v[i]))
79
+ throw new Error(`memory-rvf: embedding[${i}] is not finite`);
80
+ }
81
+ return v;
82
+ }
36
83
  /**
37
- * Create an RVF-backed backend. Returns null if RVF isn't installed —
38
- * caller falls back to the in-process HNSW.
84
+ * Create an RVF-backed memory backend. Returns null only when
85
+ * @ruvector/rvf is not installed (or has no `RvfDatabase`), so the caller
86
+ * can fall back to its default memory. Namespace files are opened lazily.
39
87
  */
40
88
  export async function createRvfBackend(opts) {
41
- const mod = await loadRvf();
42
- if (!mod)
43
- return null;
44
- const createIndex = mod.createIndex ?? mod.default?.createIndex;
45
- if (typeof createIndex !== 'function')
89
+ const Rvf = await loadRvf();
90
+ if (!Rvf)
46
91
  return null;
47
- const indexByNs = new Map();
48
- const ensure = async (ns) => {
49
- let idx = indexByNs.get(ns);
50
- if (!idx) {
51
- idx = await createIndex({ dimensions: opts.dimensions, metric: opts.metric ?? 'cosine' });
52
- indexByNs.set(ns, idx);
92
+ const dimensions = opts.dimensions;
93
+ if (!Number.isInteger(dimensions) || dimensions <= 0) {
94
+ throw new Error(`memory-rvf: dimensions must be a positive integer, got ${dimensions}`);
95
+ }
96
+ const metric = opts.metric ?? 'cosine';
97
+ if (metric !== 'cosine' && metric !== 'l2') {
98
+ throw new Error(`memory-rvf: unsupported metric ${JSON.stringify(metric)}`);
99
+ }
100
+ const persistent = typeof opts.dir === 'string' && opts.dir.length > 0;
101
+ const dir = persistent ? resolve(opts.dir) : mkdtempSync(join(tmpdir(), 'metaharness-rvf-'));
102
+ mkdirSync(dir, { recursive: true });
103
+ const toScore = metric === 'cosine' ? (d) => 1 - d : (d) => 1 / (1 + d);
104
+ const pathOf = (ns) => join(dir, checkNamespace(ns) + FILE_SUFFIX);
105
+ // Cache the promise, not the value, so concurrent first use of a namespace
106
+ // opens/creates the file exactly once.
107
+ const dbs = new Map();
108
+ let closed = false;
109
+ const openOrCreate = async (ns) => {
110
+ const p = pathOf(ns);
111
+ if (existsSync(p)) {
112
+ const db = await Rvf.open(p);
113
+ const dim = await db.dimension();
114
+ if (dim !== dimensions) {
115
+ await db.close();
116
+ throw new Error(`memory-rvf: ${p} has ${dim} dims, backend expects ${dimensions}`);
117
+ }
118
+ return db;
119
+ }
120
+ const createOpts = {
121
+ dimensions,
122
+ metric,
123
+ };
124
+ if (opts.m !== undefined)
125
+ createOpts.m = opts.m;
126
+ if (opts.efConstruction !== undefined)
127
+ createOpts.efConstruction = opts.efConstruction;
128
+ return Rvf.create(p, createOpts);
129
+ };
130
+ /** Returns the open db, or null when `create` is false and no file exists. */
131
+ const get = async (ns, create) => {
132
+ if (closed)
133
+ throw new Error('memory-rvf: backend is closed');
134
+ const cached = dbs.get(ns);
135
+ if (cached)
136
+ return cached;
137
+ if (!create && !existsSync(pathOf(ns)))
138
+ return null;
139
+ const pending = openOrCreate(ns);
140
+ dbs.set(ns, pending);
141
+ pending.catch(() => dbs.delete(ns));
142
+ return pending;
143
+ };
144
+ const listNamespaces = () => readdirSync(dir)
145
+ .filter(f => f.endsWith(FILE_SUFFIX))
146
+ .map(f => f.slice(0, -FILE_SUFFIX.length))
147
+ .filter(ns => NAMESPACE_RE.test(ns))
148
+ .sort();
149
+ const insertBatch = async (entries, namespace = 'default') => {
150
+ if (entries.length === 0)
151
+ return;
152
+ const rows = entries.map(e => {
153
+ if (typeof e.id !== 'string' || e.id.length === 0)
154
+ throw new Error('memory-rvf: id must be a non-empty string');
155
+ return { id: e.id, vector: toVector(e.embedding, dimensions) };
156
+ });
157
+ const db = (await get(namespace, true));
158
+ const res = await db.ingestBatch(rows);
159
+ if (res.rejected > 0) {
160
+ throw new Error(`memory-rvf: RVF rejected ${res.rejected} of ${rows.length} vectors in namespace ${namespace}`);
53
161
  }
54
- return idx;
55
162
  };
56
163
  return {
57
- async insert(id, embedding, namespace = 'default') {
58
- const idx = await ensure(namespace);
59
- await idx.add(id, embedding);
164
+ dir,
165
+ persistent,
166
+ insert(id, embedding, namespace = 'default') {
167
+ return insertBatch([{ id, embedding }], namespace);
168
+ },
169
+ insertBatch,
170
+ async search(embedding, k, namespace = 'default', so = {}) {
171
+ if (!Number.isInteger(k) || k <= 0)
172
+ throw new Error(`memory-rvf: k must be a positive integer, got ${k}`);
173
+ const vec = toVector(embedding, dimensions);
174
+ const db = await get(namespace, false);
175
+ if (!db)
176
+ return [];
177
+ const q = {};
178
+ if (so.efSearch !== undefined)
179
+ q.efSearch = so.efSearch;
180
+ if (so.exact)
181
+ q.forceExact = true;
182
+ const raw = await db.query(vec, k, q);
183
+ return raw.map(r => {
184
+ const score = toScore(r.distance);
185
+ // storedAt is absent: RVF has no per-vector metadata (rvf #704).
186
+ return { id: r.id, score, decayedScore: score, distance: r.distance, namespace };
187
+ });
60
188
  },
61
- async search(embedding, k, namespace = 'default') {
62
- const idx = await ensure(namespace);
63
- const raw = await idx.search(embedding, k);
64
- return raw.map(r => ({
65
- id: r.id,
66
- score: r.score,
67
- decayedScore: r.score, // memory.rankWithDecay applies decay separately
68
- namespace,
69
- }));
189
+ async delete(ids, namespace = 'default') {
190
+ if (ids.length === 0)
191
+ return 0;
192
+ const db = await get(namespace, false);
193
+ if (!db)
194
+ return 0;
195
+ return (await db.delete(ids)).deleted;
70
196
  },
71
- async size() {
197
+ async size(namespace) {
198
+ const targets = namespace === undefined ? listNamespaces() : [namespace];
72
199
  let total = 0;
73
- for (const idx of indexByNs.values()) {
74
- const count = await (idx.count?.() ?? idx.size?.() ?? Promise.resolve(0));
75
- total += count ?? 0;
200
+ for (const ns of targets) {
201
+ const db = await get(ns, false);
202
+ if (db)
203
+ total += (await db.status()).totalVectors;
76
204
  }
77
205
  return total;
78
206
  },
207
+ namespaces: listNamespaces,
79
208
  async flush() {
80
- for (const idx of indexByNs.values()) {
81
- if (typeof idx.flush === 'function')
82
- await idx.flush();
83
- }
209
+ if (closed)
210
+ throw new Error('memory-rvf: backend is closed');
211
+ await Promise.allSettled([...dbs.values()]);
212
+ },
213
+ async close() {
214
+ if (closed)
215
+ return;
216
+ closed = true;
217
+ const open = await Promise.allSettled([...dbs.values()]);
218
+ dbs.clear();
219
+ for (const r of open)
220
+ if (r.status === 'fulfilled')
221
+ await r.value.close();
222
+ if (!persistent)
223
+ rmSync(dir, { recursive: true, force: true });
84
224
  },
85
225
  };
86
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"memory-rvf.js","sourceRoot":"","sources":["../src/memory-rvf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-rvf.js","sourceRoot":"","sources":["../src/memory-rvf.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaharness/kernel",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Cross-platform kernel for the agent-harness-generator — wasm primary, NAPI-RS native fallback",
5
5
  "homepage": "https://github.com/ruvnet/metaharness",
6
6
  "repository": {
@@ -57,7 +57,7 @@
57
57
  "@ruvector/emergent-time": "^0.1.0"
58
58
  },
59
59
  "peerDependencies": {
60
- "@ruvector/rvf": "^0.2.0 || ^0.3.0 || ^0.4.0",
60
+ "@ruvector/rvf": "^0.3.0 || ^0.4.6",
61
61
  "@metaharness/kernel-darwin-arm64": "0.1.0",
62
62
  "@metaharness/kernel-darwin-x64": "0.1.0",
63
63
  "@metaharness/kernel-linux-x64-gnu": "0.1.0",
@@ -86,5 +86,8 @@
86
86
  },
87
87
  "engines": {
88
88
  "node": ">=20.0.0"
89
+ },
90
+ "devDependencies": {
91
+ "@ruvector/rvf": "^0.4.6"
89
92
  }
90
93
  }