@exulu/backend 1.34.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1327,6 +1327,35 @@ var platformConfigurationsSchema = {
1327
1327
  }
1328
1328
  ]
1329
1329
  };
1330
+ var embedderSettingsSchema = {
1331
+ type: "embedder_settings",
1332
+ name: {
1333
+ plural: "embedder_settings",
1334
+ singular: "embedder_setting"
1335
+ },
1336
+ RBAC: false,
1337
+ fields: [
1338
+ {
1339
+ name: "context",
1340
+ type: "text"
1341
+ // id of the ExuluContext class
1342
+ },
1343
+ {
1344
+ name: "embedder",
1345
+ type: "text"
1346
+ // id of the ExuluEmbedder class
1347
+ },
1348
+ {
1349
+ name: "name",
1350
+ type: "text"
1351
+ },
1352
+ {
1353
+ name: "value",
1354
+ type: "text"
1355
+ // reference to an exulu variable
1356
+ }
1357
+ ]
1358
+ };
1330
1359
  var promptLibrarySchema = {
1331
1360
  type: "prompt_library",
1332
1361
  name: {
@@ -1435,6 +1464,7 @@ var coreSchemas = {
1435
1464
  platformConfigurationsSchema: () => addCoreFields(platformConfigurationsSchema),
1436
1465
  jobResultsSchema: () => addCoreFields(jobResultsSchema),
1437
1466
  promptLibrarySchema: () => addCoreFields(promptLibrarySchema),
1467
+ embedderSettingsSchema: () => addCoreFields(embedderSettingsSchema),
1438
1468
  promptFavoritesSchema: () => addCoreFields(promptFavoritesSchema)
1439
1469
  };
1440
1470
  }
@@ -1814,6 +1844,7 @@ ${enumValues}
1814
1844
  fields.push(" capabilities: AgentCapabilities");
1815
1845
  fields.push(" maxContextLength: Int");
1816
1846
  fields.push(" provider: String");
1847
+ fields.push(" authenticationInformation: String");
1817
1848
  fields.push(" slug: String");
1818
1849
  }
1819
1850
  const rbacField = table.RBAC ? " RBAC: RBACData" : "";
@@ -2612,7 +2643,8 @@ var backendAgentFields = [
2612
2643
  "streaming",
2613
2644
  "capabilities",
2614
2645
  "maxContextLength",
2615
- "provider"
2646
+ "provider",
2647
+ "authenticationInformation"
2616
2648
  ];
2617
2649
  var removeAgentFields = (requestedFields) => {
2618
2650
  const filtered = requestedFields.filter((field) => !backendAgentFields.includes(field));
@@ -2680,6 +2712,9 @@ var addAgentFields = async (requestedFields, agents, result, tools, user) => {
2680
2712
  if (requestedFields.includes("maxContextLength")) {
2681
2713
  result.maxContextLength = backend?.maxContextLength || 0;
2682
2714
  }
2715
+ if (requestedFields.includes("authenticationInformation")) {
2716
+ result.authenticationInformation = backend?.authenticationInformation || "";
2717
+ }
2683
2718
  if (requestedFields.includes("provider")) {
2684
2719
  result.provider = backend?.provider || "";
2685
2720
  }
@@ -3078,7 +3113,7 @@ var vectorSearch = async ({
3078
3113
  itemsQuery.select(chunksTable + ".createdAt as chunk_created_at");
3079
3114
  itemsQuery.select(chunksTable + ".updatedAt as chunk_updated_at");
3080
3115
  itemsQuery.select(db3.raw("vector_dims(??) as embedding_size", [`${chunksTable}.embedding`]));
3081
- const { chunks } = await embedder.generateFromQuery(query, {
3116
+ const { chunks } = await embedder.generateFromQuery(context.id, query, {
3082
3117
  label: table.name.singular,
3083
3118
  trigger
3084
3119
  }, user.id, role);
@@ -3879,7 +3914,11 @@ type PageInfo {
3879
3914
  id: context2.id,
3880
3915
  name: context2.name,
3881
3916
  description: context2.description,
3882
- embedder: context2.embedder?.name || void 0,
3917
+ embedder: context2.embedder ? {
3918
+ name: context2.embedder.name,
3919
+ id: context2.embedder.id,
3920
+ config: context2.embedder?.config || void 0
3921
+ } : void 0,
3883
3922
  slug: "/contexts/" + context2.id,
3884
3923
  active: context2.active,
3885
3924
  sources,
@@ -3930,7 +3969,11 @@ type PageInfo {
3930
3969
  id: data.id,
3931
3970
  name: data.name,
3932
3971
  description: data.description,
3933
- embedder: data.embedder?.name || void 0,
3972
+ embedder: data.embedder ? {
3973
+ name: data.embedder.name,
3974
+ id: data.embedder.id,
3975
+ config: data.embedder?.config || void 0
3976
+ } : void 0,
3934
3977
  slug: "/contexts/" + data.id,
3935
3978
  active: data.active,
3936
3979
  sources,
@@ -4145,13 +4188,23 @@ type Context {
4145
4188
  id: ID!
4146
4189
  name: String!
4147
4190
  description: String
4148
- embedder: String
4191
+ embedder: Embedder
4149
4192
  slug: String
4150
4193
  active: Boolean
4151
4194
  fields: JSON
4152
4195
  configuration: JSON
4153
4196
  sources: [ContextSource!]
4154
4197
  }
4198
+ type Embedder {
4199
+ name: String!
4200
+ id: ID!
4201
+ config: [EmbedderConfig!]
4202
+ }
4203
+ type EmbedderConfig {
4204
+ name: String!
4205
+ description: String
4206
+ default: String
4207
+ }
4155
4208
 
4156
4209
  type ContextSource {
4157
4210
  id: String!
@@ -4859,6 +4912,9 @@ function sanitizeToolName(name) {
4859
4912
  var convertToolsArrayToObject = (currentTools, allExuluTools, configs, providerapikey, contexts, user, exuluConfig, sessionID) => {
4860
4913
  if (!currentTools) return {};
4861
4914
  if (!allExuluTools) return {};
4915
+ if (!contexts) {
4916
+ contexts = [];
4917
+ }
4862
4918
  const sanitizedTools = currentTools ? currentTools.map((tool2) => ({
4863
4919
  ...tool2,
4864
4920
  name: sanitizeToolName(tool2.name)
@@ -5057,6 +5113,7 @@ var ExuluAgent2 = class {
5057
5113
  slug = "";
5058
5114
  type;
5059
5115
  streaming = false;
5116
+ authenticationInformation;
5060
5117
  maxContextLength;
5061
5118
  queue;
5062
5119
  rateLimit;
@@ -5064,12 +5121,13 @@ var ExuluAgent2 = class {
5064
5121
  // private memory: Memory | undefined; // TODO do own implementation
5065
5122
  model;
5066
5123
  capabilities;
5067
- constructor({ id, name, description, config, rateLimit, capabilities, type, maxContextLength, provider, queue }) {
5124
+ constructor({ id, name, description, config, rateLimit, capabilities, type, maxContextLength, provider, queue, authenticationInformation }) {
5068
5125
  this.id = id;
5069
5126
  this.name = name;
5070
5127
  this.description = description;
5071
5128
  this.rateLimit = rateLimit;
5072
5129
  this.provider = provider;
5130
+ this.authenticationInformation = authenticationInformation;
5073
5131
  this.config = config;
5074
5132
  this.type = type;
5075
5133
  this.maxContextLength = maxContextLength;
@@ -5088,15 +5146,13 @@ var ExuluAgent2 = class {
5088
5146
  if (!this.config?.model?.create) {
5089
5147
  return "";
5090
5148
  }
5091
- const model = this.config?.model?.create({ apiKey: "" });
5092
- return typeof model === "string" ? model : model?.provider || "";
5149
+ return this.provider;
5093
5150
  }
5094
5151
  get modelName() {
5095
5152
  if (!this.config?.model?.create) {
5096
5153
  return "";
5097
5154
  }
5098
- const model = this.config?.model?.create({ apiKey: "" });
5099
- return typeof model === "string" ? model : model?.modelId || "";
5155
+ return this.config?.name || "";
5100
5156
  }
5101
5157
  // Exports the agent as a tool that can be used by another agent
5102
5158
  tool = async (instance, agents) => {
@@ -5122,21 +5178,21 @@ var ExuluAgent2 = class {
5122
5178
  }
5123
5179
  let enabledTools = await getEnabledTools(agentInstance, allExuluTools, [], agents, user);
5124
5180
  const variableName = agentInstance.providerapikey;
5125
- if (!variableName) {
5126
- throw new Error("Provider API key variable not set for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool.");
5127
- }
5128
- const { db: db3 } = await postgresClient();
5129
- const variable = await db3.from("variables").where({ name: variableName }).first();
5130
- if (!variable) {
5131
- throw new Error("Provider API key variable not found for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool.");
5132
- }
5133
- let providerapikey = variable.value;
5134
- if (!variable.encrypted) {
5135
- throw new Error("Provider API key variable not encrypted for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool, for security reasons you are only allowed to use encrypted variables for provider API keys.");
5136
- }
5137
- if (variable.encrypted) {
5138
- const bytes = CryptoJS2.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
5139
- providerapikey = bytes.toString(CryptoJS2.enc.Utf8);
5181
+ let providerapikey;
5182
+ if (variableName) {
5183
+ const { db: db3 } = await postgresClient();
5184
+ const variable = await db3.from("variables").where({ name: variableName }).first();
5185
+ if (!variable) {
5186
+ throw new Error("Provider API key variable not found for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool.");
5187
+ }
5188
+ providerapikey = variable.value;
5189
+ if (!variable.encrypted) {
5190
+ throw new Error("Provider API key variable not encrypted for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool, for security reasons you are only allowed to use encrypted variables for provider API keys.");
5191
+ }
5192
+ if (variable.encrypted) {
5193
+ const bytes = CryptoJS2.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
5194
+ providerapikey = bytes.toString(CryptoJS2.enc.Utf8);
5195
+ }
5140
5196
  }
5141
5197
  console.log("[EXULU] Enabled tools for agent '" + agentInstance.name + " (" + agentInstance.id + ") that is being called as a tool", enabledTools.map((x) => x.name + " (" + x.id + ")"));
5142
5198
  console.log("[EXULU] Prompt for agent '" + agentInstance.name + "' that is being called as a tool", prompt.slice(0, 100) + "...");
@@ -5200,7 +5256,7 @@ var ExuluAgent2 = class {
5200
5256
  throw new Error("Prompt is required for generating with an output schema.");
5201
5257
  }
5202
5258
  const model = this.model.create({
5203
- apiKey: providerapikey
5259
+ ...providerapikey ? { apiKey: providerapikey } : {}
5204
5260
  });
5205
5261
  console.log("[EXULU] Model for agent: " + this.name, " created for generating sync.");
5206
5262
  let messages = inputMessages || [];
@@ -5377,7 +5433,7 @@ var ExuluAgent2 = class {
5377
5433
  throw new Error("Message is required for streaming.");
5378
5434
  }
5379
5435
  const model = this.model.create({
5380
- apiKey: providerapikey
5436
+ ...providerapikey ? { apiKey: providerapikey } : {}
5381
5437
  });
5382
5438
  let messages = [];
5383
5439
  let previousMessagesContent = previousMessages || [];
@@ -5478,11 +5534,13 @@ var ExuluEmbedder = class {
5478
5534
  generateEmbeddings;
5479
5535
  description;
5480
5536
  vectorDimensions;
5537
+ config;
5481
5538
  maxChunkSize;
5482
5539
  _chunker;
5483
- constructor({ id, name, description, generateEmbeddings, queue, vectorDimensions, maxChunkSize, chunker }) {
5540
+ constructor({ id, name, description, generateEmbeddings, queue, vectorDimensions, maxChunkSize, chunker, config }) {
5484
5541
  this.id = id;
5485
5542
  this.name = name;
5543
+ this.config = config;
5486
5544
  this.description = description;
5487
5545
  this.vectorDimensions = vectorDimensions;
5488
5546
  this.maxChunkSize = maxChunkSize;
@@ -5491,13 +5549,51 @@ var ExuluEmbedder = class {
5491
5549
  this.queue = queue;
5492
5550
  this.generateEmbeddings = generateEmbeddings;
5493
5551
  }
5494
- chunker = (item, maxChunkSize, config) => {
5552
+ chunker = async (context, item, maxChunkSize, config) => {
5495
5553
  const utils = {
5496
5554
  storage: new ExuluStorage({ config })
5497
5555
  };
5498
- return this._chunker(item, maxChunkSize, utils);
5556
+ const settings = await this.hydrateEmbedderConfig(context);
5557
+ return this._chunker(item, maxChunkSize, utils, settings);
5499
5558
  };
5500
- async generateFromQuery(query, statistics, user, role) {
5559
+ hydrateEmbedderConfig = async (context) => {
5560
+ const hydrated = [];
5561
+ const { db: db3 } = await postgresClient();
5562
+ const variables = await db3.from("embedder_settings").where({
5563
+ context,
5564
+ embedder: this.id
5565
+ });
5566
+ for (const config of this.config || []) {
5567
+ const name = config.name;
5568
+ const {
5569
+ value: variableName,
5570
+ id
5571
+ } = variables.find((v) => v.name === name);
5572
+ let value = "";
5573
+ console.log("[EXULU] variable name", variableName);
5574
+ const variable = await db3.from("variables").where({ name: variableName }).first();
5575
+ if (!variable) {
5576
+ throw new Error("Variable not found for embedder setting: " + name + " in context: " + context + " and embedder: " + this.id);
5577
+ }
5578
+ if (variable.encrypted) {
5579
+ const bytes = CryptoJS2.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
5580
+ value = bytes.toString(CryptoJS2.enc.Utf8);
5581
+ } else {
5582
+ value = variable.value;
5583
+ }
5584
+ console.log("[EXULU] variable value", value);
5585
+ hydrated.push({
5586
+ id: id || "",
5587
+ name,
5588
+ value: value || ""
5589
+ });
5590
+ }
5591
+ return hydrated.reduce((acc, curr) => {
5592
+ acc[curr.name] = curr.value;
5593
+ return acc;
5594
+ }, {});
5595
+ };
5596
+ async generateFromQuery(context, query, statistics, user, role) {
5501
5597
  if (statistics) {
5502
5598
  await updateStatistic({
5503
5599
  name: "count",
@@ -5509,6 +5605,7 @@ var ExuluEmbedder = class {
5509
5605
  role
5510
5606
  });
5511
5607
  }
5608
+ const settings = await this.hydrateEmbedderConfig(context);
5512
5609
  return await this.generateEmbeddings({
5513
5610
  item: {
5514
5611
  id: "placeholder"
@@ -5517,9 +5614,9 @@ var ExuluEmbedder = class {
5517
5614
  content: query,
5518
5615
  index: 1
5519
5616
  }]
5520
- });
5617
+ }, settings);
5521
5618
  }
5522
- async generateFromDocument(input, config, statistics, user, role) {
5619
+ async generateFromDocument(context, input, config, statistics, user, role) {
5523
5620
  if (statistics) {
5524
5621
  await updateStatistic({
5525
5622
  name: "count",
@@ -5537,9 +5634,18 @@ var ExuluEmbedder = class {
5537
5634
  if (!input.id) {
5538
5635
  throw new Error("Item id is required for generating embeddings.");
5539
5636
  }
5540
- const output = await this.chunker(input, this.maxChunkSize, config);
5637
+ const settings = await this.hydrateEmbedderConfig(context);
5638
+ const output = await this.chunker(
5639
+ context,
5640
+ input,
5641
+ this.maxChunkSize,
5642
+ config
5643
+ );
5541
5644
  console.log("[EXULU] Generating embeddings.");
5542
- return await this.generateEmbeddings(output);
5645
+ return await this.generateEmbeddings(
5646
+ output,
5647
+ settings
5648
+ );
5543
5649
  }
5544
5650
  };
5545
5651
  var ExuluTool2 = class {
@@ -5714,6 +5820,7 @@ var ExuluContext = class {
5714
5820
  }
5715
5821
  const { db: db3 } = await postgresClient();
5716
5822
  const { id: source, chunks } = await this.embedder.generateFromDocument(
5823
+ this.id,
5717
5824
  {
5718
5825
  ...item,
5719
5826
  id: item.id
@@ -6032,6 +6139,7 @@ var ExuluContext = class {
6032
6139
  };
6033
6140
  };
6034
6141
  var updateStatistic = async (statistic) => {
6142
+ console.log("[EXULU] updating statistic", statistic);
6035
6143
  const currentDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
6036
6144
  const { db: db3 } = await postgresClient();
6037
6145
  const existing = await db3.from("tracking").where({
@@ -6176,6 +6284,7 @@ var {
6176
6284
  workflowTemplatesSchema: workflowTemplatesSchema2,
6177
6285
  rbacSchema: rbacSchema2,
6178
6286
  promptLibrarySchema: promptLibrarySchema2,
6287
+ embedderSettingsSchema: embedderSettingsSchema2,
6179
6288
  promptFavoritesSchema: promptFavoritesSchema2,
6180
6289
  statisticsSchema: statisticsSchema2
6181
6290
  } = coreSchemas.get();
@@ -6208,6 +6317,7 @@ var createExpressRoutes = async (app, agents, tools, contexts, config, evals, tr
6208
6317
  projectsSchema2(),
6209
6318
  jobResultsSchema2(),
6210
6319
  promptLibrarySchema2(),
6320
+ embedderSettingsSchema2(),
6211
6321
  promptFavoritesSchema2(),
6212
6322
  evalRunsSchema2(),
6213
6323
  platformConfigurationsSchema2(),
@@ -6265,7 +6375,7 @@ var createExpressRoutes = async (app, agents, tools, contexts, config, evals, tr
6265
6375
  const variable = await db3.from("variables").where({ name: "OPENAI_IMAGE_GENERATION_API_KEY" }).first();
6266
6376
  if (!variable) {
6267
6377
  res.status(400).json({
6268
- message: "Provider API key variable not found."
6378
+ message: "Provider API key variable not found for OpenAI image generation."
6269
6379
  });
6270
6380
  return;
6271
6381
  }
@@ -6445,24 +6555,30 @@ Mood: friendly and intelligent.
6445
6555
  console.log("[EXULU] agent tools", agentInstance.tools?.map((x) => x.name + " (" + x.id + ")"));
6446
6556
  const disabledTools = req.body.disabledTools ? req.body.disabledTools : [];
6447
6557
  let enabledTools = await getEnabledTools(agentInstance, tools, disabledTools, agents, user);
6558
+ let providerapikey;
6448
6559
  const variableName = agentInstance.providerapikey;
6449
- const variable = await db3.from("variables").where({ name: variableName }).first();
6450
- if (!variable) {
6451
- res.status(400).json({
6452
- message: "Provider API key variable not found."
6453
- });
6454
- return;
6455
- }
6456
- let providerapikey = variable.value;
6457
- if (!variable.encrypted) {
6458
- res.status(400).json({
6459
- message: "Provider API key variable not encrypted, for security reasons you are only allowed to use encrypted variables for provider API keys."
6460
- });
6461
- return;
6462
- }
6463
- if (variable.encrypted) {
6464
- const bytes = CryptoJS3.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
6465
- providerapikey = bytes.toString(CryptoJS3.enc.Utf8);
6560
+ if (variableName) {
6561
+ console.log("[EXULU] provider api key variable name", variableName);
6562
+ const variable = await db3.from("variables").where({ name: variableName }).first();
6563
+ if (!variable) {
6564
+ res.status(400).json({
6565
+ message: "Provider API key variable not found for " + agentInstance.name + " (" + agentInstance.id + ")."
6566
+ });
6567
+ return;
6568
+ }
6569
+ providerapikey = variable.value;
6570
+ console.log("[EXULU] encrypted value", providerapikey);
6571
+ if (!variable.encrypted) {
6572
+ res.status(400).json({
6573
+ message: "Provider API key variable not encrypted, for security reasons you are only allowed to use encrypted variables for provider API keys."
6574
+ });
6575
+ return;
6576
+ }
6577
+ if (variable.encrypted) {
6578
+ const bytes = CryptoJS3.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
6579
+ providerapikey = bytes.toString(CryptoJS3.enc.Utf8);
6580
+ console.log("[EXULU] decrypted value", providerapikey);
6581
+ }
6466
6582
  }
6467
6583
  if (!!headers.stream) {
6468
6584
  const statistics = {
@@ -6619,7 +6735,7 @@ Mood: friendly and intelligent.
6619
6735
  return;
6620
6736
  }
6621
6737
  let project = null;
6622
- if (!req.body.project || req.body.project === "DEFAULT") {
6738
+ if (!req.params.project || req.params.project === "DEFAULT") {
6623
6739
  project = null;
6624
6740
  } else {
6625
6741
  let projectQuery = db3("projects");
@@ -6896,10 +7012,11 @@ var createWorkers = async (agents, queues2, config, contexts, evals, tools, trac
6896
7012
  }));
6897
7013
  const { db: db3 } = await postgresClient();
6898
7014
  const data = bullmqJob.data;
6899
- const timeoutMs = data.timeoutInSeconds * 1e3;
7015
+ const timeoutInSeconds = data.timeoutInSeconds || 300;
7016
+ const timeoutMs = timeoutInSeconds * 1e3;
6900
7017
  const timeoutPromise = new Promise((_, reject) => {
6901
7018
  setTimeout(() => {
6902
- reject(new Error(`Timeout for job ${bullmqJob.id} reached after ${data.timeoutInSeconds}s`));
7019
+ reject(new Error(`Timeout for job ${bullmqJob.id} reached after ${timeoutInSeconds}s`));
6903
7020
  }, timeoutMs);
6904
7021
  });
6905
7022
  const workPromise = (async () => {
@@ -7425,17 +7542,20 @@ var processUiMessagesFlow = async ({
7425
7542
  console.log("[EXULU] enabled tools", enabledTools?.map((x) => x.name + " (" + x.id + ")"));
7426
7543
  const variableName = agentInstance.providerapikey;
7427
7544
  const { db: db3 } = await postgresClient();
7428
- const variable = await db3.from("variables").where({ name: variableName }).first();
7429
- if (!variable) {
7430
- throw new Error(`Provider API key variable not found for agent ${agentInstance.name} (${agentInstance.id}).`);
7431
- }
7432
- let providerapikey = variable.value;
7433
- if (!variable.encrypted) {
7434
- throw new Error(`Provider API key variable not encrypted for agent ${agentInstance.name} (${agentInstance.id}), for security reasons you are only allowed to use encrypted variables for provider API keys.`);
7435
- }
7436
- if (variable.encrypted) {
7437
- const bytes = CryptoJS4.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
7438
- providerapikey = bytes.toString(CryptoJS4.enc.Utf8);
7545
+ let providerapikey;
7546
+ if (variableName) {
7547
+ const variable = await db3.from("variables").where({ name: variableName }).first();
7548
+ if (!variable) {
7549
+ throw new Error(`Provider API key variable not found for agent ${agentInstance.name} (${agentInstance.id}).`);
7550
+ }
7551
+ providerapikey = variable.value;
7552
+ if (!variable.encrypted) {
7553
+ throw new Error(`Provider API key variable not encrypted for agent ${agentInstance.name} (${agentInstance.id}), for security reasons you are only allowed to use encrypted variables for provider API keys.`);
7554
+ }
7555
+ if (variable.encrypted) {
7556
+ const bytes = CryptoJS4.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
7557
+ providerapikey = bytes.toString(CryptoJS4.enc.Utf8);
7558
+ }
7439
7559
  }
7440
7560
  const messagesWithoutPlaceholder = inputMessages.filter(
7441
7561
  (message) => message.metadata?.type !== "placeholder"
@@ -7627,17 +7747,20 @@ var ExuluMCP = class {
7627
7747
  }
7628
7748
  const variableName = agentInstance.providerapikey;
7629
7749
  const { db: db3 } = await postgresClient();
7630
- const variable = await db3.from("variables").where({ name: variableName }).first();
7631
- if (!variable) {
7632
- throw new Error("Provider API key variable not found.");
7633
- }
7634
- let providerapikey = variable.value;
7635
- if (!variable.encrypted) {
7636
- throw new Error("Provider API key variable not encrypted, for security reasons you are only allowed to use encrypted variables for provider API keys.");
7637
- }
7638
- if (variable.encrypted) {
7639
- const bytes = CryptoJS5.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
7640
- providerapikey = bytes.toString(CryptoJS5.enc.Utf8);
7750
+ let providerapikey;
7751
+ if (variableName) {
7752
+ const variable = await db3.from("variables").where({ name: variableName }).first();
7753
+ if (!variable) {
7754
+ throw new Error("Provider API key variable not found for " + agentInstance.name + " (" + agentInstance.id + ").");
7755
+ }
7756
+ providerapikey = variable.value;
7757
+ if (!variable.encrypted) {
7758
+ throw new Error("Provider API key variable not encrypted, for security reasons you are only allowed to use encrypted variables for provider API keys.");
7759
+ }
7760
+ if (variable.encrypted) {
7761
+ const bytes = CryptoJS5.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
7762
+ providerapikey = bytes.toString(CryptoJS5.enc.Utf8);
7763
+ }
7641
7764
  }
7642
7765
  console.log("[EXULU] Enabled tools", enabledTools?.map((x) => x.name + " (" + x.id + ")"));
7643
7766
  for (const tool2 of enabledTools || []) {
@@ -7961,6 +8084,68 @@ var claudeSonnet45Agent = new ExuluAgent2({
7961
8084
  }
7962
8085
  });
7963
8086
 
8087
+ // src/templates/agents/google/vertex/index.ts
8088
+ import { createVertex } from "@ai-sdk/google-vertex";
8089
+ var wrapperJsonGoogleAuth = `{
8090
+ "project": "project-name",
8091
+ "location": "europe-west1",
8092
+ "googleAuthOptions": {
8093
+ "credentials": {
8094
+ "type": "service_account",
8095
+ "project_id": "XX-XXXX",
8096
+ "private_key_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
8097
+ "private_key": "-----BEGIN PRIVATE KEY-----
8098
+ .... your private key ....
8099
+ -----END PRIVATE KEY-----
8100
+ ",
8101
+ "client_email": "xxxx@xxxx.gserviceaccount.com",
8102
+ "client_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
8103
+ "universe_domain": "googleapis.com"
8104
+ }
8105
+ }
8106
+ }`;
8107
+ var vertexGemini25FlashAgent = new ExuluAgent2({
8108
+ id: `default_vertex_gemini_2_5_flash_agent`,
8109
+ name: `GEMINI-2.5-FLASH`,
8110
+ provider: "vertex",
8111
+ description: `Google Vertex Gemini 2.5 Flash model. Very high intelligence and capability. Moderately Fast.`,
8112
+ type: "agent",
8113
+ capabilities: {
8114
+ text: true,
8115
+ images: [".png", ".jpg", ".jpeg", ".webp"],
8116
+ files: [".pdf", ".txt"],
8117
+ audio: [".mpeg", ".mp3", ".m4a", ".wav", ".mp4"],
8118
+ video: [".mp4", ".mpeg"]
8119
+ },
8120
+ authenticationInformation: `Vertex uses Google Auth, to authenticate you need to visit
8121
+ https://console.cloud.google.com/apis/credentials, create a service account, go to 'keys'
8122
+ and download the resulting JSON file, and copy the contents of the JSON file into an
8123
+ encrypted authentication variable in your IMP Agent Instance like this: ${wrapperJsonGoogleAuth}.`,
8124
+ maxContextLength: 1048576,
8125
+ config: {
8126
+ name: `GEMINI-2.5-FLASH`,
8127
+ instructions: "",
8128
+ model: {
8129
+ create: ({ apiKey }) => {
8130
+ console.log("[EXULU] apiKey", apiKey);
8131
+ if (!apiKey) {
8132
+ throw new Error("Auth credentials not found for Google Vertex agent, make sure you have set the provider api key to a valid google authentication json.");
8133
+ }
8134
+ const googleAuthPayload = JSON.parse(apiKey || "{}");
8135
+ if (!googleAuthPayload) {
8136
+ throw new Error("API key not found for Google Vertex Gemini 2.5 Flash agent.");
8137
+ }
8138
+ if (!googleAuthPayload.location) {
8139
+ throw new Error("Location not set in authentication json for Google Vertex Gemini 2.5 Flash agent, should be for example 'europe-west1'");
8140
+ }
8141
+ const vertex = createVertex(googleAuthPayload);
8142
+ const model = vertex("gemini-2.5-flash");
8143
+ return model;
8144
+ }
8145
+ }
8146
+ }
8147
+ });
8148
+
7964
8149
  // src/templates/agents/openai/gpt.ts
7965
8150
  import { createOpenAI } from "@ai-sdk/openai";
7966
8151
  var gpt5proAgent = new ExuluAgent2({
@@ -9374,6 +9559,7 @@ var ExuluApp = class {
9374
9559
  this._agents = [
9375
9560
  claudeSonnet4Agent,
9376
9561
  claudeOpus4Agent,
9562
+ vertexGemini25FlashAgent,
9377
9563
  claudeSonnet45Agent,
9378
9564
  gpt5MiniAgent,
9379
9565
  gpt5agent,
@@ -10853,6 +11039,7 @@ var {
10853
11039
  projectsSchema: projectsSchema3,
10854
11040
  jobResultsSchema: jobResultsSchema3,
10855
11041
  promptLibrarySchema: promptLibrarySchema3,
11042
+ embedderSettingsSchema: embedderSettingsSchema3,
10856
11043
  promptFavoritesSchema: promptFavoritesSchema3
10857
11044
  } = coreSchemas.get();
10858
11045
  var addMissingFields = async (knex, tableName, fields, skipFields = []) => {
@@ -10889,6 +11076,7 @@ var up = async function(knex) {
10889
11076
  projectsSchema3(),
10890
11077
  jobResultsSchema3(),
10891
11078
  promptLibrarySchema3(),
11079
+ embedderSettingsSchema3(),
10892
11080
  promptFavoritesSchema3(),
10893
11081
  rbacSchema3(),
10894
11082
  agentsSchema3(),
@@ -11110,6 +11298,9 @@ var ExuluDefaultAgents = {
11110
11298
  sonnet4: claudeSonnet4Agent,
11111
11299
  sonnet45: claudeSonnet45Agent
11112
11300
  },
11301
+ google: {
11302
+ vertexGemini25Flash: vertexGemini25FlashAgent
11303
+ },
11113
11304
  openai: {
11114
11305
  gpt5Mini: gpt5MiniAgent,
11115
11306
  gpt5: gpt5agent,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "1.34.0",
4
+ "version": "1.35.0",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {
@@ -32,6 +32,7 @@ export interface Agent {
32
32
  description: string;
33
33
  }[];
34
34
  maxContextLength?: number;
35
+ authenticationInformation?: string;
35
36
  capabilities?: {
36
37
  text: boolean;
37
38
  images: imageTypes[];
@@ -5,7 +5,15 @@ export interface Context {
5
5
  id: string
6
6
  name: string
7
7
  description: string
8
- embedder: string
8
+ embedder?: {
9
+ name: string,
10
+ id: string,
11
+ config?: {
12
+ name: string,
13
+ description: string,
14
+ default: string
15
+ }[]
16
+ }
9
17
  active: boolean
10
18
  slug: string
11
19
  sources: {