@lumi0/sdk 0.0.4 → 0.0.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 +267 -173
- package/dist/index.d.mts +93 -9
- package/dist/index.mjs +31 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Lumi0 TypeScript SDK
|
|
2
2
|
|
|
3
|
-
The official TypeScript SDK for [Lumi0](https://lumi0.com), an AI infrastructure platform for persistent memory and
|
|
3
|
+
The official TypeScript SDK for [Lumi0](https://lumi0.com), an AI infrastructure platform for persistent memory, context compression, and document ingestion.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Lumi0 gives AI applications long-term memory: store information about users, retrieve relevant context with semantic search, manage memory versions, batch-write memories, forget stored information, upload documents from URLs, and compress large contexts before sending them to an LLM.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
@@ -13,6 +13,8 @@ Use Lumi0 to give AI applications long-term memory: store information about user
|
|
|
13
13
|
* Memory deduplication
|
|
14
14
|
* Context compression
|
|
15
15
|
* Fixed and adaptive compression modes
|
|
16
|
+
* URL-based document ingestion
|
|
17
|
+
* Automatic document type detection
|
|
16
18
|
* TypeScript-first API
|
|
17
19
|
* Bun and Node.js compatible
|
|
18
20
|
* Configurable API URL and request timeout
|
|
@@ -52,7 +54,7 @@ Create a Lumi0 client:
|
|
|
52
54
|
import { Lumi0 } from "@lumi0/sdk";
|
|
53
55
|
|
|
54
56
|
const client = new Lumi0({
|
|
55
|
-
|
|
57
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
56
58
|
});
|
|
57
59
|
```
|
|
58
60
|
|
|
@@ -62,8 +64,8 @@ Store information associated with an identifier:
|
|
|
62
64
|
|
|
63
65
|
```ts
|
|
64
66
|
await client.store({
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
id: "user_123",
|
|
68
|
+
content: "The user prefers concise TypeScript examples.",
|
|
67
69
|
});
|
|
68
70
|
```
|
|
69
71
|
|
|
@@ -73,14 +75,27 @@ Retrieve memories that are semantically relevant to a query:
|
|
|
73
75
|
|
|
74
76
|
```ts
|
|
75
77
|
const memories = await client.search({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
id: "user_123",
|
|
79
|
+
query: "What coding examples does the user prefer?",
|
|
80
|
+
limit: 5,
|
|
79
81
|
});
|
|
80
82
|
|
|
81
83
|
console.log(memories);
|
|
82
84
|
```
|
|
83
85
|
|
|
86
|
+
### Upload a document
|
|
87
|
+
|
|
88
|
+
Upload a document directly from a URL:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const upload = await client.files({
|
|
92
|
+
url: "https://example.com/document.pdf",
|
|
93
|
+
id: "tenant_123",
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The `id` identifies the tenant or external entity the uploaded document belongs to. It can be either a Lumi0 tenant ID or your own external ID.
|
|
98
|
+
|
|
84
99
|
A common AI application flow looks like:
|
|
85
100
|
|
|
86
101
|
```text
|
|
@@ -88,9 +103,10 @@ User
|
|
|
88
103
|
↓
|
|
89
104
|
Your AI Application
|
|
90
105
|
↓
|
|
91
|
-
Lumi0
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
Lumi0
|
|
107
|
+
├── Memory
|
|
108
|
+
├── File Ingestion
|
|
109
|
+
└── Context Compression
|
|
94
110
|
↓
|
|
95
111
|
Relevant Context
|
|
96
112
|
↓
|
|
@@ -107,8 +123,8 @@ Stores a single memory for an identifier.
|
|
|
107
123
|
|
|
108
124
|
```ts
|
|
109
125
|
await client.store({
|
|
110
|
-
|
|
111
|
-
|
|
126
|
+
id: "user_123",
|
|
127
|
+
content: "The user uses Bun and TypeScript.",
|
|
112
128
|
});
|
|
113
129
|
```
|
|
114
130
|
|
|
@@ -116,9 +132,9 @@ You can optionally configure deduplication:
|
|
|
116
132
|
|
|
117
133
|
```ts
|
|
118
134
|
await client.store({
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
135
|
+
id: "user_123",
|
|
136
|
+
content: "The user uses Bun and TypeScript.",
|
|
137
|
+
dedupeThreshold: 0.9,
|
|
122
138
|
});
|
|
123
139
|
```
|
|
124
140
|
|
|
@@ -130,18 +146,18 @@ Stores multiple memories in a single request.
|
|
|
130
146
|
|
|
131
147
|
```ts
|
|
132
148
|
await client.batch([
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
{
|
|
150
|
+
id: "user_123",
|
|
151
|
+
content: "The user works with Hono.",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: "user_123",
|
|
155
|
+
content: "The user prefers practical implementation details.",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
id: "user_123",
|
|
159
|
+
content: "The user uses Bun for backend services.",
|
|
160
|
+
},
|
|
145
161
|
]);
|
|
146
162
|
```
|
|
147
163
|
|
|
@@ -151,18 +167,18 @@ For example, after a conversation:
|
|
|
151
167
|
|
|
152
168
|
```ts
|
|
153
169
|
await client.batch([
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
170
|
+
{
|
|
171
|
+
id: "user_123",
|
|
172
|
+
content: "The user is building an AI application.",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "user_123",
|
|
176
|
+
content: "The user prefers TypeScript.",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: "user_123",
|
|
180
|
+
content: "The user uses Bun for backend development.",
|
|
181
|
+
},
|
|
166
182
|
]);
|
|
167
183
|
```
|
|
168
184
|
|
|
@@ -172,11 +188,11 @@ Searches stored memories semantically.
|
|
|
172
188
|
|
|
173
189
|
```ts
|
|
174
190
|
const memories = await client.search({
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
191
|
+
id: "user_123",
|
|
192
|
+
query: "Which backend framework does the user use?",
|
|
193
|
+
limit: 10,
|
|
194
|
+
minSimilarity: 0.7,
|
|
195
|
+
memoryType: "semantic",
|
|
180
196
|
});
|
|
181
197
|
```
|
|
182
198
|
|
|
@@ -188,9 +204,9 @@ You can also specify a memory type:
|
|
|
188
204
|
|
|
189
205
|
```ts
|
|
190
206
|
const memories = await client.search({
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
207
|
+
id: "user_123",
|
|
208
|
+
query: "What does the user know about this project?",
|
|
209
|
+
memoryType: "semantic",
|
|
194
210
|
});
|
|
195
211
|
```
|
|
196
212
|
|
|
@@ -200,7 +216,7 @@ Retrieves a memory by its identifier.
|
|
|
200
216
|
|
|
201
217
|
```ts
|
|
202
218
|
const memory = await client.get({
|
|
203
|
-
|
|
219
|
+
id: "memory_123",
|
|
204
220
|
});
|
|
205
221
|
```
|
|
206
222
|
|
|
@@ -208,8 +224,8 @@ To retrieve a specific version:
|
|
|
208
224
|
|
|
209
225
|
```ts
|
|
210
226
|
const memory = await client.get({
|
|
211
|
-
|
|
212
|
-
|
|
227
|
+
id: "memory_123",
|
|
228
|
+
version: 2,
|
|
213
229
|
});
|
|
214
230
|
```
|
|
215
231
|
|
|
@@ -221,10 +237,59 @@ Deletes a stored memory.
|
|
|
221
237
|
|
|
222
238
|
```ts
|
|
223
239
|
await client.forget({
|
|
224
|
-
|
|
240
|
+
id: "memory_123",
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### `files()`
|
|
245
|
+
|
|
246
|
+
Uploads and ingests a document from a URL.
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
const upload = await client.files({
|
|
250
|
+
url: "https://example.com/document.pdf",
|
|
251
|
+
id: "tenant_123",
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The `id` can be either a Lumi0 tenant ID or an external ID from your application.
|
|
256
|
+
|
|
257
|
+
Lumi0 determines the document type from the URL and supports the following file extensions:
|
|
258
|
+
|
|
259
|
+
| Extension | MIME type |
|
|
260
|
+
| --------- | --------------------------------------------------------------------------- |
|
|
261
|
+
| `.csv` | `text/csv` |
|
|
262
|
+
| `.docx` | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
|
|
263
|
+
| `.eml` | `message/rfc822` |
|
|
264
|
+
| `.htm` | `text/html` |
|
|
265
|
+
| `.html` | `text/html` |
|
|
266
|
+
| `.json` | `application/json` |
|
|
267
|
+
| `.jsonl` | `application/x-ndjson` |
|
|
268
|
+
| `.md` | `text/markdown` |
|
|
269
|
+
| `.mdx` | `text/markdown` |
|
|
270
|
+
| `.mbox` | `application/mbox` |
|
|
271
|
+
| `.pdf` | `application/pdf` |
|
|
272
|
+
| `.pptx` | `application/vnd.openxmlformats-officedocument.presentationml.presentation` |
|
|
273
|
+
| `.tsv` | `text/tab-separated-values` |
|
|
274
|
+
| `.txt` | `text/plain` |
|
|
275
|
+
| `.xls` | `application/vnd.ms-excel` |
|
|
276
|
+
| `.xlsx` | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
|
|
277
|
+
| `.xml` | `application/xml` |
|
|
278
|
+
| `.yaml` | `application/yaml` |
|
|
279
|
+
| `.yml` | `application/yaml` |
|
|
280
|
+
|
|
281
|
+
Example:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
const upload = await client.files({
|
|
285
|
+
url: "https://example.com/company-handbook.pdf",
|
|
286
|
+
id: "customer_123",
|
|
225
287
|
});
|
|
288
|
+
|
|
289
|
+
console.log(upload);
|
|
226
290
|
```
|
|
227
291
|
|
|
292
|
+
This allows applications to ingest documents without first downloading and uploading the file themselves.
|
|
228
293
|
|
|
229
294
|
### `compress()`
|
|
230
295
|
|
|
@@ -234,10 +299,10 @@ This is useful before sending large context windows to an LLM.
|
|
|
234
299
|
|
|
235
300
|
```ts
|
|
236
301
|
const result = await client.compress({
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
302
|
+
content: JSON.stringify(memories),
|
|
303
|
+
query: "What is the user's preferred backend stack?",
|
|
304
|
+
mode: "adaptive",
|
|
305
|
+
budgetRatio: 0.5,
|
|
241
306
|
});
|
|
242
307
|
|
|
243
308
|
console.log(result.data.compressedText);
|
|
@@ -248,10 +313,10 @@ The returned data can be used as the context for your LLM request:
|
|
|
248
313
|
|
|
249
314
|
```ts
|
|
250
315
|
const result = await client.compress({
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
316
|
+
content: JSON.stringify(memories),
|
|
317
|
+
query: "What is the user's preferred backend stack?",
|
|
318
|
+
mode: "adaptive",
|
|
319
|
+
budgetRatio: 0.5,
|
|
255
320
|
});
|
|
256
321
|
|
|
257
322
|
const context = result.data.compressedText;
|
|
@@ -261,16 +326,16 @@ const context = result.data.compressedText;
|
|
|
261
326
|
|
|
262
327
|
#### Compression modes
|
|
263
328
|
|
|
264
|
-
Lumi0 supports two compression modes
|
|
329
|
+
Lumi0 supports two compression modes.
|
|
265
330
|
|
|
266
331
|
**Adaptive**
|
|
267
332
|
|
|
268
333
|
```ts
|
|
269
334
|
await client.compress({
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
335
|
+
content,
|
|
336
|
+
query,
|
|
337
|
+
mode: "adaptive",
|
|
338
|
+
budgetRatio: 0.5,
|
|
274
339
|
});
|
|
275
340
|
```
|
|
276
341
|
|
|
@@ -280,10 +345,10 @@ Adaptive compression allows Lumi0 to determine how much context should be retain
|
|
|
280
345
|
|
|
281
346
|
```ts
|
|
282
347
|
await client.compress({
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
348
|
+
content,
|
|
349
|
+
query,
|
|
350
|
+
mode: "fixed",
|
|
351
|
+
budgetRatio: 0.5,
|
|
287
352
|
});
|
|
288
353
|
```
|
|
289
354
|
|
|
@@ -299,42 +364,62 @@ A typical application can combine `store()` and `search()`:
|
|
|
299
364
|
import { Lumi0 } from "@lumi0/sdk";
|
|
300
365
|
|
|
301
366
|
const client = new Lumi0({
|
|
302
|
-
|
|
367
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
303
368
|
});
|
|
304
369
|
|
|
305
370
|
// Save information learned from the conversation.
|
|
306
371
|
await client.store({
|
|
307
|
-
|
|
308
|
-
|
|
372
|
+
id: "user_123",
|
|
373
|
+
content: "The user prefers concise answers.",
|
|
309
374
|
});
|
|
310
375
|
|
|
311
376
|
// Retrieve relevant memories before generating a response.
|
|
312
377
|
const memories = await client.search({
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
378
|
+
id: "user_123",
|
|
379
|
+
query: "How should I respond to this user?",
|
|
380
|
+
limit: 5,
|
|
316
381
|
});
|
|
317
382
|
```
|
|
318
383
|
|
|
319
384
|
You can then inject the retrieved memories into your LLM context.
|
|
320
385
|
|
|
386
|
+
## File Ingestion + Memory
|
|
387
|
+
|
|
388
|
+
Lumi0 can combine external documents with persistent memory.
|
|
389
|
+
|
|
390
|
+
For example, an application can ingest a document for a tenant and later use the resulting knowledge alongside stored memories:
|
|
391
|
+
|
|
392
|
+
```ts
|
|
393
|
+
const upload = await client.files({
|
|
394
|
+
url: "https://example.com/product-documentation.pdf",
|
|
395
|
+
id: "tenant_123",
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
await client.store({
|
|
399
|
+
id: "tenant_123",
|
|
400
|
+
content: "The customer is building an AI support application.",
|
|
401
|
+
});
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
This provides a simple pipeline for applications that need both user-specific memory and external document knowledge.
|
|
405
|
+
|
|
321
406
|
## Memory + Compression
|
|
322
407
|
|
|
323
408
|
For applications with large memory collections, you can combine semantic retrieval with compression:
|
|
324
409
|
|
|
325
410
|
```ts
|
|
326
411
|
const memories = await client.search({
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
412
|
+
id: "user_123",
|
|
413
|
+
query: "What does the user prefer when writing code?",
|
|
414
|
+
limit: 20,
|
|
415
|
+
minSimilarity: 0.7,
|
|
331
416
|
});
|
|
332
417
|
|
|
333
418
|
const compressed = await client.compress({
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
419
|
+
content: JSON.stringify(memories),
|
|
420
|
+
query: "What does the user prefer when writing code?",
|
|
421
|
+
mode: "adaptive",
|
|
422
|
+
budgetRatio: 0.5,
|
|
338
423
|
});
|
|
339
424
|
|
|
340
425
|
const context = compressed.data.compressedText;
|
|
@@ -364,9 +449,9 @@ The client accepts configuration options:
|
|
|
364
449
|
|
|
365
450
|
```ts
|
|
366
451
|
const client = new Lumi0({
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
452
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
453
|
+
baseUrl: "https://api.lumi0.com/api/v1",
|
|
454
|
+
timeout: 30_000,
|
|
370
455
|
});
|
|
371
456
|
```
|
|
372
457
|
|
|
@@ -392,8 +477,8 @@ You can override it:
|
|
|
392
477
|
|
|
393
478
|
```ts
|
|
394
479
|
const client = new Lumi0({
|
|
395
|
-
|
|
396
|
-
|
|
480
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
481
|
+
baseUrl: "https://api.lumi0.com/api/v1",
|
|
397
482
|
});
|
|
398
483
|
```
|
|
399
484
|
|
|
@@ -413,8 +498,8 @@ Example:
|
|
|
413
498
|
|
|
414
499
|
```ts
|
|
415
500
|
const client = new Lumi0({
|
|
416
|
-
|
|
417
|
-
|
|
501
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
502
|
+
timeout: 60_000,
|
|
418
503
|
});
|
|
419
504
|
```
|
|
420
505
|
|
|
@@ -432,7 +517,7 @@ Then:
|
|
|
432
517
|
import { Lumi0 } from "@lumi0/sdk";
|
|
433
518
|
|
|
434
519
|
const client = new Lumi0({
|
|
435
|
-
|
|
520
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
436
521
|
});
|
|
437
522
|
```
|
|
438
523
|
|
|
@@ -446,21 +531,21 @@ Use `try/catch` around SDK operations:
|
|
|
446
531
|
|
|
447
532
|
```ts
|
|
448
533
|
try {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
534
|
+
const memories = await client.search({
|
|
535
|
+
id: "user_123",
|
|
536
|
+
query: "What does the user prefer?",
|
|
537
|
+
limit: 5,
|
|
538
|
+
});
|
|
454
539
|
|
|
455
|
-
|
|
540
|
+
console.log(memories);
|
|
456
541
|
} catch (error) {
|
|
457
|
-
|
|
542
|
+
console.error("Lumi0 request failed:", error);
|
|
458
543
|
}
|
|
459
544
|
```
|
|
460
545
|
|
|
461
546
|
The error message includes the HTTP status and the API-provided error message when available.
|
|
462
547
|
|
|
463
|
-
For production applications,
|
|
548
|
+
For production applications, handle failures explicitly rather than assuming every operation succeeds.
|
|
464
549
|
|
|
465
550
|
## Server-Side Usage
|
|
466
551
|
|
|
@@ -471,7 +556,7 @@ Recommended:
|
|
|
471
556
|
```ts
|
|
472
557
|
// Server-side code
|
|
473
558
|
const client = new Lumi0({
|
|
474
|
-
|
|
559
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
475
560
|
});
|
|
476
561
|
```
|
|
477
562
|
|
|
@@ -480,7 +565,7 @@ Avoid putting your API key directly into client-side applications:
|
|
|
480
565
|
```ts
|
|
481
566
|
// Don't expose your secret API key in browser code.
|
|
482
567
|
const client = new Lumi0({
|
|
483
|
-
|
|
568
|
+
apiKey: "your-secret-api-key",
|
|
484
569
|
});
|
|
485
570
|
```
|
|
486
571
|
|
|
@@ -492,18 +577,18 @@ A simple chat application can save user preferences:
|
|
|
492
577
|
|
|
493
578
|
```ts
|
|
494
579
|
await client.store({
|
|
495
|
-
|
|
496
|
-
|
|
580
|
+
id: "user_123",
|
|
581
|
+
content: "The user prefers concise responses.",
|
|
497
582
|
});
|
|
498
583
|
|
|
499
584
|
await client.store({
|
|
500
|
-
|
|
501
|
-
|
|
585
|
+
id: "user_123",
|
|
586
|
+
content: "The user prefers TypeScript examples.",
|
|
502
587
|
});
|
|
503
588
|
|
|
504
589
|
await client.store({
|
|
505
|
-
|
|
506
|
-
|
|
590
|
+
id: "user_123",
|
|
591
|
+
content: "The user uses Bun.",
|
|
507
592
|
});
|
|
508
593
|
```
|
|
509
594
|
|
|
@@ -511,9 +596,9 @@ Later, retrieve the relevant information:
|
|
|
511
596
|
|
|
512
597
|
```ts
|
|
513
598
|
const memories = await client.search({
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
599
|
+
id: "user_123",
|
|
600
|
+
query: "What should I know about this user's coding preferences?",
|
|
601
|
+
limit: 10,
|
|
517
602
|
});
|
|
518
603
|
```
|
|
519
604
|
|
|
@@ -523,18 +608,18 @@ You can store useful information extracted from a conversation:
|
|
|
523
608
|
|
|
524
609
|
```ts
|
|
525
610
|
await client.batch([
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
611
|
+
{
|
|
612
|
+
id: "user_123",
|
|
613
|
+
content: "The user is building a SaaS application.",
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
id: "user_123",
|
|
617
|
+
content: "The user uses TypeScript for backend development.",
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
id: "user_123",
|
|
621
|
+
content: "The user prefers concise technical explanations.",
|
|
622
|
+
},
|
|
538
623
|
]);
|
|
539
624
|
```
|
|
540
625
|
|
|
@@ -542,9 +627,9 @@ Then retrieve only the information relevant to a new request:
|
|
|
542
627
|
|
|
543
628
|
```ts
|
|
544
629
|
const memories = await client.search({
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
630
|
+
id: "user_123",
|
|
631
|
+
query: "What technical preferences should I consider?",
|
|
632
|
+
limit: 5,
|
|
548
633
|
});
|
|
549
634
|
```
|
|
550
635
|
|
|
@@ -556,13 +641,13 @@ The SDK is designed for TypeScript applications and provides typed method interf
|
|
|
556
641
|
import { Lumi0 } from "@lumi0/sdk";
|
|
557
642
|
|
|
558
643
|
const client = new Lumi0({
|
|
559
|
-
|
|
644
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
560
645
|
});
|
|
561
646
|
|
|
562
647
|
const result = await client.search({
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
648
|
+
id: "user_123",
|
|
649
|
+
query: "What does the user prefer?",
|
|
650
|
+
limit: 5,
|
|
566
651
|
});
|
|
567
652
|
```
|
|
568
653
|
|
|
@@ -589,14 +674,15 @@ npm install @lumi0/sdk
|
|
|
589
674
|
|
|
590
675
|
## API Summary
|
|
591
676
|
|
|
592
|
-
| Method | Purpose
|
|
593
|
-
| ------------ |
|
|
594
|
-
| `store()` | Store one memory
|
|
595
|
-
| `batch()` | Store multiple memories
|
|
596
|
-
| `search()` | Semantically search memories
|
|
597
|
-
| `get()` | Retrieve a memory or specific version
|
|
598
|
-
| `forget()` | Delete a memory
|
|
599
|
-
| `
|
|
677
|
+
| Method | Purpose |
|
|
678
|
+
| ------------ | --------------------------------------- |
|
|
679
|
+
| `store()` | Store one memory |
|
|
680
|
+
| `batch()` | Store multiple memories |
|
|
681
|
+
| `search()` | Semantically search memories |
|
|
682
|
+
| `get()` | Retrieve a memory or specific version |
|
|
683
|
+
| `forget()` | Delete a memory |
|
|
684
|
+
| `files()` | Upload and ingest a document from a URL |
|
|
685
|
+
| `compress()` | Compress context relevant to a query |
|
|
600
686
|
|
|
601
687
|
## Complete Example
|
|
602
688
|
|
|
@@ -604,45 +690,53 @@ npm install @lumi0/sdk
|
|
|
604
690
|
import { Lumi0 } from "@lumi0/sdk";
|
|
605
691
|
|
|
606
692
|
const client = new Lumi0({
|
|
607
|
-
|
|
693
|
+
apiKey: process.env.LUMI0_API_KEY!,
|
|
608
694
|
});
|
|
609
695
|
|
|
610
696
|
async function main() {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
697
|
+
// Upload a document.
|
|
698
|
+
const upload = await client.files({
|
|
699
|
+
url: "https://example.com/document.pdf",
|
|
700
|
+
id: "tenant_123",
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
console.log(upload);
|
|
704
|
+
|
|
705
|
+
// Store memories.
|
|
706
|
+
await client.batch([
|
|
707
|
+
{
|
|
708
|
+
id: "user_123",
|
|
709
|
+
content: "The user prefers concise TypeScript examples.",
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
id: "user_123",
|
|
713
|
+
content: "The user uses Bun for backend development.",
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
id: "user_123",
|
|
717
|
+
content: "The user works with Hono.",
|
|
718
|
+
},
|
|
719
|
+
]);
|
|
720
|
+
|
|
721
|
+
// Search relevant memories.
|
|
722
|
+
const memories = await client.search({
|
|
723
|
+
id: "user_123",
|
|
724
|
+
query: "What backend technologies does the user use?",
|
|
725
|
+
limit: 10,
|
|
726
|
+
minSimilarity: 0.7,
|
|
727
|
+
memoryType: "semantic",
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
// Compress retrieved context.
|
|
731
|
+
const compressed = await client.compress({
|
|
732
|
+
content: JSON.stringify(memories),
|
|
733
|
+
query: "What backend technologies does the user use?",
|
|
734
|
+
mode: "adaptive",
|
|
735
|
+
budgetRatio: 0.5,
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
console.log(compressed.data.compressedText);
|
|
739
|
+
console.log(`${compressed.data.tokensSaved} tokens saved`);
|
|
646
740
|
}
|
|
647
741
|
|
|
648
742
|
main().catch(console.error);
|
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,43 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
|
+
interface HttpClientOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
headers?: globalThis.HeadersInit;
|
|
7
|
+
}
|
|
8
|
+
interface ErrorResponse {
|
|
9
|
+
message?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
2
12
|
type Lumi0Options = {
|
|
3
13
|
apiKey: string;
|
|
4
14
|
baseUrl?: string;
|
|
5
15
|
timeout?: number;
|
|
6
16
|
};
|
|
17
|
+
type PostBody = Record<string, unknown>;
|
|
18
|
+
interface IPostBody {
|
|
19
|
+
userId: string;
|
|
20
|
+
collectionId: string;
|
|
21
|
+
}
|
|
7
22
|
interface StoreMemoryInput {
|
|
8
23
|
content: string;
|
|
9
24
|
dedupeThreshold?: number;
|
|
10
25
|
id: string;
|
|
11
26
|
}
|
|
27
|
+
interface BuildContextInput {
|
|
28
|
+
id: string;
|
|
29
|
+
query: string;
|
|
30
|
+
limit?: number;
|
|
31
|
+
minSimilarity?: number;
|
|
32
|
+
}
|
|
33
|
+
interface UploadFileInput {
|
|
34
|
+
id: string;
|
|
35
|
+
url: string;
|
|
36
|
+
}
|
|
37
|
+
interface MemoryRollbackInput {
|
|
38
|
+
memoryId: string;
|
|
39
|
+
version: number;
|
|
40
|
+
}
|
|
12
41
|
interface SearchMemoryInput {
|
|
13
42
|
query: string;
|
|
14
43
|
limit?: number;
|
|
@@ -26,7 +55,24 @@ interface CompressMemoryInput {
|
|
|
26
55
|
budgetRatio?: number;
|
|
27
56
|
mode: "fixed" | "adaptive";
|
|
28
57
|
}
|
|
29
|
-
interface
|
|
58
|
+
interface MemoryVersion {
|
|
59
|
+
id: string;
|
|
60
|
+
memoryId: string;
|
|
61
|
+
version: number;
|
|
62
|
+
action: "created" | "updated" | "deleted";
|
|
63
|
+
content: string;
|
|
64
|
+
metadata: {
|
|
65
|
+
tags: string[];
|
|
66
|
+
summary: string;
|
|
67
|
+
category: string;
|
|
68
|
+
externalId: string;
|
|
69
|
+
importance: number;
|
|
70
|
+
memoryType: "semantic" | "episodic" | "procedural";
|
|
71
|
+
};
|
|
72
|
+
createdBy: string;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
}
|
|
75
|
+
interface Compress {
|
|
30
76
|
compressedText: string;
|
|
31
77
|
originalTokens: number;
|
|
32
78
|
keptTokens: number;
|
|
@@ -37,24 +83,62 @@ interface CompressMemoryResult {
|
|
|
37
83
|
policyName: string;
|
|
38
84
|
keptLineRatio: number;
|
|
39
85
|
}
|
|
40
|
-
interface CompressMemoryApiResponse {
|
|
41
|
-
success: boolean;
|
|
42
|
-
data: CompressMemoryResult;
|
|
43
|
-
}
|
|
44
86
|
interface ForgetMemoryInput {
|
|
45
87
|
id: string;
|
|
46
88
|
}
|
|
89
|
+
interface Context {
|
|
90
|
+
data: string;
|
|
91
|
+
}
|
|
92
|
+
interface Search {
|
|
93
|
+
id: string;
|
|
94
|
+
collectionId: string;
|
|
95
|
+
externalId: string;
|
|
96
|
+
content: string;
|
|
97
|
+
memoryType: string;
|
|
98
|
+
importance: number;
|
|
99
|
+
category: string;
|
|
100
|
+
summary: string;
|
|
101
|
+
tags: string[];
|
|
102
|
+
version: number;
|
|
103
|
+
createdAt: Date;
|
|
104
|
+
updatedAt: Date;
|
|
105
|
+
similarity: number;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/http.d.ts
|
|
109
|
+
declare class HttpClient {
|
|
110
|
+
private readonly options;
|
|
111
|
+
constructor(options: HttpClientOptions);
|
|
112
|
+
request<T>(path: string, init?: RequestInit): Promise<T>;
|
|
113
|
+
get<T>(path: string): Promise<T>;
|
|
114
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
115
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
116
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
117
|
+
delete<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
118
|
+
private parseError;
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/memory.d.ts
|
|
122
|
+
declare class MemoryApi {
|
|
123
|
+
private readonly http;
|
|
124
|
+
constructor(http: HttpClient);
|
|
125
|
+
history(id: string): Promise<MemoryVersion[]>;
|
|
126
|
+
rollback(input: MemoryRollbackInput): Promise<unknown>;
|
|
127
|
+
}
|
|
47
128
|
//#endregion
|
|
48
129
|
//#region src/client.d.ts
|
|
49
130
|
declare class Lumi0 {
|
|
50
131
|
private readonly http;
|
|
132
|
+
readonly mem: MemoryApi;
|
|
51
133
|
constructor(option: Lumi0Options);
|
|
52
134
|
store(input: StoreMemoryInput): Promise<unknown>;
|
|
53
|
-
search(input: SearchMemoryInput): Promise<
|
|
54
|
-
get(input: GetMemoryInput): Promise<
|
|
135
|
+
search(input: SearchMemoryInput): Promise<Search>;
|
|
136
|
+
get(input: GetMemoryInput): Promise<Search>;
|
|
55
137
|
forget(input: ForgetMemoryInput): Promise<unknown>;
|
|
56
138
|
batch(input: StoreMemoryInput[]): Promise<unknown>;
|
|
57
|
-
|
|
139
|
+
context(input: BuildContextInput): Promise<Context>;
|
|
140
|
+
files(input: UploadFileInput): Promise<unknown>;
|
|
141
|
+
compress(input: CompressMemoryInput): Promise<Compress>;
|
|
58
142
|
}
|
|
59
143
|
//#endregion
|
|
60
|
-
export { Lumi0 };
|
|
144
|
+
export { BuildContextInput, Compress, CompressMemoryInput, Context, ErrorResponse, ForgetMemoryInput, GetMemoryInput, HttpClientOptions, IPostBody, Lumi0, Lumi0Options, MemoryRollbackInput, MemoryVersion, PostBody, Search, SearchMemoryInput, StoreMemoryInput, UploadFileInput };
|
package/dist/index.mjs
CHANGED
|
@@ -66,9 +66,24 @@ var HttpClient = class {
|
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
68
|
//#endregion
|
|
69
|
+
//#region src/memory.ts
|
|
70
|
+
var MemoryApi = class {
|
|
71
|
+
http;
|
|
72
|
+
constructor(http) {
|
|
73
|
+
this.http = http;
|
|
74
|
+
}
|
|
75
|
+
history(id) {
|
|
76
|
+
return this.http.get(`/memories/history/${id}`).then((response) => response.data);
|
|
77
|
+
}
|
|
78
|
+
rollback(input) {
|
|
79
|
+
return this.http.post(`/memories/${input.memoryId}/versions/${input.version}/rollback`);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
69
83
|
//#region src/client.ts
|
|
70
84
|
var Lumi0 = class {
|
|
71
85
|
http;
|
|
86
|
+
mem;
|
|
72
87
|
constructor(option) {
|
|
73
88
|
const apiKey = option.apiKey;
|
|
74
89
|
this.http = new HttpClient({
|
|
@@ -76,6 +91,7 @@ var Lumi0 = class {
|
|
|
76
91
|
apiKey,
|
|
77
92
|
timeout: option.timeout ?? 3e4
|
|
78
93
|
});
|
|
94
|
+
this.mem = new MemoryApi(this.http);
|
|
79
95
|
}
|
|
80
96
|
store(input) {
|
|
81
97
|
return this.http.post("/memory", {
|
|
@@ -87,10 +103,10 @@ var Lumi0 = class {
|
|
|
87
103
|
return this.http.post("/memory/search", {
|
|
88
104
|
...input,
|
|
89
105
|
externalId: input.id
|
|
90
|
-
});
|
|
106
|
+
}).then((res) => res.data);
|
|
91
107
|
}
|
|
92
108
|
get(input) {
|
|
93
|
-
return this.http.post("/memory/get", input);
|
|
109
|
+
return this.http.post("/memory/get", input).then((res) => res.data);
|
|
94
110
|
}
|
|
95
111
|
forget(input) {
|
|
96
112
|
return this.http.delete(`/memory/${input.id}`);
|
|
@@ -98,8 +114,20 @@ var Lumi0 = class {
|
|
|
98
114
|
batch(input) {
|
|
99
115
|
return this.http.post("/memory/batch", input.map((item) => ({ ...item })));
|
|
100
116
|
}
|
|
117
|
+
context(input) {
|
|
118
|
+
return this.http.post("/memory/context", {
|
|
119
|
+
...input,
|
|
120
|
+
externalId: input.id
|
|
121
|
+
}).then((res) => res.data);
|
|
122
|
+
}
|
|
123
|
+
files(input) {
|
|
124
|
+
return this.http.post("/memory/batch", {
|
|
125
|
+
...input,
|
|
126
|
+
externalId: input.id
|
|
127
|
+
});
|
|
128
|
+
}
|
|
101
129
|
compress(input) {
|
|
102
|
-
return this.http.post("/compress", input);
|
|
130
|
+
return this.http.post("/compress", input).then((res) => res.data);
|
|
103
131
|
}
|
|
104
132
|
};
|
|
105
133
|
//#endregion
|