@ekodb/ekodb-client 0.4.0 → 0.5.0
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/client.d.ts +83 -0
- package/dist/client.js +157 -0
- package/package.json +1 -1
- package/src/client.ts +179 -0
package/dist/client.d.ts
CHANGED
|
@@ -426,6 +426,89 @@ export declare class EkoDBClient {
|
|
|
426
426
|
* Create a WebSocket client
|
|
427
427
|
*/
|
|
428
428
|
websocket(wsURL: string): WebSocketClient;
|
|
429
|
+
/**
|
|
430
|
+
* Generate embeddings for text using ekoDB's native Functions
|
|
431
|
+
*
|
|
432
|
+
* This helper simplifies embedding generation by:
|
|
433
|
+
* 1. Creating a temporary collection with the text
|
|
434
|
+
* 2. Running a Script with FindAll + Embed Functions
|
|
435
|
+
* 3. Extracting and returning the embedding vector
|
|
436
|
+
* 4. Cleaning up temporary resources
|
|
437
|
+
*
|
|
438
|
+
* @param text - The text to generate embeddings for
|
|
439
|
+
* @param model - The embedding model to use (e.g., "text-embedding-3-small")
|
|
440
|
+
* @returns Array of floats representing the embedding vector
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```typescript
|
|
444
|
+
* const embedding = await client.embed(
|
|
445
|
+
* "Hello world",
|
|
446
|
+
* "text-embedding-3-small"
|
|
447
|
+
* );
|
|
448
|
+
* console.log(`Generated ${embedding.length} dimensions`);
|
|
449
|
+
* ```
|
|
450
|
+
*/
|
|
451
|
+
embed(text: string, model: string): Promise<number[]>;
|
|
452
|
+
/**
|
|
453
|
+
* Perform text search without embeddings
|
|
454
|
+
*
|
|
455
|
+
* Simplified text search with full-text matching, fuzzy search, and stemming.
|
|
456
|
+
*
|
|
457
|
+
* @param collection - Collection name to search
|
|
458
|
+
* @param queryText - Search query text
|
|
459
|
+
* @param limit - Maximum number of results to return
|
|
460
|
+
* @returns Array of matching records
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* const results = await client.textSearch(
|
|
465
|
+
* "documents",
|
|
466
|
+
* "ownership system",
|
|
467
|
+
* 10
|
|
468
|
+
* );
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
textSearch(collection: string, queryText: string, limit: number): Promise<Record[]>;
|
|
472
|
+
/**
|
|
473
|
+
* Perform hybrid search combining text and vector search
|
|
474
|
+
*
|
|
475
|
+
* Combines semantic similarity (vector search) with keyword matching (text search)
|
|
476
|
+
* for more accurate and relevant results.
|
|
477
|
+
*
|
|
478
|
+
* @param collection - Collection name to search
|
|
479
|
+
* @param queryText - Search query text
|
|
480
|
+
* @param queryVector - Embedding vector for semantic search
|
|
481
|
+
* @param limit - Maximum number of results to return
|
|
482
|
+
* @returns Array of matching records
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* ```typescript
|
|
486
|
+
* const embedding = await client.embed(query, "text-embedding-3-small");
|
|
487
|
+
* const results = await client.hybridSearch(
|
|
488
|
+
* "documents",
|
|
489
|
+
* query,
|
|
490
|
+
* embedding,
|
|
491
|
+
* 5
|
|
492
|
+
* );
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
hybridSearch(collection: string, queryText: string, queryVector: number[], limit: number): Promise<Record[]>;
|
|
496
|
+
/**
|
|
497
|
+
* Find all records in a collection with a limit
|
|
498
|
+
*
|
|
499
|
+
* Simplified method to query all documents in a collection.
|
|
500
|
+
*
|
|
501
|
+
* @param collection - Collection name
|
|
502
|
+
* @param limit - Maximum number of records to return
|
|
503
|
+
* @returns Array of records
|
|
504
|
+
*
|
|
505
|
+
* @example
|
|
506
|
+
* ```typescript
|
|
507
|
+
* const allMessages = await client.findAll("messages", 1000);
|
|
508
|
+
* console.log(`Found ${allMessages.length} messages`);
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
findAllWithLimit(collection: string, limit: number): Promise<Record[]>;
|
|
429
512
|
}
|
|
430
513
|
/**
|
|
431
514
|
* WebSocket client for real-time queries
|
package/dist/client.js
CHANGED
|
@@ -228,6 +228,13 @@ class EkoDBClient {
|
|
|
228
228
|
}
|
|
229
229
|
throw new RateLimitError(retryAfter);
|
|
230
230
|
}
|
|
231
|
+
// Handle unauthorized (401) - try refreshing token
|
|
232
|
+
if (response.status === 401 && attempt === 0) {
|
|
233
|
+
console.log("Authentication failed, refreshing token...");
|
|
234
|
+
await this.refreshToken();
|
|
235
|
+
// Retry with new token
|
|
236
|
+
return this.makeRequest(method, path, data, attempt + 1, forceJson);
|
|
237
|
+
}
|
|
231
238
|
// Handle service unavailable (503)
|
|
232
239
|
if (response.status === 503 &&
|
|
233
240
|
this.shouldRetry &&
|
|
@@ -595,6 +602,156 @@ class EkoDBClient {
|
|
|
595
602
|
websocket(wsURL) {
|
|
596
603
|
return new WebSocketClient(wsURL, this.token);
|
|
597
604
|
}
|
|
605
|
+
// ========== RAG Helper Methods ==========
|
|
606
|
+
/**
|
|
607
|
+
* Generate embeddings for text using ekoDB's native Functions
|
|
608
|
+
*
|
|
609
|
+
* This helper simplifies embedding generation by:
|
|
610
|
+
* 1. Creating a temporary collection with the text
|
|
611
|
+
* 2. Running a Script with FindAll + Embed Functions
|
|
612
|
+
* 3. Extracting and returning the embedding vector
|
|
613
|
+
* 4. Cleaning up temporary resources
|
|
614
|
+
*
|
|
615
|
+
* @param text - The text to generate embeddings for
|
|
616
|
+
* @param model - The embedding model to use (e.g., "text-embedding-3-small")
|
|
617
|
+
* @returns Array of floats representing the embedding vector
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```typescript
|
|
621
|
+
* const embedding = await client.embed(
|
|
622
|
+
* "Hello world",
|
|
623
|
+
* "text-embedding-3-small"
|
|
624
|
+
* );
|
|
625
|
+
* console.log(`Generated ${embedding.length} dimensions`);
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
async embed(text, model) {
|
|
629
|
+
const tempCollection = `embed_temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
630
|
+
try {
|
|
631
|
+
// Insert temporary record with the text
|
|
632
|
+
await this.insert(tempCollection, { text }, undefined);
|
|
633
|
+
// Create Script with FindAll + Embed Functions
|
|
634
|
+
const tempLabel = `embed_script_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
635
|
+
const script = {
|
|
636
|
+
label: tempLabel,
|
|
637
|
+
name: "Generate Embedding",
|
|
638
|
+
description: "Temporary script for embedding generation",
|
|
639
|
+
version: "1.0",
|
|
640
|
+
parameters: {},
|
|
641
|
+
functions: [
|
|
642
|
+
{
|
|
643
|
+
type: "FindAll",
|
|
644
|
+
collection: tempCollection,
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
type: "Embed",
|
|
648
|
+
input_field: "text",
|
|
649
|
+
output_field: "embedding",
|
|
650
|
+
model: model,
|
|
651
|
+
},
|
|
652
|
+
],
|
|
653
|
+
tags: [],
|
|
654
|
+
};
|
|
655
|
+
// Save and execute the script
|
|
656
|
+
const scriptId = await this.saveScript(script);
|
|
657
|
+
const result = await this.callScript(scriptId, undefined);
|
|
658
|
+
// Clean up
|
|
659
|
+
await this.deleteScript(scriptId).catch(() => { });
|
|
660
|
+
await this.deleteCollection(tempCollection).catch(() => { });
|
|
661
|
+
// Extract embedding from result
|
|
662
|
+
if (result.records && result.records.length > 0) {
|
|
663
|
+
const record = result.records[0];
|
|
664
|
+
if (record.embedding && Array.isArray(record.embedding)) {
|
|
665
|
+
return record.embedding;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
throw new Error("Failed to extract embedding from result");
|
|
669
|
+
}
|
|
670
|
+
catch (error) {
|
|
671
|
+
// Ensure cleanup even on error
|
|
672
|
+
await this.deleteCollection(tempCollection).catch(() => { });
|
|
673
|
+
throw error;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Perform text search without embeddings
|
|
678
|
+
*
|
|
679
|
+
* Simplified text search with full-text matching, fuzzy search, and stemming.
|
|
680
|
+
*
|
|
681
|
+
* @param collection - Collection name to search
|
|
682
|
+
* @param queryText - Search query text
|
|
683
|
+
* @param limit - Maximum number of results to return
|
|
684
|
+
* @returns Array of matching records
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```typescript
|
|
688
|
+
* const results = await client.textSearch(
|
|
689
|
+
* "documents",
|
|
690
|
+
* "ownership system",
|
|
691
|
+
* 10
|
|
692
|
+
* );
|
|
693
|
+
* ```
|
|
694
|
+
*/
|
|
695
|
+
async textSearch(collection, queryText, limit) {
|
|
696
|
+
const searchQuery = {
|
|
697
|
+
query: queryText,
|
|
698
|
+
limit,
|
|
699
|
+
};
|
|
700
|
+
const response = await this.search(collection, searchQuery);
|
|
701
|
+
return response.results.map((r) => r.record);
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Perform hybrid search combining text and vector search
|
|
705
|
+
*
|
|
706
|
+
* Combines semantic similarity (vector search) with keyword matching (text search)
|
|
707
|
+
* for more accurate and relevant results.
|
|
708
|
+
*
|
|
709
|
+
* @param collection - Collection name to search
|
|
710
|
+
* @param queryText - Search query text
|
|
711
|
+
* @param queryVector - Embedding vector for semantic search
|
|
712
|
+
* @param limit - Maximum number of results to return
|
|
713
|
+
* @returns Array of matching records
|
|
714
|
+
*
|
|
715
|
+
* @example
|
|
716
|
+
* ```typescript
|
|
717
|
+
* const embedding = await client.embed(query, "text-embedding-3-small");
|
|
718
|
+
* const results = await client.hybridSearch(
|
|
719
|
+
* "documents",
|
|
720
|
+
* query,
|
|
721
|
+
* embedding,
|
|
722
|
+
* 5
|
|
723
|
+
* );
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
async hybridSearch(collection, queryText, queryVector, limit) {
|
|
727
|
+
const searchQuery = {
|
|
728
|
+
query: queryText,
|
|
729
|
+
vector: queryVector,
|
|
730
|
+
limit,
|
|
731
|
+
};
|
|
732
|
+
const response = await this.search(collection, searchQuery);
|
|
733
|
+
return response.results.map((r) => r.record);
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Find all records in a collection with a limit
|
|
737
|
+
*
|
|
738
|
+
* Simplified method to query all documents in a collection.
|
|
739
|
+
*
|
|
740
|
+
* @param collection - Collection name
|
|
741
|
+
* @param limit - Maximum number of records to return
|
|
742
|
+
* @returns Array of records
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* ```typescript
|
|
746
|
+
* const allMessages = await client.findAll("messages", 1000);
|
|
747
|
+
* console.log(`Found ${allMessages.length} messages`);
|
|
748
|
+
* ```
|
|
749
|
+
*/
|
|
750
|
+
async findAllWithLimit(collection, limit) {
|
|
751
|
+
const query = new query_builder_1.QueryBuilder().limit(limit).build();
|
|
752
|
+
const results = await this.find(collection, query);
|
|
753
|
+
return results;
|
|
754
|
+
}
|
|
598
755
|
}
|
|
599
756
|
exports.EkoDBClient = EkoDBClient;
|
|
600
757
|
/**
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -397,6 +397,14 @@ export class EkoDBClient {
|
|
|
397
397
|
throw new RateLimitError(retryAfter);
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
+
// Handle unauthorized (401) - try refreshing token
|
|
401
|
+
if (response.status === 401 && attempt === 0) {
|
|
402
|
+
console.log("Authentication failed, refreshing token...");
|
|
403
|
+
await this.refreshToken();
|
|
404
|
+
// Retry with new token
|
|
405
|
+
return this.makeRequest<T>(method, path, data, attempt + 1, forceJson);
|
|
406
|
+
}
|
|
407
|
+
|
|
400
408
|
// Handle service unavailable (503)
|
|
401
409
|
if (
|
|
402
410
|
response.status === 503 &&
|
|
@@ -1020,6 +1028,177 @@ export class EkoDBClient {
|
|
|
1020
1028
|
websocket(wsURL: string): WebSocketClient {
|
|
1021
1029
|
return new WebSocketClient(wsURL, this.token!);
|
|
1022
1030
|
}
|
|
1031
|
+
|
|
1032
|
+
// ========== RAG Helper Methods ==========
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Generate embeddings for text using ekoDB's native Functions
|
|
1036
|
+
*
|
|
1037
|
+
* This helper simplifies embedding generation by:
|
|
1038
|
+
* 1. Creating a temporary collection with the text
|
|
1039
|
+
* 2. Running a Script with FindAll + Embed Functions
|
|
1040
|
+
* 3. Extracting and returning the embedding vector
|
|
1041
|
+
* 4. Cleaning up temporary resources
|
|
1042
|
+
*
|
|
1043
|
+
* @param text - The text to generate embeddings for
|
|
1044
|
+
* @param model - The embedding model to use (e.g., "text-embedding-3-small")
|
|
1045
|
+
* @returns Array of floats representing the embedding vector
|
|
1046
|
+
*
|
|
1047
|
+
* @example
|
|
1048
|
+
* ```typescript
|
|
1049
|
+
* const embedding = await client.embed(
|
|
1050
|
+
* "Hello world",
|
|
1051
|
+
* "text-embedding-3-small"
|
|
1052
|
+
* );
|
|
1053
|
+
* console.log(`Generated ${embedding.length} dimensions`);
|
|
1054
|
+
* ```
|
|
1055
|
+
*/
|
|
1056
|
+
async embed(text: string, model: string): Promise<number[]> {
|
|
1057
|
+
const tempCollection = `embed_temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
1058
|
+
|
|
1059
|
+
try {
|
|
1060
|
+
// Insert temporary record with the text
|
|
1061
|
+
await this.insert(tempCollection, { text }, undefined);
|
|
1062
|
+
|
|
1063
|
+
// Create Script with FindAll + Embed Functions
|
|
1064
|
+
const tempLabel = `embed_script_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
1065
|
+
const script: Script = {
|
|
1066
|
+
label: tempLabel,
|
|
1067
|
+
name: "Generate Embedding",
|
|
1068
|
+
description: "Temporary script for embedding generation",
|
|
1069
|
+
version: "1.0",
|
|
1070
|
+
parameters: {},
|
|
1071
|
+
functions: [
|
|
1072
|
+
{
|
|
1073
|
+
type: "FindAll",
|
|
1074
|
+
collection: tempCollection,
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
type: "Embed",
|
|
1078
|
+
input_field: "text",
|
|
1079
|
+
output_field: "embedding",
|
|
1080
|
+
model: model,
|
|
1081
|
+
} as any,
|
|
1082
|
+
],
|
|
1083
|
+
tags: [],
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
// Save and execute the script
|
|
1087
|
+
const scriptId = await this.saveScript(script);
|
|
1088
|
+
const result = await this.callScript(scriptId, undefined);
|
|
1089
|
+
|
|
1090
|
+
// Clean up
|
|
1091
|
+
await this.deleteScript(scriptId).catch(() => {});
|
|
1092
|
+
await this.deleteCollection(tempCollection).catch(() => {});
|
|
1093
|
+
|
|
1094
|
+
// Extract embedding from result
|
|
1095
|
+
if (result.records && result.records.length > 0) {
|
|
1096
|
+
const record = result.records[0];
|
|
1097
|
+
if (record.embedding && Array.isArray(record.embedding)) {
|
|
1098
|
+
return record.embedding as number[];
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
throw new Error("Failed to extract embedding from result");
|
|
1103
|
+
} catch (error) {
|
|
1104
|
+
// Ensure cleanup even on error
|
|
1105
|
+
await this.deleteCollection(tempCollection).catch(() => {});
|
|
1106
|
+
throw error;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Perform text search without embeddings
|
|
1112
|
+
*
|
|
1113
|
+
* Simplified text search with full-text matching, fuzzy search, and stemming.
|
|
1114
|
+
*
|
|
1115
|
+
* @param collection - Collection name to search
|
|
1116
|
+
* @param queryText - Search query text
|
|
1117
|
+
* @param limit - Maximum number of results to return
|
|
1118
|
+
* @returns Array of matching records
|
|
1119
|
+
*
|
|
1120
|
+
* @example
|
|
1121
|
+
* ```typescript
|
|
1122
|
+
* const results = await client.textSearch(
|
|
1123
|
+
* "documents",
|
|
1124
|
+
* "ownership system",
|
|
1125
|
+
* 10
|
|
1126
|
+
* );
|
|
1127
|
+
* ```
|
|
1128
|
+
*/
|
|
1129
|
+
async textSearch(
|
|
1130
|
+
collection: string,
|
|
1131
|
+
queryText: string,
|
|
1132
|
+
limit: number,
|
|
1133
|
+
): Promise<Record[]> {
|
|
1134
|
+
const searchQuery: SearchQuery = {
|
|
1135
|
+
query: queryText,
|
|
1136
|
+
limit,
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
const response = await this.search(collection, searchQuery);
|
|
1140
|
+
return response.results.map((r) => r.record);
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
/**
|
|
1144
|
+
* Perform hybrid search combining text and vector search
|
|
1145
|
+
*
|
|
1146
|
+
* Combines semantic similarity (vector search) with keyword matching (text search)
|
|
1147
|
+
* for more accurate and relevant results.
|
|
1148
|
+
*
|
|
1149
|
+
* @param collection - Collection name to search
|
|
1150
|
+
* @param queryText - Search query text
|
|
1151
|
+
* @param queryVector - Embedding vector for semantic search
|
|
1152
|
+
* @param limit - Maximum number of results to return
|
|
1153
|
+
* @returns Array of matching records
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* ```typescript
|
|
1157
|
+
* const embedding = await client.embed(query, "text-embedding-3-small");
|
|
1158
|
+
* const results = await client.hybridSearch(
|
|
1159
|
+
* "documents",
|
|
1160
|
+
* query,
|
|
1161
|
+
* embedding,
|
|
1162
|
+
* 5
|
|
1163
|
+
* );
|
|
1164
|
+
* ```
|
|
1165
|
+
*/
|
|
1166
|
+
async hybridSearch(
|
|
1167
|
+
collection: string,
|
|
1168
|
+
queryText: string,
|
|
1169
|
+
queryVector: number[],
|
|
1170
|
+
limit: number,
|
|
1171
|
+
): Promise<Record[]> {
|
|
1172
|
+
const searchQuery: SearchQuery = {
|
|
1173
|
+
query: queryText,
|
|
1174
|
+
vector: queryVector,
|
|
1175
|
+
limit,
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1178
|
+
const response = await this.search(collection, searchQuery);
|
|
1179
|
+
return response.results.map((r) => r.record);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Find all records in a collection with a limit
|
|
1184
|
+
*
|
|
1185
|
+
* Simplified method to query all documents in a collection.
|
|
1186
|
+
*
|
|
1187
|
+
* @param collection - Collection name
|
|
1188
|
+
* @param limit - Maximum number of records to return
|
|
1189
|
+
* @returns Array of records
|
|
1190
|
+
*
|
|
1191
|
+
* @example
|
|
1192
|
+
* ```typescript
|
|
1193
|
+
* const allMessages = await client.findAll("messages", 1000);
|
|
1194
|
+
* console.log(`Found ${allMessages.length} messages`);
|
|
1195
|
+
* ```
|
|
1196
|
+
*/
|
|
1197
|
+
async findAllWithLimit(collection: string, limit: number): Promise<Record[]> {
|
|
1198
|
+
const query = new QueryBuilder().limit(limit).build();
|
|
1199
|
+
const results = await this.find(collection, query);
|
|
1200
|
+
return results;
|
|
1201
|
+
}
|
|
1023
1202
|
}
|
|
1024
1203
|
|
|
1025
1204
|
/**
|