vecmindb 1.0.0-beta
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 +349 -0
- package/dist/index.d.mts +934 -0
- package/dist/index.d.ts +934 -0
- package/dist/index.js +1205 -0
- package/dist/index.mjs +1154 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# @vecmindb/sdk
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for [VecminDB](https://lingxinmind.com) — the high-performance vector database for AI agents.
|
|
4
|
+
|
|
5
|
+
⚠️ **License Note**: VecminDB is a commercial Cognitive Vector Database. The Free Tier supports up to 5 agents and 100K vectors/agent forever. For enterprise scale-out or clusters, please visit our official website to register and obtain a license key: [https://lingxinmind.com](https://lingxinmind.com).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @vecmindb/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Optional: LangChain.js Integration
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @langchain/core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> `@langchain/core` is an optional peer dependency. It is only needed if you use the `VecminDBVectorStore` adapter.
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { VecminClient } from "@vecmindb/sdk";
|
|
25
|
+
|
|
26
|
+
const client = new VecminClient({
|
|
27
|
+
baseUrl: "http://localhost:8080",
|
|
28
|
+
apiKey: "your-api-key",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Create a collection
|
|
32
|
+
await client.createCollection({
|
|
33
|
+
name: "documents",
|
|
34
|
+
dimension: 1536,
|
|
35
|
+
metric_type: "Cosine",
|
|
36
|
+
index_type: "HNSW",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Insert a vector
|
|
40
|
+
const id = await client.insert("documents", {
|
|
41
|
+
vector: [0.1, 0.2, /* ... */ 0.5],
|
|
42
|
+
metadata: { title: "My Document", source: "test" },
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Search for similar vectors
|
|
46
|
+
const results = await client.search("documents", {
|
|
47
|
+
query: [0.1, 0.15, /* ... */ 0.48],
|
|
48
|
+
k: 5,
|
|
49
|
+
ef_search: 100,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
for (const result of results) {
|
|
53
|
+
console.log(`ID: ${result.id}, Score: ${result.score}`);
|
|
54
|
+
console.log("Metadata:", result.metadata);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Clean up
|
|
58
|
+
await client.close();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Authentication
|
|
62
|
+
|
|
63
|
+
### API Key
|
|
64
|
+
|
|
65
|
+
The simplest authentication method — pass your API key in the constructor:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const client = new VecminClient({
|
|
69
|
+
baseUrl: "http://localhost:8080",
|
|
70
|
+
apiKey: "your-api-key",
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The SDK sends it as the `x-api-key` header on every request.
|
|
75
|
+
|
|
76
|
+
### JWT
|
|
77
|
+
|
|
78
|
+
For JWT-based authentication, call `login()` after constructing the client:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const client = new VecminClient({ baseUrl: "http://localhost:8080" });
|
|
82
|
+
|
|
83
|
+
const token = await client.login({
|
|
84
|
+
username: "admin",
|
|
85
|
+
password: "secret",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// The JWT is now cached and sent automatically.
|
|
89
|
+
// It will be refreshed transparently 5 minutes before expiry.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Collection Management
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// Create
|
|
96
|
+
await client.createCollection({
|
|
97
|
+
name: "my_collection",
|
|
98
|
+
dimension: 768,
|
|
99
|
+
metric_type: "Cosine", // "Cosine" | "L2" | "InnerProduct"
|
|
100
|
+
index_type: "HNSW", // "HNSW" | "IVF" | "Flat"
|
|
101
|
+
index_params: { m: 16, ef_construction: 100 },
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// List
|
|
105
|
+
const collections = await client.listCollections();
|
|
106
|
+
|
|
107
|
+
// Get details
|
|
108
|
+
const col = await client.getCollection("my_collection");
|
|
109
|
+
|
|
110
|
+
// Statistics
|
|
111
|
+
const stats = await client.getCollectionStats("my_collection");
|
|
112
|
+
console.log(`Vectors: ${stats.vector_count}, Storage: ${stats.storage_bytes} bytes`);
|
|
113
|
+
|
|
114
|
+
// Delete
|
|
115
|
+
await client.deleteCollection("my_collection");
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Vector Operations
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Single insert
|
|
122
|
+
const id = await client.insert("my_collection", {
|
|
123
|
+
id: "doc-001", // optional — auto-generated if omitted
|
|
124
|
+
vector: [0.1, 0.2, /* ... */],
|
|
125
|
+
metadata: { title: "Hello" },
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Batch insert
|
|
129
|
+
const ids = await client.batchInsert("my_collection", [
|
|
130
|
+
{ vector: [0.1, 0.2], metadata: { title: "A" } },
|
|
131
|
+
{ vector: [0.3, 0.4], metadata: { title: "B" } },
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
// Search
|
|
135
|
+
const results = await client.search("my_collection", {
|
|
136
|
+
query: [0.15, 0.25],
|
|
137
|
+
k: 10,
|
|
138
|
+
ef_search: 100,
|
|
139
|
+
filter: { category: "tech" }, // optional metadata filter
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Get a single vector
|
|
143
|
+
const vec = await client.getVector("my_collection", "doc-001");
|
|
144
|
+
|
|
145
|
+
// Delete a vector
|
|
146
|
+
await client.deleteVector("my_collection", "doc-001");
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Index Management
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
// Rebuild a collection's index
|
|
153
|
+
await client.rebuildIndex("my_collection");
|
|
154
|
+
|
|
155
|
+
// List all indexes
|
|
156
|
+
const indexes = await client.listIndexes();
|
|
157
|
+
|
|
158
|
+
// Rebuild a named index
|
|
159
|
+
await client.rebuildNamedIndex("my_collection_hnsw");
|
|
160
|
+
|
|
161
|
+
// Optimize an index
|
|
162
|
+
await client.optimizeIndex("my_collection_hnsw");
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Cluster Management
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Login
|
|
169
|
+
const jwt = await client.login({ username: "admin", password: "secret" });
|
|
170
|
+
|
|
171
|
+
// List cluster nodes
|
|
172
|
+
const nodes = await client.listNodes();
|
|
173
|
+
for (const node of nodes) {
|
|
174
|
+
console.log(`${node.id} (${node.role}) — ${node.healthy ? "healthy" : "down"}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Cluster status
|
|
178
|
+
const status = await client.clusterStatus();
|
|
179
|
+
console.log(`Status: ${status.status}, Leader: ${status.leader_id}`);
|
|
180
|
+
|
|
181
|
+
// Create snapshot
|
|
182
|
+
await client.createSnapshot();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## MCP (Model Context Protocol)
|
|
186
|
+
|
|
187
|
+
The MCP client provides a persistent SSE connection and JSON-RPC 2.0 interface for AI agent memory operations.
|
|
188
|
+
|
|
189
|
+
### Convenience Methods (via VecminClient)
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// Store a memory
|
|
193
|
+
await client.mcpStoreMemory("User prefers dark mode", "agent-1", {
|
|
194
|
+
source: "conversation",
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Search memories
|
|
198
|
+
const memories = await client.mcpSearchMemory("user preferences", "agent-1", 5);
|
|
199
|
+
for (const m of memories) {
|
|
200
|
+
console.log(m.content, m.score);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Low-level MCP Client (SSE + JSON-RPC)
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { VecminMCPClient } from "@vecmindb/sdk";
|
|
208
|
+
|
|
209
|
+
const mcp = new VecminMCPClient("http://localhost:8080", {
|
|
210
|
+
apiKey: "your-api-key",
|
|
211
|
+
agentId: "agent-1",
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Connect to the SSE event stream
|
|
215
|
+
await mcp.connect();
|
|
216
|
+
|
|
217
|
+
// Listen for events
|
|
218
|
+
mcp.on("event", ({ event, data }) => {
|
|
219
|
+
console.log(`SSE event: ${event}`, data);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Store a memory via JSON-RPC
|
|
223
|
+
await mcp.storeMemory({
|
|
224
|
+
text: "User prefers dark mode",
|
|
225
|
+
agent_id: "agent-1",
|
|
226
|
+
source: "conversation",
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Search memories via JSON-RPC
|
|
230
|
+
const results = await mcp.searchMemory({
|
|
231
|
+
query: "user preferences",
|
|
232
|
+
agent_id: "agent-1",
|
|
233
|
+
top_k: 5,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Disconnect
|
|
237
|
+
await mcp.disconnect();
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## LangChain.js Integration
|
|
241
|
+
|
|
242
|
+
Use VecminDB as a vector store in your LangChain.js applications:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { OpenAIEmbeddings } from "@langchain/openai";
|
|
246
|
+
import { VecminDBVectorStore } from "@vecmindb/sdk";
|
|
247
|
+
|
|
248
|
+
const embeddings = new OpenAIEmbeddings();
|
|
249
|
+
const store = new VecminDBVectorStore(embeddings, {
|
|
250
|
+
baseUrl: "http://localhost:8080",
|
|
251
|
+
apiKey: "your-api-key",
|
|
252
|
+
collectionName: "my_docs",
|
|
253
|
+
dimension: 1536,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Add documents
|
|
257
|
+
await store.addDocuments([
|
|
258
|
+
{ pageContent: "VecminDB is a high-performance vector database", metadata: { source: "readme" } },
|
|
259
|
+
{ pageContent: "It supports HNSW, IVF, and Flat indexes", metadata: { source: "docs" } },
|
|
260
|
+
]);
|
|
261
|
+
|
|
262
|
+
// Similarity search
|
|
263
|
+
const results = await store.similaritySearch("vector database", 5);
|
|
264
|
+
for (const doc of results) {
|
|
265
|
+
console.log(doc.pageContent, doc.metadata);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Search with scores
|
|
269
|
+
const scored = await store.similaritySearchWithScore("vector database", 5);
|
|
270
|
+
for (const [doc, score] of scored) {
|
|
271
|
+
console.log(`Score: ${score} — ${doc.pageContent}`);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Factory Methods
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
// From texts
|
|
279
|
+
const store = await VecminDBVectorStore.fromTexts(
|
|
280
|
+
["Hello world", "Goodbye world"],
|
|
281
|
+
[{ label: "greeting" }, { label: "farewell" }],
|
|
282
|
+
embeddings,
|
|
283
|
+
{ baseUrl: "http://localhost:8080", apiKey: "your-api-key" },
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
// From documents
|
|
287
|
+
const store = await VecminDBVectorStore.fromDocuments(
|
|
288
|
+
[{ pageContent: "Hello", metadata: { label: "greeting" } }],
|
|
289
|
+
embeddings,
|
|
290
|
+
{ baseUrl: "http://localhost:8080", apiKey: "your-api-key" },
|
|
291
|
+
);
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Error Handling
|
|
295
|
+
|
|
296
|
+
All errors thrown by the SDK are subclasses of `VecminError`:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
import {
|
|
300
|
+
VecminError,
|
|
301
|
+
AuthenticationError,
|
|
302
|
+
PermissionError,
|
|
303
|
+
NotFoundError,
|
|
304
|
+
RateLimitError,
|
|
305
|
+
ServerError,
|
|
306
|
+
} from "@vecmindb/sdk";
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
await client.getCollection("nonexistent");
|
|
310
|
+
} catch (err) {
|
|
311
|
+
if (err instanceof NotFoundError) {
|
|
312
|
+
console.log("Collection not found:", err.message);
|
|
313
|
+
} else if (err instanceof AuthenticationError) {
|
|
314
|
+
console.log("Check your API key");
|
|
315
|
+
} else if (err instanceof RateLimitError) {
|
|
316
|
+
console.log("Slow down!");
|
|
317
|
+
} else if (err instanceof VecminError) {
|
|
318
|
+
console.log(`Error ${err.code}: ${err.message}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Configuration Options
|
|
324
|
+
|
|
325
|
+
| Option | Type | Default | Description |
|
|
326
|
+
|--------|------|---------|-------------|
|
|
327
|
+
| `baseUrl` | `string` | — | VecminDB server URL |
|
|
328
|
+
| `apiKey` | `string` | — | API key for `x-api-key` header |
|
|
329
|
+
| `jwt` | `string` | — | JWT token for `Authorization` header |
|
|
330
|
+
| `timeout` | `number` | `30000` | Request timeout (ms) |
|
|
331
|
+
| `maxRetries` | `number` | `3` | Max retry attempts on transient failures |
|
|
332
|
+
| `backoffFactor` | `number` | `0.5` | Exponential backoff multiplier (seconds) |
|
|
333
|
+
| `defaultHeaders` | `Record<string, string>` | `{}` | Custom headers for every request |
|
|
334
|
+
| `agentId` | `string` | — | Agent identifier (`x-agent-id` header) |
|
|
335
|
+
| `modelId` | `string` | — | Model identifier (`x-model-id` header) |
|
|
336
|
+
|
|
337
|
+
## Retry Strategy
|
|
338
|
+
|
|
339
|
+
The SDK automatically retries transient failures (HTTP 429, 500, 502, 503, 504) using exponential backoff with jitter:
|
|
340
|
+
|
|
341
|
+
- **Attempt 1**: ~500ms delay
|
|
342
|
+
- **Attempt 2**: ~1000ms delay
|
|
343
|
+
- **Attempt 3**: ~2000ms delay
|
|
344
|
+
|
|
345
|
+
Each delay includes ±100ms of random jitter to avoid thundering-herd retries.
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
Apache-2.0
|