@ekodb/ekodb-client 0.10.0 → 0.12.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/README.md +24 -0
- package/dist/client.d.ts +151 -8
- package/dist/client.js +118 -52
- package/dist/client.test.js +151 -0
- package/dist/index.d.ts +1 -1
- package/package.json +7 -7
- package/src/client.test.ts +212 -0
- package/src/client.ts +270 -56
- package/src/index.ts +6 -0
- package/vitest.config.ts +7 -0
package/README.md
CHANGED
|
@@ -299,6 +299,28 @@ const joinResults = await client.find("users", multiQuery);
|
|
|
299
299
|
|
|
300
300
|
- `listCollections(): Promise<string[]>`
|
|
301
301
|
- `deleteCollection(collection: string): Promise<void>`
|
|
302
|
+
- `collectionExists(collection: string): Promise<boolean>` - Check if collection
|
|
303
|
+
exists
|
|
304
|
+
- `countDocuments(collection: string): Promise<number>` - Count documents in
|
|
305
|
+
collection
|
|
306
|
+
|
|
307
|
+
#### Chat Models
|
|
308
|
+
|
|
309
|
+
- `getChatModels(): Promise<Record<string, string[]>>` - Get all available chat
|
|
310
|
+
models by provider
|
|
311
|
+
- `getChatModel(provider: string): Promise<string[]>` - Get models for a
|
|
312
|
+
specific provider
|
|
313
|
+
|
|
314
|
+
#### User Functions
|
|
315
|
+
|
|
316
|
+
- `saveUserFunction(userFunction: object): Promise<string>` - Create a new user
|
|
317
|
+
function
|
|
318
|
+
- `getUserFunction(label: string): Promise<object>` - Get user function by label
|
|
319
|
+
- `listUserFunctions(tags?: string[]): Promise<object[]>` - List all user
|
|
320
|
+
functions (optionally filter by tags)
|
|
321
|
+
- `updateUserFunction(label: string, userFunction: object): Promise<void>` -
|
|
322
|
+
Update existing user function
|
|
323
|
+
- `deleteUserFunction(label: string): Promise<void>` - Delete user function
|
|
302
324
|
|
|
303
325
|
#### WebSocket
|
|
304
326
|
|
|
@@ -322,6 +344,8 @@ for complete working examples:
|
|
|
322
344
|
- `client_joins.ts` - Join operations
|
|
323
345
|
- `client_batch_operations.ts` - Batch operations
|
|
324
346
|
- `client_kv_operations.ts` - Key-value operations
|
|
347
|
+
- `client_chat_models.ts` - Chat models API
|
|
348
|
+
- `client_user_functions.ts` - User functions API
|
|
325
349
|
- And more...
|
|
326
350
|
|
|
327
351
|
## License
|
package/dist/client.d.ts
CHANGED
|
@@ -123,6 +123,18 @@ export interface ChatRequest {
|
|
|
123
123
|
system_prompt?: string;
|
|
124
124
|
bypass_ripple?: boolean;
|
|
125
125
|
}
|
|
126
|
+
export interface ToolChoice {
|
|
127
|
+
type: "auto" | "none" | "required" | "tool";
|
|
128
|
+
name?: string;
|
|
129
|
+
}
|
|
130
|
+
export interface ToolConfig {
|
|
131
|
+
enabled: boolean;
|
|
132
|
+
allowed_tools?: string[];
|
|
133
|
+
allowed_collections?: string[];
|
|
134
|
+
max_iterations?: number;
|
|
135
|
+
allow_write_operations?: boolean;
|
|
136
|
+
tool_choice?: ToolChoice;
|
|
137
|
+
}
|
|
126
138
|
export interface CreateChatSessionRequest {
|
|
127
139
|
collections: CollectionConfig[];
|
|
128
140
|
llm_provider: string;
|
|
@@ -132,11 +144,16 @@ export interface CreateChatSessionRequest {
|
|
|
132
144
|
parent_id?: string;
|
|
133
145
|
branch_point_idx?: number;
|
|
134
146
|
max_context_messages?: number;
|
|
147
|
+
max_tokens?: number;
|
|
148
|
+
temperature?: number;
|
|
149
|
+
tool_config?: ToolConfig;
|
|
135
150
|
}
|
|
136
151
|
export interface ChatMessageRequest {
|
|
137
152
|
message: string;
|
|
138
153
|
bypass_ripple?: boolean;
|
|
139
154
|
force_summarize?: boolean;
|
|
155
|
+
max_iterations?: number;
|
|
156
|
+
tool_config?: ToolConfig;
|
|
140
157
|
}
|
|
141
158
|
export interface TokenUsage {
|
|
142
159
|
prompt_tokens: number;
|
|
@@ -195,16 +212,77 @@ export interface UpdateSessionRequest {
|
|
|
195
212
|
llm_model?: string;
|
|
196
213
|
collections?: CollectionConfig[];
|
|
197
214
|
max_context_messages?: number;
|
|
215
|
+
bypass_ripple?: boolean;
|
|
216
|
+
title?: string;
|
|
217
|
+
memory?: any;
|
|
198
218
|
}
|
|
199
219
|
export declare enum MergeStrategy {
|
|
200
220
|
Chronological = "Chronological",
|
|
201
221
|
Summarized = "Summarized",
|
|
202
|
-
LatestOnly = "LatestOnly"
|
|
222
|
+
LatestOnly = "LatestOnly",
|
|
223
|
+
Interleaved = "Interleaved"
|
|
203
224
|
}
|
|
204
225
|
export interface MergeSessionsRequest {
|
|
205
226
|
source_chat_ids: string[];
|
|
206
227
|
target_chat_id: string;
|
|
207
228
|
merge_strategy: MergeStrategy;
|
|
229
|
+
bypass_ripple?: boolean;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Available chat models by provider
|
|
233
|
+
*/
|
|
234
|
+
export interface ChatModels {
|
|
235
|
+
openai: string[];
|
|
236
|
+
anthropic: string[];
|
|
237
|
+
perplexity: string[];
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Request to generate embeddings
|
|
241
|
+
*/
|
|
242
|
+
export interface EmbedRequest {
|
|
243
|
+
text?: string;
|
|
244
|
+
texts?: string[];
|
|
245
|
+
model?: string;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Response from embedding generation
|
|
249
|
+
*/
|
|
250
|
+
export interface EmbedResponse {
|
|
251
|
+
embeddings: number[][];
|
|
252
|
+
model: string;
|
|
253
|
+
dimensions: number;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* User function definition - reusable sequence of Functions that can be called by Scripts
|
|
257
|
+
*/
|
|
258
|
+
export interface UserFunction {
|
|
259
|
+
label: string;
|
|
260
|
+
name: string;
|
|
261
|
+
description?: string;
|
|
262
|
+
version?: string;
|
|
263
|
+
parameters: {
|
|
264
|
+
[key: string]: ParameterDefinition;
|
|
265
|
+
};
|
|
266
|
+
functions: FunctionStageConfig[];
|
|
267
|
+
tags?: string[];
|
|
268
|
+
id?: string;
|
|
269
|
+
created_at?: string;
|
|
270
|
+
updated_at?: string;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Parameter definition for functions
|
|
274
|
+
*/
|
|
275
|
+
export interface ParameterDefinition {
|
|
276
|
+
required: boolean;
|
|
277
|
+
default?: any;
|
|
278
|
+
description?: string;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Function stage configuration for pipelines
|
|
282
|
+
*/
|
|
283
|
+
export interface FunctionStageConfig {
|
|
284
|
+
type: string;
|
|
285
|
+
[key: string]: any;
|
|
208
286
|
}
|
|
209
287
|
export declare class EkoDBClient {
|
|
210
288
|
private baseURL;
|
|
@@ -635,6 +713,24 @@ export declare class EkoDBClient {
|
|
|
635
713
|
* Merge multiple chat sessions into one
|
|
636
714
|
*/
|
|
637
715
|
mergeChatSessions(request: MergeSessionsRequest): Promise<ChatSessionResponse>;
|
|
716
|
+
/**
|
|
717
|
+
* Get all available chat models from all providers
|
|
718
|
+
* @returns ChatModels object with models organized by provider
|
|
719
|
+
*/
|
|
720
|
+
getChatModels(): Promise<ChatModels>;
|
|
721
|
+
/**
|
|
722
|
+
* Get available models for a specific provider
|
|
723
|
+
* @param provider - Provider name (e.g., "openai", "anthropic", "perplexity")
|
|
724
|
+
* @returns Array of model names for the provider
|
|
725
|
+
*/
|
|
726
|
+
getChatModel(provider: string): Promise<string[]>;
|
|
727
|
+
/**
|
|
728
|
+
* Get a specific chat message by ID
|
|
729
|
+
* @param sessionId - Chat session ID
|
|
730
|
+
* @param messageId - Message ID
|
|
731
|
+
* @returns The chat message record
|
|
732
|
+
*/
|
|
733
|
+
getChatMessage(sessionId: string, messageId: string): Promise<Record>;
|
|
638
734
|
/**
|
|
639
735
|
* Save a new script definition
|
|
640
736
|
*/
|
|
@@ -661,18 +757,53 @@ export declare class EkoDBClient {
|
|
|
661
757
|
callScript(idOrLabel: string, params?: {
|
|
662
758
|
[key: string]: any;
|
|
663
759
|
}): Promise<FunctionResult>;
|
|
760
|
+
/**
|
|
761
|
+
* Save a new user function
|
|
762
|
+
* @param userFunction - The user function definition
|
|
763
|
+
* @returns The ID of the created user function
|
|
764
|
+
*/
|
|
765
|
+
saveUserFunction(userFunction: UserFunction): Promise<string>;
|
|
766
|
+
/**
|
|
767
|
+
* Get a user function by label
|
|
768
|
+
* @param label - The user function label
|
|
769
|
+
* @returns The user function definition
|
|
770
|
+
*/
|
|
771
|
+
getUserFunction(label: string): Promise<UserFunction>;
|
|
772
|
+
/**
|
|
773
|
+
* List all user functions, optionally filtered by tags
|
|
774
|
+
* @param tags - Optional array of tags to filter by
|
|
775
|
+
* @returns Array of user functions
|
|
776
|
+
*/
|
|
777
|
+
listUserFunctions(tags?: string[]): Promise<UserFunction[]>;
|
|
778
|
+
/**
|
|
779
|
+
* Update an existing user function by label
|
|
780
|
+
* @param label - The user function label
|
|
781
|
+
* @param userFunction - The updated user function definition
|
|
782
|
+
*/
|
|
783
|
+
updateUserFunction(label: string, userFunction: UserFunction): Promise<void>;
|
|
784
|
+
/**
|
|
785
|
+
* Delete a user function by label
|
|
786
|
+
* @param label - The user function label
|
|
787
|
+
*/
|
|
788
|
+
deleteUserFunction(label: string): Promise<void>;
|
|
789
|
+
/**
|
|
790
|
+
* Check if a collection exists
|
|
791
|
+
* @param collection - Collection name to check
|
|
792
|
+
* @returns true if the collection exists, false otherwise
|
|
793
|
+
*/
|
|
794
|
+
collectionExists(collection: string): Promise<boolean>;
|
|
795
|
+
/**
|
|
796
|
+
* Count documents in a collection
|
|
797
|
+
* @param collection - Collection name
|
|
798
|
+
* @returns Number of documents in the collection
|
|
799
|
+
*/
|
|
800
|
+
countDocuments(collection: string): Promise<number>;
|
|
664
801
|
/**
|
|
665
802
|
* Create a WebSocket client
|
|
666
803
|
*/
|
|
667
804
|
websocket(wsURL: string): WebSocketClient;
|
|
668
805
|
/**
|
|
669
|
-
* Generate embeddings for
|
|
670
|
-
*
|
|
671
|
-
* This helper simplifies embedding generation by:
|
|
672
|
-
* 1. Creating a temporary collection with the text
|
|
673
|
-
* 2. Running a Script with FindAll + Embed Functions
|
|
674
|
-
* 3. Extracting and returning the embedding vector
|
|
675
|
-
* 4. Cleaning up temporary resources
|
|
806
|
+
* Generate embeddings for a single text
|
|
676
807
|
*
|
|
677
808
|
* @param text - The text to generate embeddings for
|
|
678
809
|
* @param model - The embedding model to use (e.g., "text-embedding-3-small")
|
|
@@ -688,6 +819,18 @@ export declare class EkoDBClient {
|
|
|
688
819
|
* ```
|
|
689
820
|
*/
|
|
690
821
|
embed(text: string, model: string): Promise<number[]>;
|
|
822
|
+
/**
|
|
823
|
+
* Generate embeddings for multiple texts in a single batch request
|
|
824
|
+
*
|
|
825
|
+
* @param texts - Array of texts to generate embeddings for
|
|
826
|
+
* @param model - The embedding model to use
|
|
827
|
+
* @returns Array of embedding vectors
|
|
828
|
+
*/
|
|
829
|
+
embedBatch(texts: string[], model: string): Promise<number[][]>;
|
|
830
|
+
/**
|
|
831
|
+
* Internal: make embed API request
|
|
832
|
+
*/
|
|
833
|
+
private embedRequest;
|
|
691
834
|
/**
|
|
692
835
|
* Perform text search without embeddings
|
|
693
836
|
*
|
package/dist/client.js
CHANGED
|
@@ -66,6 +66,7 @@ var MergeStrategy;
|
|
|
66
66
|
MergeStrategy["Chronological"] = "Chronological";
|
|
67
67
|
MergeStrategy["Summarized"] = "Summarized";
|
|
68
68
|
MergeStrategy["LatestOnly"] = "LatestOnly";
|
|
69
|
+
MergeStrategy["Interleaved"] = "Interleaved";
|
|
69
70
|
})(MergeStrategy || (exports.MergeStrategy = MergeStrategy = {}));
|
|
70
71
|
class EkoDBClient {
|
|
71
72
|
constructor(config, apiKey) {
|
|
@@ -882,6 +883,30 @@ class EkoDBClient {
|
|
|
882
883
|
async mergeChatSessions(request) {
|
|
883
884
|
return this.makeRequest("POST", "/api/chat/merge", request, 0, true);
|
|
884
885
|
}
|
|
886
|
+
/**
|
|
887
|
+
* Get all available chat models from all providers
|
|
888
|
+
* @returns ChatModels object with models organized by provider
|
|
889
|
+
*/
|
|
890
|
+
async getChatModels() {
|
|
891
|
+
return this.makeRequest("GET", "/api/chat_models", undefined, 0, true);
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Get available models for a specific provider
|
|
895
|
+
* @param provider - Provider name (e.g., "openai", "anthropic", "perplexity")
|
|
896
|
+
* @returns Array of model names for the provider
|
|
897
|
+
*/
|
|
898
|
+
async getChatModel(provider) {
|
|
899
|
+
return this.makeRequest("GET", `/api/chat_models/${encodeURIComponent(provider)}`, undefined, 0, true);
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Get a specific chat message by ID
|
|
903
|
+
* @param sessionId - Chat session ID
|
|
904
|
+
* @param messageId - Message ID
|
|
905
|
+
* @returns The chat message record
|
|
906
|
+
*/
|
|
907
|
+
async getChatMessage(sessionId, messageId) {
|
|
908
|
+
return this.makeRequest("GET", `/api/chat/${sessionId}/messages/${messageId}`, undefined, 0, true);
|
|
909
|
+
}
|
|
885
910
|
// ========================================================================
|
|
886
911
|
// SCRIPTS API
|
|
887
912
|
// ========================================================================
|
|
@@ -923,6 +948,77 @@ class EkoDBClient {
|
|
|
923
948
|
async callScript(idOrLabel, params) {
|
|
924
949
|
return this.makeRequest("POST", `/api/functions/${idOrLabel}`, params || {});
|
|
925
950
|
}
|
|
951
|
+
// ========================================================================
|
|
952
|
+
// USER FUNCTIONS API
|
|
953
|
+
// ========================================================================
|
|
954
|
+
/**
|
|
955
|
+
* Save a new user function
|
|
956
|
+
* @param userFunction - The user function definition
|
|
957
|
+
* @returns The ID of the created user function
|
|
958
|
+
*/
|
|
959
|
+
async saveUserFunction(userFunction) {
|
|
960
|
+
const result = await this.makeRequest("POST", "/api/functions", userFunction, 0, true);
|
|
961
|
+
return result.id;
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Get a user function by label
|
|
965
|
+
* @param label - The user function label
|
|
966
|
+
* @returns The user function definition
|
|
967
|
+
*/
|
|
968
|
+
async getUserFunction(label) {
|
|
969
|
+
return this.makeRequest("GET", `/api/functions/${encodeURIComponent(label)}`, undefined, 0, true);
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* List all user functions, optionally filtered by tags
|
|
973
|
+
* @param tags - Optional array of tags to filter by
|
|
974
|
+
* @returns Array of user functions
|
|
975
|
+
*/
|
|
976
|
+
async listUserFunctions(tags) {
|
|
977
|
+
const params = tags ? `?tags=${tags.join(",")}` : "";
|
|
978
|
+
return this.makeRequest("GET", `/api/functions${params}`, undefined, 0, true);
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Update an existing user function by label
|
|
982
|
+
* @param label - The user function label
|
|
983
|
+
* @param userFunction - The updated user function definition
|
|
984
|
+
*/
|
|
985
|
+
async updateUserFunction(label, userFunction) {
|
|
986
|
+
await this.makeRequest("PUT", `/api/functions/${encodeURIComponent(label)}`, userFunction, 0, true);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Delete a user function by label
|
|
990
|
+
* @param label - The user function label
|
|
991
|
+
*/
|
|
992
|
+
async deleteUserFunction(label) {
|
|
993
|
+
await this.makeRequest("DELETE", `/api/functions/${encodeURIComponent(label)}`, undefined, 0, true);
|
|
994
|
+
}
|
|
995
|
+
// ========================================================================
|
|
996
|
+
// COLLECTION UTILITIES
|
|
997
|
+
// ========================================================================
|
|
998
|
+
/**
|
|
999
|
+
* Check if a collection exists
|
|
1000
|
+
* @param collection - Collection name to check
|
|
1001
|
+
* @returns true if the collection exists, false otherwise
|
|
1002
|
+
*/
|
|
1003
|
+
async collectionExists(collection) {
|
|
1004
|
+
try {
|
|
1005
|
+
const collections = await this.listCollections();
|
|
1006
|
+
return collections.includes(collection);
|
|
1007
|
+
}
|
|
1008
|
+
catch {
|
|
1009
|
+
return false;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Count documents in a collection
|
|
1014
|
+
* @param collection - Collection name
|
|
1015
|
+
* @returns Number of documents in the collection
|
|
1016
|
+
*/
|
|
1017
|
+
async countDocuments(collection) {
|
|
1018
|
+
const query = new query_builder_1.QueryBuilder().limit(100000).build();
|
|
1019
|
+
const records = await this.find(collection, query);
|
|
1020
|
+
return records.length;
|
|
1021
|
+
}
|
|
926
1022
|
/**
|
|
927
1023
|
* Create a WebSocket client
|
|
928
1024
|
*/
|
|
@@ -931,13 +1027,7 @@ class EkoDBClient {
|
|
|
931
1027
|
}
|
|
932
1028
|
// ========== RAG Helper Methods ==========
|
|
933
1029
|
/**
|
|
934
|
-
* Generate embeddings for
|
|
935
|
-
*
|
|
936
|
-
* This helper simplifies embedding generation by:
|
|
937
|
-
* 1. Creating a temporary collection with the text
|
|
938
|
-
* 2. Running a Script with FindAll + Embed Functions
|
|
939
|
-
* 3. Extracting and returning the embedding vector
|
|
940
|
-
* 4. Cleaning up temporary resources
|
|
1030
|
+
* Generate embeddings for a single text
|
|
941
1031
|
*
|
|
942
1032
|
* @param text - The text to generate embeddings for
|
|
943
1033
|
* @param model - The embedding model to use (e.g., "text-embedding-3-small")
|
|
@@ -953,52 +1043,28 @@ class EkoDBClient {
|
|
|
953
1043
|
* ```
|
|
954
1044
|
*/
|
|
955
1045
|
async embed(text, model) {
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
await this.insert(tempCollection, { text }, undefined);
|
|
960
|
-
// Create Script with FindAll + Embed Functions
|
|
961
|
-
const tempLabel = `embed_script_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
962
|
-
const script = {
|
|
963
|
-
label: tempLabel,
|
|
964
|
-
name: "Generate Embedding",
|
|
965
|
-
description: "Temporary script for embedding generation",
|
|
966
|
-
version: "1.0",
|
|
967
|
-
parameters: {},
|
|
968
|
-
functions: [
|
|
969
|
-
{
|
|
970
|
-
type: "FindAll",
|
|
971
|
-
collection: tempCollection,
|
|
972
|
-
},
|
|
973
|
-
{
|
|
974
|
-
type: "Embed",
|
|
975
|
-
input_field: "text",
|
|
976
|
-
output_field: "embedding",
|
|
977
|
-
model: model,
|
|
978
|
-
},
|
|
979
|
-
],
|
|
980
|
-
tags: [],
|
|
981
|
-
};
|
|
982
|
-
// Save and execute the script
|
|
983
|
-
const scriptId = await this.saveScript(script);
|
|
984
|
-
const result = await this.callScript(scriptId, undefined);
|
|
985
|
-
// Clean up
|
|
986
|
-
await this.deleteScript(scriptId).catch(() => { });
|
|
987
|
-
await this.deleteCollection(tempCollection).catch(() => { });
|
|
988
|
-
// Extract embedding from result
|
|
989
|
-
if (result.records && result.records.length > 0) {
|
|
990
|
-
const record = result.records[0];
|
|
991
|
-
if (record.embedding && Array.isArray(record.embedding)) {
|
|
992
|
-
return record.embedding;
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
throw new Error("Failed to extract embedding from result");
|
|
996
|
-
}
|
|
997
|
-
catch (error) {
|
|
998
|
-
// Ensure cleanup even on error
|
|
999
|
-
await this.deleteCollection(tempCollection).catch(() => { });
|
|
1000
|
-
throw error;
|
|
1046
|
+
const response = await this.embedRequest({ text, model });
|
|
1047
|
+
if (response.embeddings.length === 0) {
|
|
1048
|
+
throw new Error("No embedding returned");
|
|
1001
1049
|
}
|
|
1050
|
+
return response.embeddings[0];
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Generate embeddings for multiple texts in a single batch request
|
|
1054
|
+
*
|
|
1055
|
+
* @param texts - Array of texts to generate embeddings for
|
|
1056
|
+
* @param model - The embedding model to use
|
|
1057
|
+
* @returns Array of embedding vectors
|
|
1058
|
+
*/
|
|
1059
|
+
async embedBatch(texts, model) {
|
|
1060
|
+
const response = await this.embedRequest({ texts, model });
|
|
1061
|
+
return response.embeddings;
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* Internal: make embed API request
|
|
1065
|
+
*/
|
|
1066
|
+
async embedRequest(request) {
|
|
1067
|
+
return this.makeRequest("POST", "/api/embed", request, 0, true);
|
|
1002
1068
|
}
|
|
1003
1069
|
/**
|
|
1004
1070
|
* Perform text search without embeddings
|
package/dist/client.test.js
CHANGED
|
@@ -765,3 +765,154 @@ function mockErrorResponse(status, message) {
|
|
|
765
765
|
});
|
|
766
766
|
});
|
|
767
767
|
});
|
|
768
|
+
// ============================================================================
|
|
769
|
+
// Chat Models Tests
|
|
770
|
+
// ============================================================================
|
|
771
|
+
(0, vitest_1.describe)("EkoDBClient chat models", () => {
|
|
772
|
+
(0, vitest_1.it)("gets all chat models", async () => {
|
|
773
|
+
const client = createTestClient();
|
|
774
|
+
mockTokenResponse();
|
|
775
|
+
mockJsonResponse({
|
|
776
|
+
openai: ["gpt-4", "gpt-3.5-turbo"],
|
|
777
|
+
anthropic: ["claude-3-opus", "claude-3-sonnet"],
|
|
778
|
+
perplexity: ["llama-3.1-sonar-small"],
|
|
779
|
+
});
|
|
780
|
+
const result = await client.getChatModels();
|
|
781
|
+
(0, vitest_1.expect)(result.openai).toHaveLength(2);
|
|
782
|
+
(0, vitest_1.expect)(result.anthropic).toHaveLength(2);
|
|
783
|
+
(0, vitest_1.expect)(result.perplexity).toHaveLength(1);
|
|
784
|
+
});
|
|
785
|
+
(0, vitest_1.it)("gets models for specific provider", async () => {
|
|
786
|
+
const client = createTestClient();
|
|
787
|
+
mockTokenResponse();
|
|
788
|
+
mockJsonResponse(["gpt-4", "gpt-3.5-turbo", "gpt-4-turbo"]);
|
|
789
|
+
const result = await client.getChatModel("openai");
|
|
790
|
+
(0, vitest_1.expect)(result).toHaveLength(3);
|
|
791
|
+
(0, vitest_1.expect)(result).toContain("gpt-4");
|
|
792
|
+
});
|
|
793
|
+
(0, vitest_1.it)("gets specific chat message", async () => {
|
|
794
|
+
const client = createTestClient();
|
|
795
|
+
mockTokenResponse();
|
|
796
|
+
mockJsonResponse({
|
|
797
|
+
id: "msg_123",
|
|
798
|
+
role: "user",
|
|
799
|
+
content: "Hello there",
|
|
800
|
+
created_at: "2024-01-01T00:00:00Z",
|
|
801
|
+
});
|
|
802
|
+
const result = await client.getChatMessage("chat_123", "msg_123");
|
|
803
|
+
(0, vitest_1.expect)(result).toHaveProperty("id", "msg_123");
|
|
804
|
+
(0, vitest_1.expect)(result).toHaveProperty("content", "Hello there");
|
|
805
|
+
});
|
|
806
|
+
});
|
|
807
|
+
// ============================================================================
|
|
808
|
+
// User Functions Tests
|
|
809
|
+
// ============================================================================
|
|
810
|
+
(0, vitest_1.describe)("EkoDBClient user functions", () => {
|
|
811
|
+
(0, vitest_1.it)("saves user function", async () => {
|
|
812
|
+
const client = createTestClient();
|
|
813
|
+
mockTokenResponse();
|
|
814
|
+
mockJsonResponse({ id: "uf_123" });
|
|
815
|
+
const userFunction = {
|
|
816
|
+
label: "my_function",
|
|
817
|
+
name: "My Function",
|
|
818
|
+
parameters: {},
|
|
819
|
+
functions: [],
|
|
820
|
+
};
|
|
821
|
+
const result = await client.saveUserFunction(userFunction);
|
|
822
|
+
(0, vitest_1.expect)(result).toBe("uf_123");
|
|
823
|
+
});
|
|
824
|
+
(0, vitest_1.it)("gets user function by label", async () => {
|
|
825
|
+
const client = createTestClient();
|
|
826
|
+
mockTokenResponse();
|
|
827
|
+
mockJsonResponse({
|
|
828
|
+
label: "my_function",
|
|
829
|
+
name: "My Function",
|
|
830
|
+
parameters: {},
|
|
831
|
+
functions: [],
|
|
832
|
+
id: "uf_123",
|
|
833
|
+
});
|
|
834
|
+
const result = await client.getUserFunction("my_function");
|
|
835
|
+
(0, vitest_1.expect)(result).toHaveProperty("label", "my_function");
|
|
836
|
+
(0, vitest_1.expect)(result).toHaveProperty("id", "uf_123");
|
|
837
|
+
});
|
|
838
|
+
(0, vitest_1.it)("lists user functions", async () => {
|
|
839
|
+
const client = createTestClient();
|
|
840
|
+
mockTokenResponse();
|
|
841
|
+
mockJsonResponse([
|
|
842
|
+
{ label: "func_1", name: "Function 1" },
|
|
843
|
+
{ label: "func_2", name: "Function 2" },
|
|
844
|
+
]);
|
|
845
|
+
const result = await client.listUserFunctions();
|
|
846
|
+
(0, vitest_1.expect)(result).toHaveLength(2);
|
|
847
|
+
(0, vitest_1.expect)(result[0]).toHaveProperty("label", "func_1");
|
|
848
|
+
});
|
|
849
|
+
(0, vitest_1.it)("lists user functions filtered by tags", async () => {
|
|
850
|
+
const client = createTestClient();
|
|
851
|
+
mockTokenResponse();
|
|
852
|
+
mockJsonResponse([{ label: "func_1", name: "Function 1", tags: ["data"] }]);
|
|
853
|
+
const result = await client.listUserFunctions(["data"]);
|
|
854
|
+
(0, vitest_1.expect)(result).toHaveLength(1);
|
|
855
|
+
});
|
|
856
|
+
(0, vitest_1.it)("updates user function", async () => {
|
|
857
|
+
const client = createTestClient();
|
|
858
|
+
mockTokenResponse();
|
|
859
|
+
mockJsonResponse({ status: "updated" });
|
|
860
|
+
const userFunction = {
|
|
861
|
+
label: "my_function",
|
|
862
|
+
name: "Updated Function",
|
|
863
|
+
parameters: {},
|
|
864
|
+
functions: [],
|
|
865
|
+
};
|
|
866
|
+
await (0, vitest_1.expect)(client.updateUserFunction("my_function", userFunction)).resolves.not.toThrow();
|
|
867
|
+
});
|
|
868
|
+
(0, vitest_1.it)("deletes user function", async () => {
|
|
869
|
+
const client = createTestClient();
|
|
870
|
+
mockTokenResponse();
|
|
871
|
+
mockJsonResponse({ status: "deleted" });
|
|
872
|
+
await (0, vitest_1.expect)(client.deleteUserFunction("my_function")).resolves.not.toThrow();
|
|
873
|
+
});
|
|
874
|
+
});
|
|
875
|
+
// ============================================================================
|
|
876
|
+
// Collection Utility Tests
|
|
877
|
+
// ============================================================================
|
|
878
|
+
(0, vitest_1.describe)("EkoDBClient collection utilities", () => {
|
|
879
|
+
(0, vitest_1.it)("collectionExists returns true for existing collection", async () => {
|
|
880
|
+
const client = createTestClient();
|
|
881
|
+
mockTokenResponse();
|
|
882
|
+
mockJsonResponse({ collections: ["users", "posts", "comments"] });
|
|
883
|
+
const result = await client.collectionExists("users");
|
|
884
|
+
(0, vitest_1.expect)(result).toBe(true);
|
|
885
|
+
});
|
|
886
|
+
(0, vitest_1.it)("collectionExists returns false for non-existing collection", async () => {
|
|
887
|
+
const client = createTestClient();
|
|
888
|
+
mockTokenResponse();
|
|
889
|
+
mockJsonResponse({ collections: ["users", "posts", "comments"] });
|
|
890
|
+
const result = await client.collectionExists("nonexistent");
|
|
891
|
+
(0, vitest_1.expect)(result).toBe(false);
|
|
892
|
+
});
|
|
893
|
+
(0, vitest_1.it)("collectionExists returns false on error", async () => {
|
|
894
|
+
const client = createTestClient();
|
|
895
|
+
mockTokenResponse();
|
|
896
|
+
mockErrorResponse(500, "Server error");
|
|
897
|
+
const result = await client.collectionExists("users");
|
|
898
|
+
(0, vitest_1.expect)(result).toBe(false);
|
|
899
|
+
});
|
|
900
|
+
(0, vitest_1.it)("countDocuments returns correct count", async () => {
|
|
901
|
+
const client = createTestClient();
|
|
902
|
+
mockTokenResponse();
|
|
903
|
+
mockJsonResponse([
|
|
904
|
+
{ id: "1", name: "A" },
|
|
905
|
+
{ id: "2", name: "B" },
|
|
906
|
+
{ id: "3", name: "C" },
|
|
907
|
+
]);
|
|
908
|
+
const result = await client.countDocuments("users");
|
|
909
|
+
(0, vitest_1.expect)(result).toBe(3);
|
|
910
|
+
});
|
|
911
|
+
(0, vitest_1.it)("countDocuments returns zero for empty collection", async () => {
|
|
912
|
+
const client = createTestClient();
|
|
913
|
+
mockTokenResponse();
|
|
914
|
+
mockJsonResponse([]);
|
|
915
|
+
const result = await client.countDocuments("empty_collection");
|
|
916
|
+
(0, vitest_1.expect)(result).toBe(0);
|
|
917
|
+
});
|
|
918
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -10,4 +10,4 @@ export type { SearchQuery, SearchResult, SearchResponse } from "./search";
|
|
|
10
10
|
export type { Schema, FieldTypeSchema, IndexConfig, CollectionMetadata, } from "./schema";
|
|
11
11
|
export type { JoinConfig } from "./join";
|
|
12
12
|
export type { Script, ParameterDefinition, FunctionStageConfig, GroupFunctionConfig, SortFieldConfig, FunctionResult, FunctionStats, StageStats, } from "./functions";
|
|
13
|
-
export type { Record, Query, BatchOperationResult, ClientConfig, RateLimitInfo, CollectionConfig, ChatRequest, CreateChatSessionRequest, ChatMessageRequest, TokenUsage, ChatResponse, ChatSession, ChatSessionResponse, ListSessionsQuery, ListSessionsResponse, GetMessagesQuery, GetMessagesResponse, UpdateSessionRequest, MergeSessionsRequest, } from "./client";
|
|
13
|
+
export type { Record, Query, BatchOperationResult, ClientConfig, RateLimitInfo, CollectionConfig, ChatRequest, CreateChatSessionRequest, ChatMessageRequest, TokenUsage, ChatResponse, ChatSession, ChatSessionResponse, ListSessionsQuery, ListSessionsResponse, GetMessagesQuery, GetMessagesResponse, UpdateSessionRequest, MergeSessionsRequest, ChatModels, EmbedRequest, EmbedResponse, UserFunction, ToolChoice, ToolConfig, } from "./client";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekodb/ekodb-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Official TypeScript/JavaScript client for ekoDB",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
"author": "ekoDB",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^25.
|
|
23
|
-
"@types/ws": "^8.
|
|
24
|
-
"typescript": "^5.3
|
|
25
|
-
"vitest": "^
|
|
22
|
+
"@types/node": "^25.3.5",
|
|
23
|
+
"@types/ws": "^8.18.1",
|
|
24
|
+
"typescript": "^5.9.3",
|
|
25
|
+
"vitest": "^4.0.18"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@msgpack/msgpack": "^3.
|
|
29
|
-
"ws": "^8.
|
|
28
|
+
"@msgpack/msgpack": "^3.1.3",
|
|
29
|
+
"ws": "^8.19.0"
|
|
30
30
|
}
|
|
31
31
|
}
|
package/src/client.test.ts
CHANGED
|
@@ -1031,3 +1031,215 @@ describe("Convenience methods", () => {
|
|
|
1031
1031
|
});
|
|
1032
1032
|
});
|
|
1033
1033
|
});
|
|
1034
|
+
|
|
1035
|
+
// ============================================================================
|
|
1036
|
+
// Chat Models Tests
|
|
1037
|
+
// ============================================================================
|
|
1038
|
+
|
|
1039
|
+
describe("EkoDBClient chat models", () => {
|
|
1040
|
+
it("gets all chat models", async () => {
|
|
1041
|
+
const client = createTestClient();
|
|
1042
|
+
|
|
1043
|
+
mockTokenResponse();
|
|
1044
|
+
mockJsonResponse({
|
|
1045
|
+
openai: ["gpt-4", "gpt-3.5-turbo"],
|
|
1046
|
+
anthropic: ["claude-3-opus", "claude-3-sonnet"],
|
|
1047
|
+
perplexity: ["llama-3.1-sonar-small"],
|
|
1048
|
+
});
|
|
1049
|
+
|
|
1050
|
+
const result = await client.getChatModels();
|
|
1051
|
+
|
|
1052
|
+
expect(result.openai).toHaveLength(2);
|
|
1053
|
+
expect(result.anthropic).toHaveLength(2);
|
|
1054
|
+
expect(result.perplexity).toHaveLength(1);
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
it("gets models for specific provider", async () => {
|
|
1058
|
+
const client = createTestClient();
|
|
1059
|
+
|
|
1060
|
+
mockTokenResponse();
|
|
1061
|
+
mockJsonResponse(["gpt-4", "gpt-3.5-turbo", "gpt-4-turbo"]);
|
|
1062
|
+
|
|
1063
|
+
const result = await client.getChatModel("openai");
|
|
1064
|
+
|
|
1065
|
+
expect(result).toHaveLength(3);
|
|
1066
|
+
expect(result).toContain("gpt-4");
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
it("gets specific chat message", async () => {
|
|
1070
|
+
const client = createTestClient();
|
|
1071
|
+
|
|
1072
|
+
mockTokenResponse();
|
|
1073
|
+
mockJsonResponse({
|
|
1074
|
+
id: "msg_123",
|
|
1075
|
+
role: "user",
|
|
1076
|
+
content: "Hello there",
|
|
1077
|
+
created_at: "2024-01-01T00:00:00Z",
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
const result = await client.getChatMessage("chat_123", "msg_123");
|
|
1081
|
+
|
|
1082
|
+
expect(result).toHaveProperty("id", "msg_123");
|
|
1083
|
+
expect(result).toHaveProperty("content", "Hello there");
|
|
1084
|
+
});
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
// ============================================================================
|
|
1088
|
+
// User Functions Tests
|
|
1089
|
+
// ============================================================================
|
|
1090
|
+
|
|
1091
|
+
describe("EkoDBClient user functions", () => {
|
|
1092
|
+
it("saves user function", async () => {
|
|
1093
|
+
const client = createTestClient();
|
|
1094
|
+
|
|
1095
|
+
mockTokenResponse();
|
|
1096
|
+
mockJsonResponse({ id: "uf_123" });
|
|
1097
|
+
|
|
1098
|
+
const userFunction = {
|
|
1099
|
+
label: "my_function",
|
|
1100
|
+
name: "My Function",
|
|
1101
|
+
parameters: {},
|
|
1102
|
+
functions: [],
|
|
1103
|
+
};
|
|
1104
|
+
const result = await client.saveUserFunction(userFunction);
|
|
1105
|
+
|
|
1106
|
+
expect(result).toBe("uf_123");
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
it("gets user function by label", async () => {
|
|
1110
|
+
const client = createTestClient();
|
|
1111
|
+
|
|
1112
|
+
mockTokenResponse();
|
|
1113
|
+
mockJsonResponse({
|
|
1114
|
+
label: "my_function",
|
|
1115
|
+
name: "My Function",
|
|
1116
|
+
parameters: {},
|
|
1117
|
+
functions: [],
|
|
1118
|
+
id: "uf_123",
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
const result = await client.getUserFunction("my_function");
|
|
1122
|
+
|
|
1123
|
+
expect(result).toHaveProperty("label", "my_function");
|
|
1124
|
+
expect(result).toHaveProperty("id", "uf_123");
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
it("lists user functions", async () => {
|
|
1128
|
+
const client = createTestClient();
|
|
1129
|
+
|
|
1130
|
+
mockTokenResponse();
|
|
1131
|
+
mockJsonResponse([
|
|
1132
|
+
{ label: "func_1", name: "Function 1" },
|
|
1133
|
+
{ label: "func_2", name: "Function 2" },
|
|
1134
|
+
]);
|
|
1135
|
+
|
|
1136
|
+
const result = await client.listUserFunctions();
|
|
1137
|
+
|
|
1138
|
+
expect(result).toHaveLength(2);
|
|
1139
|
+
expect(result[0]).toHaveProperty("label", "func_1");
|
|
1140
|
+
});
|
|
1141
|
+
|
|
1142
|
+
it("lists user functions filtered by tags", async () => {
|
|
1143
|
+
const client = createTestClient();
|
|
1144
|
+
|
|
1145
|
+
mockTokenResponse();
|
|
1146
|
+
mockJsonResponse([{ label: "func_1", name: "Function 1", tags: ["data"] }]);
|
|
1147
|
+
|
|
1148
|
+
const result = await client.listUserFunctions(["data"]);
|
|
1149
|
+
|
|
1150
|
+
expect(result).toHaveLength(1);
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
it("updates user function", async () => {
|
|
1154
|
+
const client = createTestClient();
|
|
1155
|
+
|
|
1156
|
+
mockTokenResponse();
|
|
1157
|
+
mockJsonResponse({ status: "updated" });
|
|
1158
|
+
|
|
1159
|
+
const userFunction = {
|
|
1160
|
+
label: "my_function",
|
|
1161
|
+
name: "Updated Function",
|
|
1162
|
+
parameters: {},
|
|
1163
|
+
functions: [],
|
|
1164
|
+
};
|
|
1165
|
+
await expect(
|
|
1166
|
+
client.updateUserFunction("my_function", userFunction),
|
|
1167
|
+
).resolves.not.toThrow();
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1170
|
+
it("deletes user function", async () => {
|
|
1171
|
+
const client = createTestClient();
|
|
1172
|
+
|
|
1173
|
+
mockTokenResponse();
|
|
1174
|
+
mockJsonResponse({ status: "deleted" });
|
|
1175
|
+
|
|
1176
|
+
await expect(
|
|
1177
|
+
client.deleteUserFunction("my_function"),
|
|
1178
|
+
).resolves.not.toThrow();
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
// ============================================================================
|
|
1183
|
+
// Collection Utility Tests
|
|
1184
|
+
// ============================================================================
|
|
1185
|
+
|
|
1186
|
+
describe("EkoDBClient collection utilities", () => {
|
|
1187
|
+
it("collectionExists returns true for existing collection", async () => {
|
|
1188
|
+
const client = createTestClient();
|
|
1189
|
+
|
|
1190
|
+
mockTokenResponse();
|
|
1191
|
+
mockJsonResponse({ collections: ["users", "posts", "comments"] });
|
|
1192
|
+
|
|
1193
|
+
const result = await client.collectionExists("users");
|
|
1194
|
+
|
|
1195
|
+
expect(result).toBe(true);
|
|
1196
|
+
});
|
|
1197
|
+
|
|
1198
|
+
it("collectionExists returns false for non-existing collection", async () => {
|
|
1199
|
+
const client = createTestClient();
|
|
1200
|
+
|
|
1201
|
+
mockTokenResponse();
|
|
1202
|
+
mockJsonResponse({ collections: ["users", "posts", "comments"] });
|
|
1203
|
+
|
|
1204
|
+
const result = await client.collectionExists("nonexistent");
|
|
1205
|
+
|
|
1206
|
+
expect(result).toBe(false);
|
|
1207
|
+
});
|
|
1208
|
+
|
|
1209
|
+
it("collectionExists returns false on error", async () => {
|
|
1210
|
+
const client = createTestClient();
|
|
1211
|
+
|
|
1212
|
+
mockTokenResponse();
|
|
1213
|
+
mockErrorResponse(500, "Server error");
|
|
1214
|
+
|
|
1215
|
+
const result = await client.collectionExists("users");
|
|
1216
|
+
|
|
1217
|
+
expect(result).toBe(false);
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1220
|
+
it("countDocuments returns correct count", async () => {
|
|
1221
|
+
const client = createTestClient();
|
|
1222
|
+
|
|
1223
|
+
mockTokenResponse();
|
|
1224
|
+
mockJsonResponse([
|
|
1225
|
+
{ id: "1", name: "A" },
|
|
1226
|
+
{ id: "2", name: "B" },
|
|
1227
|
+
{ id: "3", name: "C" },
|
|
1228
|
+
]);
|
|
1229
|
+
|
|
1230
|
+
const result = await client.countDocuments("users");
|
|
1231
|
+
|
|
1232
|
+
expect(result).toBe(3);
|
|
1233
|
+
});
|
|
1234
|
+
|
|
1235
|
+
it("countDocuments returns zero for empty collection", async () => {
|
|
1236
|
+
const client = createTestClient();
|
|
1237
|
+
|
|
1238
|
+
mockTokenResponse();
|
|
1239
|
+
mockJsonResponse([]);
|
|
1240
|
+
|
|
1241
|
+
const result = await client.countDocuments("empty_collection");
|
|
1242
|
+
|
|
1243
|
+
expect(result).toBe(0);
|
|
1244
|
+
});
|
|
1245
|
+
});
|
package/src/client.ts
CHANGED
|
@@ -151,6 +151,20 @@ export interface ChatRequest {
|
|
|
151
151
|
bypass_ripple?: boolean;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
export interface ToolChoice {
|
|
155
|
+
type: "auto" | "none" | "required" | "tool";
|
|
156
|
+
name?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface ToolConfig {
|
|
160
|
+
enabled: boolean;
|
|
161
|
+
allowed_tools?: string[];
|
|
162
|
+
allowed_collections?: string[];
|
|
163
|
+
max_iterations?: number;
|
|
164
|
+
allow_write_operations?: boolean;
|
|
165
|
+
tool_choice?: ToolChoice;
|
|
166
|
+
}
|
|
167
|
+
|
|
154
168
|
export interface CreateChatSessionRequest {
|
|
155
169
|
collections: CollectionConfig[];
|
|
156
170
|
llm_provider: string;
|
|
@@ -160,12 +174,17 @@ export interface CreateChatSessionRequest {
|
|
|
160
174
|
parent_id?: string;
|
|
161
175
|
branch_point_idx?: number;
|
|
162
176
|
max_context_messages?: number;
|
|
177
|
+
max_tokens?: number;
|
|
178
|
+
temperature?: number;
|
|
179
|
+
tool_config?: ToolConfig;
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
export interface ChatMessageRequest {
|
|
166
183
|
message: string;
|
|
167
184
|
bypass_ripple?: boolean;
|
|
168
185
|
force_summarize?: boolean;
|
|
186
|
+
max_iterations?: number;
|
|
187
|
+
tool_config?: ToolConfig;
|
|
169
188
|
}
|
|
170
189
|
|
|
171
190
|
export interface TokenUsage {
|
|
@@ -233,18 +252,83 @@ export interface UpdateSessionRequest {
|
|
|
233
252
|
llm_model?: string;
|
|
234
253
|
collections?: CollectionConfig[];
|
|
235
254
|
max_context_messages?: number;
|
|
255
|
+
bypass_ripple?: boolean;
|
|
256
|
+
title?: string;
|
|
257
|
+
memory?: any;
|
|
236
258
|
}
|
|
237
259
|
|
|
238
260
|
export enum MergeStrategy {
|
|
239
261
|
Chronological = "Chronological",
|
|
240
262
|
Summarized = "Summarized",
|
|
241
263
|
LatestOnly = "LatestOnly",
|
|
264
|
+
Interleaved = "Interleaved",
|
|
242
265
|
}
|
|
243
266
|
|
|
244
267
|
export interface MergeSessionsRequest {
|
|
245
268
|
source_chat_ids: string[];
|
|
246
269
|
target_chat_id: string;
|
|
247
270
|
merge_strategy: MergeStrategy;
|
|
271
|
+
bypass_ripple?: boolean;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Available chat models by provider
|
|
276
|
+
*/
|
|
277
|
+
export interface ChatModels {
|
|
278
|
+
openai: string[];
|
|
279
|
+
anthropic: string[];
|
|
280
|
+
perplexity: string[];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Request to generate embeddings
|
|
285
|
+
*/
|
|
286
|
+
export interface EmbedRequest {
|
|
287
|
+
text?: string;
|
|
288
|
+
texts?: string[];
|
|
289
|
+
model?: string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Response from embedding generation
|
|
294
|
+
*/
|
|
295
|
+
export interface EmbedResponse {
|
|
296
|
+
embeddings: number[][];
|
|
297
|
+
model: string;
|
|
298
|
+
dimensions: number;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* User function definition - reusable sequence of Functions that can be called by Scripts
|
|
303
|
+
*/
|
|
304
|
+
export interface UserFunction {
|
|
305
|
+
label: string;
|
|
306
|
+
name: string;
|
|
307
|
+
description?: string;
|
|
308
|
+
version?: string;
|
|
309
|
+
parameters: { [key: string]: ParameterDefinition };
|
|
310
|
+
functions: FunctionStageConfig[];
|
|
311
|
+
tags?: string[];
|
|
312
|
+
id?: string;
|
|
313
|
+
created_at?: string;
|
|
314
|
+
updated_at?: string;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Parameter definition for functions
|
|
319
|
+
*/
|
|
320
|
+
export interface ParameterDefinition {
|
|
321
|
+
required: boolean;
|
|
322
|
+
default?: any;
|
|
323
|
+
description?: string;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Function stage configuration for pipelines
|
|
328
|
+
*/
|
|
329
|
+
export interface FunctionStageConfig {
|
|
330
|
+
type: string;
|
|
331
|
+
[key: string]: any;
|
|
248
332
|
}
|
|
249
333
|
|
|
250
334
|
export class EkoDBClient {
|
|
@@ -1462,6 +1546,51 @@ export class EkoDBClient {
|
|
|
1462
1546
|
);
|
|
1463
1547
|
}
|
|
1464
1548
|
|
|
1549
|
+
/**
|
|
1550
|
+
* Get all available chat models from all providers
|
|
1551
|
+
* @returns ChatModels object with models organized by provider
|
|
1552
|
+
*/
|
|
1553
|
+
async getChatModels(): Promise<ChatModels> {
|
|
1554
|
+
return this.makeRequest<ChatModels>(
|
|
1555
|
+
"GET",
|
|
1556
|
+
"/api/chat_models",
|
|
1557
|
+
undefined,
|
|
1558
|
+
0,
|
|
1559
|
+
true, // Force JSON for chat operations
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Get available models for a specific provider
|
|
1565
|
+
* @param provider - Provider name (e.g., "openai", "anthropic", "perplexity")
|
|
1566
|
+
* @returns Array of model names for the provider
|
|
1567
|
+
*/
|
|
1568
|
+
async getChatModel(provider: string): Promise<string[]> {
|
|
1569
|
+
return this.makeRequest<string[]>(
|
|
1570
|
+
"GET",
|
|
1571
|
+
`/api/chat_models/${encodeURIComponent(provider)}`,
|
|
1572
|
+
undefined,
|
|
1573
|
+
0,
|
|
1574
|
+
true, // Force JSON for chat operations
|
|
1575
|
+
);
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
/**
|
|
1579
|
+
* Get a specific chat message by ID
|
|
1580
|
+
* @param sessionId - Chat session ID
|
|
1581
|
+
* @param messageId - Message ID
|
|
1582
|
+
* @returns The chat message record
|
|
1583
|
+
*/
|
|
1584
|
+
async getChatMessage(sessionId: string, messageId: string): Promise<Record> {
|
|
1585
|
+
return this.makeRequest<Record>(
|
|
1586
|
+
"GET",
|
|
1587
|
+
`/api/chat/${sessionId}/messages/${messageId}`,
|
|
1588
|
+
undefined,
|
|
1589
|
+
0,
|
|
1590
|
+
true, // Force JSON for chat operations
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1465
1594
|
// ========================================================================
|
|
1466
1595
|
// SCRIPTS API
|
|
1467
1596
|
// ========================================================================
|
|
@@ -1521,6 +1650,118 @@ export class EkoDBClient {
|
|
|
1521
1650
|
);
|
|
1522
1651
|
}
|
|
1523
1652
|
|
|
1653
|
+
// ========================================================================
|
|
1654
|
+
// USER FUNCTIONS API
|
|
1655
|
+
// ========================================================================
|
|
1656
|
+
|
|
1657
|
+
/**
|
|
1658
|
+
* Save a new user function
|
|
1659
|
+
* @param userFunction - The user function definition
|
|
1660
|
+
* @returns The ID of the created user function
|
|
1661
|
+
*/
|
|
1662
|
+
async saveUserFunction(userFunction: UserFunction): Promise<string> {
|
|
1663
|
+
const result = await this.makeRequest<{ id: string }>(
|
|
1664
|
+
"POST",
|
|
1665
|
+
"/api/functions",
|
|
1666
|
+
userFunction,
|
|
1667
|
+
0,
|
|
1668
|
+
true, // Force JSON
|
|
1669
|
+
);
|
|
1670
|
+
return result.id;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
/**
|
|
1674
|
+
* Get a user function by label
|
|
1675
|
+
* @param label - The user function label
|
|
1676
|
+
* @returns The user function definition
|
|
1677
|
+
*/
|
|
1678
|
+
async getUserFunction(label: string): Promise<UserFunction> {
|
|
1679
|
+
return this.makeRequest<UserFunction>(
|
|
1680
|
+
"GET",
|
|
1681
|
+
`/api/functions/${encodeURIComponent(label)}`,
|
|
1682
|
+
undefined,
|
|
1683
|
+
0,
|
|
1684
|
+
true, // Force JSON
|
|
1685
|
+
);
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
/**
|
|
1689
|
+
* List all user functions, optionally filtered by tags
|
|
1690
|
+
* @param tags - Optional array of tags to filter by
|
|
1691
|
+
* @returns Array of user functions
|
|
1692
|
+
*/
|
|
1693
|
+
async listUserFunctions(tags?: string[]): Promise<UserFunction[]> {
|
|
1694
|
+
const params = tags ? `?tags=${tags.join(",")}` : "";
|
|
1695
|
+
return this.makeRequest<UserFunction[]>(
|
|
1696
|
+
"GET",
|
|
1697
|
+
`/api/functions${params}`,
|
|
1698
|
+
undefined,
|
|
1699
|
+
0,
|
|
1700
|
+
true, // Force JSON
|
|
1701
|
+
);
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Update an existing user function by label
|
|
1706
|
+
* @param label - The user function label
|
|
1707
|
+
* @param userFunction - The updated user function definition
|
|
1708
|
+
*/
|
|
1709
|
+
async updateUserFunction(
|
|
1710
|
+
label: string,
|
|
1711
|
+
userFunction: UserFunction,
|
|
1712
|
+
): Promise<void> {
|
|
1713
|
+
await this.makeRequest<void>(
|
|
1714
|
+
"PUT",
|
|
1715
|
+
`/api/functions/${encodeURIComponent(label)}`,
|
|
1716
|
+
userFunction,
|
|
1717
|
+
0,
|
|
1718
|
+
true, // Force JSON
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
/**
|
|
1723
|
+
* Delete a user function by label
|
|
1724
|
+
* @param label - The user function label
|
|
1725
|
+
*/
|
|
1726
|
+
async deleteUserFunction(label: string): Promise<void> {
|
|
1727
|
+
await this.makeRequest<void>(
|
|
1728
|
+
"DELETE",
|
|
1729
|
+
`/api/functions/${encodeURIComponent(label)}`,
|
|
1730
|
+
undefined,
|
|
1731
|
+
0,
|
|
1732
|
+
true, // Force JSON
|
|
1733
|
+
);
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
// ========================================================================
|
|
1737
|
+
// COLLECTION UTILITIES
|
|
1738
|
+
// ========================================================================
|
|
1739
|
+
|
|
1740
|
+
/**
|
|
1741
|
+
* Check if a collection exists
|
|
1742
|
+
* @param collection - Collection name to check
|
|
1743
|
+
* @returns true if the collection exists, false otherwise
|
|
1744
|
+
*/
|
|
1745
|
+
async collectionExists(collection: string): Promise<boolean> {
|
|
1746
|
+
try {
|
|
1747
|
+
const collections = await this.listCollections();
|
|
1748
|
+
return collections.includes(collection);
|
|
1749
|
+
} catch {
|
|
1750
|
+
return false;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
/**
|
|
1755
|
+
* Count documents in a collection
|
|
1756
|
+
* @param collection - Collection name
|
|
1757
|
+
* @returns Number of documents in the collection
|
|
1758
|
+
*/
|
|
1759
|
+
async countDocuments(collection: string): Promise<number> {
|
|
1760
|
+
const query = new QueryBuilder().limit(100000).build();
|
|
1761
|
+
const records = await this.find(collection, query);
|
|
1762
|
+
return records.length;
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1524
1765
|
/**
|
|
1525
1766
|
* Create a WebSocket client
|
|
1526
1767
|
*/
|
|
@@ -1531,13 +1772,7 @@ export class EkoDBClient {
|
|
|
1531
1772
|
// ========== RAG Helper Methods ==========
|
|
1532
1773
|
|
|
1533
1774
|
/**
|
|
1534
|
-
* Generate embeddings for
|
|
1535
|
-
*
|
|
1536
|
-
* This helper simplifies embedding generation by:
|
|
1537
|
-
* 1. Creating a temporary collection with the text
|
|
1538
|
-
* 2. Running a Script with FindAll + Embed Functions
|
|
1539
|
-
* 3. Extracting and returning the embedding vector
|
|
1540
|
-
* 4. Cleaning up temporary resources
|
|
1775
|
+
* Generate embeddings for a single text
|
|
1541
1776
|
*
|
|
1542
1777
|
* @param text - The text to generate embeddings for
|
|
1543
1778
|
* @param model - The embedding model to use (e.g., "text-embedding-3-small")
|
|
@@ -1553,57 +1788,36 @@ export class EkoDBClient {
|
|
|
1553
1788
|
* ```
|
|
1554
1789
|
*/
|
|
1555
1790
|
async embed(text: string, model: string): Promise<number[]> {
|
|
1556
|
-
const
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
// Create Script with FindAll + Embed Functions
|
|
1563
|
-
const tempLabel = `embed_script_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
1564
|
-
const script: Script = {
|
|
1565
|
-
label: tempLabel,
|
|
1566
|
-
name: "Generate Embedding",
|
|
1567
|
-
description: "Temporary script for embedding generation",
|
|
1568
|
-
version: "1.0",
|
|
1569
|
-
parameters: {},
|
|
1570
|
-
functions: [
|
|
1571
|
-
{
|
|
1572
|
-
type: "FindAll",
|
|
1573
|
-
collection: tempCollection,
|
|
1574
|
-
},
|
|
1575
|
-
{
|
|
1576
|
-
type: "Embed",
|
|
1577
|
-
input_field: "text",
|
|
1578
|
-
output_field: "embedding",
|
|
1579
|
-
model: model,
|
|
1580
|
-
} as any,
|
|
1581
|
-
],
|
|
1582
|
-
tags: [],
|
|
1583
|
-
};
|
|
1584
|
-
|
|
1585
|
-
// Save and execute the script
|
|
1586
|
-
const scriptId = await this.saveScript(script);
|
|
1587
|
-
const result = await this.callScript(scriptId, undefined);
|
|
1588
|
-
|
|
1589
|
-
// Clean up
|
|
1590
|
-
await this.deleteScript(scriptId).catch(() => {});
|
|
1591
|
-
await this.deleteCollection(tempCollection).catch(() => {});
|
|
1791
|
+
const response = await this.embedRequest({ text, model });
|
|
1792
|
+
if (response.embeddings.length === 0) {
|
|
1793
|
+
throw new Error("No embedding returned");
|
|
1794
|
+
}
|
|
1795
|
+
return response.embeddings[0];
|
|
1796
|
+
}
|
|
1592
1797
|
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1798
|
+
/**
|
|
1799
|
+
* Generate embeddings for multiple texts in a single batch request
|
|
1800
|
+
*
|
|
1801
|
+
* @param texts - Array of texts to generate embeddings for
|
|
1802
|
+
* @param model - The embedding model to use
|
|
1803
|
+
* @returns Array of embedding vectors
|
|
1804
|
+
*/
|
|
1805
|
+
async embedBatch(texts: string[], model: string): Promise<number[][]> {
|
|
1806
|
+
const response = await this.embedRequest({ texts, model });
|
|
1807
|
+
return response.embeddings;
|
|
1808
|
+
}
|
|
1600
1809
|
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1810
|
+
/**
|
|
1811
|
+
* Internal: make embed API request
|
|
1812
|
+
*/
|
|
1813
|
+
private async embedRequest(request: EmbedRequest): Promise<EmbedResponse> {
|
|
1814
|
+
return this.makeRequest<EmbedResponse>(
|
|
1815
|
+
"POST",
|
|
1816
|
+
"/api/embed",
|
|
1817
|
+
request,
|
|
1818
|
+
0,
|
|
1819
|
+
true, // Force JSON
|
|
1820
|
+
);
|
|
1607
1821
|
}
|
|
1608
1822
|
|
|
1609
1823
|
/**
|
package/src/index.ts
CHANGED