@wiscale/velesdb-sdk 1.15.0 → 1.18.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/LICENSE +356 -20
- package/README.md +115 -14
- package/dist/index.d.mts +91 -28
- package/dist/index.d.ts +91 -28
- package/dist/index.js +188 -116
- package/dist/index.mjs +187 -116
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -587,49 +587,49 @@ var VELES_ERROR_CODES = [
|
|
|
587
587
|
"VELES-035",
|
|
588
588
|
"VELES-036"
|
|
589
589
|
];
|
|
590
|
-
var CODE_TO_CLASS =
|
|
591
|
-
"VELES-001"
|
|
592
|
-
"VELES-002"
|
|
593
|
-
"VELES-003"
|
|
594
|
-
"VELES-004"
|
|
595
|
-
"VELES-005"
|
|
596
|
-
"VELES-006"
|
|
597
|
-
"VELES-007"
|
|
598
|
-
"VELES-008"
|
|
599
|
-
"VELES-009"
|
|
600
|
-
"VELES-010"
|
|
601
|
-
"VELES-011"
|
|
602
|
-
"VELES-012"
|
|
603
|
-
"VELES-013"
|
|
604
|
-
"VELES-014"
|
|
605
|
-
"VELES-015"
|
|
606
|
-
"VELES-016"
|
|
607
|
-
"VELES-017"
|
|
608
|
-
"VELES-018"
|
|
609
|
-
"VELES-019"
|
|
610
|
-
"VELES-020"
|
|
611
|
-
"VELES-021"
|
|
612
|
-
"VELES-022"
|
|
613
|
-
"VELES-023"
|
|
614
|
-
"VELES-024"
|
|
615
|
-
"VELES-025"
|
|
616
|
-
"VELES-026"
|
|
617
|
-
"VELES-027"
|
|
618
|
-
"VELES-028"
|
|
619
|
-
"VELES-029"
|
|
620
|
-
"VELES-030"
|
|
621
|
-
"VELES-031"
|
|
622
|
-
"VELES-032"
|
|
623
|
-
"VELES-033"
|
|
624
|
-
"VELES-034"
|
|
625
|
-
"VELES-035"
|
|
626
|
-
"VELES-036"
|
|
627
|
-
|
|
590
|
+
var CODE_TO_CLASS = /* @__PURE__ */ new Map([
|
|
591
|
+
["VELES-001", CollectionExistsError],
|
|
592
|
+
["VELES-002", CollectionNotFoundError],
|
|
593
|
+
["VELES-003", PointNotFoundError],
|
|
594
|
+
["VELES-004", DimensionMismatchError],
|
|
595
|
+
["VELES-005", InvalidVectorError],
|
|
596
|
+
["VELES-006", StorageError],
|
|
597
|
+
["VELES-007", IndexError],
|
|
598
|
+
["VELES-008", IndexCorruptedError],
|
|
599
|
+
["VELES-009", ConfigError],
|
|
600
|
+
["VELES-010", QueryError],
|
|
601
|
+
["VELES-011", IoError],
|
|
602
|
+
["VELES-012", SerializationError],
|
|
603
|
+
["VELES-013", InternalError],
|
|
604
|
+
["VELES-014", VectorNotAllowedError],
|
|
605
|
+
["VELES-015", SearchNotSupportedError],
|
|
606
|
+
["VELES-016", VectorRequiredError],
|
|
607
|
+
["VELES-017", SchemaValidationError],
|
|
608
|
+
["VELES-018", GraphNotSupportedError],
|
|
609
|
+
["VELES-019", EdgeExistsError],
|
|
610
|
+
["VELES-020", EdgeNotFoundError],
|
|
611
|
+
["VELES-021", InvalidEdgeLabelError],
|
|
612
|
+
["VELES-022", NodeNotFoundError],
|
|
613
|
+
["VELES-023", OverflowError],
|
|
614
|
+
["VELES-024", ColumnStoreError],
|
|
615
|
+
["VELES-025", GpuError],
|
|
616
|
+
["VELES-026", EpochMismatchError],
|
|
617
|
+
["VELES-027", GuardRailError],
|
|
618
|
+
["VELES-028", InvalidQuantizerConfigError],
|
|
619
|
+
["VELES-029", TrainingFailedError],
|
|
620
|
+
["VELES-030", SparseIndexError],
|
|
621
|
+
["VELES-031", DatabaseLockedError],
|
|
622
|
+
["VELES-032", InvalidDimensionError],
|
|
623
|
+
["VELES-033", AllocationFailedError],
|
|
624
|
+
["VELES-034", InvalidCollectionNameError],
|
|
625
|
+
["VELES-035", SnapshotBuildFailedError],
|
|
626
|
+
["VELES-036", IncompatibleSchemaVersionError]
|
|
627
|
+
]);
|
|
628
628
|
function parseVelesError(code, message) {
|
|
629
629
|
if (code === null || code === void 0) {
|
|
630
630
|
return new VelesError(message, "VELES-UNKNOWN");
|
|
631
631
|
}
|
|
632
|
-
const Cls = CODE_TO_CLASS
|
|
632
|
+
const Cls = CODE_TO_CLASS.get(code);
|
|
633
633
|
if (Cls !== void 0) {
|
|
634
634
|
return new Cls(message);
|
|
635
635
|
}
|
|
@@ -1676,16 +1676,13 @@ async function getEdgeCount(transport, collection) {
|
|
|
1676
1676
|
return response.data?.count ?? 0;
|
|
1677
1677
|
}
|
|
1678
1678
|
async function listNodes(transport, collection) {
|
|
1679
|
-
const response = await transport.requestJson(
|
|
1680
|
-
"GET",
|
|
1681
|
-
`${collectionPath(collection)}/graph/nodes`
|
|
1682
|
-
);
|
|
1679
|
+
const response = await transport.requestJson("GET", `${collectionPath(collection)}/graph/nodes`);
|
|
1683
1680
|
throwOnError(response, `Collection '${collection}'`);
|
|
1684
1681
|
const data = response.data;
|
|
1685
1682
|
return { nodeIds: data.node_ids, count: data.count };
|
|
1686
1683
|
}
|
|
1687
|
-
function
|
|
1688
|
-
return
|
|
1684
|
+
function idToGraphId(id) {
|
|
1685
|
+
return id;
|
|
1689
1686
|
}
|
|
1690
1687
|
async function getNodeEdges(transport, collection, nodeId, options) {
|
|
1691
1688
|
const params = new URLSearchParams();
|
|
@@ -1696,9 +1693,9 @@ async function getNodeEdges(transport, collection, nodeId, options) {
|
|
|
1696
1693
|
const response = await transport.requestJson("GET", url);
|
|
1697
1694
|
throwOnError(response, `Collection '${collection}'`);
|
|
1698
1695
|
return (response.data?.edges ?? []).map((e) => ({
|
|
1699
|
-
id:
|
|
1700
|
-
source:
|
|
1701
|
-
target:
|
|
1696
|
+
id: e.id,
|
|
1697
|
+
source: e.source,
|
|
1698
|
+
target: e.target,
|
|
1702
1699
|
label: e.label,
|
|
1703
1700
|
properties: e.properties
|
|
1704
1701
|
}));
|
|
@@ -1708,7 +1705,7 @@ async function getNodePayload(transport, collection, nodeId) {
|
|
|
1708
1705
|
throwOnError(response, `Collection '${collection}'`);
|
|
1709
1706
|
const data = response.data;
|
|
1710
1707
|
return {
|
|
1711
|
-
nodeId:
|
|
1708
|
+
nodeId: idToGraphId(data.node_id),
|
|
1712
1709
|
payload: data.payload
|
|
1713
1710
|
};
|
|
1714
1711
|
}
|
|
@@ -1732,7 +1729,7 @@ async function graphSearch(transport, collection, request2) {
|
|
|
1732
1729
|
throwOnError(response, `Collection '${collection}'`);
|
|
1733
1730
|
const items = (response.data?.results ?? []).map(
|
|
1734
1731
|
(r) => ({
|
|
1735
|
-
id:
|
|
1732
|
+
id: idToGraphId(r.id),
|
|
1736
1733
|
score: r.score,
|
|
1737
1734
|
payload: r.payload
|
|
1738
1735
|
})
|
|
@@ -1766,9 +1763,11 @@ async function storeSemanticFact(transport, collection, entry) {
|
|
|
1766
1763
|
id: entry.id,
|
|
1767
1764
|
vector: entry.embedding,
|
|
1768
1765
|
payload: {
|
|
1766
|
+
// Caller metadata is spread first so the reserved keys below
|
|
1767
|
+
// (`_memory_type`, `text`) always win and cannot be clobbered.
|
|
1768
|
+
...entry.metadata,
|
|
1769
1769
|
_memory_type: "semantic",
|
|
1770
|
-
text: entry.text
|
|
1771
|
-
...entry.metadata
|
|
1770
|
+
text: entry.text
|
|
1772
1771
|
}
|
|
1773
1772
|
}]
|
|
1774
1773
|
}
|
|
@@ -1788,16 +1787,20 @@ async function recordEpisodicEvent(transport, collection, event) {
|
|
|
1788
1787
|
id,
|
|
1789
1788
|
vector: event.embedding,
|
|
1790
1789
|
payload: {
|
|
1790
|
+
// Caller-supplied data/metadata is spread first so the reserved
|
|
1791
|
+
// keys below (`_memory_type`, `event_type`, `timestamp`) always
|
|
1792
|
+
// win and cannot be clobbered.
|
|
1793
|
+
...event.data,
|
|
1794
|
+
...event.metadata,
|
|
1791
1795
|
_memory_type: "episodic",
|
|
1792
1796
|
event_type: event.eventType,
|
|
1793
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1794
|
-
...event.data,
|
|
1795
|
-
...event.metadata
|
|
1797
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1796
1798
|
}
|
|
1797
1799
|
}]
|
|
1798
1800
|
}
|
|
1799
1801
|
);
|
|
1800
1802
|
throwOnError(response);
|
|
1803
|
+
return id;
|
|
1801
1804
|
}
|
|
1802
1805
|
async function recallEpisodicEvents(transport, collection, embedding, k = 5) {
|
|
1803
1806
|
return transport.searchVectors(collection, embedding, k, { _memory_type: "episodic" });
|
|
@@ -1810,16 +1813,21 @@ async function storeProceduralPattern(transport, collection, pattern) {
|
|
|
1810
1813
|
{
|
|
1811
1814
|
points: [{
|
|
1812
1815
|
id,
|
|
1816
|
+
vector: pattern.embedding,
|
|
1813
1817
|
payload: {
|
|
1818
|
+
// Caller metadata is spread first so the reserved keys below
|
|
1819
|
+
// (`_memory_type`, `name`, `steps`) always win and cannot be
|
|
1820
|
+
// clobbered.
|
|
1821
|
+
...pattern.metadata,
|
|
1814
1822
|
_memory_type: "procedural",
|
|
1815
1823
|
name: pattern.name,
|
|
1816
|
-
steps: pattern.steps
|
|
1817
|
-
...pattern.metadata
|
|
1824
|
+
steps: pattern.steps
|
|
1818
1825
|
}
|
|
1819
1826
|
}]
|
|
1820
1827
|
}
|
|
1821
1828
|
);
|
|
1822
1829
|
throwOnError(response);
|
|
1830
|
+
return id;
|
|
1823
1831
|
}
|
|
1824
1832
|
async function matchProceduralPatterns(transport, collection, embedding, k = 5) {
|
|
1825
1833
|
return transport.searchVectors(collection, embedding, k, { _memory_type: "procedural" });
|
|
@@ -1973,15 +1981,29 @@ async function addEdge(transport, collection, edge) {
|
|
|
1973
1981
|
throwOnError(response, `Collection '${collection}'`);
|
|
1974
1982
|
}
|
|
1975
1983
|
function toGraphEdge(e) {
|
|
1976
|
-
const toNum = (v) => typeof v === "string" ? Number(v) : v;
|
|
1977
1984
|
return {
|
|
1978
|
-
id:
|
|
1979
|
-
source:
|
|
1980
|
-
target:
|
|
1985
|
+
id: e.id,
|
|
1986
|
+
source: e.source,
|
|
1987
|
+
target: e.target,
|
|
1981
1988
|
label: e.label,
|
|
1982
1989
|
properties: e.properties
|
|
1983
1990
|
};
|
|
1984
1991
|
}
|
|
1992
|
+
function toTraverseResponse(data) {
|
|
1993
|
+
return {
|
|
1994
|
+
results: data.results.map((r) => ({
|
|
1995
|
+
targetId: r.target_id,
|
|
1996
|
+
depth: r.depth,
|
|
1997
|
+
path: r.path
|
|
1998
|
+
})),
|
|
1999
|
+
nextCursor: data.next_cursor ?? void 0,
|
|
2000
|
+
hasMore: data.has_more,
|
|
2001
|
+
stats: {
|
|
2002
|
+
visited: data.stats.visited,
|
|
2003
|
+
depthReached: data.stats.depth_reached
|
|
2004
|
+
}
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
1985
2007
|
async function getEdges(transport, collection, options) {
|
|
1986
2008
|
const queryParams = options?.label ? `?label=${encodeURIComponent(options.label)}` : "";
|
|
1987
2009
|
const response = await transport.requestJson(
|
|
@@ -2005,20 +2027,7 @@ async function traverseGraph(transport, collection, request2) {
|
|
|
2005
2027
|
}
|
|
2006
2028
|
);
|
|
2007
2029
|
throwOnError(response, `Collection '${collection}'`);
|
|
2008
|
-
|
|
2009
|
-
return {
|
|
2010
|
-
results: data.results.map((r) => ({
|
|
2011
|
-
targetId: r.target_id,
|
|
2012
|
-
depth: r.depth,
|
|
2013
|
-
path: r.path
|
|
2014
|
-
})),
|
|
2015
|
-
nextCursor: data.next_cursor ?? void 0,
|
|
2016
|
-
hasMore: data.has_more,
|
|
2017
|
-
stats: {
|
|
2018
|
-
visited: data.stats.visited,
|
|
2019
|
-
depthReached: data.stats.depth_reached
|
|
2020
|
-
}
|
|
2021
|
-
};
|
|
2030
|
+
return toTraverseResponse(response.data);
|
|
2022
2031
|
}
|
|
2023
2032
|
async function getNodeDegree(transport, collection, nodeId) {
|
|
2024
2033
|
const response = await transport.requestJson(
|
|
@@ -2053,20 +2062,7 @@ async function traverseParallel(transport, collection, request2) {
|
|
|
2053
2062
|
}
|
|
2054
2063
|
);
|
|
2055
2064
|
throwOnError(response, `Collection '${collection}'`);
|
|
2056
|
-
|
|
2057
|
-
return {
|
|
2058
|
-
results: data.results.map((r) => ({
|
|
2059
|
-
targetId: r.target_id,
|
|
2060
|
-
depth: r.depth,
|
|
2061
|
-
path: r.path
|
|
2062
|
-
})),
|
|
2063
|
-
nextCursor: data.next_cursor ?? void 0,
|
|
2064
|
-
hasMore: data.has_more,
|
|
2065
|
-
stats: {
|
|
2066
|
-
visited: data.stats.visited,
|
|
2067
|
-
depthReached: data.stats.depth_reached
|
|
2068
|
-
}
|
|
2069
|
-
};
|
|
2065
|
+
return toTraverseResponse(response.data);
|
|
2070
2066
|
}
|
|
2071
2067
|
|
|
2072
2068
|
// src/backends/query-backend.ts
|
|
@@ -2751,7 +2747,16 @@ var AgentMemoryClient = class {
|
|
|
2751
2747
|
this.backend = backend;
|
|
2752
2748
|
this.config = config;
|
|
2753
2749
|
}
|
|
2754
|
-
/**
|
|
2750
|
+
/**
|
|
2751
|
+
* Advisory embedding dimension passed at construction (default: 384).
|
|
2752
|
+
*
|
|
2753
|
+
* This value is **not** enforced and does not create or size any
|
|
2754
|
+
* collection — the dimension that actually governs storage and search
|
|
2755
|
+
* is the one fixed when the collection was created
|
|
2756
|
+
* (`db.createCollection(name, { dimension, metric: 'cosine' })`).
|
|
2757
|
+
* Embeddings you pass to `storeFact` / `recordEvent` / `learnProcedure`
|
|
2758
|
+
* must match that collection dimension.
|
|
2759
|
+
*/
|
|
2755
2760
|
get dimension() {
|
|
2756
2761
|
return this.config?.dimension ?? 384;
|
|
2757
2762
|
}
|
|
@@ -2763,7 +2768,7 @@ var AgentMemoryClient = class {
|
|
|
2763
2768
|
async searchFacts(collection, embedding, k = 5) {
|
|
2764
2769
|
return this.backend.searchSemanticMemory(collection, embedding, k);
|
|
2765
2770
|
}
|
|
2766
|
-
/** Record an episodic event */
|
|
2771
|
+
/** Record an episodic event. Returns the generated point ID. */
|
|
2767
2772
|
async recordEvent(collection, event) {
|
|
2768
2773
|
return this.backend.recordEpisodicEvent(collection, event);
|
|
2769
2774
|
}
|
|
@@ -2771,7 +2776,7 @@ var AgentMemoryClient = class {
|
|
|
2771
2776
|
async recallEvents(collection, embedding, k = 5) {
|
|
2772
2777
|
return this.backend.recallEpisodicEvents(collection, embedding, k);
|
|
2773
2778
|
}
|
|
2774
|
-
/** Store a procedural pattern */
|
|
2779
|
+
/** Store a procedural pattern. Returns the generated point ID. */
|
|
2775
2780
|
async learnProcedure(collection, pattern) {
|
|
2776
2781
|
return this.backend.storeProceduralPattern(collection, pattern);
|
|
2777
2782
|
}
|
|
@@ -2779,6 +2784,10 @@ var AgentMemoryClient = class {
|
|
|
2779
2784
|
async recallProcedures(collection, embedding, k = 5) {
|
|
2780
2785
|
return this.backend.matchProceduralPatterns(collection, embedding, k);
|
|
2781
2786
|
}
|
|
2787
|
+
/** Delete a memory entry (fact, event, or procedure) by its point ID. */
|
|
2788
|
+
async deleteMemory(collection, id) {
|
|
2789
|
+
return this.backend.delete(collection, id);
|
|
2790
|
+
}
|
|
2782
2791
|
};
|
|
2783
2792
|
|
|
2784
2793
|
// src/client/validation.ts
|
|
@@ -2801,7 +2810,8 @@ function validateDocsBatch(docs, validateDoc) {
|
|
|
2801
2810
|
}
|
|
2802
2811
|
}
|
|
2803
2812
|
function validateDocument(doc, config) {
|
|
2804
|
-
|
|
2813
|
+
const id = doc.id;
|
|
2814
|
+
if (id === void 0 || id === null) {
|
|
2805
2815
|
throw new ValidationError("Document ID is required");
|
|
2806
2816
|
}
|
|
2807
2817
|
requireVector(doc.vector, "Vector");
|
|
@@ -2856,11 +2866,15 @@ function trainPq2(backend, collection, options) {
|
|
|
2856
2866
|
return backend.trainPq(collection, options);
|
|
2857
2867
|
}
|
|
2858
2868
|
function streamInsert2(backend, config, collection, docs) {
|
|
2859
|
-
validateDocsBatch(docs, (doc) =>
|
|
2869
|
+
validateDocsBatch(docs, (doc) => {
|
|
2870
|
+
validateDocument(doc, config);
|
|
2871
|
+
});
|
|
2860
2872
|
return backend.streamInsert(collection, docs);
|
|
2861
2873
|
}
|
|
2862
2874
|
function streamUpsertPoints2(backend, config, collection, docs) {
|
|
2863
|
-
validateDocsBatch(docs, (doc) =>
|
|
2875
|
+
validateDocsBatch(docs, (doc) => {
|
|
2876
|
+
validateDocument(doc, config);
|
|
2877
|
+
});
|
|
2864
2878
|
return backend.streamUpsertPoints(collection, docs);
|
|
2865
2879
|
}
|
|
2866
2880
|
function scroll2(backend, collection, request2) {
|
|
@@ -2913,12 +2927,15 @@ function aggregate2(backend, queryString, params, options) {
|
|
|
2913
2927
|
}
|
|
2914
2928
|
|
|
2915
2929
|
// src/client/graph-methods.ts
|
|
2930
|
+
function isGraphNodeId(value) {
|
|
2931
|
+
return typeof value === "number" || typeof value === "string";
|
|
2932
|
+
}
|
|
2916
2933
|
function addEdge2(backend, collection, edge) {
|
|
2917
2934
|
if (!edge.label || typeof edge.label !== "string") {
|
|
2918
2935
|
throw new ValidationError("Edge label is required and must be a string");
|
|
2919
2936
|
}
|
|
2920
|
-
if (
|
|
2921
|
-
throw new ValidationError("Edge source and target must be numbers");
|
|
2937
|
+
if (!isGraphNodeId(edge.source) || !isGraphNodeId(edge.target)) {
|
|
2938
|
+
throw new ValidationError("Edge source and target must be numbers or strings");
|
|
2922
2939
|
}
|
|
2923
2940
|
return backend.addEdge(collection, edge);
|
|
2924
2941
|
}
|
|
@@ -2926,8 +2943,8 @@ function getEdges2(backend, collection, options) {
|
|
|
2926
2943
|
return backend.getEdges(collection, options);
|
|
2927
2944
|
}
|
|
2928
2945
|
function traverseGraph2(backend, collection, request2) {
|
|
2929
|
-
if (
|
|
2930
|
-
throw new ValidationError("Source node ID must be a number");
|
|
2946
|
+
if (!isGraphNodeId(request2.source)) {
|
|
2947
|
+
throw new ValidationError("Source node ID must be a number or string");
|
|
2931
2948
|
}
|
|
2932
2949
|
if (request2.strategy && !["bfs", "dfs"].includes(request2.strategy)) {
|
|
2933
2950
|
throw new ValidationError("Strategy must be 'bfs' or 'dfs'");
|
|
@@ -2938,6 +2955,9 @@ function traverseParallel2(backend, collection, request2) {
|
|
|
2938
2955
|
if (!Array.isArray(request2.sources) || request2.sources.length === 0) {
|
|
2939
2956
|
throw new ValidationError("At least one source node ID is required");
|
|
2940
2957
|
}
|
|
2958
|
+
if (!request2.sources.every(isGraphNodeId)) {
|
|
2959
|
+
throw new ValidationError("Source node IDs must be numbers or strings");
|
|
2960
|
+
}
|
|
2941
2961
|
return backend.traverseParallel(collection, request2);
|
|
2942
2962
|
}
|
|
2943
2963
|
function getNodeDegree2(backend, collection, nodeId) {
|
|
@@ -2993,13 +3013,14 @@ var VelesDB = class {
|
|
|
2993
3013
|
this.backend = this.createBackend(config);
|
|
2994
3014
|
}
|
|
2995
3015
|
validateConfig(config) {
|
|
2996
|
-
|
|
3016
|
+
const backend = config.backend;
|
|
3017
|
+
if (!backend) {
|
|
2997
3018
|
throw new ValidationError("Backend type is required");
|
|
2998
3019
|
}
|
|
2999
|
-
if (
|
|
3000
|
-
throw new ValidationError(`Invalid backend type: ${
|
|
3020
|
+
if (backend !== "wasm" && backend !== "rest") {
|
|
3021
|
+
throw new ValidationError(`Invalid backend type: ${backend}. Use 'wasm' or 'rest'`);
|
|
3001
3022
|
}
|
|
3002
|
-
if (
|
|
3023
|
+
if (backend === "rest" && !config.url) {
|
|
3003
3024
|
throw new ValidationError("URL is required for REST backend");
|
|
3004
3025
|
}
|
|
3005
3026
|
}
|
|
@@ -3007,10 +3028,14 @@ var VelesDB = class {
|
|
|
3007
3028
|
switch (config.backend) {
|
|
3008
3029
|
case "wasm":
|
|
3009
3030
|
return new WasmBackend();
|
|
3010
|
-
case "rest":
|
|
3031
|
+
case "rest": {
|
|
3032
|
+
if (!config.url) {
|
|
3033
|
+
throw new ValidationError("URL is required for REST backend");
|
|
3034
|
+
}
|
|
3011
3035
|
return new RestBackend(config.url, config.apiKey, config.timeout);
|
|
3036
|
+
}
|
|
3012
3037
|
default:
|
|
3013
|
-
throw new ValidationError(`Unknown backend: ${config.backend}`);
|
|
3038
|
+
throw new ValidationError(`Unknown backend: ${String(config.backend)}`);
|
|
3014
3039
|
}
|
|
3015
3040
|
}
|
|
3016
3041
|
/** Initialize the client. Must be called before any other operations. */
|
|
@@ -3069,7 +3094,9 @@ var VelesDB = class {
|
|
|
3069
3094
|
}
|
|
3070
3095
|
async upsertBatch(collection, docs) {
|
|
3071
3096
|
this.ensureInitialized();
|
|
3072
|
-
validateDocsBatch(docs, (doc) =>
|
|
3097
|
+
validateDocsBatch(docs, (doc) => {
|
|
3098
|
+
validateDocument(doc, this.config);
|
|
3099
|
+
});
|
|
3073
3100
|
await this.backend.upsertBatch(collection, docs);
|
|
3074
3101
|
}
|
|
3075
3102
|
async delete(collection, id) {
|
|
@@ -3585,13 +3612,14 @@ var VelesQLBuilder = class _VelesQLBuilder {
|
|
|
3585
3612
|
return `*${min}..${max}`;
|
|
3586
3613
|
}
|
|
3587
3614
|
buildWhereClause() {
|
|
3588
|
-
|
|
3589
|
-
const
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3615
|
+
let result = "";
|
|
3616
|
+
for (const [idx, clause] of this.state.whereClauses.entries()) {
|
|
3617
|
+
if (idx === 0) {
|
|
3618
|
+
if (!clause) return "";
|
|
3619
|
+
result = clause;
|
|
3620
|
+
continue;
|
|
3621
|
+
}
|
|
3622
|
+
const operator = this.state.whereOperators[idx - 1] ?? "AND";
|
|
3595
3623
|
if (clause) {
|
|
3596
3624
|
result += ` ${operator} ${clause}`;
|
|
3597
3625
|
}
|
|
@@ -3605,13 +3633,14 @@ function velesql() {
|
|
|
3605
3633
|
|
|
3606
3634
|
// src/filter.ts
|
|
3607
3635
|
function isTypedFilter(input) {
|
|
3608
|
-
|
|
3636
|
+
const value = input;
|
|
3637
|
+
if (typeof value !== "object" || value === null) {
|
|
3609
3638
|
return false;
|
|
3610
3639
|
}
|
|
3611
|
-
if (!("condition" in
|
|
3640
|
+
if (!("condition" in value)) {
|
|
3612
3641
|
return false;
|
|
3613
3642
|
}
|
|
3614
|
-
const cond =
|
|
3643
|
+
const cond = value.condition;
|
|
3615
3644
|
return typeof cond === "object" && cond !== null;
|
|
3616
3645
|
}
|
|
3617
3646
|
function normalizeFilter(input) {
|
|
@@ -3746,6 +3775,47 @@ var f = {
|
|
|
3746
3775
|
return { condition: { type: "not", condition: filter.condition } };
|
|
3747
3776
|
}
|
|
3748
3777
|
};
|
|
3778
|
+
|
|
3779
|
+
// src/embed.ts
|
|
3780
|
+
var OpenAIEmbedder = class {
|
|
3781
|
+
constructor(options) {
|
|
3782
|
+
this.model = options.model ?? "text-embedding-3-small";
|
|
3783
|
+
this.apiKey = options.apiKey;
|
|
3784
|
+
this.baseUrl = options.baseUrl?.replace(/\/$/, "") ?? "https://api.openai.com/v1";
|
|
3785
|
+
this.requestedDimensions = options.dimensions;
|
|
3786
|
+
this.dimension = options.dimensions ?? 0;
|
|
3787
|
+
}
|
|
3788
|
+
async embed(texts) {
|
|
3789
|
+
if (texts.length === 0) return [];
|
|
3790
|
+
const body = { model: this.model, input: texts };
|
|
3791
|
+
if (this.requestedDimensions !== void 0) {
|
|
3792
|
+
body["dimensions"] = this.requestedDimensions;
|
|
3793
|
+
}
|
|
3794
|
+
const response = await fetch(`${this.baseUrl}/embeddings`, {
|
|
3795
|
+
method: "POST",
|
|
3796
|
+
headers: {
|
|
3797
|
+
"Content-Type": "application/json",
|
|
3798
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
3799
|
+
},
|
|
3800
|
+
body: JSON.stringify(body)
|
|
3801
|
+
});
|
|
3802
|
+
if (!response.ok) {
|
|
3803
|
+
const text = await response.text().catch(() => "");
|
|
3804
|
+
throw new Error(
|
|
3805
|
+
`OpenAI embeddings request failed: ${response.status} ${response.statusText} \u2014 ${text.slice(0, 500)}`
|
|
3806
|
+
);
|
|
3807
|
+
}
|
|
3808
|
+
const json = await response.json();
|
|
3809
|
+
const vectors = json.data.map((item) => item.embedding);
|
|
3810
|
+
if (this.dimension === 0) {
|
|
3811
|
+
for (const vec of vectors) {
|
|
3812
|
+
this.dimension = vec.length;
|
|
3813
|
+
break;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
return vectors;
|
|
3817
|
+
}
|
|
3818
|
+
};
|
|
3749
3819
|
export {
|
|
3750
3820
|
AgentMemoryClient,
|
|
3751
3821
|
AllocationFailedError,
|
|
@@ -3775,6 +3845,7 @@ export {
|
|
|
3775
3845
|
IoError,
|
|
3776
3846
|
NodeNotFoundError,
|
|
3777
3847
|
NotFoundError,
|
|
3848
|
+
OpenAIEmbedder,
|
|
3778
3849
|
OverflowError,
|
|
3779
3850
|
PointNotFoundError,
|
|
3780
3851
|
QueryError,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiscale/velesdb-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "VelesDB TypeScript SDK: The Local Vector Database for AI & RAG. Microsecond semantic search in Browser & Node.js.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"README.md"
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
18
19
|
],
|
|
19
20
|
"scripts": {
|
|
20
21
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
"llm"
|
|
44
45
|
],
|
|
45
46
|
"author": "Wiscale France",
|
|
46
|
-
"license": "
|
|
47
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
47
48
|
"repository": {
|
|
48
49
|
"type": "git",
|
|
49
50
|
"url": "https://github.com/cyberlife-coder/VelesDB.git",
|
|
@@ -54,12 +55,12 @@
|
|
|
54
55
|
"url": "https://github.com/cyberlife-coder/VelesDB/issues"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
|
-
"@eslint/js": "^
|
|
58
|
+
"@eslint/js": "^10.0.1",
|
|
58
59
|
"@types/node": "^25.6.0",
|
|
59
60
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
60
61
|
"@typescript-eslint/parser": "^8.0.0",
|
|
61
62
|
"@vitest/coverage-v8": "^4.0.16",
|
|
62
|
-
"eslint": "^10.
|
|
63
|
+
"eslint": "^10.4.0",
|
|
63
64
|
"eslint-config-prettier": "^10.1.8",
|
|
64
65
|
"prettier": "^3.0.0",
|
|
65
66
|
"tsup": "^8.0.0",
|