@wiscale/velesdb-sdk 1.18.0 → 2.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,17 @@
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
+ **v2.0.0** | Node.js >= 18 | Browser (WASM) | VelesDB Core License 1.0
6
+
7
+ ## What's New (unreleased)
8
+
9
+ - **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.
10
+ - The shipped example (`examples/hybrid_queries.ts`) was rewritten against the real API and is now compile-checked in CI.
11
+
12
+ ## What's New in v2.0.0
13
+
14
+ - 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.
15
+ - v1.18.0: agent-memory parity wave — temporal recall facades (`recallRecent` / `recallOlderThan`), id-coercion hardening for `deleteMemory(string | number)`.
6
16
 
7
17
  ## What's New in v1.16.0
8
18
 
@@ -30,7 +40,7 @@ Official TypeScript SDK for [VelesDB](https://github.com/cyberlife-coder/VelesDB
30
40
  ### Previous (v1.13.0)
31
41
 
32
42
  - **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`
43
+ - **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
44
  - **SIFT1M standardized ANN benchmark** -- fvecs/ivecs loader + Criterion ef sweep on the INRIA TEXMEX dataset, feature-gated behind `--features bench-sift1m`
35
45
  - **Security hardening** -- `validateCollectionName()` helper on TS SDK prevents VelesQL injection in `trainPq`
36
46
  - **API consistency** -- `streamInsert` now serializes `payload: null` explicitly (matches `streamUpsertPoints`)
@@ -160,7 +170,13 @@ const queryVector = new Float32Array(1536).fill(0.1);
160
170
  const results = await db.search('products', queryVector, { k: 10 });
161
171
  ```
162
172
 
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.
173
+ > **REST backend note:** Document IDs must be non-negative `u64` integers. Pass a JS
174
+ > number in the range `0..Number.MAX_SAFE_INTEGER`, or a decimal string for the full
175
+ > `u64` range — string ids above 2^53-1 (up to `18446744073709551615`) are kept
176
+ > verbatim on the wire, so the ids returned by `recordEvent`/`learnProcedure`
177
+ > round-trip through `get`/`delete` without precision loss. Exception: the NDJSON
178
+ > bulk endpoint (`streamUpsertPoints`) only accepts safe-range numeric ids.
179
+ > Arbitrary (non-numeric) string IDs are only supported with the WASM backend.
164
180
 
165
181
  > **Versioned routes:** The REST backend uses `/v1/` as the canonical route prefix
166
182
  > (e.g. `POST /v1/collections/{name}/search`). Legacy routes without the prefix
@@ -537,6 +553,14 @@ Get detailed collection configuration (dimension, metric, storage mode, point co
537
553
 
538
554
  Execute a VelesQL query. Supports SELECT, WHERE, vector NEAR, GROUP BY, HAVING, ORDER BY, JOIN, UNION/INTERSECT/EXCEPT, and USING FUSION.
539
555
 
556
+ > **Backend support:** full VelesQL execution requires the **REST backend** (`velesdb-server`).
557
+ > The WASM backend only executes pure top-k vector queries of the form
558
+ > `SELECT * FROM <collection> WHERE vector NEAR $param [LIMIT n]` (`vector` is the
559
+ > grammar keyword, not a column name) and throws a
560
+ > `NOT_SUPPORTED` error for anything else (WHERE predicates, JOIN, GROUP BY, MATCH,
561
+ > set operations, FUSION) instead of silently ignoring clauses. Accordingly,
562
+ > `db.capabilities().velesqlQuery` is `false` on WASM.
563
+
540
564
  ```typescript
541
565
  // Vector similarity search
542
566
  const result = await db.query(
@@ -717,6 +741,56 @@ for (const node of result.results) {
717
741
  }
718
742
  ```
719
743
 
744
+ #### `db.relate(collection, request)`
745
+
746
+ Create a typed relation edge between two existing points. Returns the
747
+ allocated edge ID (`RelateResponse = { edgeId: number | string }`). Point and
748
+ edge IDs are `number | string` — IDs above `Number.MAX_SAFE_INTEGER` travel as
749
+ decimal strings to avoid u64 precision loss. **REST backend only** (the WASM
750
+ backend throws `NOT_SUPPORTED`).
751
+
752
+ ```typescript
753
+ const { edgeId } = await db.relate('social', {
754
+ source: 100,
755
+ target: 200,
756
+ relType: 'FOLLOWS',
757
+ properties: { since: '2024-01-01' } // optional, defaults to {}
758
+ });
759
+ ```
760
+
761
+ #### `db.unrelate(collection, edgeId)`
762
+
763
+ Remove a relation edge by its ID. Returns `true` if the edge was removed,
764
+ `false` if it did not exist. **REST backend only.**
765
+
766
+ ```typescript
767
+ const removed = await db.unrelate('social', edgeId);
768
+ ```
769
+
770
+ #### `db.getRelations(collection, pointId)`
771
+
772
+ List the outgoing relation edges of a point. Returns
773
+ `RelationsResponse = { edges: RelationEdge[]; count: number }` where each edge
774
+ carries `{ id, source, target, relType, properties? }`. **REST backend only.**
775
+
776
+ ```typescript
777
+ const { edges, count } = await db.getRelations('social', 100);
778
+ for (const edge of edges) {
779
+ console.log(`${edge.source} -[${edge.relType}]-> ${edge.target}`);
780
+ }
781
+ ```
782
+
783
+ #### `db.setTtlDurable(collection, pointId, ttlSeconds)`
784
+
785
+ Durably set (or refresh) the time-to-live of a point, in **seconds**. The
786
+ expiry is persisted server-side (reserved `_veles_expires_at` payload field),
787
+ so it survives a restart. `ttlSeconds` must be a non-negative number.
788
+ **REST backend only.**
789
+
790
+ ```typescript
791
+ await db.setTtlDurable('social', 100, 3600); // expire point 100 in 1 hour
792
+ ```
793
+
720
794
  ---
721
795
 
722
796
  ### Property Indexes
@@ -810,18 +884,25 @@ await memory.storeFact('knowledge', {
810
884
  const facts = await memory.searchFacts('knowledge', queryEmbedding, 5);
811
885
  ```
812
886
 
813
- Each recall method returns `SearchResult[]`:
887
+ Each similarity-recall method (`searchFacts`, `recallEvents`,
888
+ `recallProcedures`) returns `SearchResult[]`:
814
889
 
815
890
  ```typescript
816
891
  // SearchResult = { id: number; score: number; payload?: Record<string, unknown>; vector?: number[] }
817
892
  ```
818
893
 
894
+ The temporal-recall methods (`recallRecent`, `recallOlderThan`) return
895
+ `EpisodicRecord[]` instead — see [Episodic Memory](#episodic-memory-events-and-experiences).
896
+
819
897
  - `score` is the cosine similarity in `[0, 1]` (for a `cosine` collection);
820
898
  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` /
899
+ - `payload` carries the stored fields (`content` for semantic text,
900
+ `event_type` / `timestamp` for episodic, `name` / `steps` for procedural,
901
+ plus your metadata). The reserved payload keys `_memory_type` / `content` /
823
902
  `event_type` / `timestamp` / `name` / `steps` always take precedence over
824
903
  caller `metadata`/`data` of the same name, so they cannot be clobbered.
904
+ Note: the `SemanticEntry.text` input field is stored as `content` in the
905
+ payload — `result.payload?.content` is the fact text on recall.
825
906
 
826
907
  #### Semantic Memory (facts and knowledge)
827
908
 
@@ -850,6 +931,17 @@ const eventId = await memory.recordEvent('events', {
850
931
 
851
932
  // Recall similar events
852
933
  const events = await memory.recallEvents('events', queryEmbedding, 5);
934
+
935
+ // Temporal recall — no embedding needed, most-recent-first.
936
+ // recallRecent(collection, since?): events with timestamp >= since
937
+ // (inclusive, unix-seconds); recallOlderThan(collection, before): strictly older.
938
+ const nowSecs = Math.floor(Date.now() / 1000);
939
+ const allRecent = await memory.recallRecent('events');
940
+ const lastHour = await memory.recallRecent('events', nowSecs - 3600);
941
+ const stale = await memory.recallOlderThan('events', nowSecs - 86_400);
942
+
943
+ // Both return EpisodicRecord[]:
944
+ // { id: string; timestamp: number; payload: Record<string, unknown> }
853
945
  ```
854
946
 
855
947
  #### Procedural Memory (learned patterns)
@@ -880,9 +972,14 @@ await memory.deleteMemory('procedures', procId);
880
972
  > collection — the collection's own dimension (set at `createCollection`)
881
973
  > governs storage and search, and your embeddings must match it.
882
974
 
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).
975
+ > **TTL & snapshots.** Durable per-point TTL (in **seconds**) **is** available
976
+ > from this SDK: memory entries are regular points, so
977
+ > [`db.setTtlDurable(collection, pointId, ttlSeconds)`](#dbsetttldurablecollection-pointid-ttlseconds)
978
+ > expires a fact/event/procedure durably over REST. The subsystem-namespaced
979
+ > TTL helpers (`set_semantic_ttl`, `store_with_ttl`, `auto_expire`) and
980
+ > versioned snapshots remain embedded-only (Rust **and** Python bindings) and
981
+ > are not exposed over REST. See the API-availability table in the
982
+ > [Agent Memory guide](../../docs/guides/AGENT_MEMORY.md#api-availability-by-binding).
886
983
 
887
984
  ---
888
985
 
@@ -961,10 +1058,14 @@ import {
961
1058
  type AddEdgeRequest,
962
1059
  type TraverseRequest,
963
1060
  type TraverseResponse,
1061
+ type RelateRequest,
1062
+ type RelateResponse,
1063
+ type RelationsResponse,
964
1064
  type QueryApiResponse,
965
1065
  type AgentMemoryConfig,
966
1066
  type SemanticEntry,
967
1067
  type EpisodicEvent,
1068
+ type EpisodicRecord,
968
1069
  type ProceduralPattern,
969
1070
  } from '@wiscale/velesdb-sdk';
970
1071
  ```
package/dist/index.d.mts CHANGED
@@ -12,8 +12,15 @@ type StorageMode = 'full' | 'sq8' | 'binary' | 'pq' | 'rabitq';
12
12
  type SearchQuality = 'fast' | 'balanced' | 'accurate' | 'perfect' | 'autotune' | `custom:${number}` | `adaptive:${number}:${number}`;
13
13
  /** Backend type for VelesDB connection */
14
14
  type BackendType = 'wasm' | 'rest';
15
- /** Numeric point ID required by velesdb-server REST API (`u64`). */
16
- type RestPointId = number;
15
+ /**
16
+ * Point ID accepted by the velesdb-server REST API (`u64`).
17
+ *
18
+ * Ids within the JS safe-integer range are numbers; decimal-string ids above
19
+ * `Number.MAX_SAFE_INTEGER` (2^53-1) stay verbatim strings so the full u64
20
+ * range survives the JavaScript boundary without precision loss (the server
21
+ * deserialises both forms since #1004).
22
+ */
23
+ type RestPointId = number | string;
17
24
  /** Configuration options for VelesDB client */
18
25
  interface VelesDBConfig {
19
26
  /** Backend type: 'wasm' for browser/Node.js, 'rest' for server */
@@ -563,6 +570,42 @@ interface DegreeResponse {
563
570
  /** Number of outgoing edges */
564
571
  outDegree: number;
565
572
  }
573
+ /** Request body for POST /collections/{name}/relations */
574
+ interface RelateRequest {
575
+ /** Source point ID */
576
+ source: GraphNodeId;
577
+ /** Target point ID */
578
+ target: GraphNodeId;
579
+ /** Relationship type label (e.g. "KNOWS", "RELATED_TO") */
580
+ relType: string;
581
+ /** Optional edge properties */
582
+ properties?: Record<string, unknown>;
583
+ }
584
+ /** Response from POST /collections/{name}/relations */
585
+ interface RelateResponse {
586
+ /** Allocated edge ID */
587
+ edgeId: GraphNodeId;
588
+ }
589
+ /** A single outgoing relation edge */
590
+ interface RelationEdge {
591
+ /** Edge ID */
592
+ id: GraphNodeId;
593
+ /** Source point ID */
594
+ source: GraphNodeId;
595
+ /** Target point ID */
596
+ target: GraphNodeId;
597
+ /** Relationship type label */
598
+ relType: string;
599
+ /** Edge properties */
600
+ properties?: Record<string, unknown>;
601
+ }
602
+ /** Response from GET /collections/{name}/points/{id}/relations */
603
+ interface RelationsResponse {
604
+ /** Outgoing relation edges */
605
+ edges: RelationEdge[];
606
+ /** Total count */
607
+ count: number;
608
+ }
566
609
  /** Schema mode for graph collections */
567
610
  type GraphSchemaMode = 'schemaless' | 'strict';
568
611
  /** Graph collection configuration */
@@ -583,8 +626,15 @@ interface GraphCollectionConfig {
583
626
  */
584
627
  /** Semantic memory entry */
585
628
  interface SemanticEntry {
586
- /** Unique fact ID */
587
- id: number;
629
+ /**
630
+ * Unique fact ID.
631
+ *
632
+ * `string | number` is accepted as a convenience (a string must be a decimal
633
+ * integer). Ids must be non-negative integers within the JS safe-integer
634
+ * range (0..2^53-1): the REST wire transmits point ids as JSON numbers, so
635
+ * out-of-range ids are rejected (not silently truncated).
636
+ */
637
+ id: string | number;
588
638
  /** Fact text content */
589
639
  text: string;
590
640
  /** Embedding vector */
@@ -594,8 +644,24 @@ interface SemanticEntry {
594
644
  }
595
645
  /** Episodic memory event */
596
646
  interface EpisodicEvent {
647
+ /**
648
+ * Optional caller-provided event ID. When omitted, a monotonic id is
649
+ * generated. `string | number` is accepted as a convenience; ids must be
650
+ * non-negative integers within the JS safe-integer range (0..2^53-1) because
651
+ * the REST wire transmits them as JSON numbers, and out-of-range ids are
652
+ * rejected (not silently truncated).
653
+ */
654
+ id?: string | number;
597
655
  /** Event type identifier */
598
656
  eventType: string;
657
+ /**
658
+ * Event timestamp as a NUMERIC unix time in **seconds**.
659
+ *
660
+ * Mirrors the core episodic store, which persists a numeric `timestamp`
661
+ * that feeds `recent(since)` / `older_than(before)`. When omitted it
662
+ * defaults to the current unix-seconds value (`floor(Date.now() / 1000)`).
663
+ */
664
+ timestamp?: number;
599
665
  /** Event data */
600
666
  data: Record<string, unknown>;
601
667
  /** Embedding vector */
@@ -605,6 +671,14 @@ interface EpisodicEvent {
605
671
  }
606
672
  /** Procedural memory pattern */
607
673
  interface ProceduralPattern {
674
+ /**
675
+ * Optional caller-provided pattern ID. When omitted, a monotonic id is
676
+ * generated. `string | number` is accepted as a convenience; ids must be
677
+ * non-negative integers within the JS safe-integer range (0..2^53-1) because
678
+ * the REST wire transmits them as JSON numbers, and out-of-range ids are
679
+ * rejected (not silently truncated).
680
+ */
681
+ id?: string | number;
608
682
  /** Procedure name */
609
683
  name: string;
610
684
  /** Ordered steps */
@@ -620,6 +694,15 @@ interface ProceduralPattern {
620
694
  /** Optional metadata */
621
695
  metadata?: Record<string, unknown>;
622
696
  }
697
+ /** A single episodic event recalled by timestamp. */
698
+ interface EpisodicRecord {
699
+ /** Point id as a string (u64 precision preserved). */
700
+ id: string;
701
+ /** Numeric unix-seconds timestamp. */
702
+ timestamp: number;
703
+ /** Full point payload (includes `event_type`, caller data/metadata). */
704
+ payload: Record<string, unknown>;
705
+ }
623
706
  /** Agent memory configuration */
624
707
  interface AgentMemoryConfig {
625
708
  /** Embedding dimension (default: 384) */
@@ -939,11 +1022,17 @@ declare const REST_CAPABILITIES: Readonly<CapabilityMap>;
939
1022
  * Capability map for the WASM backend.
940
1023
  *
941
1024
  * The WASM build ships a focused subset: the dense / text / hybrid /
942
- * multi-query search paths plus VelesQL execution. Everything that
943
- * relies on persistent on-disk structures (secondary indexes, graph,
944
- * streaming, PQ training, agent memory, introspection, sparse
945
- * inverted index) is explicitly `false`. See `backends/wasm-stubs.ts`
946
- * for the exact set of `wasmNotSupported()` throw sites.
1025
+ * multi-query search paths. Everything that relies on persistent
1026
+ * on-disk structures (secondary indexes, graph, streaming, PQ
1027
+ * training, agent memory, introspection, sparse inverted index) is
1028
+ * explicitly `false`. See `backends/wasm-stubs.ts` for the exact set
1029
+ * of `wasmNotSupported()` throw sites.
1030
+ *
1031
+ * `velesqlQuery` is `false`: `query()` only executes pure top-k NEAR
1032
+ * statements (`SELECT * FROM <collection> WHERE vector NEAR $param
1033
+ * [LIMIT n]`) and throws `NOT_SUPPORTED` for any other VelesQL clause
1034
+ * (WHERE predicates, JOIN, GROUP BY, MATCH, set operations, FUSION),
1035
+ * so full VelesQL is not advertised.
947
1036
  */
948
1037
  declare const WASM_CAPABILITIES: Readonly<CapabilityMap>;
949
1038
 
@@ -1104,13 +1193,6 @@ interface StreamUpsertResponse {
1104
1193
  networkErrors: number;
1105
1194
  }
1106
1195
 
1107
- /**
1108
- * VelesDB TypeScript SDK - Backend Interface
1109
- *
1110
- * The `IVelesDBBackend` interface that all backends must implement.
1111
- * @packageDocumentation
1112
- */
1113
-
1114
1196
  /** Backend interface that all backends must implement */
1115
1197
  interface IVelesDBBackend {
1116
1198
  /** Initialize the backend */
@@ -1239,12 +1321,28 @@ interface IVelesDBBackend {
1239
1321
  storeSemanticFact(collection: string, entry: SemanticEntry): Promise<void>;
1240
1322
  /** Search semantic memory */
1241
1323
  searchSemanticMemory(collection: string, embedding: number[], k?: number): Promise<SearchResult[]>;
1242
- /** Record an episodic event. Returns the generated point ID. */
1243
- recordEpisodicEvent(collection: string, event: EpisodicEvent): Promise<number>;
1244
- /** Recall episodic events */
1324
+ /**
1325
+ * Record an episodic event. Returns the point ID as a string (u64
1326
+ * precision preserved).
1327
+ */
1328
+ recordEpisodicEvent(collection: string, event: EpisodicEvent): Promise<string>;
1329
+ /** Recall episodic events by vector similarity. */
1245
1330
  recallEpisodicEvents(collection: string, embedding: number[], k?: number): Promise<SearchResult[]>;
1246
- /** Store a procedural pattern. Returns the generated point ID. */
1247
- storeProceduralPattern(collection: string, pattern: ProceduralPattern): Promise<number>;
1331
+ /**
1332
+ * Recall episodic events most-recent-first, optionally bounded below by
1333
+ * `since` (inclusive unix-seconds). Mirrors core `episodic.recent(since)`.
1334
+ */
1335
+ recallRecentEvents(collection: string, since?: number): Promise<EpisodicRecord[]>;
1336
+ /**
1337
+ * Recall episodic events strictly older than `before` (unix-seconds),
1338
+ * most-recent-first. Mirrors core `episodic.older_than(before)`.
1339
+ */
1340
+ recallOlderThanEvents(collection: string, before: number): Promise<EpisodicRecord[]>;
1341
+ /**
1342
+ * Store a procedural pattern. Returns the point ID as a string (u64
1343
+ * precision preserved).
1344
+ */
1345
+ storeProceduralPattern(collection: string, pattern: ProceduralPattern): Promise<string>;
1248
1346
  /** Match procedural patterns */
1249
1347
  matchProceduralPatterns(collection: string, embedding: number[], k?: number): Promise<SearchResult[]>;
1250
1348
  /** Rebuild a collection's HNSW index (compacts tombstones). */
@@ -1271,6 +1369,14 @@ interface IVelesDBBackend {
1271
1369
  upsertNodePayload(collection: string, nodeId: number, payload: Record<string, unknown>): Promise<void>;
1272
1370
  /** Vector similarity search scoped to graph nodes only. */
1273
1371
  graphSearch(collection: string, request: GraphSearchRequest): Promise<GraphSearchResponse>;
1372
+ /** Create a typed relation edge between two points. Returns the allocated edge ID. */
1373
+ relate(collection: string, req: RelateRequest): Promise<RelateResponse>;
1374
+ /** Remove a relation edge by ID. Returns `true` if removed. */
1375
+ unrelate(collection: string, edgeId: GraphNodeId): Promise<boolean>;
1376
+ /** List outgoing relation edges for a point. */
1377
+ getRelations(collection: string, pointId: GraphNodeId): Promise<RelationsResponse>;
1378
+ /** Durably set (or refresh) the TTL of a point. */
1379
+ setTtlDurable(collection: string, pointId: GraphNodeId, ttlSeconds: number): Promise<void>;
1274
1380
  }
1275
1381
 
1276
1382
  /**
@@ -1328,16 +1434,31 @@ declare class AgentMemoryClient {
1328
1434
  storeFact(collection: string, entry: SemanticEntry): Promise<void>;
1329
1435
  /** Search semantic memory */
1330
1436
  searchFacts(collection: string, embedding: number[], k?: number): Promise<SearchResult[]>;
1331
- /** Record an episodic event. Returns the generated point ID. */
1332
- recordEvent(collection: string, event: EpisodicEvent): Promise<number>;
1333
- /** Recall episodic events */
1437
+ /** Record an episodic event. Returns the point ID (string, u64-safe). */
1438
+ recordEvent(collection: string, event: EpisodicEvent): Promise<string>;
1439
+ /** Recall episodic events by vector similarity. */
1334
1440
  recallEvents(collection: string, embedding: number[], k?: number): Promise<SearchResult[]>;
1335
- /** Store a procedural pattern. Returns the generated point ID. */
1336
- learnProcedure(collection: string, pattern: ProceduralPattern): Promise<number>;
1441
+ /**
1442
+ * Recall episodic events most-recent-first, optionally bounded below by
1443
+ * `since` (inclusive unix-seconds). Mirrors core `episodic.recent(since)`.
1444
+ */
1445
+ recallRecent(collection: string, since?: number): Promise<EpisodicRecord[]>;
1446
+ /**
1447
+ * Recall episodic events strictly older than `before` (unix-seconds),
1448
+ * most-recent-first. Mirrors core `episodic.older_than(before)`.
1449
+ */
1450
+ recallOlderThan(collection: string, before: number): Promise<EpisodicRecord[]>;
1451
+ /** Store a procedural pattern. Returns the point ID (string, u64-safe). */
1452
+ learnProcedure(collection: string, pattern: ProceduralPattern): Promise<string>;
1337
1453
  /** Match procedural patterns */
1338
1454
  recallProcedures(collection: string, embedding: number[], k?: number): Promise<SearchResult[]>;
1339
- /** Delete a memory entry (fact, event, or procedure) by its point ID. */
1340
- deleteMemory(collection: string, id: number): Promise<boolean>;
1455
+ /**
1456
+ * Delete a memory entry (fact, event, or procedure) by its point ID.
1457
+ *
1458
+ * Accepts the `string` ids returned by `recordEvent` / `learnProcedure`
1459
+ * (u64-safe decimal strings) as well as numeric ids.
1460
+ */
1461
+ deleteMemory(collection: string, id: string | number): Promise<boolean>;
1341
1462
  }
1342
1463
 
1343
1464
  /**
@@ -1436,6 +1557,10 @@ declare class VelesDB {
1436
1557
  getNodePayload(collection: string, nodeId: number): Promise<NodePayloadResponse>;
1437
1558
  upsertNodePayload(collection: string, nodeId: number, payload: Record<string, unknown>): Promise<void>;
1438
1559
  graphSearch(collection: string, request: GraphSearchRequest): Promise<GraphSearchResponse>;
1560
+ relate(collection: string, req: RelateRequest): Promise<RelateResponse>;
1561
+ unrelate(collection: string, edgeId: GraphNodeId): Promise<boolean>;
1562
+ getRelations(collection: string, pointId: GraphNodeId): Promise<RelationsResponse>;
1563
+ setTtlDurable(collection: string, pointId: GraphNodeId, ttlSeconds: number): Promise<void>;
1439
1564
  capabilities(): Readonly<CapabilityMap>;
1440
1565
  get backendType(): string;
1441
1566
  agentMemory(config?: AgentMemoryConfig): AgentMemoryClient;
@@ -1514,9 +1639,11 @@ declare class WasmBackend implements IVelesDBBackend {
1514
1639
  }>>;
1515
1640
  storeSemanticFact(c: string, e: SemanticEntry): Promise<void>;
1516
1641
  searchSemanticMemory(c: string, e: number[], k?: number): Promise<SearchResult[]>;
1517
- recordEpisodicEvent(c: string, e: EpisodicEvent): Promise<number>;
1642
+ recordEpisodicEvent(c: string, e: EpisodicEvent): Promise<string>;
1518
1643
  recallEpisodicEvents(c: string, e: number[], k?: number): Promise<SearchResult[]>;
1519
- storeProceduralPattern(c: string, p: ProceduralPattern): Promise<number>;
1644
+ recallRecentEvents(c: string, since?: number): Promise<EpisodicRecord[]>;
1645
+ recallOlderThanEvents(c: string, before: number): Promise<EpisodicRecord[]>;
1646
+ storeProceduralPattern(c: string, p: ProceduralPattern): Promise<string>;
1520
1647
  matchProceduralPatterns(c: string, e: number[], k?: number): Promise<SearchResult[]>;
1521
1648
  rebuildIndex(c: string): Promise<RebuildIndexResponse>;
1522
1649
  getGuardrails(): Promise<GuardRailsConfigResponse>;
@@ -1531,6 +1658,10 @@ declare class WasmBackend implements IVelesDBBackend {
1531
1658
  upsertNodePayload(c: string, id: number, p: Record<string, unknown>): Promise<void>;
1532
1659
  graphSearch(c: string, r: GraphSearchRequest): Promise<GraphSearchResponse>;
1533
1660
  sparseSearchNamed(c: string, q: SparseVector, idx: string, o?: SparseSearchNamedOptions): Promise<SearchResult[]>;
1661
+ relate(c: string, req: RelateRequest): Promise<RelateResponse>;
1662
+ unrelate(c: string, edgeId: GraphNodeId): Promise<boolean>;
1663
+ getRelations(c: string, pointId: GraphNodeId): Promise<RelationsResponse>;
1664
+ setTtlDurable(c: string, pointId: GraphNodeId, ttlSeconds: number): Promise<void>;
1534
1665
  }
1535
1666
 
1536
1667
  /**
@@ -1569,6 +1700,10 @@ declare class RestBackend implements IVelesDBBackend {
1569
1700
  getNodePayload(c: string, id: number): Promise<NodePayloadResponse>;
1570
1701
  upsertNodePayload(c: string, id: number, p: Record<string, unknown>): Promise<void>;
1571
1702
  graphSearch(c: string, r: GraphSearchRequest): Promise<GraphSearchResponse>;
1703
+ relate(c: string, req: RelateRequest): Promise<RelateResponse>;
1704
+ unrelate(c: string, edgeId: GraphNodeId): Promise<boolean>;
1705
+ getRelations(c: string, pointId: GraphNodeId): Promise<RelationsResponse>;
1706
+ setTtlDurable(c: string, pointId: GraphNodeId, ttlSeconds: number): Promise<void>;
1572
1707
  search(c: string, q: number[] | Float32Array, o?: SearchOptions): Promise<SearchResult[]>;
1573
1708
  searchBatch(c: string, s: Array<{
1574
1709
  vector: number[] | Float32Array;
@@ -1615,9 +1750,11 @@ declare class RestBackend implements IVelesDBBackend {
1615
1750
  streamUpsertPoints(c: string, d: VectorDocument[]): Promise<StreamUpsertResponse>;
1616
1751
  storeSemanticFact(c: string, e: SemanticEntry): Promise<void>;
1617
1752
  searchSemanticMemory(c: string, e: number[], k?: number): Promise<SearchResult[]>;
1618
- recordEpisodicEvent(c: string, e: EpisodicEvent): Promise<number>;
1753
+ recordEpisodicEvent(c: string, e: EpisodicEvent): Promise<string>;
1619
1754
  recallEpisodicEvents(c: string, e: number[], k?: number): Promise<SearchResult[]>;
1620
- storeProceduralPattern(c: string, p: ProceduralPattern): Promise<number>;
1755
+ recallRecentEvents(c: string, since?: number): Promise<EpisodicRecord[]>;
1756
+ recallOlderThanEvents(c: string, before: number): Promise<EpisodicRecord[]>;
1757
+ storeProceduralPattern(c: string, p: ProceduralPattern): Promise<string>;
1621
1758
  matchProceduralPatterns(c: string, e: number[], k?: number): Promise<SearchResult[]>;
1622
1759
  }
1623
1760
 
@@ -2109,4 +2246,4 @@ declare class OpenAIEmbedder implements Embedder {
2109
2246
  embed(texts: string[]): Promise<number[][]>;
2110
2247
  }
2111
2248
 
2112
- export { type ActualStats, type AddEdgeRequest, AgentMemoryClient, type AgentMemoryConfig, type AggregateQueryOptions, type AggregateResponse, type AggregationQueryResponse, AllocationFailedError, type AsyncIndexBuilderOptions, type BackendType, BackpressureError, type CapabilityMap, type Collection, type CollectionConfig, type CollectionConfigResponse, CollectionExistsError, CollectionNotFoundError, type CollectionSanityChecks, type CollectionSanityDiagnostics, type CollectionSanityResponse, type CollectionStatsResponse, type CollectionType, type ColumnStatsDetail, ColumnStoreError, type CompareOp, type Condition, ConfigError, ConnectionError, type CreateIndexOptions, DatabaseLockedError, type DeferredIndexerOptions, type DegreeResponse, DimensionMismatchError, type DistanceMetric, EdgeExistsError, EdgeNotFoundError, type EdgesResponse, type Embedder, type EpisodicEvent, EpochMismatchError, type ExplainCost, type ExplainFeatures, type ExplainPlanStep, type ExplainResponse, type Filter, type FilterInput, type FusionOptions, type FusionStrategy, type GetEdgesOptions, type GetNodeEdgesOptions, GpuError, type GraphCollectionConfig, type GraphEdge, type GraphNodeId, GraphNotSupportedError, type GraphSchemaMode, type GraphSearchRequest, type GraphSearchResponse, type GraphSearchResultItem, GuardRailError, type GuardRailsConfigResponse, type GuardRailsUpdateRequest, type HnswParams, type IVelesDBBackend, IncompatibleSchemaVersionError, IndexCorruptedError, IndexError, type IndexInfo, type IndexType, InternalError, InvalidCollectionNameError, InvalidDimensionError, InvalidEdgeLabelError, InvalidQuantizerConfigError, InvalidVectorError, IoError, type JsonValue, type ListNodesResponse, type MatchQueryOptions, type MatchQueryResponse, type MatchQueryResultItem, type MultiQuerySearchOptions, type NearVectorOptions, NodeNotFoundError, type NodePayloadResponse, type NodeStats, NotFoundError, OpenAIEmbedder, type OpenAIEmbedderOptions, OverflowError, PointNotFoundError, type PqTrainOptions, type ProceduralPattern, type QueryApiResponse, QueryError, type QueryOptions, type QueryResponse, type QueryResult, type QueryStats, REST_CAPABILITIES, type RebuildIndexResponse, type RelDirection, type RelOptions, RestBackend, type RestPointId, SchemaValidationError, type ScrollRequest, type ScrollResponse, SearchNotSupportedError, type SearchOptions, type SearchQuality, type SearchQualityWire, type SearchResult, type SemanticEntry, SerializationError, SnapshotBuildFailedError, SparseIndexError, type SparseSearchNamedOptions, type SparseVector, StorageError, type StorageMode, type StreamUpsertResponse, TrainingFailedError, type TraversalResultItem, type TraversalStats, type TraverseParallelRequest, type TraverseRequest, type TraverseResponse, VELES_ERROR_CODES, ValidationError, type VectorDocument, VectorNotAllowedError, VectorRequiredError, VelesDB, type VelesDBConfig, VelesDBError, VelesError, type VelesErrorCode, VelesQLBuilder, WASM_CAPABILITIES, WasmBackend, f, isTypedFilter, normalizeFilter, parseVelesError, searchQualityToMode, velesql };
2249
+ export { type ActualStats, type AddEdgeRequest, AgentMemoryClient, type AgentMemoryConfig, type AggregateQueryOptions, type AggregateResponse, type AggregationQueryResponse, AllocationFailedError, type AsyncIndexBuilderOptions, type BackendType, BackpressureError, type CapabilityMap, type Collection, type CollectionConfig, type CollectionConfigResponse, CollectionExistsError, CollectionNotFoundError, type CollectionSanityChecks, type CollectionSanityDiagnostics, type CollectionSanityResponse, type CollectionStatsResponse, type CollectionType, type ColumnStatsDetail, ColumnStoreError, type CompareOp, type Condition, ConfigError, ConnectionError, type CreateIndexOptions, DatabaseLockedError, type DeferredIndexerOptions, type DegreeResponse, DimensionMismatchError, type DistanceMetric, EdgeExistsError, EdgeNotFoundError, type EdgesResponse, type Embedder, type EpisodicEvent, type EpisodicRecord, EpochMismatchError, type ExplainCost, type ExplainFeatures, type ExplainPlanStep, type ExplainResponse, type Filter, type FilterInput, type FusionOptions, type FusionStrategy, type GetEdgesOptions, type GetNodeEdgesOptions, GpuError, type GraphCollectionConfig, type GraphEdge, type GraphNodeId, GraphNotSupportedError, type GraphSchemaMode, type GraphSearchRequest, type GraphSearchResponse, type GraphSearchResultItem, GuardRailError, type GuardRailsConfigResponse, type GuardRailsUpdateRequest, type HnswParams, type IVelesDBBackend, IncompatibleSchemaVersionError, IndexCorruptedError, IndexError, type IndexInfo, type IndexType, InternalError, InvalidCollectionNameError, InvalidDimensionError, InvalidEdgeLabelError, InvalidQuantizerConfigError, InvalidVectorError, IoError, type JsonValue, type ListNodesResponse, type MatchQueryOptions, type MatchQueryResponse, type MatchQueryResultItem, type MultiQuerySearchOptions, type NearVectorOptions, NodeNotFoundError, type NodePayloadResponse, type NodeStats, NotFoundError, OpenAIEmbedder, type OpenAIEmbedderOptions, OverflowError, PointNotFoundError, type PqTrainOptions, type ProceduralPattern, type QueryApiResponse, QueryError, type QueryOptions, type QueryResponse, type QueryResult, type QueryStats, REST_CAPABILITIES, type RebuildIndexResponse, type RelDirection, type RelOptions, type RelateRequest, type RelateResponse, type RelationEdge, type RelationsResponse, RestBackend, type RestPointId, SchemaValidationError, type ScrollRequest, type ScrollResponse, SearchNotSupportedError, type SearchOptions, type SearchQuality, type SearchQualityWire, type SearchResult, type SemanticEntry, SerializationError, SnapshotBuildFailedError, SparseIndexError, type SparseSearchNamedOptions, type SparseVector, StorageError, type StorageMode, type StreamUpsertResponse, TrainingFailedError, type TraversalResultItem, type TraversalStats, type TraverseParallelRequest, type TraverseRequest, type TraverseResponse, VELES_ERROR_CODES, ValidationError, type VectorDocument, VectorNotAllowedError, VectorRequiredError, VelesDB, type VelesDBConfig, VelesDBError, VelesError, type VelesErrorCode, VelesQLBuilder, WASM_CAPABILITIES, WasmBackend, f, isTypedFilter, normalizeFilter, parseVelesError, searchQualityToMode, velesql };