@nebula-ai/sdk 0.0.27 → 0.0.31

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/dist/index.mjs CHANGED
@@ -39,10 +39,16 @@ var NebulaValidationException = class extends NebulaException {
39
39
  this.name = "NebulaValidationException";
40
40
  }
41
41
  };
42
- var NebulaClusterNotFoundException = class extends NebulaException {
43
- constructor(message = "Cluster not found") {
42
+ var NebulaCollectionNotFoundException = class extends NebulaException {
43
+ constructor(message = "Collection not found") {
44
44
  super(message, 404);
45
- this.name = "NebulaClusterNotFoundException";
45
+ this.name = "NebulaCollectionNotFoundException";
46
+ }
47
+ };
48
+ var NebulaNotFoundException = class extends NebulaException {
49
+ constructor(resourceId, resourceType = "Resource") {
50
+ super(`${resourceType} not found: ${resourceId}`, 404);
51
+ this.name = "NebulaNotFoundException";
46
52
  }
47
53
  };
48
54
 
@@ -135,6 +141,17 @@ var NebulaClient = class {
135
141
  } else if (response.status === 400) {
136
142
  const errorData = await response.json().catch(() => ({}));
137
143
  throw new NebulaValidationException(errorData.message || "Validation error", errorData.details);
144
+ } else if (response.status === 422) {
145
+ const errorData = await response.json().catch(() => ({}));
146
+ console.error("[SDK] 422 Validation error - Full details:");
147
+ console.error(" Status:", response.status);
148
+ console.error(" Error data:", JSON.stringify(errorData, null, 2));
149
+ console.error(" Message:", errorData.message);
150
+ console.error(" Detail:", errorData.detail);
151
+ throw new NebulaValidationException(
152
+ errorData.message || (typeof errorData.detail === "string" ? errorData.detail : JSON.stringify(errorData.detail)) || "Validation error",
153
+ errorData
154
+ );
138
155
  } else {
139
156
  const errorData = await response.json().catch(() => ({}));
140
157
  throw new NebulaException(errorData.message || `API error: ${response.status}`, response.status, errorData);
@@ -153,54 +170,85 @@ var NebulaClient = class {
153
170
  throw new NebulaClientException(`Request failed: ${String(error)}`);
154
171
  }
155
172
  }
156
- // Cluster Management Methods
157
- /** Create a new cluster */
158
- async createCluster(options) {
173
+ // Collection Management Methods
174
+ /** Create a new collection */
175
+ async createCollection(options) {
159
176
  const data = { name: options.name };
160
177
  if (options.description) data.description = options.description;
161
178
  if (options.metadata) data.metadata = options.metadata;
162
179
  const response = await this._makeRequest("POST", "/v1/collections", data);
163
180
  const result = response.results || response;
164
- return this._clusterFromDict(result);
181
+ return this._collectionFromDict(result);
165
182
  }
166
- /** Get a specific cluster by ID */
167
- async getCluster(clusterId) {
168
- const response = await this._makeRequest("GET", `/v1/collections/${clusterId}`);
183
+ /** Get a specific collection by ID */
184
+ async getCollection(collectionId) {
185
+ const response = await this._makeRequest("GET", `/v1/collections/${collectionId}`);
169
186
  const result = response.results || response;
170
- return this._clusterFromDict(result);
187
+ return this._collectionFromDict(result);
171
188
  }
172
- /** Get a specific cluster by name */
173
- async getClusterByName(name) {
189
+ /** Get a specific collection by name */
190
+ async getCollectionByName(name) {
174
191
  const response = await this._makeRequest("GET", `/v1/collections/name/${name}`);
175
192
  const result = response.results || response;
176
- return this._clusterFromDict(result);
193
+ return this._collectionFromDict(result);
177
194
  }
178
- /** Get all clusters */
179
- async listClusters(options) {
195
+ /** Get all collections */
196
+ async listCollections(options) {
180
197
  const params = {
181
198
  limit: options?.limit ?? 100,
182
199
  offset: options?.offset ?? 0
183
200
  };
184
201
  const response = await this._makeRequest("GET", "/v1/collections", void 0, params);
185
- let clusters;
202
+ let collections;
186
203
  if (response.results) {
187
- clusters = response.results;
204
+ collections = response.results;
188
205
  } else if (Array.isArray(response)) {
189
- clusters = response;
206
+ collections = response;
190
207
  } else {
191
- clusters = [response];
208
+ collections = [response];
192
209
  }
193
- return clusters.map((cluster) => this._clusterFromDict(cluster));
210
+ return collections.map((collection) => this._collectionFromDict(collection));
194
211
  }
195
212
  // Conversations Methods
196
- /** List conversations for the authenticated user */
213
+ /**
214
+ * List conversations for the authenticated user with optional metadata filtering
215
+ *
216
+ * @param options - Configuration for listing conversations
217
+ * @param options.limit - Maximum number of conversations to return (default: 100)
218
+ * @param options.offset - Number of conversations to skip for pagination (default: 0)
219
+ * @param options.collection_ids - Optional list of collection IDs to filter conversations by
220
+ * @param options.metadata_filters - Optional metadata filters using MongoDB-like operators.
221
+ * Supported operators: $eq, $ne, $in, $nin, $exists, $and, $or
222
+ *
223
+ * @returns Promise resolving to array of conversation objects with fields: id, created_at, user_id, name, collection_ids
224
+ *
225
+ * @example
226
+ * // Get all playground conversations
227
+ * const conversations = await client.listConversations({
228
+ * collection_ids: ['collection-id'],
229
+ * metadata_filters: {
230
+ * 'metadata.playground': { $eq: true }
231
+ * }
232
+ * });
233
+ *
234
+ * @example
235
+ * // Filter by session ID
236
+ * const conversations = await client.listConversations({
237
+ * metadata_filters: {
238
+ * 'metadata.session_id': { $eq: 'session-123' }
239
+ * }
240
+ * });
241
+ */
197
242
  async listConversations(options) {
198
243
  const params = {
199
244
  limit: options?.limit ?? 100,
200
245
  offset: options?.offset ?? 0
201
246
  };
202
- if (options?.cluster_ids && options.cluster_ids.length > 0) {
203
- params.collection_ids = options.cluster_ids;
247
+ if (options?.collection_ids && options.collection_ids.length > 0) {
248
+ params.collection_ids = options.collection_ids;
249
+ }
250
+ if (options?.metadata_filters) {
251
+ params.metadata_filters = JSON.stringify(options.metadata_filters);
204
252
  }
205
253
  const response = await this._makeRequest("GET", "/v1/conversations", void 0, params);
206
254
  let conversations;
@@ -281,30 +329,30 @@ var NebulaClient = class {
281
329
  content: text,
282
330
  metadata: combinedMetadata,
283
331
  created_at: msgResp.created_at,
284
- cluster_ids: msgResp.collection_ids || []
332
+ collection_ids: msgResp.collection_ids || []
285
333
  };
286
334
  });
287
335
  }
288
- /** Update a cluster */
289
- async updateCluster(options) {
336
+ /** Update a collection */
337
+ async updateCollection(options) {
290
338
  const data = {};
291
339
  if (options.name !== void 0) data.name = options.name;
292
340
  if (options.description !== void 0) data.description = options.description;
293
341
  if (options.metadata !== void 0) data.metadata = options.metadata;
294
- const response = await this._makeRequest("POST", `/v1/collections/${options.clusterId}`, data);
342
+ const response = await this._makeRequest("POST", `/v1/collections/${options.collectionId}`, data);
295
343
  const result = response.results || response;
296
- return this._clusterFromDict(result);
344
+ return this._collectionFromDict(result);
297
345
  }
298
- /** Delete a cluster */
299
- async deleteCluster(clusterId) {
300
- await this._makeRequest("DELETE", `/v1/collections/${clusterId}`);
346
+ /** Delete a collection */
347
+ async deleteCollection(collectionId) {
348
+ await this._makeRequest("DELETE", `/v1/collections/${collectionId}`);
301
349
  return true;
302
350
  }
303
351
  // Memory Management Methods
304
352
  /**
305
- * Legacy convenience: store raw text content into a cluster as a document
353
+ * Legacy convenience: store raw text content into a collection as a document
306
354
  */
307
- async store(content, clusterId, metadata = {}) {
355
+ async store(content, collectionId, metadata = {}) {
308
356
  const docMetadata = {
309
357
  ...metadata,
310
358
  memory_type: "memory",
@@ -313,10 +361,10 @@ var NebulaClient = class {
313
361
  const data = {
314
362
  metadata: JSON.stringify(docMetadata),
315
363
  ingestion_mode: "fast",
316
- collection_ids: JSON.stringify([clusterId]),
364
+ collection_ids: JSON.stringify([collectionId]),
317
365
  raw_text: String(content || "")
318
366
  };
319
- const url = `${this.baseUrl}/v1/documents`;
367
+ const url = `${this.baseUrl}/v1/memories`;
320
368
  const headers = this._buildAuthHeaders(false);
321
369
  const response = await fetch(url, {
322
370
  method: "POST",
@@ -326,72 +374,117 @@ var NebulaClient = class {
326
374
  if (!response.ok) {
327
375
  const errorData = await response.json().catch(() => ({}));
328
376
  throw new NebulaException(
329
- errorData.message || `Failed to create document: ${response.status}`,
377
+ errorData.message || `Failed to create engram: ${response.status}`,
330
378
  response.status,
331
379
  errorData
332
380
  );
333
381
  }
334
382
  const respData = await response.json();
335
- const id = respData?.results?.document_id || respData?.results?.id || respData?.id || "";
383
+ const id = respData?.results?.engram_id || respData?.results?.id || respData?.id || "";
336
384
  const result = {
337
385
  id: String(id),
338
386
  content: String(content || ""),
339
387
  metadata: docMetadata,
340
- cluster_ids: [clusterId],
388
+ collection_ids: [collectionId],
341
389
  created_at: docMetadata.timestamp,
342
390
  updated_at: docMetadata.timestamp
343
391
  };
344
392
  return result;
345
393
  }
346
- /** Store a single memory */
347
- async storeMemory(memory) {
394
+ /**
395
+ * Store a single memory using the unified engrams API.
396
+ *
397
+ * Automatically infers memory type:
398
+ * - If role is present, creates a conversation
399
+ * - Otherwise, creates a document
400
+ */
401
+ async storeMemory(memory, name) {
348
402
  let mem;
349
- if ("cluster_id" in memory) {
403
+ if ("collection_id" in memory) {
350
404
  mem = memory;
351
405
  } else {
352
406
  mem = {
353
- cluster_id: memory.cluster_id,
354
- content: memory.content,
407
+ collection_id: memory.collection_id,
408
+ content: memory.content || "",
355
409
  role: memory.role,
356
- parent_id: memory.parent_id,
410
+ memory_id: memory.memory_id,
357
411
  metadata: memory.metadata || {}
358
412
  };
359
413
  }
360
- if (mem.role) {
361
- let convId = mem.parent_id;
362
- if (!convId) {
363
- const created = await this._makeRequest("POST", "/v1/conversations", {});
364
- const conv = created.results || created;
365
- convId = conv.id;
414
+ if (mem.memory_id) {
415
+ return await this._appendToMemory(mem.memory_id, mem);
416
+ }
417
+ const memoryType = mem.role ? "conversation" : "document";
418
+ if (memoryType === "conversation") {
419
+ const docMetadata2 = { ...mem.metadata };
420
+ const data2 = {
421
+ engram_type: "conversation",
422
+ name: name || "Conversation",
423
+ metadata: JSON.stringify(docMetadata2),
424
+ collection_ids: JSON.stringify([mem.collection_id])
425
+ };
426
+ const url2 = `${this.baseUrl}/v1/memories`;
427
+ const headers2 = this._buildAuthHeaders(false);
428
+ const response2 = await fetch(url2, {
429
+ method: "POST",
430
+ headers: headers2,
431
+ body: this._formDataFromObject(data2)
432
+ });
433
+ if (!response2.ok) {
434
+ const errorData = await response2.json().catch(() => ({}));
435
+ throw new NebulaException(
436
+ errorData.message || `Failed to create conversation: ${response2.status}`,
437
+ response2.status,
438
+ errorData
439
+ );
440
+ }
441
+ const respData2 = await response2.json();
442
+ if (respData2.results) {
443
+ const convId = respData2.results.engram_id || respData2.results.id;
366
444
  if (!convId) {
367
445
  throw new NebulaClientException("Failed to create conversation: no id returned");
368
446
  }
447
+ if (mem.content && mem.role) {
448
+ const appendMem = {
449
+ collection_id: mem.collection_id,
450
+ content: [
451
+ {
452
+ content: String(mem.content),
453
+ role: mem.role,
454
+ metadata: mem.metadata,
455
+ ...typeof mem.authority === "number" ? { authority: Number(mem.authority) } : {}
456
+ }
457
+ ],
458
+ memory_id: convId,
459
+ metadata: {}
460
+ };
461
+ await this._appendToMemory(convId, appendMem);
462
+ }
463
+ return String(convId);
369
464
  }
370
- const payload = {
371
- messages: [
372
- {
373
- content: String(mem.content),
374
- role: mem.role,
375
- metadata: mem.metadata
376
- }
377
- ],
378
- collection_id: mem.cluster_id
379
- };
380
- await this._makeRequest("POST", `/v1/conversations/${convId}/messages`, payload);
381
- return String(convId);
465
+ throw new NebulaClientException("Failed to create conversation: invalid response format");
382
466
  }
383
467
  const contentText = String(mem.content || "");
468
+ if (!contentText) {
469
+ throw new NebulaClientException("Content is required for document memories");
470
+ }
384
471
  const contentHash = await this._sha256(contentText);
385
472
  const docMetadata = { ...mem.metadata };
386
473
  docMetadata.memory_type = "memory";
387
474
  docMetadata.content_hash = contentHash;
475
+ if (typeof mem.authority === "number") {
476
+ const v = Number(mem.authority);
477
+ if (!Number.isNaN(v) && v >= 0 && v <= 1) {
478
+ docMetadata.authority = v;
479
+ }
480
+ }
388
481
  const data = {
389
482
  metadata: JSON.stringify(docMetadata),
390
483
  ingestion_mode: "fast",
391
- collection_ids: JSON.stringify([mem.cluster_id]),
484
+ collection_ids: JSON.stringify([mem.collection_id]),
392
485
  raw_text: contentText
393
486
  };
394
- const url = `${this.baseUrl}/v1/documents`;
487
+ const url = `${this.baseUrl}/v1/memories`;
395
488
  const headers = this._buildAuthHeaders(false);
396
489
  const response = await fetch(url, {
397
490
  method: "POST",
@@ -401,26 +494,67 @@ var NebulaClient = class {
401
494
  if (!response.ok) {
402
495
  const errorData = await response.json().catch(() => ({}));
403
496
  throw new NebulaException(
404
- errorData.message || `Failed to create document: ${response.status}`,
497
+ errorData.message || `Failed to create engram: ${response.status}`,
405
498
  response.status,
406
499
  errorData
407
500
  );
408
501
  }
409
502
  const respData = await response.json();
410
503
  if (respData.results) {
411
- if (respData.results.document_id) return String(respData.results.document_id);
504
+ if (respData.results.engram_id) return String(respData.results.engram_id);
412
505
  if (respData.results.id) return String(respData.results.id);
413
506
  }
414
507
  return "";
415
508
  }
416
- /** Store multiple memories */
509
+ /**
510
+ * Internal method to append content to an existing engram
511
+ *
512
+ * @throws NebulaNotFoundException if engram_id doesn't exist
513
+ */
514
+ async _appendToMemory(memoryId, memory) {
515
+ const collectionId = memory.collection_id;
516
+ const content = memory.content;
517
+ const metadata = memory.metadata;
518
+ if (!collectionId) {
519
+ throw new NebulaClientException("collection_id is required");
520
+ }
521
+ const payload = {
522
+ collection_id: collectionId
523
+ };
524
+ if (Array.isArray(content)) {
525
+ if (content.length > 0 && typeof content[0] === "object" && "content" in content[0]) {
526
+ payload.messages = content;
527
+ } else {
528
+ payload.chunks = content;
529
+ }
530
+ } else if (typeof content === "string") {
531
+ payload.raw_text = content;
532
+ } else {
533
+ throw new NebulaClientException(
534
+ "content must be a string, array of strings, or array of message objects"
535
+ );
536
+ }
537
+ if (metadata) {
538
+ payload.metadata = metadata;
539
+ }
540
+ try {
541
+ await this._makeRequest("POST", `/v1/memories/${memoryId}/append`, payload);
542
+ return memoryId;
543
+ } catch (error) {
544
+ if (error instanceof NebulaException && error.statusCode === 404) {
545
+ throw new NebulaNotFoundException(memoryId, "Memory");
546
+ }
547
+ throw error;
548
+ }
549
+ }
550
+ /** Store multiple memories using the unified engrams API */
417
551
  async storeMemories(memories) {
418
552
  const results = [];
419
553
  const convGroups = {};
420
554
  const others = [];
421
555
  for (const m of memories) {
422
556
  if (m.role) {
423
- const key = m.parent_id || `__new__::${m.cluster_id}`;
557
+ const key = m.memory_id || `__new__::${m.collection_id}`;
424
558
  if (!convGroups[key]) convGroups[key] = [];
425
559
  convGroups[key].push(m);
426
560
  } else {
@@ -428,15 +562,19 @@ var NebulaClient = class {
428
562
  }
429
563
  }
430
564
  for (const [key, group] of Object.entries(convGroups)) {
431
- const clusterId = group[0].cluster_id;
565
+ const collectionId = group[0].collection_id;
432
566
  let convId;
433
567
  if (key.startsWith("__new__::")) {
434
- const created = await this._makeRequest("POST", "/v1/conversations", {});
435
- const conv = created.results || created;
436
- convId = conv.id;
437
- if (!convId) {
438
- throw new NebulaClientException("Failed to create conversation: no id returned");
439
- }
568
+ convId = await this.storeMemory(
569
+ {
570
+ collection_id: collectionId,
571
+ content: "",
572
+ role: "assistant",
573
+ // Placeholder role to infer conversation type
574
+ metadata: {}
575
+ },
576
+ "Conversation"
577
+ );
440
578
  } else {
441
579
  convId = key;
442
580
  }
@@ -445,8 +583,13 @@ var NebulaClient = class {
445
583
  role: m.role,
446
584
  metadata: m.metadata || {}
447
585
  }));
448
- const payload = { messages, collection_id: clusterId };
449
- await this._makeRequest("POST", `/v1/conversations/${convId}/messages`, payload);
586
+ const appendMem = {
587
+ collection_id: collectionId,
588
+ content: messages,
589
+ memory_id: convId,
590
+ metadata: {}
591
+ };
592
+ await this._appendToMemory(convId, appendMem);
450
593
  results.push(...Array(group.length).fill(String(convId)));
451
594
  }
452
595
  for (const m of others) {
@@ -457,33 +600,113 @@ var NebulaClient = class {
457
600
  /** Delete one or more memories */
458
601
  async delete(memoryIds) {
459
602
  try {
603
+ console.log("[SDK] delete() called with:", { memoryIds, type: typeof memoryIds, isArray: Array.isArray(memoryIds) });
460
604
  if (typeof memoryIds === "string") {
605
+ console.log("[SDK] Single deletion path for ID:", memoryIds);
461
606
  try {
462
- await this._makeRequest("DELETE", `/v1/documents/${memoryIds}`);
607
+ await this._makeRequest("DELETE", `/v1/memories/${memoryIds}`);
463
608
  return true;
464
609
  } catch {
465
610
  try {
466
- const response = await this._makeRequest("POST", "/v1/documents/delete", {
467
- ids: memoryIds
468
- });
611
+ console.log("[SDK] Falling back to POST /v1/memories/delete with single ID");
612
+ const response = await this._makeRequest("POST", "/v1/memories/delete", memoryIds);
469
613
  return typeof response === "object" && response.success !== void 0 ? response.success : true;
470
614
  } catch (error) {
471
615
  throw error;
472
616
  }
473
617
  }
474
618
  } else {
475
- const response = await this._makeRequest("POST", "/v1/documents/delete", {
476
- ids: memoryIds
477
- });
619
+ console.log("[SDK] Batch deletion path for IDs:", memoryIds);
620
+ console.log("[SDK] Sending POST request with body:", memoryIds);
621
+ const response = await this._makeRequest("POST", "/v1/memories/delete", memoryIds);
622
+ console.log("[SDK] Batch deletion response:", response);
478
623
  return response;
479
624
  }
480
625
  } catch (error) {
626
+ console.error("[SDK] Delete error:", error);
481
627
  if (error instanceof Error) {
482
628
  throw error;
483
629
  }
484
630
  throw new NebulaClientException(`Unknown error: ${String(error)}`);
485
631
  }
486
632
  }
633
+ /** Delete a specific chunk or message within a memory */
634
+ async deleteChunk(chunkId) {
635
+ try {
636
+ await this._makeRequest("DELETE", `/v1/chunks/${chunkId}`);
637
+ return true;
638
+ } catch (error) {
639
+ if (error instanceof NebulaException && error.statusCode === 404) {
640
+ throw new NebulaNotFoundException(chunkId, "Chunk");
641
+ }
642
+ throw error;
643
+ }
644
+ }
645
+ /** Update a specific chunk or message within a memory */
646
+ async updateChunk(chunkId, content, metadata) {
647
+ const payload = { content };
648
+ if (metadata !== void 0) {
649
+ payload.metadata = metadata;
650
+ }
651
+ try {
652
+ await this._makeRequest("PATCH", `/v1/chunks/${chunkId}`, payload);
653
+ return true;
654
+ } catch (error) {
655
+ if (error instanceof NebulaException && error.statusCode === 404) {
656
+ throw new NebulaNotFoundException(chunkId, "Chunk");
657
+ }
658
+ throw error;
659
+ }
660
+ }
661
+ /**
662
+ * Update memory-level properties including name, metadata, and collection associations.
663
+ *
664
+ * This method allows updating properties of an entire memory (document or conversation)
665
+ * without modifying its content. For updating individual chunks or messages within a memory,
666
+ * use updateChunk(). For updating content, use storeMemory() to append.
667
+ *
668
+ * @param options - Update configuration
669
+ * @param options.memoryId - The ID of the memory to update
670
+ * @param options.name - New name for the memory (useful for conversations and documents)
671
+ * @param options.metadata - Metadata to set. By default, replaces existing metadata.
672
+ * Set mergeMetadata=true to merge with existing metadata instead.
673
+ * @param options.collectionIds - New collection associations. Must specify at least one valid collection.
674
+ * @param options.mergeMetadata - If true, merges provided metadata with existing metadata.
675
+ * If false (default), replaces existing metadata entirely.
676
+ *
677
+ * @returns Promise resolving to true if successful
678
+ *
679
+ * @throws NebulaNotFoundException if memory_id doesn't exist
680
+ * @throws NebulaValidationException if validation fails (e.g., no fields provided)
681
+ * @throws NebulaAuthenticationException if user doesn't have permission to update this memory
682
+ */
683
+ async updateMemory(options) {
684
+ const payload = {};
685
+ if (options.name !== void 0) {
686
+ payload.name = options.name;
687
+ }
688
+ if (options.metadata !== void 0) {
689
+ payload.metadata = options.metadata;
690
+ payload.merge_metadata = options.mergeMetadata ?? false;
691
+ }
692
+ if (options.collectionIds !== void 0) {
693
+ payload.collection_ids = options.collectionIds;
694
+ }
695
+ if (Object.keys(payload).length === 0) {
696
+ throw new NebulaValidationException(
697
+ "At least one field (name, metadata, or collectionIds) must be provided to update"
698
+ );
699
+ }
700
+ try {
701
+ await this._makeRequest("PATCH", `/v1/memories/${options.memoryId}`, payload);
702
+ return true;
703
+ } catch (error) {
704
+ if (error instanceof NebulaException && error.statusCode === 404) {
705
+ throw new NebulaNotFoundException(options.memoryId, "Memory");
706
+ }
707
+ throw error;
708
+ }
709
+ }
487
710
  /** Delete a conversation and all its messages */
488
711
  async deleteConversation(conversationId) {
489
712
  try {
@@ -496,18 +719,53 @@ var NebulaClient = class {
496
719
  throw new NebulaClientException(`Unknown error: ${String(error)}`);
497
720
  }
498
721
  }
499
- /** Get all memories from specific clusters */
722
+ /**
723
+ * Get all memories from specific collections with optional metadata filtering
724
+ *
725
+ * @param options - Configuration for listing memories
726
+ * @param options.collection_ids - One or more collection IDs to retrieve memories from
727
+ * @param options.limit - Maximum number of memories to return (default: 100)
728
+ * @param options.offset - Number of memories to skip for pagination (default: 0)
729
+ * @param options.metadata_filters - Optional metadata filters using MongoDB-like operators.
730
+ * Supported operators: $eq, $ne, $in, $nin, $exists, $and, $or
731
+ *
732
+ * @returns Promise resolving to array of MemoryResponse objects
733
+ *
734
+ * @example
735
+ * // Get all playground memories excluding conversations
736
+ * const memories = await client.listMemories({
737
+ * collection_ids: ['collection-id'],
738
+ * metadata_filters: {
739
+ * 'metadata.content_type': { $ne: 'conversation' }
740
+ * }
741
+ * });
742
+ *
743
+ * @example
744
+ * // Complex filter with multiple conditions
745
+ * const memories = await client.listMemories({
746
+ * collection_ids: ['collection-id'],
747
+ * metadata_filters: {
748
+ * $and: [
749
+ * { 'metadata.playground': { $eq: true } },
750
+ * { 'metadata.session_id': { $exists: true } }
751
+ * ]
752
+ * }
753
+ * });
754
+ */
500
755
  async listMemories(options) {
501
- const ids = Array.isArray(options.cluster_ids) ? options.cluster_ids : [options.cluster_ids];
756
+ const ids = Array.isArray(options.collection_ids) ? options.collection_ids : [options.collection_ids];
502
757
  if (!ids.length) {
503
- throw new NebulaClientException("cluster_ids must be provided to list_memories().");
758
+ throw new NebulaClientException("collection_ids must be provided to list_memories().");
504
759
  }
505
760
  const params = {
506
761
  limit: options.limit ?? 100,
507
762
  offset: options.offset ?? 0,
508
763
  collection_ids: ids
509
764
  };
510
- const response = await this._makeRequest("GET", "/v1/documents", void 0, params);
765
+ if (options.metadata_filters) {
766
+ params.metadata_filters = JSON.stringify(options.metadata_filters);
767
+ }
768
+ const response = await this._makeRequest("GET", "/v1/memories", void 0, params);
511
769
  let documents;
512
770
  if (response.results) {
513
771
  documents = response.results;
@@ -518,9 +776,9 @@ var NebulaClient = class {
518
776
  }
519
777
  return documents.map((doc) => this._memoryResponseFromDict(doc, ids));
520
778
  }
521
- /** Get a specific memory by ID */
779
+ /** Get a specific memory by engram ID */
522
780
  async getMemory(memoryId) {
523
- const response = await this._makeRequest("GET", `/v1/documents/${memoryId}`);
781
+ const response = await this._makeRequest("GET", `/v1/memories/${memoryId}`);
524
782
  const content = response.text || response.content;
525
783
  const chunks = Array.isArray(response.chunks) ? response.chunks : void 0;
526
784
  const memoryData = {
@@ -534,11 +792,11 @@ var NebulaClient = class {
534
792
  }
535
793
  // Search Methods
536
794
  /**
537
- * Search within specific clusters with optional metadata filtering.
795
+ * Search within specific collections with optional metadata filtering.
538
796
  *
539
797
  * @param options - Search configuration
540
798
  * @param options.query - Search query string
541
- * @param options.cluster_ids - One or more cluster IDs to search within
799
+ * @param options.collection_ids - One or more collection IDs to search within
542
800
  * @param options.limit - Maximum number of results to return (default: 10)
543
801
  * @param options.retrieval_type - Retrieval strategy (default: ADVANCED)
544
802
  * @param options.filters - Optional filters to apply to the search. Supports comprehensive metadata filtering
@@ -551,7 +809,7 @@ var NebulaClient = class {
551
809
  * // Basic equality filter
552
810
  * await client.search({
553
811
  * query: "machine learning",
554
- * cluster_ids: ["research-cluster"],
812
+ * collection_ids: ["research-collection"],
555
813
  * filters: {
556
814
  * "metadata.category": { $eq: "research" },
557
815
  * "metadata.verified": true // Shorthand for $eq
@@ -562,7 +820,7 @@ var NebulaClient = class {
562
820
  * // Numeric comparisons
563
821
  * await client.search({
564
822
  * query: "high priority",
565
- * cluster_ids: ["tasks"],
823
+ * collection_ids: ["tasks"],
566
824
  * filters: {
567
825
  * "metadata.priority": { $gte: 8 },
568
826
  * "metadata.score": { $lt: 100 }
@@ -573,7 +831,7 @@ var NebulaClient = class {
573
831
  * // String matching
574
832
  * await client.search({
575
833
  * query: "employees",
576
- * cluster_ids: ["team"],
834
+ * collection_ids: ["team"],
577
835
  * filters: {
578
836
  * "metadata.email": { $ilike: "%@company.com" } // Case-insensitive
579
837
  * }
@@ -583,7 +841,7 @@ var NebulaClient = class {
583
841
  * // Array operations
584
842
  * await client.search({
585
843
  * query: "developers",
586
- * cluster_ids: ["team"],
844
+ * collection_ids: ["team"],
587
845
  * filters: {
588
846
  * "metadata.skills": { $overlap: ["python", "typescript"] } // Has any
589
847
  * }
@@ -593,7 +851,7 @@ var NebulaClient = class {
593
851
  * // Nested paths
594
852
  * await client.search({
595
853
  * query: "users",
596
- * cluster_ids: ["profiles"],
854
+ * collection_ids: ["profiles"],
597
855
  * filters: {
598
856
  * "metadata.user.preferences.theme": { $eq: "dark" }
599
857
  * }
@@ -603,7 +861,7 @@ var NebulaClient = class {
603
861
  * // Complex logical combinations
604
862
  * await client.search({
605
863
  * query: "candidates",
606
- * cluster_ids: ["hiring"],
864
+ * collection_ids: ["hiring"],
607
865
  * filters: {
608
866
  * $and: [
609
867
  * { "metadata.verified": true },
@@ -630,9 +888,10 @@ var NebulaClient = class {
630
888
  * https://docs.nebulacloud.app/guides/metadata-filtering
631
889
  */
632
890
  async search(options) {
633
- const clusterIds = Array.isArray(options.cluster_ids) ? options.cluster_ids : [options.cluster_ids];
634
- if (!clusterIds.length) {
635
- throw new NebulaClientException("cluster_ids must be provided to search().");
891
+ const collectionIds = Array.isArray(options.collection_ids) ? options.collection_ids : [options.collection_ids];
892
+ const validCollectionIds = collectionIds.filter((id) => id && id.trim() !== "");
893
+ if (!validCollectionIds.length) {
894
+ throw new NebulaClientException("collection_ids must be provided to search().");
636
895
  }
637
896
  const limit = options.limit ?? 10;
638
897
  const searchMode = options.search_mode ?? "super";
@@ -644,7 +903,7 @@ var NebulaClient = class {
644
903
  if (options.filters) {
645
904
  Object.assign(userFilters, options.filters);
646
905
  }
647
- userFilters.collection_ids = { $overlap: clusterIds };
906
+ userFilters.collection_ids = { $overlap: validCollectionIds };
648
907
  effectiveSettings.filters = userFilters;
649
908
  const data = {
650
909
  query: options.query,
@@ -668,23 +927,23 @@ var NebulaClient = class {
668
927
  /**
669
928
  * Legacy wrapper: store a two-message conversation turn as a document
670
929
  */
671
- async storeConversation(userMessage, assistantMessage, clusterId, sessionId) {
930
+ async storeConversation(userMessage, assistantMessage, collectionId, sessionId) {
672
931
  const content = `User: ${String(userMessage || "")}
673
932
  Assistant: ${String(assistantMessage || "")}`;
674
933
  const metadata = { session_id: sessionId, content_type: "conversation" };
675
- return this.store(content, clusterId, metadata);
934
+ return this.store(content, collectionId, metadata);
676
935
  }
677
936
  /**
678
937
  * Legacy wrapper: search conversations optionally scoped by session
679
938
  */
680
- async searchConversations(query, clusterId, sessionId, includeAllSessions = true) {
939
+ async searchConversations(query, collectionId, sessionId, includeAllSessions = true) {
681
940
  const filters = { "metadata.content_type": "conversation" };
682
941
  if (sessionId && !includeAllSessions) {
683
942
  filters["metadata.session_id"] = sessionId;
684
943
  }
685
944
  return this.search({
686
945
  query,
687
- cluster_ids: [clusterId],
946
+ collection_ids: [collectionId],
688
947
  limit: 10,
689
948
  filters
690
949
  });
@@ -694,7 +953,7 @@ Assistant: ${String(assistantMessage || "")}`;
694
953
  return this._makeRequest("GET", "/health");
695
954
  }
696
955
  // Helpers
697
- _clusterFromDict(data) {
956
+ _collectionFromDict(data) {
698
957
  let createdAt;
699
958
  if (data.created_at) {
700
959
  createdAt = typeof data.created_at === "string" ? data.created_at : data.created_at.toISOString();
@@ -703,29 +962,29 @@ Assistant: ${String(assistantMessage || "")}`;
703
962
  if (data.updated_at) {
704
963
  updatedAt = typeof data.updated_at === "string" ? data.updated_at : data.updated_at.toISOString();
705
964
  }
706
- const clusterId = String(data.id || "");
707
- const clusterName = data.name || "";
708
- const clusterDescription = data.description;
709
- const clusterOwnerId = data.owner_id ? String(data.owner_id) : void 0;
965
+ const collectionId = String(data.id || "");
966
+ const collectionName = data.name || "";
967
+ const collectionDescription = data.description;
968
+ const collectionOwnerId = data.owner_id ? String(data.owner_id) : void 0;
710
969
  const memoryCount = data.document_count || 0;
711
970
  const metadata = {
712
- graph_cluster_status: data.graph_cluster_status || "",
971
+ graph_collection_status: data.graph_collection_status || "",
713
972
  graph_sync_status: data.graph_sync_status || "",
714
973
  user_count: data.user_count || 0,
715
974
  document_count: data.document_count || 0
716
975
  };
717
976
  return {
718
- id: clusterId,
719
- name: clusterName,
720
- description: clusterDescription,
977
+ id: collectionId,
978
+ name: collectionName,
979
+ description: collectionDescription,
721
980
  metadata,
722
981
  created_at: createdAt,
723
982
  updated_at: updatedAt,
724
983
  memory_count: memoryCount,
725
- owner_id: clusterOwnerId
984
+ owner_id: collectionOwnerId
726
985
  };
727
986
  }
728
- _memoryResponseFromDict(data, clusterIds) {
987
+ _memoryResponseFromDict(data, collectionIds) {
729
988
  let createdAt;
730
989
  if (data.created_at) {
731
990
  createdAt = typeof data.created_at === "string" ? data.created_at : data.created_at.toISOString();
@@ -734,7 +993,7 @@ Assistant: ${String(assistantMessage || "")}`;
734
993
  if (data.updated_at) {
735
994
  updatedAt = typeof data.updated_at === "string" ? data.updated_at : data.updated_at.toISOString();
736
995
  }
737
- const memoryId = String(data.id || "");
996
+ const engramId = String(data.id || "");
738
997
  const content = data.content || data.text;
739
998
  let chunks;
740
999
  if (data.chunks && Array.isArray(data.chunks)) {
@@ -745,12 +1004,12 @@ Assistant: ${String(assistantMessage || "")}`;
745
1004
  }
746
1005
  }
747
1006
  const metadata = { ...data.metadata };
748
- if (data.document_id) {
749
- metadata.document_id = data.document_id;
1007
+ if (data.engram_id) {
1008
+ metadata.engram_id = data.engram_id;
750
1009
  }
751
- let finalId = memoryId;
752
- if (data.document_id && !memoryId) {
753
- finalId = data.document_id;
1010
+ let finalId = engramId;
1011
+ if (data.engram_id && !engramId) {
1012
+ finalId = data.engram_id;
754
1013
  }
755
1014
  if (data.document_metadata) {
756
1015
  Object.assign(metadata, data.document_metadata);
@@ -760,7 +1019,7 @@ Assistant: ${String(assistantMessage || "")}`;
760
1019
  content,
761
1020
  chunks,
762
1021
  metadata,
763
- cluster_ids: data.collection_ids || clusterIds,
1022
+ collection_ids: data.collection_ids || collectionIds,
764
1023
  created_at: createdAt,
765
1024
  updated_at: updatedAt
766
1025
  };
@@ -798,7 +1057,7 @@ Assistant: ${String(assistantMessage || "")}`;
798
1057
  }
799
1058
  const displayName = typeof data.display_name === "string" ? data.display_name : void 0;
800
1059
  const sourceRole = typeof data.source_role === "string" ? data.source_role : void 0;
801
- const documentId = data.document_id ? String(data.document_id) : void 0;
1060
+ const engramId = data.engram_id ? String(data.engram_id) : void 0;
802
1061
  const ownerId = data.owner_id ? String(data.owner_id) : void 0;
803
1062
  let entity;
804
1063
  let rel;
@@ -843,7 +1102,7 @@ Assistant: ${String(assistantMessage || "")}`;
843
1102
  timestamp,
844
1103
  display_name: displayName,
845
1104
  source_role: sourceRole,
846
- document_id: documentId,
1105
+ engram_id: engramId,
847
1106
  owner_id: ownerId
848
1107
  };
849
1108
  }
@@ -863,6 +1122,6 @@ Assistant: ${String(assistantMessage || "")}`;
863
1122
  }
864
1123
  };
865
1124
 
866
- export { GraphSearchResultType, NebulaAuthenticationException, NebulaClient, NebulaClientException, NebulaClusterNotFoundException, NebulaException, NebulaRateLimitException, NebulaValidationException };
1125
+ export { GraphSearchResultType, NebulaAuthenticationException, NebulaClient, NebulaClientException, NebulaCollectionNotFoundException, NebulaException, NebulaNotFoundException, NebulaRateLimitException, NebulaValidationException };
867
1126
  //# sourceMappingURL=index.mjs.map
868
1127
  //# sourceMappingURL=index.mjs.map