@lumi0/sdk 0.0.2 → 0.0.4

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
@@ -1,21 +1,52 @@
1
1
  # Lumi0 TypeScript SDK
2
2
 
3
- The official TypeScript SDK for storing, retrieving, and compressing persistent
4
- AI memory with Lumi0.
3
+ The official TypeScript SDK for [Lumi0](https://lumi0.com), an AI infrastructure platform for persistent memory and context compression.
4
+
5
+ Use Lumi0 to give AI applications long-term memory: store information about users, retrieve relevant context with semantic search, manage memory versions, batch-write memories, forget stored information, and compress large contexts before sending them to an LLM.
6
+
7
+ ## Features
8
+
9
+ * Persistent AI memory
10
+ * Semantic memory search
11
+ * Memory versioning
12
+ * Batch memory storage
13
+ * Memory deduplication
14
+ * Context compression
15
+ * Fixed and adaptive compression modes
16
+ * TypeScript-first API
17
+ * Bun and Node.js compatible
18
+ * Configurable API URL and request timeout
5
19
 
6
20
  ## Installation
7
21
 
22
+ ### Bun
23
+
8
24
  ```bash
9
25
  bun add @lumi0/sdk
10
26
  ```
11
27
 
28
+ ### npm
29
+
12
30
  ```bash
13
31
  npm install @lumi0/sdk
14
32
  ```
15
33
 
16
- ## Quick start
34
+ ## Requirements
35
+
36
+ * Node.js 18+ or Bun
37
+ * A Lumi0 API key
38
+
39
+ Set your API key as an environment variable:
40
+
41
+ ```bash
42
+ LUMI0_API_KEY=your_api_key
43
+ ```
17
44
 
18
- Create a client with a Lumi0 API key:
45
+ Never expose your Lumi0 API key in browser-side code. Keep it on your server or in a trusted backend environment.
46
+
47
+ ## Quick Start
48
+
49
+ Create a Lumi0 client:
19
50
 
20
51
  ```ts
21
52
  import { Lumi0 } from "@lumi0/sdk";
@@ -25,26 +56,63 @@ const client = new Lumi0({
25
56
  });
26
57
  ```
27
58
 
28
- Store a memory, then search for relevant context:
59
+ ### Store a memory
60
+
61
+ Store information associated with an identifier:
29
62
 
30
63
  ```ts
31
64
  await client.store({
32
65
  id: "user_123",
33
66
  content: "The user prefers concise TypeScript examples.",
34
67
  });
68
+ ```
69
+
70
+ ### Search memories
35
71
 
72
+ Retrieve memories that are semantically relevant to a query:
73
+
74
+ ```ts
36
75
  const memories = await client.search({
37
76
  id: "user_123",
38
77
  query: "What coding examples does the user prefer?",
39
78
  limit: 5,
40
79
  });
80
+
81
+ console.log(memories);
82
+ ```
83
+
84
+ A common AI application flow looks like:
85
+
86
+ ```text
87
+ User
88
+
89
+ Your AI Application
90
+
91
+ Lumi0 Memory
92
+
93
+ Semantic Search
94
+
95
+ Relevant Context
96
+
97
+ LLM
98
+
99
+ Response
41
100
  ```
42
101
 
43
- ## API
102
+ ## API Reference
103
+
104
+ ### `store()`
105
+
106
+ Stores a single memory for an identifier.
44
107
 
45
- ### `store`
108
+ ```ts
109
+ await client.store({
110
+ id: "user_123",
111
+ content: "The user uses Bun and TypeScript.",
112
+ });
113
+ ```
46
114
 
47
- Stores one memory for an identifier.
115
+ You can optionally configure deduplication:
48
116
 
49
117
  ```ts
50
118
  await client.store({
@@ -54,9 +122,11 @@ await client.store({
54
122
  });
55
123
  ```
56
124
 
57
- ### `batch`
125
+ `dedupeThreshold` controls how similar an existing memory can be before Lumi0 considers the new memory a duplicate.
126
+
127
+ ### `batch()`
58
128
 
59
- Stores multiple memories in one request.
129
+ Stores multiple memories in a single request.
60
130
 
61
131
  ```ts
62
132
  await client.batch([
@@ -68,12 +138,37 @@ await client.batch([
68
138
  id: "user_123",
69
139
  content: "The user prefers practical implementation details.",
70
140
  },
141
+ {
142
+ id: "user_123",
143
+ content: "The user uses Bun for backend services.",
144
+ },
71
145
  ]);
72
146
  ```
73
147
 
74
- ### `search`
148
+ Batching is useful when your application needs to save multiple pieces of context at once.
75
149
 
76
- Searches memories semantically.
150
+ For example, after a conversation:
151
+
152
+ ```ts
153
+ await client.batch([
154
+ {
155
+ id: "user_123",
156
+ content: "The user is building an AI application.",
157
+ },
158
+ {
159
+ id: "user_123",
160
+ content: "The user prefers TypeScript.",
161
+ },
162
+ {
163
+ id: "user_123",
164
+ content: "The user uses Bun for backend development.",
165
+ },
166
+ ]);
167
+ ```
168
+
169
+ ### `search()`
170
+
171
+ Searches stored memories semantically.
77
172
 
78
173
  ```ts
79
174
  const memories = await client.search({
@@ -85,9 +180,31 @@ const memories = await client.search({
85
180
  });
86
181
  ```
87
182
 
88
- ### `get`
183
+ You can use `limit` to control the maximum number of memories returned.
89
184
 
90
- Retrieves a memory by identifier. Pass `version` to retrieve a specific version.
185
+ `minSimilarity` can be used to filter out results below a similarity threshold.
186
+
187
+ You can also specify a memory type:
188
+
189
+ ```ts
190
+ const memories = await client.search({
191
+ id: "user_123",
192
+ query: "What does the user know about this project?",
193
+ memoryType: "semantic",
194
+ });
195
+ ```
196
+
197
+ ### `get()`
198
+
199
+ Retrieves a memory by its identifier.
200
+
201
+ ```ts
202
+ const memory = await client.get({
203
+ id: "memory_123",
204
+ });
205
+ ```
206
+
207
+ To retrieve a specific version:
91
208
 
92
209
  ```ts
93
210
  const memory = await client.get({
@@ -96,20 +213,24 @@ const memory = await client.get({
96
213
  });
97
214
  ```
98
215
 
99
- ### `forget`
216
+ This is useful when your application needs to inspect a particular historical version of a memory.
217
+
218
+ ### `forget()`
100
219
 
101
- Deletes a memory for a user.
220
+ Deletes a stored memory.
102
221
 
103
222
  ```ts
104
223
  await client.forget({
105
224
  id: "memory_123",
106
- userId: "user_123",
107
225
  });
108
226
  ```
109
227
 
110
- ### `compress`
111
228
 
112
- Reduces context while retaining information relevant to a query.
229
+ ### `compress()`
230
+
231
+ Compresses context while attempting to retain information that is relevant to a query.
232
+
233
+ This is useful before sending large context windows to an LLM.
113
234
 
114
235
  ```ts
115
236
  const result = await client.compress({
@@ -123,12 +244,124 @@ console.log(result.data.compressedText);
123
244
  console.log(`${result.data.tokensSaved} tokens saved`);
124
245
  ```
125
246
 
126
- Use `"fixed"` mode with `budgetRatio` to target a specific retained-context
127
- ratio. Use `"adaptive"` mode to let Lumi0 determine the appropriate amount of
128
- context to retain for the query.
247
+ The returned data can be used as the context for your LLM request:
248
+
249
+ ```ts
250
+ const result = await client.compress({
251
+ content: JSON.stringify(memories),
252
+ query: "What is the user's preferred backend stack?",
253
+ mode: "adaptive",
254
+ budgetRatio: 0.5,
255
+ });
256
+
257
+ const context = result.data.compressedText;
258
+
259
+ // Pass `context` to your LLM.
260
+ ```
261
+
262
+ #### Compression modes
263
+
264
+ Lumi0 supports two compression modes:
265
+
266
+ **Adaptive**
267
+
268
+ ```ts
269
+ await client.compress({
270
+ content,
271
+ query,
272
+ mode: "adaptive",
273
+ budgetRatio: 0.5,
274
+ });
275
+ ```
276
+
277
+ Adaptive compression allows Lumi0 to determine how much context should be retained based on the query and content.
278
+
279
+ **Fixed**
280
+
281
+ ```ts
282
+ await client.compress({
283
+ content,
284
+ query,
285
+ mode: "fixed",
286
+ budgetRatio: 0.5,
287
+ });
288
+ ```
289
+
290
+ Fixed compression uses `budgetRatio` to target a specific retained-context ratio.
291
+
292
+ For example, a `budgetRatio` of `0.5` targets approximately half of the original context budget.
293
+
294
+ ## Building an AI Memory Loop
295
+
296
+ A typical application can combine `store()` and `search()`:
297
+
298
+ ```ts
299
+ import { Lumi0 } from "@lumi0/sdk";
300
+
301
+ const client = new Lumi0({
302
+ apiKey: process.env.LUMI0_API_KEY!,
303
+ });
304
+
305
+ // Save information learned from the conversation.
306
+ await client.store({
307
+ id: "user_123",
308
+ content: "The user prefers concise answers.",
309
+ });
310
+
311
+ // Retrieve relevant memories before generating a response.
312
+ const memories = await client.search({
313
+ id: "user_123",
314
+ query: "How should I respond to this user?",
315
+ limit: 5,
316
+ });
317
+ ```
318
+
319
+ You can then inject the retrieved memories into your LLM context.
320
+
321
+ ## Memory + Compression
322
+
323
+ For applications with large memory collections, you can combine semantic retrieval with compression:
324
+
325
+ ```ts
326
+ const memories = await client.search({
327
+ id: "user_123",
328
+ query: "What does the user prefer when writing code?",
329
+ limit: 20,
330
+ minSimilarity: 0.7,
331
+ });
332
+
333
+ const compressed = await client.compress({
334
+ content: JSON.stringify(memories),
335
+ query: "What does the user prefer when writing code?",
336
+ mode: "adaptive",
337
+ budgetRatio: 0.5,
338
+ });
339
+
340
+ const context = compressed.data.compressedText;
341
+
342
+ console.log(context);
343
+ ```
344
+
345
+ This creates a pipeline:
346
+
347
+ ```text
348
+ Stored Memories
349
+
350
+ Semantic Search
351
+
352
+ Relevant Memories
353
+
354
+ Context Compression
355
+
356
+ Compressed Context
357
+
358
+ LLM
359
+ ```
129
360
 
130
361
  ## Configuration
131
362
 
363
+ The client accepts configuration options:
364
+
132
365
  ```ts
133
366
  const client = new Lumi0({
134
367
  apiKey: process.env.LUMI0_API_KEY!,
@@ -137,11 +370,290 @@ const client = new Lumi0({
137
370
  });
138
371
  ```
139
372
 
140
- `baseUrl` defaults to `https://api.lumi0.com/api/v1` and `timeout` defaults to
141
- 30 seconds.
373
+ ### `apiKey`
374
+
375
+ Your Lumi0 API key.
376
+
377
+ ```ts
378
+ apiKey: process.env.LUMI0_API_KEY!
379
+ ```
380
+
381
+ ### `baseUrl`
382
+
383
+ The Lumi0 API endpoint.
384
+
385
+ Default:
386
+
387
+ ```text
388
+ https://api.lumi0.com/api/v1
389
+ ```
390
+
391
+ You can override it:
392
+
393
+ ```ts
394
+ const client = new Lumi0({
395
+ apiKey: process.env.LUMI0_API_KEY!,
396
+ baseUrl: "https://api.lumi0.com/api/v1",
397
+ });
398
+ ```
399
+
400
+ This can be useful when working with a different API environment.
401
+
402
+ ### `timeout`
403
+
404
+ Maximum time, in milliseconds, that the SDK waits for an HTTP request.
405
+
406
+ Default:
407
+
408
+ ```ts
409
+ 30_000
410
+ ```
411
+
412
+ Example:
413
+
414
+ ```ts
415
+ const client = new Lumi0({
416
+ apiKey: process.env.LUMI0_API_KEY!,
417
+ timeout: 60_000,
418
+ });
419
+ ```
420
+
421
+ ## Environment Variables
422
+
423
+ A typical `.env` file:
424
+
425
+ ```env
426
+ LUMI0_API_KEY=your_api_key
427
+ ```
428
+
429
+ Then:
430
+
431
+ ```ts
432
+ import { Lumi0 } from "@lumi0/sdk";
433
+
434
+ const client = new Lumi0({
435
+ apiKey: process.env.LUMI0_API_KEY!,
436
+ });
437
+ ```
438
+
439
+ Do not commit your `.env` file or API keys to source control.
440
+
441
+ ## Error Handling
442
+
443
+ SDK requests reject with an `Error` when Lumi0 returns a non-success HTTP status.
444
+
445
+ Use `try/catch` around SDK operations:
446
+
447
+ ```ts
448
+ try {
449
+ const memories = await client.search({
450
+ id: "user_123",
451
+ query: "What does the user prefer?",
452
+ limit: 5,
453
+ });
454
+
455
+ console.log(memories);
456
+ } catch (error) {
457
+ console.error("Lumi0 request failed:", error);
458
+ }
459
+ ```
460
+
461
+ The error message includes the HTTP status and the API-provided error message when available.
462
+
463
+ For production applications, you should handle failures explicitly rather than assuming every memory operation succeeds.
464
+
465
+ ## Server-Side Usage
466
+
467
+ The Lumi0 API key should be kept private.
468
+
469
+ Recommended:
470
+
471
+ ```ts
472
+ // Server-side code
473
+ const client = new Lumi0({
474
+ apiKey: process.env.LUMI0_API_KEY!,
475
+ });
476
+ ```
477
+
478
+ Avoid putting your API key directly into client-side applications:
479
+
480
+ ```ts
481
+ // Don't expose your secret API key in browser code.
482
+ const client = new Lumi0({
483
+ apiKey: "your-secret-api-key",
484
+ });
485
+ ```
486
+
487
+ For a Next.js application, use Lumi0 from server-side code such as API routes, Route Handlers, Server Actions, or your backend.
488
+
489
+ ## Example: User Memory
490
+
491
+ A simple chat application can save user preferences:
492
+
493
+ ```ts
494
+ await client.store({
495
+ id: "user_123",
496
+ content: "The user prefers concise responses.",
497
+ });
498
+
499
+ await client.store({
500
+ id: "user_123",
501
+ content: "The user prefers TypeScript examples.",
502
+ });
503
+
504
+ await client.store({
505
+ id: "user_123",
506
+ content: "The user uses Bun.",
507
+ });
508
+ ```
509
+
510
+ Later, retrieve the relevant information:
511
+
512
+ ```ts
513
+ const memories = await client.search({
514
+ id: "user_123",
515
+ query: "What should I know about this user's coding preferences?",
516
+ limit: 10,
517
+ });
518
+ ```
519
+
520
+ ## Example: Conversation Memory
521
+
522
+ You can store useful information extracted from a conversation:
523
+
524
+ ```ts
525
+ await client.batch([
526
+ {
527
+ id: "user_123",
528
+ content: "The user is building a SaaS application.",
529
+ },
530
+ {
531
+ id: "user_123",
532
+ content: "The user uses TypeScript for backend development.",
533
+ },
534
+ {
535
+ id: "user_123",
536
+ content: "The user prefers concise technical explanations.",
537
+ },
538
+ ]);
539
+ ```
540
+
541
+ Then retrieve only the information relevant to a new request:
542
+
543
+ ```ts
544
+ const memories = await client.search({
545
+ id: "user_123",
546
+ query: "What technical preferences should I consider?",
547
+ limit: 5,
548
+ });
549
+ ```
550
+
551
+ ## TypeScript
552
+
553
+ The SDK is designed for TypeScript applications and provides typed method interfaces.
554
+
555
+ ```ts
556
+ import { Lumi0 } from "@lumi0/sdk";
557
+
558
+ const client = new Lumi0({
559
+ apiKey: process.env.LUMI0_API_KEY!,
560
+ });
561
+
562
+ const result = await client.search({
563
+ id: "user_123",
564
+ query: "What does the user prefer?",
565
+ limit: 5,
566
+ });
567
+ ```
568
+
569
+ Your editor can provide autocomplete and type checking for Lumi0 client methods and their options.
570
+
571
+ ## Runtime Support
572
+
573
+ The SDK is designed to work with modern JavaScript runtimes, including:
574
+
575
+ * Bun
576
+ * Node.js
577
+
578
+ Bun installation:
579
+
580
+ ```bash
581
+ bun add @lumi0/sdk
582
+ ```
583
+
584
+ npm installation:
585
+
586
+ ```bash
587
+ npm install @lumi0/sdk
588
+ ```
589
+
590
+ ## API Summary
591
+
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
+ | `compress()` | Compress context relevant to a query |
600
+
601
+ ## Complete Example
602
+
603
+ ```ts
604
+ import { Lumi0 } from "@lumi0/sdk";
605
+
606
+ const client = new Lumi0({
607
+ apiKey: process.env.LUMI0_API_KEY!,
608
+ });
609
+
610
+ async function main() {
611
+ // Store memories.
612
+ await client.batch([
613
+ {
614
+ id: "user_123",
615
+ content: "The user prefers concise TypeScript examples.",
616
+ },
617
+ {
618
+ id: "user_123",
619
+ content: "The user uses Bun for backend development.",
620
+ },
621
+ {
622
+ id: "user_123",
623
+ content: "The user works with Hono.",
624
+ },
625
+ ]);
626
+
627
+ // Search relevant memories.
628
+ const memories = await client.search({
629
+ id: "user_123",
630
+ query: "What backend technologies does the user use?",
631
+ limit: 10,
632
+ minSimilarity: 0.7,
633
+ memoryType: "semantic",
634
+ });
635
+
636
+ // Compress retrieved context.
637
+ const compressed = await client.compress({
638
+ content: JSON.stringify(memories),
639
+ query: "What backend technologies does the user use?",
640
+ mode: "adaptive",
641
+ budgetRatio: 0.5,
642
+ });
643
+
644
+ console.log(compressed.data.compressedText);
645
+ console.log(`${compressed.data.tokensSaved} tokens saved`);
646
+ }
647
+
648
+ main().catch(console.error);
649
+ ```
650
+
651
+ ## Links
652
+
653
+ * Website: https://lumi0.com
654
+ * API: https://api.lumi0.com
655
+ * npm: https://www.npmjs.com/package/@lumi0/sdk
142
656
 
143
- ## Errors
657
+ ## License
144
658
 
145
- SDK requests reject with an `Error` when Lumi0 returns a non-success status.
146
- The error message includes the HTTP status and the API-provided error message
147
- when available.
659
+ MIT
package/dist/index.d.mts CHANGED
@@ -1,27 +1,9 @@
1
- //#region ../../../apps/api/src/shared/utils/types.d.ts
2
- interface ForgetMemoryInput {
3
- userId: string;
4
- id: string;
5
- }
6
- //#endregion
7
1
  //#region src/types.d.ts
8
2
  type Lumi0Options = {
9
3
  apiKey: string;
10
4
  baseUrl?: string;
11
5
  timeout?: number;
12
6
  };
13
- //#endregion
14
- //#region src/client.d.ts
15
- declare class Lumi0 {
16
- private readonly http;
17
- constructor(option: Lumi0Options);
18
- store(input: StoreMemoryInput): Promise<unknown>;
19
- search(input: SearchMemoryInput): Promise<unknown>;
20
- get(input: GetMemoryInput): Promise<unknown>;
21
- forget(input: ForgetMemoryInput): Promise<unknown>;
22
- batch(input: StoreMemoryInput[]): Promise<unknown>;
23
- compress(input: CompressMemoryInput): Promise<CompressMemoryApiResponse>;
24
- }
25
7
  interface StoreMemoryInput {
26
8
  content: string;
27
9
  dedupeThreshold?: number;
@@ -59,5 +41,20 @@ interface CompressMemoryApiResponse {
59
41
  success: boolean;
60
42
  data: CompressMemoryResult;
61
43
  }
44
+ interface ForgetMemoryInput {
45
+ id: string;
46
+ }
47
+ //#endregion
48
+ //#region src/client.d.ts
49
+ declare class Lumi0 {
50
+ private readonly http;
51
+ constructor(option: Lumi0Options);
52
+ store(input: StoreMemoryInput): Promise<unknown>;
53
+ search(input: SearchMemoryInput): Promise<unknown>;
54
+ get(input: GetMemoryInput): Promise<unknown>;
55
+ forget(input: ForgetMemoryInput): Promise<unknown>;
56
+ batch(input: StoreMemoryInput[]): Promise<unknown>;
57
+ compress(input: CompressMemoryInput): Promise<CompressMemoryApiResponse>;
58
+ }
62
59
  //#endregion
63
- export { CompressMemoryApiResponse, CompressMemoryInput, CompressMemoryResult, GetMemoryInput, Lumi0, SearchMemoryInput, StoreMemoryInput };
60
+ export { Lumi0 };
package/dist/index.mjs CHANGED
@@ -36,12 +36,6 @@ var HttpClient = class {
36
36
  body: body ? JSON.stringify(body) : void 0
37
37
  });
38
38
  }
39
- list(path, items) {
40
- return this.request(path, {
41
- method: "POST",
42
- body: JSON.stringify(items)
43
- });
44
- }
45
39
  put(path, body) {
46
40
  return this.request(path, {
47
41
  method: "PUT",
@@ -99,7 +93,7 @@ var Lumi0 = class {
99
93
  return this.http.post("/memory/get", input);
100
94
  }
101
95
  forget(input) {
102
- return this.http.delete(`/memory/${input.id}`, { userId: input.userId });
96
+ return this.http.delete(`/memory/${input.id}`);
103
97
  }
104
98
  batch(input) {
105
99
  return this.http.post("/memory/batch", input.map((item) => ({ ...item })));
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@lumi0/sdk",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Official TypeScript SDK for Lumi0",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "main": "./dist/index.mjs",
8
+ "types": "./dist/index.d.mts",
7
9
  "repository": {
8
10
  "type": "git",
9
11
  "url": "https://github.com/lumi0ai/lumi0-ts.git"