@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 CHANGED
@@ -1,9 +1,9 @@
1
- # [1.15.0](https://github.com/Qventu/exulu-backend/compare/v1.14.1...v1.15.0) (2025-08-22)
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
- * image generation for agent profile images, added "ByIds" to graphql Schema ([c084070](https://github.com/Qventu/exulu-backend/commit/c084070b9f61830fcdf0745da7727c70b718fa64))
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: headers.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: headers.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: "tool" | "agent" | "flow" | "api" | "claude-code";
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: "tool" | "agent" | "flow" | "api" | "claude-code";
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: headers.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: headers.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);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "1.15.0",
4
+ "version": "1.16.0",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {