@exulu/backend 1.15.0 → 1.16.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/CHANGELOG.md +2 -2
- package/dist/index.cjs +55 -26
- package/dist/index.d.cts +13 -8
- package/dist/index.d.ts +13 -8
- package/dist/index.js +55 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# [1.
|
|
1
|
+
# [1.16.0](https://github.com/Qventu/exulu-backend/compare/v1.15.0...v1.16.0) (2025-08-23)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Features
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* add user and role to statistics ([f9c6d84](https://github.com/Qventu/exulu-backend/commit/f9c6d84a8cf4b5c32a2d5935bf9074fc6960f10b))
|
|
7
7
|
|
|
8
8
|
# [1.1.0](https://github.com/Qventu/exulu-backend/compare/v1.0.1...v1.1.0) (2025-07-30)
|
|
9
9
|
|
package/dist/index.cjs
CHANGED
|
@@ -478,7 +478,7 @@ function sanitizeToolName(name) {
|
|
|
478
478
|
}
|
|
479
479
|
return sanitized;
|
|
480
480
|
}
|
|
481
|
-
var convertToolsArrayToObject = (tools, configs, providerApiKey) => {
|
|
481
|
+
var convertToolsArrayToObject = (tools, configs, providerApiKey, user, role) => {
|
|
482
482
|
if (!tools) return {};
|
|
483
483
|
const sanitizedTools = tools ? tools.map((tool2) => ({
|
|
484
484
|
...tool2,
|
|
@@ -513,6 +513,8 @@ var convertToolsArrayToObject = (tools, configs, providerApiKey) => {
|
|
|
513
513
|
// is available, after we added the .value property
|
|
514
514
|
// by hydrating it from the variables table.
|
|
515
515
|
providerApiKey,
|
|
516
|
+
user,
|
|
517
|
+
role,
|
|
516
518
|
config: config ? config.config.reduce((acc, curr) => {
|
|
517
519
|
acc[curr.name] = curr.value;
|
|
518
520
|
return acc;
|
|
@@ -618,10 +620,12 @@ var ExuluAgent = class {
|
|
|
618
620
|
}),
|
|
619
621
|
description: `A function that calls an AI agent named: ${this.name}. The agent does the following: ${this.description}.`,
|
|
620
622
|
config: [],
|
|
621
|
-
execute: async ({ prompt, config, providerApiKey }) => {
|
|
623
|
+
execute: async ({ prompt, config, providerApiKey, user, role }) => {
|
|
622
624
|
return await this.generateSync({
|
|
623
625
|
prompt,
|
|
624
626
|
providerApiKey,
|
|
627
|
+
user,
|
|
628
|
+
role,
|
|
625
629
|
statistics: {
|
|
626
630
|
label: "",
|
|
627
631
|
trigger: "tool"
|
|
@@ -630,7 +634,7 @@ var ExuluAgent = class {
|
|
|
630
634
|
}
|
|
631
635
|
});
|
|
632
636
|
};
|
|
633
|
-
generateSync = async ({ prompt, user, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
637
|
+
generateSync = async ({ prompt, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
634
638
|
if (!this.model) {
|
|
635
639
|
throw new Error("Model is required for streaming.");
|
|
636
640
|
}
|
|
@@ -666,7 +670,7 @@ var ExuluAgent = class {
|
|
|
666
670
|
messages: messages ? (0, import_ai.convertToModelMessages)(messages) : void 0,
|
|
667
671
|
prompt,
|
|
668
672
|
maxRetries: 2,
|
|
669
|
-
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey),
|
|
673
|
+
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey, user, role),
|
|
670
674
|
stopWhen: [(0, import_ai.stepCountIs)(5)]
|
|
671
675
|
});
|
|
672
676
|
if (statistics) {
|
|
@@ -675,12 +679,14 @@ var ExuluAgent = class {
|
|
|
675
679
|
label: statistics.label,
|
|
676
680
|
type: STATISTICS_TYPE_ENUM.AGENT_RUN,
|
|
677
681
|
trigger: statistics.trigger,
|
|
678
|
-
count: 1
|
|
682
|
+
count: 1,
|
|
683
|
+
user,
|
|
684
|
+
role
|
|
679
685
|
});
|
|
680
686
|
}
|
|
681
687
|
return text;
|
|
682
688
|
};
|
|
683
|
-
generateStream = async ({ express: express3, user, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
689
|
+
generateStream = async ({ express: express3, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
684
690
|
if (!this.model) {
|
|
685
691
|
throw new Error("Model is required for streaming.");
|
|
686
692
|
}
|
|
@@ -713,7 +719,7 @@ var ExuluAgent = class {
|
|
|
713
719
|
messages: messages ? (0, import_ai.convertToModelMessages)(messages) : void 0,
|
|
714
720
|
system: "You are a helpful assistant. When you use a tool to answer a question do not explicitly comment on the result of the tool call unless the user has explicitly you to do something with the result.",
|
|
715
721
|
maxRetries: 2,
|
|
716
|
-
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey),
|
|
722
|
+
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey, user, role),
|
|
717
723
|
onError: (error) => console.error("[EXULU] chat stream error.", error),
|
|
718
724
|
stopWhen: [(0, import_ai.stepCountIs)(5)]
|
|
719
725
|
});
|
|
@@ -741,7 +747,9 @@ var ExuluAgent = class {
|
|
|
741
747
|
label: statistics.label,
|
|
742
748
|
type: STATISTICS_TYPE_ENUM.AGENT_RUN,
|
|
743
749
|
trigger: statistics.trigger,
|
|
744
|
-
count: 1
|
|
750
|
+
count: 1,
|
|
751
|
+
user,
|
|
752
|
+
role
|
|
745
753
|
});
|
|
746
754
|
}
|
|
747
755
|
}
|
|
@@ -785,14 +793,16 @@ var ExuluEmbedder = class {
|
|
|
785
793
|
this.queue = queue;
|
|
786
794
|
this.generateEmbeddings = generateEmbeddings;
|
|
787
795
|
}
|
|
788
|
-
async generateFromQuery(query, statistics) {
|
|
796
|
+
async generateFromQuery(query, statistics, user, role) {
|
|
789
797
|
if (statistics) {
|
|
790
798
|
await updateStatistic({
|
|
791
799
|
name: "count",
|
|
792
800
|
label: statistics.label,
|
|
793
801
|
type: STATISTICS_TYPE_ENUM.EMBEDDER_GENERATE,
|
|
794
802
|
trigger: statistics.trigger,
|
|
795
|
-
count: 1
|
|
803
|
+
count: 1,
|
|
804
|
+
user,
|
|
805
|
+
role
|
|
796
806
|
});
|
|
797
807
|
}
|
|
798
808
|
return await this.generateEmbeddings({
|
|
@@ -805,14 +815,16 @@ var ExuluEmbedder = class {
|
|
|
805
815
|
}]
|
|
806
816
|
});
|
|
807
817
|
}
|
|
808
|
-
async generateFromDocument(input, statistics) {
|
|
818
|
+
async generateFromDocument(input, statistics, user, role) {
|
|
809
819
|
if (statistics) {
|
|
810
820
|
await updateStatistic({
|
|
811
821
|
name: "count",
|
|
812
822
|
label: statistics.label,
|
|
813
823
|
type: STATISTICS_TYPE_ENUM.EMBEDDER_GENERATE,
|
|
814
824
|
trigger: statistics.trigger,
|
|
815
|
-
count: 1
|
|
825
|
+
count: 1,
|
|
826
|
+
user,
|
|
827
|
+
role
|
|
816
828
|
});
|
|
817
829
|
}
|
|
818
830
|
if (!this.chunker) {
|
|
@@ -1066,7 +1078,7 @@ var ExuluContext = class {
|
|
|
1066
1078
|
const tableExists = await db3.schema.hasTable(this.getTableName());
|
|
1067
1079
|
return tableExists;
|
|
1068
1080
|
};
|
|
1069
|
-
async updateItem(user, id, item) {
|
|
1081
|
+
async updateItem(user, id, item, role) {
|
|
1070
1082
|
if (!id) {
|
|
1071
1083
|
throw new Error("Id is required for updating an item.");
|
|
1072
1084
|
}
|
|
@@ -1107,7 +1119,7 @@ var ExuluContext = class {
|
|
|
1107
1119
|
}, {
|
|
1108
1120
|
label: this.name,
|
|
1109
1121
|
trigger: "agent"
|
|
1110
|
-
});
|
|
1122
|
+
}, user, role);
|
|
1111
1123
|
const exists = await db3.schema.hasTable(this.getChunksTableName());
|
|
1112
1124
|
if (!exists) {
|
|
1113
1125
|
await this.createChunksTable();
|
|
@@ -1128,7 +1140,7 @@ var ExuluContext = class {
|
|
|
1128
1140
|
job: void 0
|
|
1129
1141
|
};
|
|
1130
1142
|
}
|
|
1131
|
-
async insertItem(user, item, upsert = false) {
|
|
1143
|
+
async insertItem(user, item, upsert = false, role) {
|
|
1132
1144
|
if (!item.name) {
|
|
1133
1145
|
throw new Error("Name field is required.");
|
|
1134
1146
|
}
|
|
@@ -1139,14 +1151,14 @@ var ExuluContext = class {
|
|
|
1139
1151
|
throw new Error("Item with external id " + item.external_id + " already exists.");
|
|
1140
1152
|
}
|
|
1141
1153
|
if (existingItem && upsert) {
|
|
1142
|
-
await this.updateItem(user, existingItem.id, item);
|
|
1154
|
+
await this.updateItem(user, existingItem.id, item, role);
|
|
1143
1155
|
return existingItem.id;
|
|
1144
1156
|
}
|
|
1145
1157
|
}
|
|
1146
1158
|
if (upsert && item.id) {
|
|
1147
1159
|
const existingItem = await db3.from(this.getTableName()).where({ id: item.id }).first();
|
|
1148
1160
|
if (existingItem && upsert) {
|
|
1149
|
-
await this.updateItem(user, existingItem.id, item);
|
|
1161
|
+
await this.updateItem(user, existingItem.id, item, role);
|
|
1150
1162
|
return existingItem.id;
|
|
1151
1163
|
}
|
|
1152
1164
|
}
|
|
@@ -1190,7 +1202,7 @@ var ExuluContext = class {
|
|
|
1190
1202
|
}, {
|
|
1191
1203
|
label: this.name,
|
|
1192
1204
|
trigger: "agent"
|
|
1193
|
-
});
|
|
1205
|
+
}, user, role);
|
|
1194
1206
|
const exists = await db3.schema.hasTable(this.getChunksTableName());
|
|
1195
1207
|
if (!exists) {
|
|
1196
1208
|
await this.createChunksTable();
|
|
@@ -1218,6 +1230,8 @@ var ExuluContext = class {
|
|
|
1218
1230
|
order,
|
|
1219
1231
|
page,
|
|
1220
1232
|
name,
|
|
1233
|
+
user,
|
|
1234
|
+
role,
|
|
1221
1235
|
archived,
|
|
1222
1236
|
query,
|
|
1223
1237
|
method
|
|
@@ -1286,7 +1300,9 @@ var ExuluContext = class {
|
|
|
1286
1300
|
name: "count",
|
|
1287
1301
|
label: statistics.label,
|
|
1288
1302
|
type: STATISTICS_TYPE_ENUM.CONTEXT_RETRIEVE,
|
|
1289
|
-
trigger: statistics.trigger
|
|
1303
|
+
trigger: statistics.trigger,
|
|
1304
|
+
user,
|
|
1305
|
+
role
|
|
1290
1306
|
});
|
|
1291
1307
|
}
|
|
1292
1308
|
if (this.queryRewriter) {
|
|
@@ -1302,7 +1318,10 @@ var ExuluContext = class {
|
|
|
1302
1318
|
itemsQuery.select(chunksTable + ".chunk_index");
|
|
1303
1319
|
itemsQuery.select(chunksTable + ".created_at as chunk_created_at");
|
|
1304
1320
|
itemsQuery.select(chunksTable + ".updated_at as chunk_updated_at");
|
|
1305
|
-
const { chunks } = await this.embedder.generateFromQuery(query
|
|
1321
|
+
const { chunks } = await this.embedder.generateFromQuery(query, {
|
|
1322
|
+
label: this.name,
|
|
1323
|
+
trigger: "agent"
|
|
1324
|
+
}, user, role);
|
|
1306
1325
|
if (!chunks?.[0]?.vector) {
|
|
1307
1326
|
throw new Error("No vector generated for query.");
|
|
1308
1327
|
}
|
|
@@ -1450,11 +1469,13 @@ var ExuluContext = class {
|
|
|
1450
1469
|
}),
|
|
1451
1470
|
config: [],
|
|
1452
1471
|
description: `Gets information from the context called: ${this.name}. The context description is: ${this.description}.`,
|
|
1453
|
-
execute: async ({ query }) => {
|
|
1472
|
+
execute: async ({ query, user, role }) => {
|
|
1454
1473
|
return await this.getItems({
|
|
1455
1474
|
page: 1,
|
|
1456
1475
|
limit: 10,
|
|
1457
1476
|
query,
|
|
1477
|
+
user,
|
|
1478
|
+
role,
|
|
1458
1479
|
statistics: {
|
|
1459
1480
|
label: this.name,
|
|
1460
1481
|
trigger: "agent"
|
|
@@ -4218,7 +4239,7 @@ Mood: friendly and intelligent.
|
|
|
4218
4239
|
if (!exists) {
|
|
4219
4240
|
await context.createItemsTable();
|
|
4220
4241
|
}
|
|
4221
|
-
const result = await context.updateItem(authenticationResult.user.id, req.params.id, req.body);
|
|
4242
|
+
const result = await context.updateItem(authenticationResult.user.id, req.params.id, req.body, authenticationResult.user.role?.id);
|
|
4222
4243
|
res.status(200).json({
|
|
4223
4244
|
message: "Item updated successfully.",
|
|
4224
4245
|
id: result
|
|
@@ -4265,7 +4286,7 @@ Mood: friendly and intelligent.
|
|
|
4265
4286
|
await context.createItemsTable();
|
|
4266
4287
|
}
|
|
4267
4288
|
console.log("[EXULU] inserting item", req.body);
|
|
4268
|
-
const result = await context.insertItem(authenticationResult.user.id, req.body, !!req.body.upsert);
|
|
4289
|
+
const result = await context.insertItem(authenticationResult.user.id, req.body, !!req.body.upsert, authenticationResult.user.role?.id);
|
|
4269
4290
|
console.log("[EXULU] result", result);
|
|
4270
4291
|
res.status(200).json({
|
|
4271
4292
|
message: "Item created successfully.",
|
|
@@ -4326,6 +4347,8 @@ Mood: friendly and intelligent.
|
|
|
4326
4347
|
const result = await context.getItems({
|
|
4327
4348
|
sort,
|
|
4328
4349
|
order,
|
|
4350
|
+
user: authenticationResult.user?.id,
|
|
4351
|
+
role: authenticationResult.user?.role?.id,
|
|
4329
4352
|
page,
|
|
4330
4353
|
limit,
|
|
4331
4354
|
archived: req.query.archived === "true",
|
|
@@ -4487,6 +4510,8 @@ Mood: friendly and intelligent.
|
|
|
4487
4510
|
const items = await context.getItems({
|
|
4488
4511
|
page: 1,
|
|
4489
4512
|
// todo add pagination
|
|
4513
|
+
user: authenticationResult.user?.id,
|
|
4514
|
+
role: authenticationResult.user?.role?.id,
|
|
4490
4515
|
limit: 500
|
|
4491
4516
|
});
|
|
4492
4517
|
const csv = Papa.unparse(items);
|
|
@@ -4637,7 +4662,8 @@ Mood: friendly and intelligent.
|
|
|
4637
4662
|
res,
|
|
4638
4663
|
req
|
|
4639
4664
|
},
|
|
4640
|
-
user:
|
|
4665
|
+
user: user?.id,
|
|
4666
|
+
role: user?.role?.id,
|
|
4641
4667
|
session: headers.session,
|
|
4642
4668
|
message: req.body.message,
|
|
4643
4669
|
tools: enabledTools,
|
|
@@ -4651,8 +4677,9 @@ Mood: friendly and intelligent.
|
|
|
4651
4677
|
return;
|
|
4652
4678
|
} else {
|
|
4653
4679
|
const response = await agent.generateSync({
|
|
4654
|
-
user:
|
|
4680
|
+
user: user?.id,
|
|
4655
4681
|
session: headers.session,
|
|
4682
|
+
role: user?.role?.id,
|
|
4656
4683
|
message: req.body.message,
|
|
4657
4684
|
tools: enabledTools.map((tool2) => tool2.tool),
|
|
4658
4685
|
providerApiKey,
|
|
@@ -4751,7 +4778,9 @@ Mood: friendly and intelligent.
|
|
|
4751
4778
|
label: "Claude Code",
|
|
4752
4779
|
type: STATISTICS_TYPE_ENUM.AGENT_RUN,
|
|
4753
4780
|
trigger: "claude-code",
|
|
4754
|
-
count: 1
|
|
4781
|
+
count: 1,
|
|
4782
|
+
user: authenticationResult.user?.id,
|
|
4783
|
+
role: authenticationResult.user.role?.id
|
|
4755
4784
|
});
|
|
4756
4785
|
response.headers.forEach((value, key) => {
|
|
4757
4786
|
res.setHeader(key, value);
|
package/dist/index.d.cts
CHANGED
|
@@ -163,9 +163,10 @@ declare class ExuluAgent {
|
|
|
163
163
|
get providerName(): string;
|
|
164
164
|
get modelName(): string;
|
|
165
165
|
tool: () => ExuluTool;
|
|
166
|
-
generateSync: ({ prompt, user, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
166
|
+
generateSync: ({ prompt, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
167
167
|
prompt?: string;
|
|
168
168
|
user?: string;
|
|
169
|
+
role?: string;
|
|
169
170
|
session?: string;
|
|
170
171
|
message?: UIMessage;
|
|
171
172
|
tools?: ExuluTool[];
|
|
@@ -173,12 +174,13 @@ declare class ExuluAgent {
|
|
|
173
174
|
toolConfigs?: ExuluAgentToolConfig[];
|
|
174
175
|
providerApiKey: string;
|
|
175
176
|
}) => Promise<string>;
|
|
176
|
-
generateStream: ({ express, user, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
177
|
+
generateStream: ({ express, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
177
178
|
express: {
|
|
178
179
|
res: Response;
|
|
179
180
|
req: Request;
|
|
180
181
|
};
|
|
181
182
|
user: string;
|
|
183
|
+
role: string;
|
|
182
184
|
session: string;
|
|
183
185
|
message?: UIMessage;
|
|
184
186
|
tools?: ExuluTool[];
|
|
@@ -232,8 +234,8 @@ declare class ExuluEmbedder {
|
|
|
232
234
|
vectorDimensions: number;
|
|
233
235
|
maxChunkSize: number;
|
|
234
236
|
});
|
|
235
|
-
generateFromQuery(query: string, statistics?: ExuluStatisticParams): VectorGenerationResponse;
|
|
236
|
-
generateFromDocument(input: Item, statistics?: ExuluStatisticParams): VectorGenerationResponse;
|
|
237
|
+
generateFromQuery(query: string, statistics?: ExuluStatisticParams, user?: string, role?: string): VectorGenerationResponse;
|
|
238
|
+
generateFromDocument(input: Item, statistics?: ExuluStatisticParams, user?: string, role?: string): VectorGenerationResponse;
|
|
237
239
|
}
|
|
238
240
|
declare class ExuluLogger {
|
|
239
241
|
private readonly logPath?;
|
|
@@ -386,21 +388,23 @@ declare class ExuluContext {
|
|
|
386
388
|
getTableName: () => string;
|
|
387
389
|
getChunksTableName: () => string;
|
|
388
390
|
tableExists: () => Promise<boolean>;
|
|
389
|
-
updateItem(user: string, id: string, item: Item): Promise<{
|
|
391
|
+
updateItem(user: string, id: string, item: Item, role?: string): Promise<{
|
|
390
392
|
id: string;
|
|
391
393
|
job?: string;
|
|
392
394
|
}>;
|
|
393
|
-
insertItem(user: string, item: Item, upsert?: boolean): Promise<{
|
|
395
|
+
insertItem(user: string, item: Item, upsert?: boolean, role?: string): Promise<{
|
|
394
396
|
id: string;
|
|
395
397
|
job?: string;
|
|
396
398
|
}>;
|
|
397
|
-
getItems: ({ statistics, limit, sort, order, page, name, archived, query, method }: {
|
|
399
|
+
getItems: ({ statistics, limit, sort, order, page, name, user, role, archived, query, method }: {
|
|
398
400
|
statistics?: ExuluStatisticParams;
|
|
399
401
|
page: number;
|
|
400
402
|
sort?: "created_at" | "embeddings_updated_at";
|
|
401
403
|
order?: "desc" | "asc";
|
|
402
404
|
limit: number;
|
|
403
405
|
name?: string;
|
|
406
|
+
user?: string;
|
|
407
|
+
role?: string;
|
|
404
408
|
archived?: boolean;
|
|
405
409
|
query?: string;
|
|
406
410
|
method?: VectorMethod;
|
|
@@ -481,11 +485,12 @@ type ExuluSourceUpdaterArgs = {
|
|
|
481
485
|
example: string;
|
|
482
486
|
}>;
|
|
483
487
|
};
|
|
488
|
+
type STATISTICS_LABELS = "tool" | "agent" | "flow" | "api" | "claude-code";
|
|
484
489
|
type ExuluStatistic = {
|
|
485
490
|
name: string;
|
|
486
491
|
label: string;
|
|
487
492
|
type: STATISTICS_TYPE;
|
|
488
|
-
trigger:
|
|
493
|
+
trigger: STATISTICS_LABELS;
|
|
489
494
|
total: number;
|
|
490
495
|
};
|
|
491
496
|
type ExuluStatisticParams = Omit<ExuluStatistic, "total" | "name" | "type">;
|
package/dist/index.d.ts
CHANGED
|
@@ -163,9 +163,10 @@ declare class ExuluAgent {
|
|
|
163
163
|
get providerName(): string;
|
|
164
164
|
get modelName(): string;
|
|
165
165
|
tool: () => ExuluTool;
|
|
166
|
-
generateSync: ({ prompt, user, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
166
|
+
generateSync: ({ prompt, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
167
167
|
prompt?: string;
|
|
168
168
|
user?: string;
|
|
169
|
+
role?: string;
|
|
169
170
|
session?: string;
|
|
170
171
|
message?: UIMessage;
|
|
171
172
|
tools?: ExuluTool[];
|
|
@@ -173,12 +174,13 @@ declare class ExuluAgent {
|
|
|
173
174
|
toolConfigs?: ExuluAgentToolConfig[];
|
|
174
175
|
providerApiKey: string;
|
|
175
176
|
}) => Promise<string>;
|
|
176
|
-
generateStream: ({ express, user, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
177
|
+
generateStream: ({ express, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }: {
|
|
177
178
|
express: {
|
|
178
179
|
res: Response;
|
|
179
180
|
req: Request;
|
|
180
181
|
};
|
|
181
182
|
user: string;
|
|
183
|
+
role: string;
|
|
182
184
|
session: string;
|
|
183
185
|
message?: UIMessage;
|
|
184
186
|
tools?: ExuluTool[];
|
|
@@ -232,8 +234,8 @@ declare class ExuluEmbedder {
|
|
|
232
234
|
vectorDimensions: number;
|
|
233
235
|
maxChunkSize: number;
|
|
234
236
|
});
|
|
235
|
-
generateFromQuery(query: string, statistics?: ExuluStatisticParams): VectorGenerationResponse;
|
|
236
|
-
generateFromDocument(input: Item, statistics?: ExuluStatisticParams): VectorGenerationResponse;
|
|
237
|
+
generateFromQuery(query: string, statistics?: ExuluStatisticParams, user?: string, role?: string): VectorGenerationResponse;
|
|
238
|
+
generateFromDocument(input: Item, statistics?: ExuluStatisticParams, user?: string, role?: string): VectorGenerationResponse;
|
|
237
239
|
}
|
|
238
240
|
declare class ExuluLogger {
|
|
239
241
|
private readonly logPath?;
|
|
@@ -386,21 +388,23 @@ declare class ExuluContext {
|
|
|
386
388
|
getTableName: () => string;
|
|
387
389
|
getChunksTableName: () => string;
|
|
388
390
|
tableExists: () => Promise<boolean>;
|
|
389
|
-
updateItem(user: string, id: string, item: Item): Promise<{
|
|
391
|
+
updateItem(user: string, id: string, item: Item, role?: string): Promise<{
|
|
390
392
|
id: string;
|
|
391
393
|
job?: string;
|
|
392
394
|
}>;
|
|
393
|
-
insertItem(user: string, item: Item, upsert?: boolean): Promise<{
|
|
395
|
+
insertItem(user: string, item: Item, upsert?: boolean, role?: string): Promise<{
|
|
394
396
|
id: string;
|
|
395
397
|
job?: string;
|
|
396
398
|
}>;
|
|
397
|
-
getItems: ({ statistics, limit, sort, order, page, name, archived, query, method }: {
|
|
399
|
+
getItems: ({ statistics, limit, sort, order, page, name, user, role, archived, query, method }: {
|
|
398
400
|
statistics?: ExuluStatisticParams;
|
|
399
401
|
page: number;
|
|
400
402
|
sort?: "created_at" | "embeddings_updated_at";
|
|
401
403
|
order?: "desc" | "asc";
|
|
402
404
|
limit: number;
|
|
403
405
|
name?: string;
|
|
406
|
+
user?: string;
|
|
407
|
+
role?: string;
|
|
404
408
|
archived?: boolean;
|
|
405
409
|
query?: string;
|
|
406
410
|
method?: VectorMethod;
|
|
@@ -481,11 +485,12 @@ type ExuluSourceUpdaterArgs = {
|
|
|
481
485
|
example: string;
|
|
482
486
|
}>;
|
|
483
487
|
};
|
|
488
|
+
type STATISTICS_LABELS = "tool" | "agent" | "flow" | "api" | "claude-code";
|
|
484
489
|
type ExuluStatistic = {
|
|
485
490
|
name: string;
|
|
486
491
|
label: string;
|
|
487
492
|
type: STATISTICS_TYPE;
|
|
488
|
-
trigger:
|
|
493
|
+
trigger: STATISTICS_LABELS;
|
|
489
494
|
total: number;
|
|
490
495
|
};
|
|
491
496
|
type ExuluStatisticParams = Omit<ExuluStatistic, "total" | "name" | "type">;
|
package/dist/index.js
CHANGED
|
@@ -436,7 +436,7 @@ function sanitizeToolName(name) {
|
|
|
436
436
|
}
|
|
437
437
|
return sanitized;
|
|
438
438
|
}
|
|
439
|
-
var convertToolsArrayToObject = (tools, configs, providerApiKey) => {
|
|
439
|
+
var convertToolsArrayToObject = (tools, configs, providerApiKey, user, role) => {
|
|
440
440
|
if (!tools) return {};
|
|
441
441
|
const sanitizedTools = tools ? tools.map((tool2) => ({
|
|
442
442
|
...tool2,
|
|
@@ -471,6 +471,8 @@ var convertToolsArrayToObject = (tools, configs, providerApiKey) => {
|
|
|
471
471
|
// is available, after we added the .value property
|
|
472
472
|
// by hydrating it from the variables table.
|
|
473
473
|
providerApiKey,
|
|
474
|
+
user,
|
|
475
|
+
role,
|
|
474
476
|
config: config ? config.config.reduce((acc, curr) => {
|
|
475
477
|
acc[curr.name] = curr.value;
|
|
476
478
|
return acc;
|
|
@@ -576,10 +578,12 @@ var ExuluAgent = class {
|
|
|
576
578
|
}),
|
|
577
579
|
description: `A function that calls an AI agent named: ${this.name}. The agent does the following: ${this.description}.`,
|
|
578
580
|
config: [],
|
|
579
|
-
execute: async ({ prompt, config, providerApiKey }) => {
|
|
581
|
+
execute: async ({ prompt, config, providerApiKey, user, role }) => {
|
|
580
582
|
return await this.generateSync({
|
|
581
583
|
prompt,
|
|
582
584
|
providerApiKey,
|
|
585
|
+
user,
|
|
586
|
+
role,
|
|
583
587
|
statistics: {
|
|
584
588
|
label: "",
|
|
585
589
|
trigger: "tool"
|
|
@@ -588,7 +592,7 @@ var ExuluAgent = class {
|
|
|
588
592
|
}
|
|
589
593
|
});
|
|
590
594
|
};
|
|
591
|
-
generateSync = async ({ prompt, user, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
595
|
+
generateSync = async ({ prompt, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
592
596
|
if (!this.model) {
|
|
593
597
|
throw new Error("Model is required for streaming.");
|
|
594
598
|
}
|
|
@@ -624,7 +628,7 @@ var ExuluAgent = class {
|
|
|
624
628
|
messages: messages ? convertToModelMessages(messages) : void 0,
|
|
625
629
|
prompt,
|
|
626
630
|
maxRetries: 2,
|
|
627
|
-
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey),
|
|
631
|
+
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey, user, role),
|
|
628
632
|
stopWhen: [stepCountIs(5)]
|
|
629
633
|
});
|
|
630
634
|
if (statistics) {
|
|
@@ -633,12 +637,14 @@ var ExuluAgent = class {
|
|
|
633
637
|
label: statistics.label,
|
|
634
638
|
type: STATISTICS_TYPE_ENUM.AGENT_RUN,
|
|
635
639
|
trigger: statistics.trigger,
|
|
636
|
-
count: 1
|
|
640
|
+
count: 1,
|
|
641
|
+
user,
|
|
642
|
+
role
|
|
637
643
|
});
|
|
638
644
|
}
|
|
639
645
|
return text;
|
|
640
646
|
};
|
|
641
|
-
generateStream = async ({ express: express3, user, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
647
|
+
generateStream = async ({ express: express3, user, role, session, message, tools, statistics, toolConfigs, providerApiKey }) => {
|
|
642
648
|
if (!this.model) {
|
|
643
649
|
throw new Error("Model is required for streaming.");
|
|
644
650
|
}
|
|
@@ -671,7 +677,7 @@ var ExuluAgent = class {
|
|
|
671
677
|
messages: messages ? convertToModelMessages(messages) : void 0,
|
|
672
678
|
system: "You are a helpful assistant. When you use a tool to answer a question do not explicitly comment on the result of the tool call unless the user has explicitly you to do something with the result.",
|
|
673
679
|
maxRetries: 2,
|
|
674
|
-
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey),
|
|
680
|
+
tools: convertToolsArrayToObject(tools, toolConfigs, providerApiKey, user, role),
|
|
675
681
|
onError: (error) => console.error("[EXULU] chat stream error.", error),
|
|
676
682
|
stopWhen: [stepCountIs(5)]
|
|
677
683
|
});
|
|
@@ -699,7 +705,9 @@ var ExuluAgent = class {
|
|
|
699
705
|
label: statistics.label,
|
|
700
706
|
type: STATISTICS_TYPE_ENUM.AGENT_RUN,
|
|
701
707
|
trigger: statistics.trigger,
|
|
702
|
-
count: 1
|
|
708
|
+
count: 1,
|
|
709
|
+
user,
|
|
710
|
+
role
|
|
703
711
|
});
|
|
704
712
|
}
|
|
705
713
|
}
|
|
@@ -743,14 +751,16 @@ var ExuluEmbedder = class {
|
|
|
743
751
|
this.queue = queue;
|
|
744
752
|
this.generateEmbeddings = generateEmbeddings;
|
|
745
753
|
}
|
|
746
|
-
async generateFromQuery(query, statistics) {
|
|
754
|
+
async generateFromQuery(query, statistics, user, role) {
|
|
747
755
|
if (statistics) {
|
|
748
756
|
await updateStatistic({
|
|
749
757
|
name: "count",
|
|
750
758
|
label: statistics.label,
|
|
751
759
|
type: STATISTICS_TYPE_ENUM.EMBEDDER_GENERATE,
|
|
752
760
|
trigger: statistics.trigger,
|
|
753
|
-
count: 1
|
|
761
|
+
count: 1,
|
|
762
|
+
user,
|
|
763
|
+
role
|
|
754
764
|
});
|
|
755
765
|
}
|
|
756
766
|
return await this.generateEmbeddings({
|
|
@@ -763,14 +773,16 @@ var ExuluEmbedder = class {
|
|
|
763
773
|
}]
|
|
764
774
|
});
|
|
765
775
|
}
|
|
766
|
-
async generateFromDocument(input, statistics) {
|
|
776
|
+
async generateFromDocument(input, statistics, user, role) {
|
|
767
777
|
if (statistics) {
|
|
768
778
|
await updateStatistic({
|
|
769
779
|
name: "count",
|
|
770
780
|
label: statistics.label,
|
|
771
781
|
type: STATISTICS_TYPE_ENUM.EMBEDDER_GENERATE,
|
|
772
782
|
trigger: statistics.trigger,
|
|
773
|
-
count: 1
|
|
783
|
+
count: 1,
|
|
784
|
+
user,
|
|
785
|
+
role
|
|
774
786
|
});
|
|
775
787
|
}
|
|
776
788
|
if (!this.chunker) {
|
|
@@ -1024,7 +1036,7 @@ var ExuluContext = class {
|
|
|
1024
1036
|
const tableExists = await db3.schema.hasTable(this.getTableName());
|
|
1025
1037
|
return tableExists;
|
|
1026
1038
|
};
|
|
1027
|
-
async updateItem(user, id, item) {
|
|
1039
|
+
async updateItem(user, id, item, role) {
|
|
1028
1040
|
if (!id) {
|
|
1029
1041
|
throw new Error("Id is required for updating an item.");
|
|
1030
1042
|
}
|
|
@@ -1065,7 +1077,7 @@ var ExuluContext = class {
|
|
|
1065
1077
|
}, {
|
|
1066
1078
|
label: this.name,
|
|
1067
1079
|
trigger: "agent"
|
|
1068
|
-
});
|
|
1080
|
+
}, user, role);
|
|
1069
1081
|
const exists = await db3.schema.hasTable(this.getChunksTableName());
|
|
1070
1082
|
if (!exists) {
|
|
1071
1083
|
await this.createChunksTable();
|
|
@@ -1086,7 +1098,7 @@ var ExuluContext = class {
|
|
|
1086
1098
|
job: void 0
|
|
1087
1099
|
};
|
|
1088
1100
|
}
|
|
1089
|
-
async insertItem(user, item, upsert = false) {
|
|
1101
|
+
async insertItem(user, item, upsert = false, role) {
|
|
1090
1102
|
if (!item.name) {
|
|
1091
1103
|
throw new Error("Name field is required.");
|
|
1092
1104
|
}
|
|
@@ -1097,14 +1109,14 @@ var ExuluContext = class {
|
|
|
1097
1109
|
throw new Error("Item with external id " + item.external_id + " already exists.");
|
|
1098
1110
|
}
|
|
1099
1111
|
if (existingItem && upsert) {
|
|
1100
|
-
await this.updateItem(user, existingItem.id, item);
|
|
1112
|
+
await this.updateItem(user, existingItem.id, item, role);
|
|
1101
1113
|
return existingItem.id;
|
|
1102
1114
|
}
|
|
1103
1115
|
}
|
|
1104
1116
|
if (upsert && item.id) {
|
|
1105
1117
|
const existingItem = await db3.from(this.getTableName()).where({ id: item.id }).first();
|
|
1106
1118
|
if (existingItem && upsert) {
|
|
1107
|
-
await this.updateItem(user, existingItem.id, item);
|
|
1119
|
+
await this.updateItem(user, existingItem.id, item, role);
|
|
1108
1120
|
return existingItem.id;
|
|
1109
1121
|
}
|
|
1110
1122
|
}
|
|
@@ -1148,7 +1160,7 @@ var ExuluContext = class {
|
|
|
1148
1160
|
}, {
|
|
1149
1161
|
label: this.name,
|
|
1150
1162
|
trigger: "agent"
|
|
1151
|
-
});
|
|
1163
|
+
}, user, role);
|
|
1152
1164
|
const exists = await db3.schema.hasTable(this.getChunksTableName());
|
|
1153
1165
|
if (!exists) {
|
|
1154
1166
|
await this.createChunksTable();
|
|
@@ -1176,6 +1188,8 @@ var ExuluContext = class {
|
|
|
1176
1188
|
order,
|
|
1177
1189
|
page,
|
|
1178
1190
|
name,
|
|
1191
|
+
user,
|
|
1192
|
+
role,
|
|
1179
1193
|
archived,
|
|
1180
1194
|
query,
|
|
1181
1195
|
method
|
|
@@ -1244,7 +1258,9 @@ var ExuluContext = class {
|
|
|
1244
1258
|
name: "count",
|
|
1245
1259
|
label: statistics.label,
|
|
1246
1260
|
type: STATISTICS_TYPE_ENUM.CONTEXT_RETRIEVE,
|
|
1247
|
-
trigger: statistics.trigger
|
|
1261
|
+
trigger: statistics.trigger,
|
|
1262
|
+
user,
|
|
1263
|
+
role
|
|
1248
1264
|
});
|
|
1249
1265
|
}
|
|
1250
1266
|
if (this.queryRewriter) {
|
|
@@ -1260,7 +1276,10 @@ var ExuluContext = class {
|
|
|
1260
1276
|
itemsQuery.select(chunksTable + ".chunk_index");
|
|
1261
1277
|
itemsQuery.select(chunksTable + ".created_at as chunk_created_at");
|
|
1262
1278
|
itemsQuery.select(chunksTable + ".updated_at as chunk_updated_at");
|
|
1263
|
-
const { chunks } = await this.embedder.generateFromQuery(query
|
|
1279
|
+
const { chunks } = await this.embedder.generateFromQuery(query, {
|
|
1280
|
+
label: this.name,
|
|
1281
|
+
trigger: "agent"
|
|
1282
|
+
}, user, role);
|
|
1264
1283
|
if (!chunks?.[0]?.vector) {
|
|
1265
1284
|
throw new Error("No vector generated for query.");
|
|
1266
1285
|
}
|
|
@@ -1408,11 +1427,13 @@ var ExuluContext = class {
|
|
|
1408
1427
|
}),
|
|
1409
1428
|
config: [],
|
|
1410
1429
|
description: `Gets information from the context called: ${this.name}. The context description is: ${this.description}.`,
|
|
1411
|
-
execute: async ({ query }) => {
|
|
1430
|
+
execute: async ({ query, user, role }) => {
|
|
1412
1431
|
return await this.getItems({
|
|
1413
1432
|
page: 1,
|
|
1414
1433
|
limit: 10,
|
|
1415
1434
|
query,
|
|
1435
|
+
user,
|
|
1436
|
+
role,
|
|
1416
1437
|
statistics: {
|
|
1417
1438
|
label: this.name,
|
|
1418
1439
|
trigger: "agent"
|
|
@@ -4176,7 +4197,7 @@ Mood: friendly and intelligent.
|
|
|
4176
4197
|
if (!exists) {
|
|
4177
4198
|
await context.createItemsTable();
|
|
4178
4199
|
}
|
|
4179
|
-
const result = await context.updateItem(authenticationResult.user.id, req.params.id, req.body);
|
|
4200
|
+
const result = await context.updateItem(authenticationResult.user.id, req.params.id, req.body, authenticationResult.user.role?.id);
|
|
4180
4201
|
res.status(200).json({
|
|
4181
4202
|
message: "Item updated successfully.",
|
|
4182
4203
|
id: result
|
|
@@ -4223,7 +4244,7 @@ Mood: friendly and intelligent.
|
|
|
4223
4244
|
await context.createItemsTable();
|
|
4224
4245
|
}
|
|
4225
4246
|
console.log("[EXULU] inserting item", req.body);
|
|
4226
|
-
const result = await context.insertItem(authenticationResult.user.id, req.body, !!req.body.upsert);
|
|
4247
|
+
const result = await context.insertItem(authenticationResult.user.id, req.body, !!req.body.upsert, authenticationResult.user.role?.id);
|
|
4227
4248
|
console.log("[EXULU] result", result);
|
|
4228
4249
|
res.status(200).json({
|
|
4229
4250
|
message: "Item created successfully.",
|
|
@@ -4284,6 +4305,8 @@ Mood: friendly and intelligent.
|
|
|
4284
4305
|
const result = await context.getItems({
|
|
4285
4306
|
sort,
|
|
4286
4307
|
order,
|
|
4308
|
+
user: authenticationResult.user?.id,
|
|
4309
|
+
role: authenticationResult.user?.role?.id,
|
|
4287
4310
|
page,
|
|
4288
4311
|
limit,
|
|
4289
4312
|
archived: req.query.archived === "true",
|
|
@@ -4445,6 +4468,8 @@ Mood: friendly and intelligent.
|
|
|
4445
4468
|
const items = await context.getItems({
|
|
4446
4469
|
page: 1,
|
|
4447
4470
|
// todo add pagination
|
|
4471
|
+
user: authenticationResult.user?.id,
|
|
4472
|
+
role: authenticationResult.user?.role?.id,
|
|
4448
4473
|
limit: 500
|
|
4449
4474
|
});
|
|
4450
4475
|
const csv = Papa.unparse(items);
|
|
@@ -4595,7 +4620,8 @@ Mood: friendly and intelligent.
|
|
|
4595
4620
|
res,
|
|
4596
4621
|
req
|
|
4597
4622
|
},
|
|
4598
|
-
user:
|
|
4623
|
+
user: user?.id,
|
|
4624
|
+
role: user?.role?.id,
|
|
4599
4625
|
session: headers.session,
|
|
4600
4626
|
message: req.body.message,
|
|
4601
4627
|
tools: enabledTools,
|
|
@@ -4609,8 +4635,9 @@ Mood: friendly and intelligent.
|
|
|
4609
4635
|
return;
|
|
4610
4636
|
} else {
|
|
4611
4637
|
const response = await agent.generateSync({
|
|
4612
|
-
user:
|
|
4638
|
+
user: user?.id,
|
|
4613
4639
|
session: headers.session,
|
|
4640
|
+
role: user?.role?.id,
|
|
4614
4641
|
message: req.body.message,
|
|
4615
4642
|
tools: enabledTools.map((tool2) => tool2.tool),
|
|
4616
4643
|
providerApiKey,
|
|
@@ -4709,7 +4736,9 @@ Mood: friendly and intelligent.
|
|
|
4709
4736
|
label: "Claude Code",
|
|
4710
4737
|
type: STATISTICS_TYPE_ENUM.AGENT_RUN,
|
|
4711
4738
|
trigger: "claude-code",
|
|
4712
|
-
count: 1
|
|
4739
|
+
count: 1,
|
|
4740
|
+
user: authenticationResult.user?.id,
|
|
4741
|
+
role: authenticationResult.user.role?.id
|
|
4713
4742
|
});
|
|
4714
4743
|
response.headers.forEach((value, key) => {
|
|
4715
4744
|
res.setHeader(key, value);
|