@exulu/backend 1.5.0 → 1.6.1

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.cjs CHANGED
@@ -45,7 +45,8 @@ __export(index_exports, {
45
45
  ExuluSource: () => ExuluSource,
46
46
  ExuluTool: () => ExuluTool,
47
47
  ExuluWorkflow: () => ExuluWorkflow,
48
- ExuluZodFileType: () => ExuluZodFileType
48
+ ExuluZodFileType: () => ExuluZodFileType,
49
+ db: () => db2
49
50
  });
50
51
  module.exports = __toCommonJS(index_exports);
51
52
  var import_config = require("dotenv/config");
@@ -142,6 +143,36 @@ var import_knex = __toESM(require("knex"), 1);
142
143
  var import_knex2 = require("knex");
143
144
  var import_knex3 = require("pgvector/knex");
144
145
  var db = {};
146
+ var databaseExistsChecked = false;
147
+ async function ensureDatabaseExists() {
148
+ console.log("[EXULU] Ensuring exulu database exists...");
149
+ const defaultKnex = (0, import_knex.default)({
150
+ client: "pg",
151
+ connection: {
152
+ host: process.env.POSTGRES_DB_HOST,
153
+ port: parseInt(process.env.POSTGRES_DB_PORT || "5432"),
154
+ user: process.env.POSTGRES_DB_USER,
155
+ database: "postgres",
156
+ // Connect to default database
157
+ password: process.env.POSTGRES_DB_PASSWORD,
158
+ ssl: process.env.POSTGRES_DB_SSL === "true" ? { rejectUnauthorized: false } : false
159
+ }
160
+ });
161
+ try {
162
+ const result = await defaultKnex.raw(`
163
+ SELECT 1 FROM pg_database WHERE datname = 'exulu'
164
+ `);
165
+ if (result.rows.length === 0) {
166
+ console.log("[EXULU] Database 'exulu' does not exist. Creating it...");
167
+ await defaultKnex.raw(`CREATE DATABASE exulu`);
168
+ console.log("[EXULU] Database 'exulu' created successfully.");
169
+ } else {
170
+ console.log("[EXULU] Database 'exulu' already exists.");
171
+ }
172
+ } finally {
173
+ await defaultKnex.destroy();
174
+ }
175
+ }
145
176
  async function postgresClient() {
146
177
  if (!db["exulu"]) {
147
178
  try {
@@ -151,6 +182,12 @@ async function postgresClient() {
151
182
  console.log("[EXULU] POSTGRES_DB_USER:", process.env.POSTGRES_DB_USER);
152
183
  console.log("[EXULU] POSTGRES_DB_PASSWORD:", process.env.POSTGRES_DB_PASSWORD);
153
184
  console.log("[EXULU] POSTGRES_DB_SSL:", process.env.POSTGRES_DB_SSL);
185
+ console.log("[EXULU] Database exists checked:", databaseExistsChecked);
186
+ if (!databaseExistsChecked) {
187
+ console.log("[EXULU] Ensuring exulu database exists...");
188
+ await ensureDatabaseExists();
189
+ databaseExistsChecked = true;
190
+ }
154
191
  const knex = (0, import_knex.default)({
155
192
  client: "pg",
156
193
  connection: {
@@ -224,7 +261,7 @@ var bullmqDecorator = async ({
224
261
  jobId: redisId
225
262
  }
226
263
  );
227
- const { db: db2 } = await postgresClient();
264
+ const { db: db3 } = await postgresClient();
228
265
  const now = /* @__PURE__ */ new Date();
229
266
  console.log("[EXULU] scheduling new job", inputs);
230
267
  const insertData = {
@@ -249,12 +286,12 @@ var bullmqDecorator = async ({
249
286
  ...documents && { documents: documents.map((doc2) => doc2.id) },
250
287
  ...trigger && { trigger }
251
288
  };
252
- await db2("jobs").insert(insertData).onConflict("redis").merge({
289
+ await db3("jobs").insert(insertData).onConflict("redis").merge({
253
290
  ...insertData,
254
291
  updatedAt: now
255
292
  // Only updatedAt changes on updates
256
293
  });
257
- const doc = await db2.from("jobs").where({ redis: job.id }).first();
294
+ const doc = await db3.from("jobs").where({ redis: job.id }).first();
258
295
  if (!doc?.id) {
259
296
  throw new Error("Failed to get job ID after insert/update");
260
297
  }
@@ -657,10 +694,10 @@ var ExuluWorkflow = class {
657
694
  label
658
695
  }) => {
659
696
  let inputs;
660
- const { db: db2 } = await postgresClient();
697
+ const { db: db3 } = await postgresClient();
661
698
  if (!job?.id) {
662
699
  logger.write(`Creating new job for workflow ${this.name} with inputs: ${JSON.stringify(initialInputs)}`, "INFO");
663
- const result = await db2("jobs").insert({
700
+ const result = await db3("jobs").insert({
664
701
  status: JOB_STATUS_ENUM.active,
665
702
  name: `Job running '${this.name}' for '${label}'`,
666
703
  agent,
@@ -678,7 +715,7 @@ var ExuluWorkflow = class {
678
715
  throw new Error("Job not found, or failed to be created.");
679
716
  }
680
717
  if (job.status !== JOB_STATUS_ENUM.active) {
681
- await db2("jobs").update({
718
+ await db3("jobs").update({
682
719
  status: JOB_STATUS_ENUM.active,
683
720
  inputs: initialInputs
684
721
  }).where({ id: job?.id }).returning("id");
@@ -721,15 +758,15 @@ var ExuluWorkflow = class {
721
758
  logger.write(`Step ${step.name} output: ${JSON.stringify(result)}`, "INFO");
722
759
  final = result;
723
760
  }
724
- await db2("jobs").update({
761
+ await db3("jobs").update({
725
762
  status: JOB_STATUS_ENUM.completed,
726
763
  result: JSON.stringify(final),
727
- finished_at: db2.fn.now()
764
+ finished_at: db3.fn.now()
728
765
  }).where({ id: job?.id }).returning("id");
729
766
  return final;
730
767
  } catch (error) {
731
768
  logger.write(`Workflow ${this.name} failed with error: ${error.message} for job ${job?.id}`, "ERROR");
732
- await db2("jobs").update({
769
+ await db3("jobs").update({
733
770
  status: JOB_STATUS_ENUM.failed,
734
771
  result: JSON.stringify({
735
772
  error: error.message || error,
@@ -842,8 +879,8 @@ var ExuluEval = class {
842
879
  </correct_answers>`
843
880
  });
844
881
  console.log("[EXULU] eval result", object);
845
- const { db: db2 } = await postgresClient();
846
- await db2("eval_results").insert({
882
+ const { db: db3 } = await postgresClient();
883
+ await db3("eval_results").insert({
847
884
  input: data.prompt,
848
885
  output: data.result,
849
886
  duration: data.duration,
@@ -854,8 +891,8 @@ var ExuluEval = class {
854
891
  comment: object.comment,
855
892
  category: data.category,
856
893
  metadata: data.metadata,
857
- createdAt: db2.fn.now(),
858
- updatedAt: db2.fn.now()
894
+ createdAt: db3.fn.now(),
895
+ updatedAt: db3.fn.now()
859
896
  });
860
897
  return {
861
898
  score: object.correctnessScore,
@@ -959,15 +996,15 @@ var ExuluContext = class {
959
996
  return sanitizeName(this.name) + "_chunks";
960
997
  };
961
998
  tableExists = async () => {
962
- const { db: db2 } = await postgresClient();
963
- const tableExists = await db2.schema.hasTable(this.getTableName());
999
+ const { db: db3 } = await postgresClient();
1000
+ const tableExists = await db3.schema.hasTable(this.getTableName());
964
1001
  return tableExists;
965
1002
  };
966
1003
  async updateItem(user, id, item) {
967
1004
  if (!id) {
968
1005
  throw new Error("Id is required for updating an item.");
969
1006
  }
970
- const { db: db2 } = await postgresClient();
1007
+ const { db: db3 } = await postgresClient();
971
1008
  Object.keys(item).forEach((key) => {
972
1009
  if (key === "name" || key === "description" || key === "external_id" || key === "tags" || key === "source" || key === "textLength" || key === "upsert" || key === "archived") {
973
1010
  return;
@@ -980,8 +1017,8 @@ var ExuluContext = class {
980
1017
  delete item.id;
981
1018
  delete item.created_at;
982
1019
  delete item.upsert;
983
- item.updated_at = db2.fn.now();
984
- const result = await db2.from(this.getTableName()).where({ id }).update(item).returning("id");
1020
+ item.updated_at = db3.fn.now();
1021
+ const result = await db3.from(this.getTableName()).where({ id }).update(item).returning("id");
985
1022
  if (this.configuration.calculateVectors === "onUpdate" || this.configuration.calculateVectors === "always") {
986
1023
  if (this.embedder.queue?.name) {
987
1024
  console.log("[EXULU] embedder is in queue mode, scheduling job.");
@@ -1005,18 +1042,18 @@ var ExuluContext = class {
1005
1042
  label: this.name,
1006
1043
  trigger: "agent"
1007
1044
  });
1008
- const exists = await db2.schema.hasTable(this.getChunksTableName());
1045
+ const exists = await db3.schema.hasTable(this.getChunksTableName());
1009
1046
  if (!exists) {
1010
1047
  await this.createChunksTable();
1011
1048
  }
1012
- await db2.from(this.getChunksTableName()).where({ source }).delete();
1013
- await db2.from(this.getChunksTableName()).insert(chunks.map((chunk) => ({
1049
+ await db3.from(this.getChunksTableName()).where({ source }).delete();
1050
+ await db3.from(this.getChunksTableName()).insert(chunks.map((chunk) => ({
1014
1051
  source,
1015
1052
  content: chunk.content,
1016
1053
  chunk_index: chunk.index,
1017
1054
  embedding: import_knex4.default.toSql(chunk.vector)
1018
1055
  })));
1019
- await db2.from(this.getTableName()).where({ id }).update({
1056
+ await db3.from(this.getTableName()).where({ id }).update({
1020
1057
  embeddings_updated_at: (/* @__PURE__ */ new Date()).toISOString()
1021
1058
  }).returning("id");
1022
1059
  }
@@ -1029,9 +1066,9 @@ var ExuluContext = class {
1029
1066
  if (!item.name) {
1030
1067
  throw new Error("Name field is required.");
1031
1068
  }
1032
- const { db: db2 } = await postgresClient();
1069
+ const { db: db3 } = await postgresClient();
1033
1070
  if (item.external_id) {
1034
- const existingItem = await db2.from(this.getTableName()).where({ external_id: item.external_id }).first();
1071
+ const existingItem = await db3.from(this.getTableName()).where({ external_id: item.external_id }).first();
1035
1072
  if (existingItem && !upsert) {
1036
1073
  throw new Error("Item with external id " + item.external_id + " already exists.");
1037
1074
  }
@@ -1041,7 +1078,7 @@ var ExuluContext = class {
1041
1078
  }
1042
1079
  }
1043
1080
  if (upsert && item.id) {
1044
- const existingItem = await db2.from(this.getTableName()).where({ id: item.id }).first();
1081
+ const existingItem = await db3.from(this.getTableName()).where({ id: item.id }).first();
1045
1082
  if (existingItem && upsert) {
1046
1083
  await this.updateItem(user, existingItem.id, item);
1047
1084
  return existingItem.id;
@@ -1058,11 +1095,11 @@ var ExuluContext = class {
1058
1095
  });
1059
1096
  delete item.id;
1060
1097
  delete item.upsert;
1061
- const result = await db2.from(this.getTableName()).insert({
1098
+ const result = await db3.from(this.getTableName()).insert({
1062
1099
  ...item,
1063
- id: db2.fn.uuid(),
1064
- created_at: db2.fn.now(),
1065
- updated_at: db2.fn.now()
1100
+ id: db3.fn.uuid(),
1101
+ created_at: db3.fn.now(),
1102
+ updated_at: db3.fn.now()
1066
1103
  }).returning("id");
1067
1104
  if (this.configuration.calculateVectors === "onInsert" || this.configuration.calculateVectors === "always") {
1068
1105
  if (this.embedder.queue?.name) {
@@ -1088,18 +1125,18 @@ var ExuluContext = class {
1088
1125
  label: this.name,
1089
1126
  trigger: "agent"
1090
1127
  });
1091
- const exists = await db2.schema.hasTable(this.getChunksTableName());
1128
+ const exists = await db3.schema.hasTable(this.getChunksTableName());
1092
1129
  if (!exists) {
1093
1130
  await this.createChunksTable();
1094
1131
  }
1095
1132
  console.log("[EXULU] Inserting chunks.");
1096
- await db2.from(this.getChunksTableName()).insert(chunks.map((chunk) => ({
1133
+ await db3.from(this.getChunksTableName()).insert(chunks.map((chunk) => ({
1097
1134
  source,
1098
1135
  content: chunk.content,
1099
1136
  chunk_index: chunk.index,
1100
1137
  embedding: import_knex4.default.toSql(chunk.vector)
1101
1138
  })));
1102
- await db2.from(this.getTableName()).where({ id: result[0].id }).update({
1139
+ await db3.from(this.getTableName()).where({ id: result[0].id }).update({
1103
1140
  embeddings_updated_at: (/* @__PURE__ */ new Date()).toISOString()
1104
1141
  }).returning("id");
1105
1142
  }
@@ -1129,10 +1166,10 @@ var ExuluContext = class {
1129
1166
  if (limit < 1) limit = 10;
1130
1167
  let offset = (page - 1) * limit;
1131
1168
  const mainTable = this.getTableName();
1132
- const { db: db2 } = await postgresClient();
1133
- const columns = await db2(mainTable).columnInfo();
1134
- const totalQuery = db2.count("* as count").from(mainTable).first();
1135
- const itemsQuery = db2.select(Object.keys(columns).map((column) => mainTable + "." + column)).from(mainTable).offset(offset).limit(limit);
1169
+ const { db: db3 } = await postgresClient();
1170
+ const columns = await db3(mainTable).columnInfo();
1171
+ const totalQuery = db3.count("* as count").from(mainTable).first();
1172
+ const itemsQuery = db3.select(Object.keys(columns).map((column) => mainTable + "." + column)).from(mainTable).offset(offset).limit(limit);
1136
1173
  if (sort) {
1137
1174
  itemsQuery.orderBy(sort, order === "desc" ? "desc" : "asc");
1138
1175
  }
@@ -1208,29 +1245,29 @@ var ExuluContext = class {
1208
1245
  const vectorExpr = `${vectorStr}::vector`;
1209
1246
  switch (method) {
1210
1247
  case "l1Distance":
1211
- itemsQuery.select(db2.raw(`?? <-> ${vectorExpr} as l1_distance`, [`${chunksTable}.embedding`]));
1212
- itemsQuery.orderByRaw(db2.raw(`?? <-> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1248
+ itemsQuery.select(db3.raw(`?? <-> ${vectorExpr} as l1_distance`, [`${chunksTable}.embedding`]));
1249
+ itemsQuery.orderByRaw(db3.raw(`?? <-> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1213
1250
  break;
1214
1251
  case "l2Distance":
1215
- itemsQuery.select(db2.raw(`?? <-> ${vectorExpr} as l2_distance`, [`${chunksTable}.embedding`]));
1216
- itemsQuery.orderByRaw(db2.raw(`?? <-> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1252
+ itemsQuery.select(db3.raw(`?? <-> ${vectorExpr} as l2_distance`, [`${chunksTable}.embedding`]));
1253
+ itemsQuery.orderByRaw(db3.raw(`?? <-> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1217
1254
  break;
1218
1255
  case "hammingDistance":
1219
- itemsQuery.select(db2.raw(`?? <#> ${vectorExpr} as hamming_distance`, [`${chunksTable}.embedding`]));
1220
- itemsQuery.orderByRaw(db2.raw(`?? <#> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1256
+ itemsQuery.select(db3.raw(`?? <#> ${vectorExpr} as hamming_distance`, [`${chunksTable}.embedding`]));
1257
+ itemsQuery.orderByRaw(db3.raw(`?? <#> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1221
1258
  break;
1222
1259
  case "jaccardDistance":
1223
- itemsQuery.select(db2.raw(`?? <#> ${vectorExpr} as jaccard_distance`, [`${chunksTable}.embedding`]));
1224
- itemsQuery.orderByRaw(db2.raw(`?? <#> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1260
+ itemsQuery.select(db3.raw(`?? <#> ${vectorExpr} as jaccard_distance`, [`${chunksTable}.embedding`]));
1261
+ itemsQuery.orderByRaw(db3.raw(`?? <#> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1225
1262
  break;
1226
1263
  case "maxInnerProduct":
1227
- itemsQuery.select(db2.raw(`?? <#> ${vectorExpr} as inner_product`, [`${chunksTable}.embedding`]));
1228
- itemsQuery.orderByRaw(db2.raw(`?? <#> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1264
+ itemsQuery.select(db3.raw(`?? <#> ${vectorExpr} as inner_product`, [`${chunksTable}.embedding`]));
1265
+ itemsQuery.orderByRaw(db3.raw(`?? <#> ${vectorExpr} ASC`, [`${chunksTable}.embedding`]));
1229
1266
  break;
1230
1267
  case "cosineDistance":
1231
1268
  default:
1232
- itemsQuery.select(db2.raw(`1 - (?? <#> ${vectorExpr}) as cosine_distance`, [`${chunksTable}.embedding`]));
1233
- itemsQuery.orderByRaw(db2.raw(`1 - (?? <#> ${vectorExpr}) DESC`, [`${chunksTable}.embedding`]));
1269
+ itemsQuery.select(db3.raw(`1 - (?? <#> ${vectorExpr}) as cosine_distance`, [`${chunksTable}.embedding`]));
1270
+ itemsQuery.orderByRaw(db3.raw(`1 - (?? <#> ${vectorExpr}) DESC`, [`${chunksTable}.embedding`]));
1234
1271
  break;
1235
1272
  }
1236
1273
  let items = await itemsQuery;
@@ -1299,12 +1336,12 @@ var ExuluContext = class {
1299
1336
  }
1300
1337
  };
1301
1338
  createItemsTable = async () => {
1302
- const { db: db2 } = await postgresClient();
1339
+ const { db: db3 } = await postgresClient();
1303
1340
  const tableName = this.getTableName();
1304
1341
  console.log("[EXULU] Creating table: " + tableName);
1305
- return await db2.schema.createTable(tableName, (table) => {
1342
+ return await db3.schema.createTable(tableName, (table) => {
1306
1343
  console.log("[EXULU] Creating fields for table.", this.fields);
1307
- table.uuid("id").primary().defaultTo(db2.fn.uuid());
1344
+ table.uuid("id").primary().defaultTo(db3.fn.uuid());
1308
1345
  table.text("name");
1309
1346
  table.text("description");
1310
1347
  table.text("tags");
@@ -1324,11 +1361,11 @@ var ExuluContext = class {
1324
1361
  });
1325
1362
  };
1326
1363
  createChunksTable = async () => {
1327
- const { db: db2 } = await postgresClient();
1364
+ const { db: db3 } = await postgresClient();
1328
1365
  const tableName = this.getChunksTableName();
1329
1366
  console.log("[EXULU] Creating table: " + tableName);
1330
- return await db2.schema.createTable(tableName, (table) => {
1331
- table.uuid("id").primary().defaultTo(db2.fn.uuid());
1367
+ return await db3.schema.createTable(tableName, (table) => {
1368
+ table.uuid("id").primary().defaultTo(db3.fn.uuid());
1332
1369
  table.uuid("source").references("id").inTable(this.getTableName());
1333
1370
  table.text("content");
1334
1371
  table.integer("chunk_index");
@@ -1400,15 +1437,15 @@ var ExuluSource = class {
1400
1437
  };
1401
1438
  var updateStatistic = async (statistic) => {
1402
1439
  const currentDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1403
- const { db: db2 } = await postgresClient();
1404
- const existing = await db2.from("statistics").where({
1440
+ const { db: db3 } = await postgresClient();
1441
+ const existing = await db3.from("statistics").where({
1405
1442
  name: statistic.name,
1406
1443
  label: statistic.label,
1407
1444
  type: statistic.type,
1408
1445
  createdAt: currentDate
1409
1446
  }).first();
1410
1447
  if (!existing) {
1411
- await db2.from("statistics").insert({
1448
+ await db3.from("statistics").insert({
1412
1449
  name: statistic.name,
1413
1450
  label: statistic.label,
1414
1451
  type: statistic.type,
@@ -1416,8 +1453,8 @@ var updateStatistic = async (statistic) => {
1416
1453
  createdAt: currentDate
1417
1454
  });
1418
1455
  } else {
1419
- await db2.from("statistics").update({
1420
- total: db2.raw("total + ?", [statistic.count ?? 1])
1456
+ await db3.from("statistics").update({
1457
+ total: db3.raw("total + ?", [statistic.count ?? 1])
1421
1458
  }).where({
1422
1459
  name: statistic.name,
1423
1460
  label: statistic.label,
@@ -1495,7 +1532,7 @@ var authentication = async ({
1495
1532
  apikey,
1496
1533
  authtoken,
1497
1534
  internalkey,
1498
- db: db2
1535
+ db: db3
1499
1536
  }) => {
1500
1537
  if (internalkey) {
1501
1538
  if (!process.env.INTERNAL_SECRET) {
@@ -1532,7 +1569,7 @@ var authentication = async ({
1532
1569
  code: 401
1533
1570
  };
1534
1571
  }
1535
- const user = await db2.from("users").select("*").where("email", authtoken?.email).first();
1572
+ const user = await db3.from("users").select("*").where("email", authtoken?.email).first();
1536
1573
  if (!user) {
1537
1574
  return {
1538
1575
  error: true,
@@ -1555,7 +1592,7 @@ var authentication = async ({
1555
1592
  }
1556
1593
  }
1557
1594
  if (apikey) {
1558
- const users = await db2.from("users").select("*").where("type", "api");
1595
+ const users = await db3.from("users").select("*").where("type", "api");
1559
1596
  if (!users || users.length === 0) {
1560
1597
  return {
1561
1598
  error: true,
@@ -1587,7 +1624,7 @@ var authentication = async ({
1587
1624
  const user_key_compare_value = user.apikey.substring(0, user_key_last_slash_index);
1588
1625
  const isMatch = await import_bcryptjs.default.compare(request_key_compare_value, user_key_compare_value);
1589
1626
  if (isMatch) {
1590
- await db2.from("users").where({ id: user.id }).update({
1627
+ await db3.from("users").where({ id: user.id }).update({
1591
1628
  last_used: /* @__PURE__ */ new Date()
1592
1629
  }).returning("id");
1593
1630
  return {
@@ -1615,7 +1652,7 @@ var authentication = async ({
1615
1652
  var requestValidators = {
1616
1653
  authenticate: async (req) => {
1617
1654
  const apikey = req.headers["exulu-api-key"] || null;
1618
- const { db: db2 } = await postgresClient();
1655
+ const { db: db3 } = await postgresClient();
1619
1656
  let authtoken = null;
1620
1657
  if (typeof apikey !== "string") {
1621
1658
  authtoken = await getToken((req.headers["authorization"] || req.headers["x-api-key"]) ?? "");
@@ -1623,7 +1660,7 @@ var requestValidators = {
1623
1660
  return await authentication({
1624
1661
  authtoken,
1625
1662
  apikey,
1626
- db: db2
1663
+ db: db3
1627
1664
  });
1628
1665
  },
1629
1666
  workflows: (req) => {
@@ -1966,11 +2003,11 @@ function createMutations(table) {
1966
2003
  const tableNameSingular = table.name.singular.toLowerCase();
1967
2004
  return {
1968
2005
  [`${tableNamePlural}CreateOne`]: async (_, args, context, info) => {
1969
- const { db: db2 } = context;
2006
+ const { db: db3 } = context;
1970
2007
  const requestedFields = getRequestedFields(info);
1971
2008
  let { input } = args;
1972
2009
  input = encryptSensitiveFields(input);
1973
- const results = await db2(tableNamePlural).insert({
2010
+ const results = await db3(tableNamePlural).insert({
1974
2011
  ...input,
1975
2012
  createdAt: /* @__PURE__ */ new Date(),
1976
2013
  updatedAt: /* @__PURE__ */ new Date()
@@ -1978,43 +2015,43 @@ function createMutations(table) {
1978
2015
  return results[0];
1979
2016
  },
1980
2017
  [`${tableNamePlural}UpdateOne`]: async (_, args, context, info) => {
1981
- const { db: db2 } = context;
2018
+ const { db: db3 } = context;
1982
2019
  let { where, input } = args;
1983
2020
  input = encryptSensitiveFields(input);
1984
- await db2(tableNamePlural).where(where).update({
2021
+ await db3(tableNamePlural).where(where).update({
1985
2022
  ...input,
1986
2023
  updatedAt: /* @__PURE__ */ new Date()
1987
2024
  });
1988
2025
  const requestedFields = getRequestedFields(info);
1989
- const result = await db2.from(tableNamePlural).select(requestedFields).where(where).first();
2026
+ const result = await db3.from(tableNamePlural).select(requestedFields).where(where).first();
1990
2027
  return result;
1991
2028
  },
1992
2029
  [`${tableNamePlural}UpdateOneById`]: async (_, args, context, info) => {
1993
2030
  let { id, input } = args;
1994
2031
  input = encryptSensitiveFields(input);
1995
- const { db: db2 } = context;
1996
- await db2(tableNamePlural).where({ id }).update({
2032
+ const { db: db3 } = context;
2033
+ await db3(tableNamePlural).where({ id }).update({
1997
2034
  ...input,
1998
2035
  updatedAt: /* @__PURE__ */ new Date()
1999
2036
  });
2000
2037
  const requestedFields = getRequestedFields(info);
2001
- const result = await db2.from(tableNamePlural).select(requestedFields).where({ id }).first();
2038
+ const result = await db3.from(tableNamePlural).select(requestedFields).where({ id }).first();
2002
2039
  return result;
2003
2040
  },
2004
2041
  [`${tableNamePlural}RemoveOne`]: async (_, args, context, info) => {
2005
- const { db: db2 } = context;
2042
+ const { db: db3 } = context;
2006
2043
  const { where } = args;
2007
2044
  const requestedFields = getRequestedFields(info);
2008
- const result = await db2.from(tableNamePlural).select(requestedFields).where(where).first();
2009
- await db2(tableNamePlural).where(where).del();
2045
+ const result = await db3.from(tableNamePlural).select(requestedFields).where(where).first();
2046
+ await db3(tableNamePlural).where(where).del();
2010
2047
  return result;
2011
2048
  },
2012
2049
  [`${tableNamePlural}RemoveOneById`]: async (_, args, context, info) => {
2013
2050
  const { id } = args;
2014
- const { db: db2 } = context;
2051
+ const { db: db3 } = context;
2015
2052
  const requestedFields = getRequestedFields(info);
2016
- const result = await db2.from(tableNamePlural).select(requestedFields).where({ id }).first();
2017
- await db2(tableNamePlural).where({ id }).del();
2053
+ const result = await db3.from(tableNamePlural).select(requestedFields).where({ id }).first();
2054
+ await db3(tableNamePlural).where({ id }).del();
2018
2055
  return result;
2019
2056
  }
2020
2057
  };
@@ -2051,16 +2088,16 @@ function createQueries(table) {
2051
2088
  };
2052
2089
  return {
2053
2090
  [`${tableNameSingular}ById`]: async (_, args, context, info) => {
2054
- const { db: db2 } = context;
2091
+ const { db: db3 } = context;
2055
2092
  const requestedFields = getRequestedFields(info);
2056
- const result = await db2.from(tableNamePlural).select(requestedFields).where({ id: args.id }).first();
2093
+ const result = await db3.from(tableNamePlural).select(requestedFields).where({ id: args.id }).first();
2057
2094
  return result;
2058
2095
  },
2059
2096
  [`${tableNameSingular}One`]: async (_, args, context, info) => {
2060
2097
  const { filters = [], sort } = args;
2061
- const { db: db2 } = context;
2098
+ const { db: db3 } = context;
2062
2099
  const requestedFields = getRequestedFields(info);
2063
- let query = db2.from(tableNamePlural).select(requestedFields);
2100
+ let query = db3.from(tableNamePlural).select(requestedFields);
2064
2101
  query = applyFilters(query, filters);
2065
2102
  query = applySorting(query, sort);
2066
2103
  const result = await query.first();
@@ -2068,8 +2105,8 @@ function createQueries(table) {
2068
2105
  },
2069
2106
  [`${tableNamePlural}Pagination`]: async (_, args, context, info) => {
2070
2107
  const { limit = 10, page = 0, filters = [], sort } = args;
2071
- const { db: db2 } = context;
2072
- let baseQuery = db2(tableNamePlural);
2108
+ const { db: db3 } = context;
2109
+ let baseQuery = db3(tableNamePlural);
2073
2110
  baseQuery = applyFilters(baseQuery, filters);
2074
2111
  const [{ count }] = await baseQuery.clone().count("* as count");
2075
2112
  const itemCount = Number(count);
@@ -2099,8 +2136,8 @@ function createQueries(table) {
2099
2136
  ...tableNamePlural === "jobs" ? {
2100
2137
  jobStatistics: async (_, args, context, info) => {
2101
2138
  const { user, agent, from, to } = args;
2102
- const { db: db2 } = context;
2103
- let query = db2("jobs");
2139
+ const { db: db3 } = context;
2140
+ let query = db3("jobs");
2104
2141
  if (user) {
2105
2142
  query = query.where("user", user);
2106
2143
  }
@@ -2117,7 +2154,7 @@ function createQueries(table) {
2117
2154
  const [{ completedCount }] = await completedQuery.count("* as completedCount");
2118
2155
  const failedQuery = query.clone().where("status", "failed");
2119
2156
  const [{ failedCount }] = await failedQuery.count("* as failedCount");
2120
- const durationQuery = query.clone().where("status", "completed").whereNotNull("duration").select(db2.raw('AVG("duration") as averageDuration'));
2157
+ const durationQuery = query.clone().where("status", "completed").whereNotNull("duration").select(db3.raw('AVG("duration") as averageDuration'));
2121
2158
  const [{ averageDuration }] = await durationQuery;
2122
2159
  return {
2123
2160
  completedCount: Number(completedCount),
@@ -2634,11 +2671,11 @@ var createUppyRoutes = async (app) => {
2634
2671
  if (typeof apikey !== "string") {
2635
2672
  authtoken = await getToken(req.headers.authorization ?? "");
2636
2673
  }
2637
- const { db: db2 } = await postgresClient();
2674
+ const { db: db3 } = await postgresClient();
2638
2675
  const authenticationResult = await authentication({
2639
2676
  authtoken,
2640
2677
  apikey,
2641
- db: db2
2678
+ db: db3
2642
2679
  });
2643
2680
  if (!authenticationResult.user?.id) {
2644
2681
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
@@ -2679,7 +2716,7 @@ var createUppyRoutes = async (app) => {
2679
2716
  app.get("/s3/download", async (req, res, next) => {
2680
2717
  const apikey = req.headers["exulu-api-key"] || null;
2681
2718
  const internalkey = req.headers["internal-key"] || null;
2682
- const { db: db2 } = await postgresClient();
2719
+ const { db: db3 } = await postgresClient();
2683
2720
  let authtoken = null;
2684
2721
  if (typeof apikey !== "string" && typeof internalkey !== "string") {
2685
2722
  authtoken = await getToken(req.headers.authorization ?? "");
@@ -2688,7 +2725,7 @@ var createUppyRoutes = async (app) => {
2688
2725
  authtoken,
2689
2726
  apikey,
2690
2727
  internalkey,
2691
- db: db2
2728
+ db: db3
2692
2729
  });
2693
2730
  if (!authenticationResult.user?.id) {
2694
2731
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
@@ -2752,7 +2789,7 @@ var createUppyRoutes = async (app) => {
2752
2789
  const generateS3Key = (filename) => `${crypto.randomUUID()}-${filename}`;
2753
2790
  const signOnServer = async (req, res, next) => {
2754
2791
  const apikey = req.headers["exulu-api-key"] || null;
2755
- const { db: db2 } = await postgresClient();
2792
+ const { db: db3 } = await postgresClient();
2756
2793
  let authtoken = null;
2757
2794
  if (typeof apikey !== "string") {
2758
2795
  authtoken = await getToken(req.headers.authorization ?? "");
@@ -2760,7 +2797,7 @@ var createUppyRoutes = async (app) => {
2760
2797
  const authenticationResult = await authentication({
2761
2798
  authtoken,
2762
2799
  apikey,
2763
- db: db2
2800
+ db: db3
2764
2801
  });
2765
2802
  if (!authenticationResult.user?.id) {
2766
2803
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
@@ -2800,7 +2837,7 @@ var createUppyRoutes = async (app) => {
2800
2837
  });
2801
2838
  app.post("/s3/multipart", async (req, res, next) => {
2802
2839
  const apikey = req.headers["exulu-api-key"] || null;
2803
- const { db: db2 } = await postgresClient();
2840
+ const { db: db3 } = await postgresClient();
2804
2841
  let authtoken = null;
2805
2842
  if (typeof apikey !== "string") {
2806
2843
  authtoken = await getToken(req.headers.authorization ?? "");
@@ -2808,7 +2845,7 @@ var createUppyRoutes = async (app) => {
2808
2845
  const authenticationResult = await authentication({
2809
2846
  authtoken,
2810
2847
  apikey,
2811
- db: db2
2848
+ db: db3
2812
2849
  });
2813
2850
  if (!authenticationResult.user?.id) {
2814
2851
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
@@ -2992,6 +3029,7 @@ var global_queues = {
2992
3029
  logs_cleaner: "logs-cleaner"
2993
3030
  };
2994
3031
  var createRecurringJobs = async () => {
3032
+ console.log("[EXULU] creating recurring jobs.");
2995
3033
  const recurringJobSchedulersLogs = [];
2996
3034
  const queue = queues.use(global_queues.logs_cleaner);
2997
3035
  recurringJobSchedulersLogs.push({
@@ -3019,7 +3057,7 @@ var createRecurringJobs = async () => {
3019
3057
  }
3020
3058
  }
3021
3059
  );
3022
- console.log("Recurring job schedulers:");
3060
+ console.log("[EXULU] recurring job schedulers:");
3023
3061
  console.table(recurringJobSchedulersLogs);
3024
3062
  return queue;
3025
3063
  };
@@ -3112,10 +3150,10 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3112
3150
  if (!authenticationResult.user?.id) {
3113
3151
  throw new Error(authenticationResult.message);
3114
3152
  }
3115
- const { db: db2 } = await postgresClient();
3153
+ const { db: db3 } = await postgresClient();
3116
3154
  return {
3117
3155
  req,
3118
- db: db2
3156
+ db: db3
3119
3157
  };
3120
3158
  }
3121
3159
  })
@@ -3134,8 +3172,8 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3134
3172
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
3135
3173
  return;
3136
3174
  }
3137
- const { db: db2 } = await postgresClient();
3138
- const agentsFromDb = await db2.from("agents").select("*");
3175
+ const { db: db3 } = await postgresClient();
3176
+ const agentsFromDb = await db3.from("agents").select("*");
3139
3177
  res.status(200).json(agentsFromDb.map((agent) => {
3140
3178
  const backend = agents.find((a) => a.id === agent.backend);
3141
3179
  if (!backend) {
@@ -3166,7 +3204,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3166
3204
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
3167
3205
  return;
3168
3206
  }
3169
- const { db: db2 } = await postgresClient();
3207
+ const { db: db3 } = await postgresClient();
3170
3208
  const id = req.params.id;
3171
3209
  if (!id) {
3172
3210
  res.status(400).json({
@@ -3174,7 +3212,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3174
3212
  });
3175
3213
  return;
3176
3214
  }
3177
- const agent = await db2.from("agents").where({ id }).first();
3215
+ const agent = await db3.from("agents").where({ id }).first();
3178
3216
  if (!agent) {
3179
3217
  res.status(400).json({
3180
3218
  message: "Agent not found in database."
@@ -3240,7 +3278,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3240
3278
  if (!id && !external_id) {
3241
3279
  throw new Error("Missing id or external_id in request.");
3242
3280
  }
3243
- const { db: db2 } = await postgresClient();
3281
+ const { db: db3 } = await postgresClient();
3244
3282
  const context = contexts.find((context2) => context2.id === contextId);
3245
3283
  if (!context) {
3246
3284
  throw new Error("Context not found in registry.");
@@ -3249,7 +3287,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3249
3287
  if (!exists) {
3250
3288
  throw new Error("Table with name " + context.getTableName() + " does not exist.");
3251
3289
  }
3252
- const query = db2.from(context.getTableName()).select("id");
3290
+ const query = db3.from(context.getTableName()).select("id");
3253
3291
  if (id) {
3254
3292
  query.where({ id });
3255
3293
  }
@@ -3260,11 +3298,11 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3260
3298
  if (!item) {
3261
3299
  return null;
3262
3300
  }
3263
- const chunks = await db2.from(context.getChunksTableName()).where({ source: item.id }).select("id");
3301
+ const chunks = await db3.from(context.getChunksTableName()).where({ source: item.id }).select("id");
3264
3302
  if (chunks.length > 0) {
3265
- await db2.from(context.getChunksTableName()).where({ source: item.id }).delete();
3303
+ await db3.from(context.getChunksTableName()).where({ source: item.id }).delete();
3266
3304
  }
3267
- const mutation = db2.from(context.getTableName()).where({ id: item.id }).delete().returning("id");
3305
+ const mutation = db3.from(context.getTableName()).where({ id: item.id }).delete().returning("id");
3268
3306
  const result = await mutation;
3269
3307
  return result;
3270
3308
  };
@@ -3319,7 +3357,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3319
3357
  });
3320
3358
  return;
3321
3359
  }
3322
- const { db: db2 } = await postgresClient();
3360
+ const { db: db3 } = await postgresClient();
3323
3361
  const context = contexts.find((context2) => context2.id === req.params.context);
3324
3362
  if (!context) {
3325
3363
  res.status(400).json({
@@ -3331,11 +3369,11 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3331
3369
  if (!itemsTableExists) {
3332
3370
  await context.createItemsTable();
3333
3371
  }
3334
- const chunksTableExists = await db2.schema.hasTable(context.getChunksTableName());
3372
+ const chunksTableExists = await db3.schema.hasTable(context.getChunksTableName());
3335
3373
  if (!chunksTableExists) {
3336
3374
  await context.createChunksTable();
3337
3375
  }
3338
- const item = await db2.from(context.getTableName()).where({ id: req.params.id }).select("*").first();
3376
+ const item = await db3.from(context.getTableName()).where({ id: req.params.id }).select("*").first();
3339
3377
  if (!item) {
3340
3378
  res.status(404).json({
3341
3379
  message: "Item not found."
@@ -3343,7 +3381,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3343
3381
  return;
3344
3382
  }
3345
3383
  console.log("[EXULU] chunks table name.", context.getChunksTableName());
3346
- const chunks = await db2.from(context.getChunksTableName()).where({ source: req.params.id }).select("id", "content", "source", "embedding", "chunk_index", "created_at", "updated_at");
3384
+ const chunks = await db3.from(context.getChunksTableName()).where({ source: req.params.id }).select("id", "content", "source", "embedding", "chunk_index", "created_at", "updated_at");
3347
3385
  console.log("[EXULU] chunks", chunks);
3348
3386
  res.status(200).json({
3349
3387
  ...item,
@@ -3593,7 +3631,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3593
3631
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
3594
3632
  return;
3595
3633
  }
3596
- const { db: db2 } = await postgresClient();
3634
+ const { db: db3 } = await postgresClient();
3597
3635
  const type = req.body.type;
3598
3636
  if (!Object.values(STATISTICS_TYPE_ENUM).includes(type)) {
3599
3637
  res.status(400).json({
@@ -3607,7 +3645,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3607
3645
  from = new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3);
3608
3646
  to = /* @__PURE__ */ new Date();
3609
3647
  }
3610
- const query = db2.from("statistics").select("*");
3648
+ const query = db3.from("statistics").select("*");
3611
3649
  query.where("name", "count");
3612
3650
  query.andWhere("type", type);
3613
3651
  query.andWhere("createdAt", ">=", from);
@@ -3642,7 +3680,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3642
3680
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
3643
3681
  return;
3644
3682
  }
3645
- const { db: db2 } = await postgresClient();
3683
+ const { db: db3 } = await postgresClient();
3646
3684
  let from = new Date(req.body.from);
3647
3685
  let to = new Date(req.body.to);
3648
3686
  if (!from || !to) {
@@ -3650,7 +3688,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3650
3688
  to = /* @__PURE__ */ new Date();
3651
3689
  }
3652
3690
  let promises2 = Object.values(STATISTICS_TYPE_ENUM).map(async (type) => {
3653
- const result = await db2.from("statistics").where("name", "count").andWhere("type", type).andWhere("createdAt", ">=", from).andWhere("createdAt", "<=", to).sum("total as total");
3691
+ const result = await db3.from("statistics").where("name", "count").andWhere("type", type).andWhere("createdAt", ">=", from).andWhere("createdAt", "<=", to).sum("total as total");
3654
3692
  return {
3655
3693
  [type]: result[0]?.total || 0
3656
3694
  };
@@ -3671,9 +3709,9 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3671
3709
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
3672
3710
  return;
3673
3711
  }
3674
- const { db: db2 } = await postgresClient();
3675
- const statistics = await db2("statistics").where("name", "count").andWhere("type", "context.retrieve").sum("total as total").first();
3676
- const response = await db2("jobs").select(db2.raw(`to_char("createdAt", 'YYYY-MM-DD') as date`)).count("* as count").where("type", "embedder").groupByRaw(`to_char("createdAt", 'YYYY-MM-DD')`).then((rows) => ({
3712
+ const { db: db3 } = await postgresClient();
3713
+ const statistics = await db3("statistics").where("name", "count").andWhere("type", "context.retrieve").sum("total as total").first();
3714
+ const response = await db3("jobs").select(db3.raw(`to_char("createdAt", 'YYYY-MM-DD') as date`)).count("* as count").where("type", "embedder").groupByRaw(`to_char("createdAt", 'YYYY-MM-DD')`).then((rows) => ({
3677
3715
  jobs: rows
3678
3716
  }));
3679
3717
  let jobs = [];
@@ -3683,7 +3721,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3683
3721
  count: job.count
3684
3722
  }));
3685
3723
  }
3686
- const embeddingsCountResult = await db2("jobs").where("type", "embedder").count("* as count").first();
3724
+ const embeddingsCountResult = await db3("jobs").where("type", "embedder").count("* as count").first();
3687
3725
  res.status(200).json({
3688
3726
  active: contexts.filter((context) => context.active).length,
3689
3727
  inactive: contexts.filter((context) => !context.active).length,
@@ -3883,8 +3921,8 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
3883
3921
  });
3884
3922
  return;
3885
3923
  }
3886
- const { db: db2 } = await postgresClient();
3887
- const agentInstance = await db2.from("agents").where({
3924
+ const { db: db3 } = await postgresClient();
3925
+ const agentInstance = await db3.from("agents").where({
3888
3926
  id: instance
3889
3927
  }).first();
3890
3928
  if (!agentInstance) {
@@ -4019,26 +4057,18 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
4019
4057
  app.use("/gateway/anthropic/:id", import_express3.default.raw({ type: "*/*", limit: REQUEST_SIZE_LIMIT }), async (req, res) => {
4020
4058
  const path3 = req.url;
4021
4059
  const url = `${TARGET_API}${path3}`;
4022
- console.log("[PROXY] Manual proxy to:", url);
4023
- console.log("[PROXY] Method:", req.method);
4024
- console.log("[PROXY] Headers:", Object.keys(req.headers));
4025
- console.log("[PROXY] Request body length:", req.body ? req.body.length : 0);
4026
- console.log("[PROXY] Request model name:", req.body.model);
4027
- console.log("[PROXY] Request stream:", req.body.stream);
4028
- console.log("[PROXY] Request messages:", req.body.messages?.length);
4029
4060
  try {
4030
- console.log("[PROXY] Request body tools array length:", req.body.tools?.length);
4031
4061
  if (!req.body.tools) {
4032
4062
  req.body.tools = [];
4033
4063
  }
4034
4064
  const authenticationResult = await requestValidators.authenticate(req);
4035
4065
  if (!authenticationResult.user?.id) {
4066
+ console.log("[EXULU] failed authentication result", authenticationResult);
4036
4067
  res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
4037
4068
  return;
4038
4069
  }
4039
- console.log("[EXULU] authentication result", authenticationResult);
4040
- const { db: db2 } = await postgresClient();
4041
- const agent = await db2.from("agents").where({
4070
+ const { db: db3 } = await postgresClient();
4071
+ const agent = await db3.from("agents").where({
4042
4072
  id: req.params.id
4043
4073
  }).first();
4044
4074
  if (!agent) {
@@ -4049,7 +4079,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
4049
4079
  res.end(Buffer.from(arrayBuffer));
4050
4080
  return;
4051
4081
  }
4052
- console.log("[EXULU] agent", agent?.name);
4082
+ console.log("[EXULU] anthropic proxy called for agent:", agent?.name);
4053
4083
  if (!process.env.NEXTAUTH_SECRET) {
4054
4084
  const arrayBuffer = createCustomAnthropicStreamingMessage(CLAUDE_MESSAGES.missing_nextauth_secret);
4055
4085
  res.setHeader("Content-Type", "application/json");
@@ -4071,14 +4101,11 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
4071
4101
  };
4072
4102
  if (req.headers["accept"]) headers["accept"] = req.headers["accept"];
4073
4103
  if (req.headers["user-agent"]) headers["user-agent"] = req.headers["user-agent"];
4074
- console.log("[EXULU] anthropic api key", anthropicApiKey);
4075
4104
  const response = await fetch(url, {
4076
4105
  method: req.method,
4077
4106
  headers,
4078
4107
  body: req.method !== "GET" ? JSON.stringify(req.body) : void 0
4079
4108
  });
4080
- console.log("[PROXY] Response:", response);
4081
- console.log("[PROXY] Response:", response.body);
4082
4109
  await updateStatistic({
4083
4110
  name: "count",
4084
4111
  label: "Claude Code",
@@ -4104,14 +4131,12 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
4104
4131
  const { done, value } = await reader.read();
4105
4132
  if (done) break;
4106
4133
  const chunk = decoder.decode(value, { stream: true });
4107
- console.log("[PROXY] Chunk:", chunk);
4108
4134
  res.write(chunk);
4109
4135
  }
4110
4136
  res.end();
4111
4137
  return;
4112
4138
  }
4113
4139
  const data = await response.arrayBuffer();
4114
- console.log("[PROXY] Data:", data);
4115
4140
  res.end(Buffer.from(data));
4116
4141
  } catch (error) {
4117
4142
  console.error("[PROXY] Manual proxy error:", error);
@@ -4236,8 +4261,8 @@ var defaultLogsDir = import_path.default.join(process.cwd(), "logs");
4236
4261
  var redisConnection;
4237
4262
  var createWorkers = async (queues2, contexts, workflows, _logsDir) => {
4238
4263
  if (!redisServer.host || !redisServer.port) {
4239
- console.error("[EXULU] you are trying to start workers, but no redis server is configured in the environment.");
4240
- throw new Error("No redis server configured in the environment, so cannot start workers.");
4264
+ console.error("[EXULU] you are trying to start worker, but no redis server is configured in the environment.");
4265
+ throw new Error("No redis server configured in the environment, so cannot start worker.");
4241
4266
  }
4242
4267
  if (!redisConnection) {
4243
4268
  redisConnection = new import_ioredis.default({
@@ -4251,7 +4276,7 @@ var createWorkers = async (queues2, contexts, workflows, _logsDir) => {
4251
4276
  const worker = new import_bullmq7.Worker(
4252
4277
  `${queue}`,
4253
4278
  async (bullmqJob) => {
4254
- const { db: db2 } = await postgresClient();
4279
+ const { db: db3 } = await postgresClient();
4255
4280
  try {
4256
4281
  bullmq.validate(bullmqJob);
4257
4282
  if (bullmqJob.data.type === "embedder") {
@@ -4293,19 +4318,19 @@ var createWorkers = async (queues2, contexts, workflows, _logsDir) => {
4293
4318
  label: context.name,
4294
4319
  trigger: bullmqJob.data.trigger || "unknown"
4295
4320
  });
4296
- const mongoRecord = await db2.from("jobs").where({ redis: bullmqJob.id }).first();
4321
+ const mongoRecord = await db3.from("jobs").where({ redis: bullmqJob.id }).first();
4297
4322
  if (!mongoRecord) {
4298
4323
  throw new Error("Job not found in the database.");
4299
4324
  }
4300
4325
  const finishedAt = /* @__PURE__ */ new Date();
4301
4326
  const duration = (finishedAt.getTime() - new Date(mongoRecord.createdAt).getTime()) / 1e3;
4302
- await db2.from("jobs").where({ redis: bullmqJob.id }).update({
4327
+ await db3.from("jobs").where({ redis: bullmqJob.id }).update({
4303
4328
  status: "completed",
4304
4329
  finishedAt,
4305
4330
  duration,
4306
4331
  result: JSON.stringify(result)
4307
4332
  });
4308
- await db2.from((void 0).getTableName()).where({ id: result[0].id }).update({
4333
+ await db3.from((void 0).getTableName()).where({ id: result[0].id }).update({
4309
4334
  embeddings_updated_at: (/* @__PURE__ */ new Date()).toISOString()
4310
4335
  }).returning("id");
4311
4336
  return result;
@@ -4315,14 +4340,14 @@ var createWorkers = async (queues2, contexts, workflows, _logsDir) => {
4315
4340
  if (!workflow) {
4316
4341
  throw new Error(`Workflow ${bullmqJob.data.workflow} not found in the registry.`);
4317
4342
  }
4318
- const exuluJob = await db2.from("jobs").where({ redis: bullmqJob.id }).first();
4343
+ const exuluJob = await db3.from("jobs").where({ redis: bullmqJob.id }).first();
4319
4344
  if (!exuluJob) {
4320
4345
  throw new Error("Job not found in the database.");
4321
4346
  }
4322
4347
  const result = await bullmq.process.workflow(bullmqJob, exuluJob, workflow, logsDir);
4323
4348
  const finishedAt = /* @__PURE__ */ new Date();
4324
4349
  const duration = (finishedAt.getTime() - new Date(exuluJob.createdAt).getTime()) / 1e3;
4325
- await db2.from("jobs").where({ redis: bullmqJob.id }).update({
4350
+ await db3.from("jobs").where({ redis: bullmqJob.id }).update({
4326
4351
  status: "completed",
4327
4352
  finishedAt,
4328
4353
  duration,
@@ -4331,7 +4356,7 @@ var createWorkers = async (queues2, contexts, workflows, _logsDir) => {
4331
4356
  return result;
4332
4357
  }
4333
4358
  } catch (error) {
4334
- await db2.from("jobs").where({ redis: bullmqJob.id }).update({
4359
+ await db3.from("jobs").where({ redis: bullmqJob.id }).update({
4335
4360
  status: "failed",
4336
4361
  finishedAt: /* @__PURE__ */ new Date(),
4337
4362
  error: error instanceof Error ? error.message : String(error)
@@ -4703,259 +4728,6 @@ var getTicket = new ExuluTool({
4703
4728
  }
4704
4729
  });
4705
4730
 
4706
- // src/auth/generate-key.ts
4707
- var import_bcryptjs2 = __toESM(require("bcryptjs"), 1);
4708
- var SALT_ROUNDS = 12;
4709
- async function encryptString(string) {
4710
- const hash = await import_bcryptjs2.default.hash(string, SALT_ROUNDS);
4711
- return hash;
4712
- }
4713
- var generateApiKey = async (name, email) => {
4714
- const { db: db2 } = await postgresClient();
4715
- console.log("[EXULU] Inserting default user and admin role.");
4716
- const existingRole = await db2.from("roles").where({ name: "admin" }).first();
4717
- let roleId;
4718
- if (!existingRole) {
4719
- console.log("[EXULU] Creating default admin role.");
4720
- const role = await db2.from("roles").insert({
4721
- name: "admin",
4722
- is_admin: true,
4723
- agents: []
4724
- }).returning("id");
4725
- roleId = role[0].id;
4726
- } else {
4727
- roleId = existingRole.id;
4728
- }
4729
- const newKeyName = name;
4730
- const plainKey = `sk_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
4731
- const postFix = `/${newKeyName.toLowerCase().trim().replaceAll(" ", "_")}`;
4732
- const encryptedKey = await encryptString(plainKey);
4733
- const existingApiUser = await db2.from("users").where({ email }).first();
4734
- if (!existingApiUser) {
4735
- console.log("[EXULU] Creating default api user.");
4736
- await db2.from("users").insert({
4737
- name,
4738
- email,
4739
- super_admin: true,
4740
- createdAt: /* @__PURE__ */ new Date(),
4741
- updatedAt: /* @__PURE__ */ new Date(),
4742
- type: "api",
4743
- emailVerified: /* @__PURE__ */ new Date(),
4744
- apikey: `${encryptedKey}${postFix}`,
4745
- // password: "admin", todo add this again when we implement password auth / encryption as alternative to OTP
4746
- role: roleId
4747
- });
4748
- console.log("[EXULU] Default api user created. Key: ", `${plainKey}${postFix}`);
4749
- } else {
4750
- console.log("[EXULU] API user with that name already exists.");
4751
- }
4752
- console.log("[EXULU] Key generated, copy and use the plain key from here, you will not be able to access it again.");
4753
- console.log("[EXULU] Key: ", `${plainKey}${postFix}`);
4754
- return {
4755
- key: `${plainKey}${postFix}`
4756
- };
4757
- };
4758
-
4759
- // src/postgres/init-db.ts
4760
- var up = async function(knex) {
4761
- if (!await knex.schema.hasTable("agent_sessions")) {
4762
- console.log("[EXULU] Creating agent_sessions table.");
4763
- await knex.schema.createTable("agent_sessions", (table) => {
4764
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4765
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4766
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4767
- for (const field of agentSessionsSchema.fields) {
4768
- const { type, name, default: defaultValue } = field;
4769
- if (!type || !name) {
4770
- continue;
4771
- }
4772
- mapType(table, type, sanitizeName(name), defaultValue);
4773
- }
4774
- });
4775
- }
4776
- if (!await knex.schema.hasTable("agent_messages")) {
4777
- console.log("[EXULU] Creating agent_messages table.");
4778
- await knex.schema.createTable("agent_messages", (table) => {
4779
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4780
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4781
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4782
- for (const field of agentMessagesSchema.fields) {
4783
- const { type, name, default: defaultValue } = field;
4784
- if (!type || !name) {
4785
- continue;
4786
- }
4787
- mapType(table, type, sanitizeName(name), defaultValue);
4788
- }
4789
- });
4790
- }
4791
- if (!await knex.schema.hasTable("roles")) {
4792
- console.log("[EXULU] Creating roles table.");
4793
- await knex.schema.createTable("roles", (table) => {
4794
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4795
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4796
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4797
- for (const field of rolesSchema.fields) {
4798
- const { type, name, default: defaultValue } = field;
4799
- if (!type || !name) {
4800
- continue;
4801
- }
4802
- mapType(table, type, sanitizeName(name), defaultValue);
4803
- }
4804
- });
4805
- }
4806
- if (!await knex.schema.hasTable("eval_results")) {
4807
- console.log("[EXULU] Creating eval_results table.");
4808
- await knex.schema.createTable("eval_results", (table) => {
4809
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4810
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4811
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4812
- for (const field of evalResultsSchema.fields) {
4813
- const { type, name, default: defaultValue } = field;
4814
- if (!type || !name) {
4815
- continue;
4816
- }
4817
- mapType(table, type, sanitizeName(name), defaultValue);
4818
- }
4819
- });
4820
- }
4821
- if (!await knex.schema.hasTable("statistics")) {
4822
- console.log("[EXULU] Creating statistics table.");
4823
- await knex.schema.createTable("statistics", (table) => {
4824
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4825
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4826
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4827
- for (const field of statisticsSchema.fields) {
4828
- const { type, name, default: defaultValue } = field;
4829
- if (!type || !name) {
4830
- continue;
4831
- }
4832
- mapType(table, type, sanitizeName(name), defaultValue);
4833
- }
4834
- });
4835
- }
4836
- if (!await knex.schema.hasTable("jobs")) {
4837
- console.log("[EXULU] Creating jobs table.");
4838
- await knex.schema.createTable("jobs", (table) => {
4839
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4840
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4841
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4842
- for (const field of jobsSchema.fields) {
4843
- const { type, name, default: defaultValue } = field;
4844
- if (!type || !name) {
4845
- continue;
4846
- }
4847
- mapType(table, type, sanitizeName(name), defaultValue);
4848
- }
4849
- });
4850
- }
4851
- if (!await knex.schema.hasTable("agents")) {
4852
- console.log("[EXULU] Creating agents table.");
4853
- await knex.schema.createTable("agents", (table) => {
4854
- table.uuid("id").primary().defaultTo(knex.fn.uuid());
4855
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4856
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4857
- for (const field of agentsSchema.fields) {
4858
- const { type, name, default: defaultValue } = field;
4859
- if (!type || !name) {
4860
- continue;
4861
- }
4862
- mapType(table, type, sanitizeName(name), defaultValue);
4863
- }
4864
- });
4865
- }
4866
- if (!await knex.schema.hasTable("verification_token")) {
4867
- console.log("[EXULU] Creating verification_token table.");
4868
- await knex.schema.createTable("verification_token", (table) => {
4869
- table.text("identifier").notNullable();
4870
- table.timestamp("expires", { useTz: true }).notNullable();
4871
- table.text("token").notNullable();
4872
- table.primary(["identifier", "token"]);
4873
- });
4874
- }
4875
- if (!await knex.schema.hasTable("users")) {
4876
- console.log("[EXULU] Creating users table.");
4877
- await knex.schema.createTable("users", (table) => {
4878
- table.increments("id").primary();
4879
- table.timestamp("createdAt").defaultTo(knex.fn.now());
4880
- table.timestamp("updatedAt").defaultTo(knex.fn.now());
4881
- table.string("name", 255);
4882
- table.string("password", 255);
4883
- table.string("email", 255);
4884
- table.timestamp("emailVerified", { useTz: true });
4885
- table.text("image");
4886
- for (const field of usersSchema.fields) {
4887
- console.log("[EXULU] field", field);
4888
- const { type, name, default: defaultValue } = field;
4889
- if (name === "id" || name === "name" || name === "email" || name === "emailVerified" || name === "image") {
4890
- continue;
4891
- }
4892
- if (!type || !name) {
4893
- continue;
4894
- }
4895
- mapType(table, type, sanitizeName(name), defaultValue);
4896
- }
4897
- });
4898
- }
4899
- if (!await knex.schema.hasTable("accounts")) {
4900
- console.log("[EXULU] Creating accounts table.");
4901
- await knex.schema.createTable("accounts", (table) => {
4902
- table.increments("id").primary();
4903
- table.integer("userId").notNullable();
4904
- table.string("type", 255).notNullable();
4905
- table.string("provider", 255).notNullable();
4906
- table.string("providerAccountId", 255).notNullable();
4907
- table.text("refresh_token");
4908
- table.text("access_token");
4909
- table.bigInteger("expires_at");
4910
- table.text("id_token");
4911
- table.text("scope");
4912
- table.text("session_state");
4913
- table.text("token_type");
4914
- });
4915
- }
4916
- };
4917
- var execute = async () => {
4918
- const { db: db2 } = await postgresClient();
4919
- console.log("[EXULU] Checking Exulu IMP database status.");
4920
- await up(db2);
4921
- console.log("[EXULU] Inserting default user and admin role.");
4922
- const existingRole = await db2.from("roles").where({ name: "admin" }).first();
4923
- let roleId;
4924
- if (!existingRole) {
4925
- console.log("[EXULU] Creating default admin role.");
4926
- const role = await db2.from("roles").insert({
4927
- name: "admin",
4928
- is_admin: true,
4929
- agents: JSON.stringify([])
4930
- }).returning("id");
4931
- roleId = role[0].id;
4932
- } else {
4933
- roleId = existingRole.id;
4934
- }
4935
- const existingUser = await db2.from("users").where({ email: "admin@exulu.com" }).first();
4936
- if (!existingUser) {
4937
- const password = await encryptString("admin");
4938
- console.log("[EXULU] Creating default admin user.");
4939
- await db2.from("users").insert({
4940
- name: "exulu",
4941
- email: "admin@exulu.com",
4942
- super_admin: true,
4943
- createdAt: /* @__PURE__ */ new Date(),
4944
- emailVerified: /* @__PURE__ */ new Date(),
4945
- updatedAt: /* @__PURE__ */ new Date(),
4946
- password,
4947
- type: "user",
4948
- role: roleId
4949
- });
4950
- }
4951
- const { key } = await generateApiKey("exulu", "api@exulu.com");
4952
- console.log("[EXULU] Database initialized.");
4953
- console.log("[EXULU] Default api key: ", `${key}`);
4954
- console.log("[EXULU] Default password if using password auth: ", `admin`);
4955
- console.log("[EXULU] Default email if using password auth: ", `admin@exulu.com`);
4956
- return;
4957
- };
4958
-
4959
4731
  // src/registry/index.ts
4960
4732
  var ExuluApp = class {
4961
4733
  _agents = [];
@@ -4970,7 +4742,6 @@ var ExuluApp = class {
4970
4742
  // Factory function so we can async
4971
4743
  // initialize the MCP server if needed.
4972
4744
  create = async ({ contexts, agents, workflows, config, tools }) => {
4973
- await execute();
4974
4745
  this._workflows = workflows ?? [];
4975
4746
  this._contexts = contexts ?? {};
4976
4747
  this._agents = [
@@ -6272,6 +6043,257 @@ var SentenceChunker = class _SentenceChunker extends BaseChunker {
6272
6043
  }
6273
6044
  };
6274
6045
 
6046
+ // src/auth/generate-key.ts
6047
+ var import_bcryptjs2 = __toESM(require("bcryptjs"), 1);
6048
+ var SALT_ROUNDS = 12;
6049
+ async function encryptString(string) {
6050
+ const hash = await import_bcryptjs2.default.hash(string, SALT_ROUNDS);
6051
+ return hash;
6052
+ }
6053
+ var generateApiKey = async (name, email) => {
6054
+ const { db: db3 } = await postgresClient();
6055
+ console.log("[EXULU] Inserting default user and admin role.");
6056
+ const existingRole = await db3.from("roles").where({ name: "admin" }).first();
6057
+ let roleId;
6058
+ if (!existingRole) {
6059
+ console.log("[EXULU] Creating default admin role.");
6060
+ const role = await db3.from("roles").insert({
6061
+ name: "admin",
6062
+ is_admin: true,
6063
+ agents: []
6064
+ }).returning("id");
6065
+ roleId = role[0].id;
6066
+ } else {
6067
+ roleId = existingRole.id;
6068
+ }
6069
+ const newKeyName = name;
6070
+ const plainKey = `sk_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
6071
+ const postFix = `/${newKeyName.toLowerCase().trim().replaceAll(" ", "_")}`;
6072
+ const encryptedKey = await encryptString(plainKey);
6073
+ const existingApiUser = await db3.from("users").where({ email }).first();
6074
+ if (!existingApiUser) {
6075
+ console.log("[EXULU] Creating default api user.");
6076
+ await db3.from("users").insert({
6077
+ name,
6078
+ email,
6079
+ super_admin: true,
6080
+ createdAt: /* @__PURE__ */ new Date(),
6081
+ updatedAt: /* @__PURE__ */ new Date(),
6082
+ type: "api",
6083
+ emailVerified: /* @__PURE__ */ new Date(),
6084
+ apikey: `${encryptedKey}${postFix}`,
6085
+ // password: "admin", todo add this again when we implement password auth / encryption as alternative to OTP
6086
+ role: roleId
6087
+ });
6088
+ console.log("[EXULU] Default api user created. Key: ", `${plainKey}${postFix}`);
6089
+ } else {
6090
+ console.log("[EXULU] API user with that name already exists.");
6091
+ }
6092
+ return {
6093
+ key: `${plainKey}${postFix}`
6094
+ };
6095
+ };
6096
+
6097
+ // src/postgres/init-db.ts
6098
+ var up = async function(knex) {
6099
+ if (!await knex.schema.hasTable("agent_sessions")) {
6100
+ console.log("[EXULU] Creating agent_sessions table.");
6101
+ await knex.schema.createTable("agent_sessions", (table) => {
6102
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6103
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6104
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6105
+ for (const field of agentSessionsSchema.fields) {
6106
+ const { type, name, default: defaultValue } = field;
6107
+ if (!type || !name) {
6108
+ continue;
6109
+ }
6110
+ mapType(table, type, sanitizeName(name), defaultValue);
6111
+ }
6112
+ });
6113
+ }
6114
+ if (!await knex.schema.hasTable("agent_messages")) {
6115
+ console.log("[EXULU] Creating agent_messages table.");
6116
+ await knex.schema.createTable("agent_messages", (table) => {
6117
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6118
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6119
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6120
+ for (const field of agentMessagesSchema.fields) {
6121
+ const { type, name, default: defaultValue } = field;
6122
+ if (!type || !name) {
6123
+ continue;
6124
+ }
6125
+ mapType(table, type, sanitizeName(name), defaultValue);
6126
+ }
6127
+ });
6128
+ }
6129
+ if (!await knex.schema.hasTable("roles")) {
6130
+ console.log("[EXULU] Creating roles table.");
6131
+ await knex.schema.createTable("roles", (table) => {
6132
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6133
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6134
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6135
+ for (const field of rolesSchema.fields) {
6136
+ const { type, name, default: defaultValue } = field;
6137
+ if (!type || !name) {
6138
+ continue;
6139
+ }
6140
+ mapType(table, type, sanitizeName(name), defaultValue);
6141
+ }
6142
+ });
6143
+ }
6144
+ if (!await knex.schema.hasTable("eval_results")) {
6145
+ console.log("[EXULU] Creating eval_results table.");
6146
+ await knex.schema.createTable("eval_results", (table) => {
6147
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6148
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6149
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6150
+ for (const field of evalResultsSchema.fields) {
6151
+ const { type, name, default: defaultValue } = field;
6152
+ if (!type || !name) {
6153
+ continue;
6154
+ }
6155
+ mapType(table, type, sanitizeName(name), defaultValue);
6156
+ }
6157
+ });
6158
+ }
6159
+ if (!await knex.schema.hasTable("statistics")) {
6160
+ console.log("[EXULU] Creating statistics table.");
6161
+ await knex.schema.createTable("statistics", (table) => {
6162
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6163
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6164
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6165
+ for (const field of statisticsSchema.fields) {
6166
+ const { type, name, default: defaultValue } = field;
6167
+ if (!type || !name) {
6168
+ continue;
6169
+ }
6170
+ mapType(table, type, sanitizeName(name), defaultValue);
6171
+ }
6172
+ });
6173
+ }
6174
+ if (!await knex.schema.hasTable("jobs")) {
6175
+ console.log("[EXULU] Creating jobs table.");
6176
+ await knex.schema.createTable("jobs", (table) => {
6177
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6178
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6179
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6180
+ for (const field of jobsSchema.fields) {
6181
+ const { type, name, default: defaultValue } = field;
6182
+ if (!type || !name) {
6183
+ continue;
6184
+ }
6185
+ mapType(table, type, sanitizeName(name), defaultValue);
6186
+ }
6187
+ });
6188
+ }
6189
+ if (!await knex.schema.hasTable("agents")) {
6190
+ console.log("[EXULU] Creating agents table.");
6191
+ await knex.schema.createTable("agents", (table) => {
6192
+ table.uuid("id").primary().defaultTo(knex.fn.uuid());
6193
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6194
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6195
+ for (const field of agentsSchema.fields) {
6196
+ const { type, name, default: defaultValue } = field;
6197
+ if (!type || !name) {
6198
+ continue;
6199
+ }
6200
+ mapType(table, type, sanitizeName(name), defaultValue);
6201
+ }
6202
+ });
6203
+ }
6204
+ if (!await knex.schema.hasTable("verification_token")) {
6205
+ console.log("[EXULU] Creating verification_token table.");
6206
+ await knex.schema.createTable("verification_token", (table) => {
6207
+ table.text("identifier").notNullable();
6208
+ table.timestamp("expires", { useTz: true }).notNullable();
6209
+ table.text("token").notNullable();
6210
+ table.primary(["identifier", "token"]);
6211
+ });
6212
+ }
6213
+ if (!await knex.schema.hasTable("users")) {
6214
+ console.log("[EXULU] Creating users table.");
6215
+ await knex.schema.createTable("users", (table) => {
6216
+ table.increments("id").primary();
6217
+ table.timestamp("createdAt").defaultTo(knex.fn.now());
6218
+ table.timestamp("updatedAt").defaultTo(knex.fn.now());
6219
+ table.string("name", 255);
6220
+ table.string("password", 255);
6221
+ table.string("email", 255);
6222
+ table.timestamp("emailVerified", { useTz: true });
6223
+ table.text("image");
6224
+ for (const field of usersSchema.fields) {
6225
+ console.log("[EXULU] field", field);
6226
+ const { type, name, default: defaultValue } = field;
6227
+ if (name === "id" || name === "name" || name === "email" || name === "emailVerified" || name === "image") {
6228
+ continue;
6229
+ }
6230
+ if (!type || !name) {
6231
+ continue;
6232
+ }
6233
+ mapType(table, type, sanitizeName(name), defaultValue);
6234
+ }
6235
+ });
6236
+ }
6237
+ if (!await knex.schema.hasTable("accounts")) {
6238
+ console.log("[EXULU] Creating accounts table.");
6239
+ await knex.schema.createTable("accounts", (table) => {
6240
+ table.increments("id").primary();
6241
+ table.integer("userId").notNullable();
6242
+ table.string("type", 255).notNullable();
6243
+ table.string("provider", 255).notNullable();
6244
+ table.string("providerAccountId", 255).notNullable();
6245
+ table.text("refresh_token");
6246
+ table.text("access_token");
6247
+ table.bigInteger("expires_at");
6248
+ table.text("id_token");
6249
+ table.text("scope");
6250
+ table.text("session_state");
6251
+ table.text("token_type");
6252
+ });
6253
+ }
6254
+ };
6255
+ var execute = async () => {
6256
+ const { db: db3 } = await postgresClient();
6257
+ console.log("[EXULU] Checking Exulu IMP database status.");
6258
+ await up(db3);
6259
+ console.log("[EXULU] Inserting default user and admin role.");
6260
+ const existingRole = await db3.from("roles").where({ name: "admin" }).first();
6261
+ let roleId;
6262
+ if (!existingRole) {
6263
+ console.log("[EXULU] Creating default admin role.");
6264
+ const role = await db3.from("roles").insert({
6265
+ name: "admin",
6266
+ is_admin: true,
6267
+ agents: JSON.stringify([])
6268
+ }).returning("id");
6269
+ roleId = role[0].id;
6270
+ } else {
6271
+ roleId = existingRole.id;
6272
+ }
6273
+ const existingUser = await db3.from("users").where({ email: "admin@exulu.com" }).first();
6274
+ if (!existingUser) {
6275
+ const password = await encryptString("admin");
6276
+ console.log("[EXULU] Creating default admin user.");
6277
+ await db3.from("users").insert({
6278
+ name: "exulu",
6279
+ email: "admin@exulu.com",
6280
+ super_admin: true,
6281
+ createdAt: /* @__PURE__ */ new Date(),
6282
+ emailVerified: /* @__PURE__ */ new Date(),
6283
+ updatedAt: /* @__PURE__ */ new Date(),
6284
+ password,
6285
+ type: "user",
6286
+ role: roleId
6287
+ });
6288
+ }
6289
+ const { key } = await generateApiKey("exulu", "api@exulu.com");
6290
+ console.log("[EXULU] Database initialized.");
6291
+ console.log("[EXULU] Default api key: ", `${key}`);
6292
+ console.log("[EXULU] Default password if using password auth: ", `admin`);
6293
+ console.log("[EXULU] Default email if using password auth: ", `admin@exulu.com`);
6294
+ return;
6295
+ };
6296
+
6275
6297
  // src/index.ts
6276
6298
  var ExuluJobs = {
6277
6299
  redis: redisClient,
@@ -6279,6 +6301,11 @@ var ExuluJobs = {
6279
6301
  validate: validateJob
6280
6302
  }
6281
6303
  };
6304
+ var db2 = {
6305
+ init: async () => {
6306
+ await execute();
6307
+ }
6308
+ };
6282
6309
  var ExuluChunkers = {
6283
6310
  sentence: SentenceChunker,
6284
6311
  recursive: {
@@ -6303,5 +6330,6 @@ var ExuluChunkers = {
6303
6330
  ExuluSource,
6304
6331
  ExuluTool,
6305
6332
  ExuluWorkflow,
6306
- ExuluZodFileType
6333
+ ExuluZodFileType,
6334
+ db
6307
6335
  });