@wiscale/velesdb-sdk 1.18.0 → 3.0.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.
package/README.md CHANGED
@@ -2,7 +2,18 @@
2
2
 
3
3
  Official TypeScript SDK for [VelesDB](https://github.com/cyberlife-coder/VelesDB) -- the local-first vector database for AI and RAG. Sub-millisecond semantic search in Browser and Node.js.
4
4
 
5
- **v1.18.0** | Node.js >= 18 | Browser (WASM) | VelesDB Core License 1.0
5
+ **v3.0.0** | Node.js >= 18 | Browser (WASM) | VelesDB Core License 1.0
6
+
7
+ ## What's New (unreleased)
8
+
9
+ - **Streaming ingestion enablement (2026-06-14)** (REST backend): `enableStreaming(collection, config?)` turns on the bounded streaming-ingestion channel before `streamInsert()`. The optional `StreamingConfig` (`bufferSize`, `batchSize`, `flushIntervalMs`) is camelCase; omitted fields fall back to the server defaults. See [`db.enableStreaming`](#dbenablestreamingcollection-config) below. The WASM backend throws `NOT_SUPPORTED`.
10
+ - **Relation + durable-TTL surface** (REST backend): `relate()`, `unrelate()`, `getRelations()`, `setTtlDurable()` — now fully tested and documented (see [Knowledge Graph API](#knowledge-graph-api) and [Agent Memory API](#agent-memory-api) below). The WASM backend throws `NOT_SUPPORTED` for these methods.
11
+ - The shipped example (`examples/hybrid_queries.ts`) was rewritten against the real API and is now compile-checked in CI.
12
+
13
+ ## What's New in v2.0.0
14
+
15
+ - v2.0.0: graph dimension on agent memory — `relate()` / `relations()` / `unrelate()`; durable-TTL setters; aligns with the engine 2.0 release. See the root [CHANGELOG](../../CHANGELOG.md) for the breaking VelesQL changes.
16
+ - v1.18.0: agent-memory parity wave — temporal recall facades (`recallRecent` / `recallOlderThan`), id-coercion hardening for `deleteMemory(string | number)`.
6
17
 
7
18
  ## What's New in v1.16.0
8
19
 
@@ -30,7 +41,7 @@ Official TypeScript SDK for [VelesDB](https://github.com/cyberlife-coder/VelesDB
30
41
  ### Previous (v1.13.0)
31
42
 
32
43
  - **WASM VelesQL executor** -- full browser-side VelesQL execution: SELECT/INSERT/UPDATE/DELETE/DDL + aggregations (COUNT/SUM/AVG/MIN/MAX) + GROUP BY/HAVING/UNION/INTERSECT/EXCEPT/JOIN/FUSION/MATCH 1-2 hops + NOT De Morgan distribution
33
- - **TS SDK coverage raised to 94%** -- 423 tests, per-file thresholds codified in `vitest.config.ts`
44
+ - **TS SDK coverage raised** -- per-file thresholds codified in `vitest.config.ts` (423 tests as of v1.13.0; the vitest suite has since grown past 770 cases). Note: the suite runs locally via `npm test` and is not currently executed in CI
34
45
  - **SIFT1M standardized ANN benchmark** -- fvecs/ivecs loader + Criterion ef sweep on the INRIA TEXMEX dataset, feature-gated behind `--features bench-sift1m`
35
46
  - **Security hardening** -- `validateCollectionName()` helper on TS SDK prevents VelesQL injection in `trainPq`
36
47
  - **API consistency** -- `streamInsert` now serializes `payload: null` explicitly (matches `streamUpsertPoints`)
@@ -160,7 +171,13 @@ const queryVector = new Float32Array(1536).fill(0.1);
160
171
  const results = await db.search('products', queryVector, { k: 10 });
161
172
  ```
162
173
 
163
- > **REST backend note:** Document IDs must be numeric integers in the range `0..Number.MAX_SAFE_INTEGER`. String IDs are only supported with the WASM backend.
174
+ > **REST backend note:** Document IDs must be non-negative `u64` integers. Pass a JS
175
+ > number in the range `0..Number.MAX_SAFE_INTEGER`, or a decimal string for the full
176
+ > `u64` range — string ids above 2^53-1 (up to `18446744073709551615`) are kept
177
+ > verbatim on the wire, so the ids returned by `recordEvent`/`learnProcedure`
178
+ > round-trip through `get`/`delete` without precision loss. Exception: the NDJSON
179
+ > bulk endpoint (`streamUpsertPoints`) only accepts safe-range numeric ids.
180
+ > Arbitrary (non-numeric) string IDs are only supported with the WASM backend.
164
181
 
165
182
  > **Versioned routes:** The REST backend uses `/v1/` as the canonical route prefix
166
183
  > (e.g. `POST /v1/collections/{name}/search`). Legacy routes without the prefix
@@ -316,6 +333,21 @@ await db.upsertBatch('docs', [
316
333
  ]);
317
334
  ```
318
335
 
336
+ #### `db.enableStreaming(collection, config?)`
337
+
338
+ Enable the bounded streaming-ingestion channel on a collection. Call this once before `streamInsert()`. The optional `config` is camelCase; every field is optional and omitted fields fall back to the server defaults (REST only; the WASM backend throws `NOT_SUPPORTED`).
339
+
340
+ | Option | Type | Default | Description |
341
+ |--------|------|---------|-------------|
342
+ | `bufferSize` | `number` | `10000` | Bounded ingestion channel capacity |
343
+ | `batchSize` | `number` | `128` | Points flushed to the index per batch |
344
+ | `flushIntervalMs` | `number` | `50` | Max milliseconds before a partial batch is flushed |
345
+
346
+ ```typescript
347
+ await db.enableStreaming('docs', { bufferSize: 4096, batchSize: 64 });
348
+ await db.streamInsert('docs', largeDocumentArray);
349
+ ```
350
+
319
351
  #### `db.streamInsert(collection, documents)`
320
352
 
321
353
  Insert documents with server backpressure support. Sends documents sequentially, respecting 429 rate limits. Throws `BackpressureError` if the server pushes back.
@@ -537,6 +569,14 @@ Get detailed collection configuration (dimension, metric, storage mode, point co
537
569
 
538
570
  Execute a VelesQL query. Supports SELECT, WHERE, vector NEAR, GROUP BY, HAVING, ORDER BY, JOIN, UNION/INTERSECT/EXCEPT, and USING FUSION.
539
571
 
572
+ > **Backend support:** full VelesQL execution requires the **REST backend** (`velesdb-server`).
573
+ > The WASM backend only executes pure top-k vector queries of the form
574
+ > `SELECT * FROM <collection> WHERE vector NEAR $param [LIMIT n]` (`vector` is the
575
+ > grammar keyword, not a column name) and throws a
576
+ > `NOT_SUPPORTED` error for anything else (WHERE predicates, JOIN, GROUP BY, MATCH,
577
+ > set operations, FUSION) instead of silently ignoring clauses. Accordingly,
578
+ > `db.capabilities().velesqlQuery` is `false` on WASM.
579
+
540
580
  ```typescript
541
581
  // Vector similarity search
542
582
  const result = await db.query(
@@ -717,6 +757,56 @@ for (const node of result.results) {
717
757
  }
718
758
  ```
719
759
 
760
+ #### `db.relate(collection, request)`
761
+
762
+ Create a typed relation edge between two existing points. Returns the
763
+ allocated edge ID (`RelateResponse = { edgeId: number | string }`). Point and
764
+ edge IDs are `number | string` — IDs above `Number.MAX_SAFE_INTEGER` travel as
765
+ decimal strings to avoid u64 precision loss. **REST backend only** (the WASM
766
+ backend throws `NOT_SUPPORTED`).
767
+
768
+ ```typescript
769
+ const { edgeId } = await db.relate('social', {
770
+ source: 100,
771
+ target: 200,
772
+ relType: 'FOLLOWS',
773
+ properties: { since: '2024-01-01' } // optional, defaults to {}
774
+ });
775
+ ```
776
+
777
+ #### `db.unrelate(collection, edgeId)`
778
+
779
+ Remove a relation edge by its ID. Returns `true` if the edge was removed,
780
+ `false` if it did not exist. **REST backend only.**
781
+
782
+ ```typescript
783
+ const removed = await db.unrelate('social', edgeId);
784
+ ```
785
+
786
+ #### `db.getRelations(collection, pointId)`
787
+
788
+ List the outgoing relation edges of a point. Returns
789
+ `RelationsResponse = { edges: RelationEdge[]; count: number }` where each edge
790
+ carries `{ id, source, target, relType, properties? }`. **REST backend only.**
791
+
792
+ ```typescript
793
+ const { edges, count } = await db.getRelations('social', 100);
794
+ for (const edge of edges) {
795
+ console.log(`${edge.source} -[${edge.relType}]-> ${edge.target}`);
796
+ }
797
+ ```
798
+
799
+ #### `db.setTtlDurable(collection, pointId, ttlSeconds)`
800
+
801
+ Durably set (or refresh) the time-to-live of a point, in **seconds**. The
802
+ expiry is persisted server-side (reserved `_veles_expires_at` payload field),
803
+ so it survives a restart. `ttlSeconds` must be a non-negative number.
804
+ **REST backend only.**
805
+
806
+ ```typescript
807
+ await db.setTtlDurable('social', 100, 3600); // expire point 100 in 1 hour
808
+ ```
809
+
720
810
  ---
721
811
 
722
812
  ### Property Indexes
@@ -810,18 +900,25 @@ await memory.storeFact('knowledge', {
810
900
  const facts = await memory.searchFacts('knowledge', queryEmbedding, 5);
811
901
  ```
812
902
 
813
- Each recall method returns `SearchResult[]`:
903
+ Each similarity-recall method (`searchFacts`, `recallEvents`,
904
+ `recallProcedures`) returns `SearchResult[]`:
814
905
 
815
906
  ```typescript
816
907
  // SearchResult = { id: number; score: number; payload?: Record<string, unknown>; vector?: number[] }
817
908
  ```
818
909
 
910
+ The temporal-recall methods (`recallRecent`, `recallOlderThan`) return
911
+ `EpisodicRecord[]` instead — see [Episodic Memory](#episodic-memory-events-and-experiences).
912
+
819
913
  - `score` is the cosine similarity in `[0, 1]` (for a `cosine` collection);
820
914
  higher means more similar.
821
- - `payload` carries the stored fields (`text`, `event_type`, `name`, `steps`,
822
- plus your metadata). The reserved keys `_memory_type` / `text` /
915
+ - `payload` carries the stored fields (`content` for semantic text,
916
+ `event_type` / `timestamp` for episodic, `name` / `steps` for procedural,
917
+ plus your metadata). The reserved payload keys `_memory_type` / `content` /
823
918
  `event_type` / `timestamp` / `name` / `steps` always take precedence over
824
919
  caller `metadata`/`data` of the same name, so they cannot be clobbered.
920
+ Note: the `SemanticEntry.text` input field is stored as `content` in the
921
+ payload — `result.payload?.content` is the fact text on recall.
825
922
 
826
923
  #### Semantic Memory (facts and knowledge)
827
924
 
@@ -850,6 +947,17 @@ const eventId = await memory.recordEvent('events', {
850
947
 
851
948
  // Recall similar events
852
949
  const events = await memory.recallEvents('events', queryEmbedding, 5);
950
+
951
+ // Temporal recall — no embedding needed, most-recent-first.
952
+ // recallRecent(collection, since?): events with timestamp >= since
953
+ // (inclusive, unix-seconds); recallOlderThan(collection, before): strictly older.
954
+ const nowSecs = Math.floor(Date.now() / 1000);
955
+ const allRecent = await memory.recallRecent('events');
956
+ const lastHour = await memory.recallRecent('events', nowSecs - 3600);
957
+ const stale = await memory.recallOlderThan('events', nowSecs - 86_400);
958
+
959
+ // Both return EpisodicRecord[]:
960
+ // { id: string; timestamp: number; payload: Record<string, unknown> }
853
961
  ```
854
962
 
855
963
  #### Procedural Memory (learned patterns)
@@ -880,9 +988,14 @@ await memory.deleteMemory('procedures', procId);
880
988
  > collection — the collection's own dimension (set at `createCollection`)
881
989
  > governs storage and search, and your embeddings must match it.
882
990
 
883
- > **TTL & snapshots.** Per-entry TTL (in **seconds**) and versioned snapshots are
884
- > exposed by the embedded Rust API only; the REST-backed TypeScript facade does
885
- > not surface them. See the [Agent Memory guide](../../docs/guides/AGENT_MEMORY.md).
991
+ > **TTL & snapshots.** Durable per-point TTL (in **seconds**) **is** available
992
+ > from this SDK: memory entries are regular points, so
993
+ > [`db.setTtlDurable(collection, pointId, ttlSeconds)`](#dbsetttldurablecollection-pointid-ttlseconds)
994
+ > expires a fact/event/procedure durably over REST. The subsystem-namespaced
995
+ > TTL helpers (`set_semantic_ttl`, `store_with_ttl`, `auto_expire`) and
996
+ > versioned snapshots remain embedded-only (Rust **and** Python bindings) and
997
+ > are not exposed over REST. See the API-availability table in the
998
+ > [Agent Memory guide](../../docs/guides/AGENT_MEMORY.md#api-availability-by-binding).
886
999
 
887
1000
  ---
888
1001
 
@@ -961,10 +1074,14 @@ import {
961
1074
  type AddEdgeRequest,
962
1075
  type TraverseRequest,
963
1076
  type TraverseResponse,
1077
+ type RelateRequest,
1078
+ type RelateResponse,
1079
+ type RelationsResponse,
964
1080
  type QueryApiResponse,
965
1081
  type AgentMemoryConfig,
966
1082
  type SemanticEntry,
967
1083
  type EpisodicEvent,
1084
+ type EpisodicRecord,
968
1085
  type ProceduralPattern,
969
1086
  } from '@wiscale/velesdb-sdk';
970
1087
  ```