@nebula-ai/sdk 0.0.21 → 0.0.27

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
@@ -6,18 +6,6 @@ Official JavaScript/TypeScript SDK for Nebula - Memory, Search, and AI-powered c
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
8
8
 
9
- ## Features
10
-
11
- - 🚀 **Full API Parity** - Mirrors the exact Nebula Python SDK client.py implementation
12
- - 🔐 **Flexible Authentication** - Supports both API keys and Bearer tokens
13
- - 🌐 **Browser & Node.js Ready** - Works in browsers and Node.js environments
14
- - 📱 **TypeScript First** - Full type safety with comprehensive interfaces
15
- - 🎯 **Unified Memory Model** - Store text, conversations, and structured data
16
- - 🔍 **Advanced Search** - Vector search with graph results (entities, relationships, communities)
17
- - 💬 **Conversation Support** - Built-in conversation tracking and management
18
- - ⚡ **Performance Optimized** - Configurable timeouts and error handling
19
- - 🧠 **Graph Intelligence** - Leverage knowledge graphs for enhanced search
20
-
21
9
  ## Installation
22
10
 
23
11
  ```bash
@@ -41,10 +29,10 @@ const client = new NebulaClient({
41
29
  });
42
30
 
43
31
  // Create a cluster
44
- const cluster = await client.createCluster(
45
- 'My Project',
46
- 'A collection of project memories'
47
- );
32
+ const cluster = await client.createCluster({
33
+ name: 'My Project',
34
+ description: 'A collection of project memories'
35
+ });
48
36
 
49
37
  // Store a memory using the unified Memory model
50
38
  const memoryId = await client.storeMemory({
@@ -54,13 +42,13 @@ const memoryId = await client.storeMemory({
54
42
  });
55
43
 
56
44
  // Search for memories with advanced options
57
- const results = await client.search(
58
- 'project information',
59
- [cluster.id],
60
- 5,
61
- RetrievalType.ADVANCED,
62
- { 'metadata.category': 'project' }
63
- );
45
+ const results = await client.search({
46
+ query: 'project information',
47
+ cluster_ids: [cluster.id],
48
+ limit: 5,
49
+ retrieval_type: RetrievalType.ADVANCED,
50
+ filters: { 'metadata.category': 'project' }
51
+ });
64
52
 
65
53
  console.log('Found memories:', results);
66
54
  ```
@@ -84,7 +72,7 @@ new NebulaClient(config: NebulaClientConfig)
84
72
 
85
73
  ```typescript
86
74
  // Create a new cluster
87
- await client.createCluster(name: string, description?: string, metadata?: Record<string, any>)
75
+ await client.createCluster(options: { name: string, description?: string, metadata?: Record<string, any> })
88
76
 
89
77
  // Get a cluster by ID
90
78
  await client.getCluster(clusterId: string)
@@ -93,10 +81,10 @@ await client.getCluster(clusterId: string)
93
81
  await client.getClusterByName(name: string)
94
82
 
95
83
  // List all clusters
96
- await client.listClusters(limit?: number, offset?: number)
84
+ await client.listClusters(options?: { limit?: number, offset?: number })
97
85
 
98
86
  // Update a cluster
99
- await client.updateCluster(clusterId: string, name?: string, description?: string, metadata?: Record<string, any>)
87
+ await client.updateCluster(options: { clusterId: string, name?: string, description?: string, metadata?: Record<string, any> })
100
88
 
101
89
  // Delete a cluster
102
90
  await client.deleteCluster(clusterId: string)
@@ -106,7 +94,7 @@ await client.deleteCluster(clusterId: string)
106
94
 
107
95
  ```typescript
108
96
  // List conversations for the authenticated user
109
- await client.listConversations(limit?: number, offset?: number, cluster_ids?: string[])
97
+ await client.listConversations(options?: { limit?: number, offset?: number, cluster_ids?: string[] })
110
98
 
111
99
  // Get conversation messages
112
100
  await client.getConversationMessages(conversationId: string): Promise<MemoryResponse[]>
@@ -129,24 +117,28 @@ await client.storeMemories(memories: Memory[])
129
117
  await client.getMemory(memoryId: string)
130
118
 
131
119
  // List memories from clusters
132
- await client.listMemories(clusterIds: string | string[], limit?: number, offset?: number)
120
+ await client.listMemories(options: { cluster_ids: string | string[], limit?: number, offset?: number })
133
121
 
134
- // Delete a memory
135
- await client.delete(memoryId: string)
122
+ // Delete one or more memories
123
+ // Single deletion:
124
+ await client.delete('memory-id') // Returns: boolean
125
+
126
+ // Batch deletion:
127
+ await client.delete(['id1', 'id2', 'id3']) // Returns: detailed results object
136
128
  ```
137
129
 
138
130
  #### Search
139
131
 
140
132
  ```typescript
141
133
  // Search within clusters
142
- await client.search(
134
+ await client.search(options: {
143
135
  query: string,
144
- clusters: string | string[],
145
- limitOrOptions?: number | { limit?: number },
146
- retrievalType?: RetrievalType | string,
136
+ cluster_ids: string | string[],
137
+ limit?: number,
138
+ retrieval_type?: RetrievalType | string,
147
139
  filters?: Record<string, any>,
148
140
  searchSettings?: Record<string, any>
149
- )
141
+ })
150
142
  ```
151
143
 
152
144
  #### Health Check
@@ -232,22 +224,21 @@ enum RetrievalType {
232
224
  The search method supports advanced configuration:
233
225
 
234
226
  ```typescript
235
- const results = await client.search(
236
- 'query',
237
- [clusterId],
238
- 10,
239
- RetrievalType.ADVANCED,
240
- { 'metadata.category': 'science' },
241
- {
227
+ const results = await client.search({
228
+ query: 'query',
229
+ cluster_ids: [clusterId],
230
+ limit: 10,
231
+ retrieval_type: RetrievalType.ADVANCED,
232
+ filters: { 'metadata.category': 'science' },
233
+ searchSettings: {
242
234
  graph_settings: {
243
235
  enabled: true,
244
236
  bfs_enabled: true,
245
237
  bfs_max_depth: 2
246
238
  },
247
- search_strategy: 'rag_fusion',
248
239
  num_sub_queries: 3
249
240
  }
250
- );
241
+ });
251
242
  ```
252
243
 
253
244
  ### Error Handling
@@ -265,7 +256,7 @@ import {
265
256
  } from '@nebula-ai/sdk';
266
257
 
267
258
  try {
268
- await client.search('query', [clusterId]);
259
+ await client.search({ query: 'query', cluster_ids: [clusterId] });
269
260
  } catch (error) {
270
261
  if (error instanceof NebulaAuthenticationException) {
271
262
  console.log('Invalid API key');
@@ -290,10 +281,10 @@ const client = new NebulaClient({ apiKey: 'your-key' });
290
281
 
291
282
  async function manageMemories() {
292
283
  // Create a cluster
293
- const cluster = await client.createCluster(
294
- 'Knowledge Base',
295
- 'My personal knowledge repository'
296
- );
284
+ const cluster = await client.createCluster({
285
+ name: 'Knowledge Base',
286
+ description: 'My personal knowledge repository'
287
+ });
297
288
 
298
289
  // Store memories using the unified model
299
290
  const memories = [
@@ -314,8 +305,24 @@ async function manageMemories() {
314
305
  console.log('Stored memories:', memoryIds);
315
306
 
316
307
  // Search for memories
317
- const results = await client.search('JavaScript', [cluster.id]);
308
+ const results = await client.search({ query: 'JavaScript', cluster_ids: [cluster.id] });
318
309
  console.log('Search results:', results);
310
+
311
+ // Delete a single memory
312
+ const deleted = await client.delete(memoryIds[0]);
313
+ console.log('Deleted single memory:', deleted); // true
314
+
315
+ // Delete multiple memories at once
316
+ const batchResult = await client.delete([memoryIds[1], memoryIds[2]]);
317
+ console.log('Batch deletion results:', batchResult);
318
+ // {
319
+ // message: "Deleted 2 of 2 documents",
320
+ // results: {
321
+ // successful: ["id1", "id2"],
322
+ // failed: [],
323
+ // summary: { total: 2, succeeded: 2, failed: 0 }
324
+ // }
325
+ // }
319
326
  }
320
327
  ```
321
328
 
@@ -327,7 +334,10 @@ import { NebulaClient } from '@nebula-ai/sdk';
327
334
  const client = new NebulaClient({ apiKey: 'your-key' });
328
335
 
329
336
  async function trackConversation() {
330
- const cluster = await client.createCluster('Conversations', 'AI chat history');
337
+ const cluster = await client.createCluster({
338
+ name: 'Conversations',
339
+ description: 'AI chat history'
340
+ });
331
341
 
332
342
  // Store conversation turns
333
343
  const conversationMemories = [
@@ -363,7 +373,7 @@ const client = new NebulaClient({ apiKey: 'your-key' });
363
373
 
364
374
  async function manageConversations() {
365
375
  // List all conversations
366
- const conversations = await client.listConversations(10, 0);
376
+ const conversations = await client.listConversations({ limit: 10, offset: 0 });
367
377
  console.log('All conversations:', conversations);
368
378
 
369
379
  // Get messages from a specific conversation
@@ -388,7 +398,10 @@ import { NebulaClient, RetrievalType } from '@nebula-ai/sdk';
388
398
  const client = new NebulaClient({ apiKey: 'your-key' });
389
399
 
390
400
  async function advancedSearch() {
391
- const cluster = await client.createCluster('Knowledge Graph', 'Entity relationships');
401
+ const cluster = await client.createCluster({
402
+ name: 'Knowledge Graph',
403
+ description: 'Entity relationships'
404
+ });
392
405
 
393
406
  // Store knowledge graph data
394
407
  await client.storeMemory({
@@ -398,20 +411,19 @@ async function advancedSearch() {
398
411
  });
399
412
 
400
413
  // Search with graph settings
401
- const results = await client.search(
402
- 'Einstein relativity',
403
- [cluster.id],
404
- 10,
405
- RetrievalType.ADVANCED,
406
- undefined,
407
- {
414
+ const results = await client.search({
415
+ query: 'Einstein relativity',
416
+ cluster_ids: [cluster.id],
417
+ limit: 10,
418
+ retrieval_type: RetrievalType.ADVANCED,
419
+ searchSettings: {
408
420
  graph_settings: {
409
421
  enabled: true,
410
422
  bfs_enabled: true,
411
423
  bfs_max_depth: 2
412
424
  }
413
425
  }
414
- );
426
+ });
415
427
 
416
428
  // Handle both chunk and graph results
417
429
  results.forEach(result => {
package/dist/index.d.mts CHANGED
@@ -1,8 +1,3 @@
1
- declare enum RetrievalType {
2
- BASIC = "basic",
3
- ADVANCED = "advanced",
4
- CUSTOM = "custom"
5
- }
6
1
  declare enum GraphSearchResultType {
7
2
  ENTITY = "entity",
8
3
  RELATIONSHIP = "relationship",
@@ -39,6 +34,11 @@ interface SearchResult {
39
34
  score: number;
40
35
  metadata: Record<string, any>;
41
36
  source?: string;
37
+ timestamp?: string;
38
+ display_name?: string;
39
+ source_role?: string;
40
+ document_id?: string;
41
+ owner_id?: string;
42
42
  content?: string;
43
43
  graph_result_type?: GraphSearchResultType;
44
44
  graph_entity?: GraphEntityResult;
@@ -78,17 +78,17 @@ interface AgentResponse {
78
78
  interface SearchOptions {
79
79
  limit: number;
80
80
  filters?: Record<string, any>;
81
- retrieval_type: RetrievalType;
81
+ search_mode?: 'fast' | 'super';
82
82
  }
83
- interface NebulaSDKConfig {
83
+ interface NebulaClientConfig {
84
84
  apiKey: string;
85
85
  baseUrl?: string;
86
86
  timeout?: number;
87
87
  }
88
88
  declare class NebulaException extends Error {
89
89
  statusCode?: number | undefined;
90
- details?: any;
91
- constructor(message: string, statusCode?: number | undefined, details?: any);
90
+ details?: any | undefined;
91
+ constructor(message: string, statusCode?: number | undefined, details?: any | undefined);
92
92
  }
93
93
  declare class NebulaClientException extends NebulaException {
94
94
  cause?: Error | undefined;
@@ -101,122 +101,221 @@ declare class NebulaRateLimitException extends NebulaException {
101
101
  constructor(message?: string);
102
102
  }
103
103
  declare class NebulaValidationException extends NebulaException {
104
- details?: any;
105
- constructor(message?: string, details?: any);
104
+ details?: any | undefined;
105
+ constructor(message?: string, details?: any | undefined);
106
106
  }
107
107
  declare class NebulaClusterNotFoundException extends NebulaException {
108
108
  constructor(message?: string);
109
109
  }
110
110
 
111
111
  /**
112
- * Official Nebula Cloud JavaScript/TypeScript SDK
112
+ * Official Nebula JavaScript/TypeScript SDK
113
113
  * Mirrors the exact Nebula Python SDK client.py implementation
114
114
  */
115
- declare class NebulaSDK {
115
+ declare class NebulaClient {
116
116
  private apiKey;
117
117
  private baseUrl;
118
118
  private timeout;
119
- constructor(config: NebulaSDKConfig);
120
- /**
121
- * Check if API key is set
122
- */
119
+ constructor(config: NebulaClientConfig);
120
+ setApiKey(next: string): void;
121
+ setBaseUrl(next: string): void;
122
+ setCorsProxy(_next: string): void;
123
+ /** Check if API key is set */
123
124
  isApiKeySet(): boolean;
124
- /**
125
- * Detect if a token looks like a Nebula API key (public.raw)
126
- */
125
+ /** Detect if a token looks like a Nebula API key (public.raw) */
127
126
  private _isNebulaApiKey;
128
- /**
129
- * Build authentication headers
130
- */
127
+ /** Build authentication headers */
131
128
  private _buildAuthHeaders;
132
- /**
133
- * Make an HTTP request to the Nebula API
134
- */
129
+ /** Make an HTTP request to the Nebula API */
135
130
  private _makeRequest;
136
- /**
137
- * Create a new cluster
138
- */
139
- createCluster(name: string, description?: string, metadata?: Record<string, any>): Promise<Cluster>;
140
- /**
141
- * Get a specific cluster by ID
142
- */
131
+ /** Create a new cluster */
132
+ createCluster(options: {
133
+ name: string;
134
+ description?: string;
135
+ metadata?: Record<string, any>;
136
+ }): Promise<Cluster>;
137
+ /** Get a specific cluster by ID */
143
138
  getCluster(clusterId: string): Promise<Cluster>;
144
- /**
145
- * Get a specific cluster by name
146
- */
139
+ /** Get a specific cluster by name */
147
140
  getClusterByName(name: string): Promise<Cluster>;
148
- /**
149
- * Get all clusters
150
- */
151
- listClusters(limit?: number, offset?: number): Promise<Cluster[]>;
152
- /**
153
- * List conversations for the authenticated user
154
- */
155
- listConversations(limit?: number, offset?: number): Promise<any[]>;
156
- /**
157
- * Update a cluster
158
- */
159
- updateCluster(clusterId: string, name?: string, description?: string, metadata?: Record<string, any>): Promise<Cluster>;
160
- /**
161
- * Delete a cluster
162
- */
141
+ /** Get all clusters */
142
+ listClusters(options?: {
143
+ limit?: number;
144
+ offset?: number;
145
+ }): Promise<Cluster[]>;
146
+ /** List conversations for the authenticated user */
147
+ listConversations(options?: {
148
+ limit?: number;
149
+ offset?: number;
150
+ cluster_ids?: string[];
151
+ }): Promise<any[]>;
152
+ /** Get conversation messages directly from the conversations API */
153
+ getConversationMessages(conversationId: string): Promise<MemoryResponse[]>;
154
+ getConversationMessages(conversationIds: string[]): Promise<Record<string, MemoryResponse[]>>;
155
+ /** Helper method to transform conversation messages to MemoryResponse format */
156
+ private _transformConversationMessages;
157
+ /** Update a cluster */
158
+ updateCluster(options: {
159
+ clusterId: string;
160
+ name?: string;
161
+ description?: string;
162
+ metadata?: Record<string, any>;
163
+ }): Promise<Cluster>;
164
+ /** Delete a cluster */
163
165
  deleteCluster(clusterId: string): Promise<boolean>;
164
166
  /**
165
- * Store a single memory
167
+ * Legacy convenience: store raw text content into a cluster as a document
166
168
  */
169
+ store(content: string, clusterId: string, metadata?: Record<string, any>): Promise<MemoryResponse>;
170
+ /** Store a single memory */
167
171
  storeMemory(memory: Memory | Record<string, any>): Promise<string>;
168
- /**
169
- * Store multiple memories
170
- */
172
+ /** Store multiple memories */
171
173
  storeMemories(memories: Memory[]): Promise<string[]>;
172
- /**
173
- * Delete a specific memory
174
- */
175
- delete(memoryId: string): Promise<boolean>;
176
- /**
177
- * Delete a conversation and all its messages
178
- */
174
+ /** Delete one or more memories */
175
+ delete(memoryIds: string | string[]): Promise<boolean | {
176
+ message: string;
177
+ results: {
178
+ successful: string[];
179
+ failed: Array<{
180
+ id: string;
181
+ error: string;
182
+ }>;
183
+ summary: {
184
+ total: number;
185
+ succeeded: number;
186
+ failed: number;
187
+ };
188
+ };
189
+ }>;
190
+ /** Delete a conversation and all its messages */
179
191
  deleteConversation(conversationId: string): Promise<boolean>;
180
- /**
181
- * Get all memories from specific clusters
182
- */
183
- listMemories(clusterIds: string[], limit?: number, offset?: number): Promise<MemoryResponse[]>;
184
- /**
185
- * Get a specific memory by ID
186
- */
192
+ /** Get all memories from specific clusters */
193
+ listMemories(options: {
194
+ cluster_ids: string | string[];
195
+ limit?: number;
196
+ offset?: number;
197
+ }): Promise<MemoryResponse[]>;
198
+ /** Get a specific memory by ID */
187
199
  getMemory(memoryId: string): Promise<MemoryResponse>;
188
200
  /**
189
- * Search within specific clusters
201
+ * Search within specific clusters with optional metadata filtering.
202
+ *
203
+ * @param options - Search configuration
204
+ * @param options.query - Search query string
205
+ * @param options.cluster_ids - One or more cluster IDs to search within
206
+ * @param options.limit - Maximum number of results to return (default: 10)
207
+ * @param options.retrieval_type - Retrieval strategy (default: ADVANCED)
208
+ * @param options.filters - Optional filters to apply to the search. Supports comprehensive metadata filtering
209
+ * with MongoDB-like operators for both vector/chunk search and graph search.
210
+ * @param options.searchSettings - Optional search configuration
211
+ *
212
+ * @returns Promise resolving to array of SearchResult objects containing both vector/chunk and graph search results
213
+ *
214
+ * @example
215
+ * // Basic equality filter
216
+ * await client.search({
217
+ * query: "machine learning",
218
+ * cluster_ids: ["research-cluster"],
219
+ * filters: {
220
+ * "metadata.category": { $eq: "research" },
221
+ * "metadata.verified": true // Shorthand for $eq
222
+ * }
223
+ * });
224
+ *
225
+ * @example
226
+ * // Numeric comparisons
227
+ * await client.search({
228
+ * query: "high priority",
229
+ * cluster_ids: ["tasks"],
230
+ * filters: {
231
+ * "metadata.priority": { $gte: 8 },
232
+ * "metadata.score": { $lt: 100 }
233
+ * }
234
+ * });
235
+ *
236
+ * @example
237
+ * // String matching
238
+ * await client.search({
239
+ * query: "employees",
240
+ * cluster_ids: ["team"],
241
+ * filters: {
242
+ * "metadata.email": { $ilike: "%@company.com" } // Case-insensitive
243
+ * }
244
+ * });
245
+ *
246
+ * @example
247
+ * // Array operations
248
+ * await client.search({
249
+ * query: "developers",
250
+ * cluster_ids: ["team"],
251
+ * filters: {
252
+ * "metadata.skills": { $overlap: ["python", "typescript"] } // Has any
253
+ * }
254
+ * });
255
+ *
256
+ * @example
257
+ * // Nested paths
258
+ * await client.search({
259
+ * query: "users",
260
+ * cluster_ids: ["profiles"],
261
+ * filters: {
262
+ * "metadata.user.preferences.theme": { $eq: "dark" }
263
+ * }
264
+ * });
265
+ *
266
+ * @example
267
+ * // Complex logical combinations
268
+ * await client.search({
269
+ * query: "candidates",
270
+ * cluster_ids: ["hiring"],
271
+ * filters: {
272
+ * $and: [
273
+ * { "metadata.verified": true },
274
+ * { "metadata.level": { $gte: 5 } },
275
+ * {
276
+ * $or: [
277
+ * { "metadata.skills": { $overlap: ["python", "go"] } },
278
+ * { "metadata.years_experience": { $gte: 8 } }
279
+ * ]
280
+ * }
281
+ * ]
282
+ * }
283
+ * });
284
+ *
285
+ * @remarks
286
+ * Supported Operators:
287
+ * - Comparison: $eq, $ne, $lt, $lte, $gt, $gte
288
+ * - String: $like (case-sensitive), $ilike (case-insensitive)
289
+ * - Array: $in, $nin, $overlap, $contains
290
+ * - JSONB: $json_contains
291
+ * - Logical: $and, $or
292
+ *
293
+ * For comprehensive filtering documentation, see the Metadata Filtering Guide:
294
+ * https://docs.nebulacloud.app/guides/metadata-filtering
190
295
  */
191
- search(query: string, clusterIds: string[], limit?: number, retrievalType?: RetrievalType | string, filters?: Record<string, any>, searchSettings?: Record<string, any>): Promise<SearchResult[]>;
296
+ search(options: {
297
+ query: string;
298
+ cluster_ids: string | string[];
299
+ limit?: number;
300
+ filters?: Record<string, any>;
301
+ search_mode?: 'fast' | 'super';
302
+ searchSettings?: Record<string, any>;
303
+ }): Promise<SearchResult[]>;
192
304
  /**
193
- * Check the health of the Nebula API
305
+ * Legacy wrapper: store a two-message conversation turn as a document
194
306
  */
195
- healthCheck(): Promise<Record<string, any>>;
307
+ storeConversation(userMessage: string, assistantMessage: string, clusterId: string, sessionId: string): Promise<MemoryResponse>;
196
308
  /**
197
- * Convert cluster dict to Cluster object
309
+ * Legacy wrapper: search conversations optionally scoped by session
198
310
  */
311
+ searchConversations(query: string, clusterId: string, sessionId?: string, includeAllSessions?: boolean): Promise<SearchResult[]>;
312
+ healthCheck(): Promise<Record<string, any>>;
199
313
  private _clusterFromDict;
200
- /**
201
- * Convert memory dict to MemoryResponse object
202
- */
203
314
  private _memoryResponseFromDict;
204
- /**
205
- * Convert search result dict to SearchResult object
206
- */
207
315
  private _searchResultFromDict;
208
- /**
209
- * Convert graph search result dict to SearchResult object
210
- */
211
316
  private _searchResultFromGraphDict;
212
- /**
213
- * SHA-256 hash function
214
- */
215
317
  private _sha256;
216
- /**
217
- * Convert object to FormData
218
- */
219
318
  private _formDataFromObject;
220
319
  }
221
320
 
222
- export { type AgentResponse, type Cluster, type GraphCommunityResult, type GraphEntityResult, type GraphRelationshipResult, GraphSearchResultType, type Memory, type MemoryResponse, NebulaAuthenticationException, NebulaClientException, NebulaClusterNotFoundException, NebulaException, NebulaRateLimitException, NebulaSDK, type NebulaSDKConfig, NebulaValidationException, RetrievalType, type SearchOptions, type SearchResult, NebulaSDK as default };
321
+ export { type AgentResponse, type Cluster, type GraphCommunityResult, type GraphEntityResult, type GraphRelationshipResult, GraphSearchResultType, type Memory, type MemoryResponse, NebulaAuthenticationException, NebulaClient, type NebulaClientConfig, NebulaClientException, NebulaClusterNotFoundException, NebulaException, NebulaRateLimitException, NebulaValidationException, type SearchOptions, type SearchResult };