@exulu/backend 1.27.0 → 1.27.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/CHANGELOG.md +4 -3
- package/dist/index.cjs +245 -240
- package/dist/index.js +245 -240
- package/package.json +1 -1
- package/patch-older-releases-readme.md +42 -0
package/dist/index.js
CHANGED
|
@@ -393,7 +393,7 @@ var authentication = async ({
|
|
|
393
393
|
apikey,
|
|
394
394
|
authtoken,
|
|
395
395
|
internalkey,
|
|
396
|
-
db:
|
|
396
|
+
db: db3
|
|
397
397
|
}) => {
|
|
398
398
|
if (internalkey) {
|
|
399
399
|
if (!process.env.INTERNAL_SECRET) {
|
|
@@ -439,9 +439,9 @@ var authentication = async ({
|
|
|
439
439
|
code: 401
|
|
440
440
|
};
|
|
441
441
|
}
|
|
442
|
-
const user = await
|
|
442
|
+
const user = await db3.from("users").select("*").where("email", authtoken?.email).first();
|
|
443
443
|
if (user?.role) {
|
|
444
|
-
const role = await
|
|
444
|
+
const role = await db3.from("roles").select("*").where("id", user?.role).first();
|
|
445
445
|
if (role) {
|
|
446
446
|
user.role = role;
|
|
447
447
|
}
|
|
@@ -468,7 +468,7 @@ var authentication = async ({
|
|
|
468
468
|
}
|
|
469
469
|
}
|
|
470
470
|
if (apikey) {
|
|
471
|
-
const users = await
|
|
471
|
+
const users = await db3.from("users").select("*").where("type", "api");
|
|
472
472
|
if (!users || users.length === 0) {
|
|
473
473
|
return {
|
|
474
474
|
error: true,
|
|
@@ -500,11 +500,11 @@ var authentication = async ({
|
|
|
500
500
|
const user_key_compare_value = user.apikey.substring(0, user_key_last_slash_index);
|
|
501
501
|
const isMatch = await bcrypt.compare(request_key_compare_value, user_key_compare_value);
|
|
502
502
|
if (isMatch) {
|
|
503
|
-
await
|
|
503
|
+
await db3.from("users").where({ id: user.id }).update({
|
|
504
504
|
last_used: /* @__PURE__ */ new Date()
|
|
505
505
|
}).returning("id");
|
|
506
506
|
if (user?.role) {
|
|
507
|
-
const role = await
|
|
507
|
+
const role = await db3.from("roles").select("*").where("id", user?.role).first();
|
|
508
508
|
if (role) {
|
|
509
509
|
user.role = role;
|
|
510
510
|
}
|
|
@@ -534,7 +534,7 @@ var authentication = async ({
|
|
|
534
534
|
var requestValidators = {
|
|
535
535
|
authenticate: async (req) => {
|
|
536
536
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
537
|
-
const { db:
|
|
537
|
+
const { db: db3 } = await postgresClient();
|
|
538
538
|
let authtoken = null;
|
|
539
539
|
if (typeof apikey !== "string") {
|
|
540
540
|
authtoken = await getToken((req.headers["authorization"] || req.headers["x-api-key"]) ?? "");
|
|
@@ -542,7 +542,7 @@ var requestValidators = {
|
|
|
542
542
|
return await authentication({
|
|
543
543
|
authtoken,
|
|
544
544
|
apikey,
|
|
545
|
-
db:
|
|
545
|
+
db: db3
|
|
546
546
|
});
|
|
547
547
|
},
|
|
548
548
|
workflows: (req) => {
|
|
@@ -682,7 +682,7 @@ var requestValidators = {
|
|
|
682
682
|
};
|
|
683
683
|
|
|
684
684
|
// src/registry/utils/graphql.ts
|
|
685
|
-
import
|
|
685
|
+
import bcrypt3 from "bcryptjs";
|
|
686
686
|
|
|
687
687
|
// src/postgres/core-schema.ts
|
|
688
688
|
var agentMessagesSchema = {
|
|
@@ -1381,10 +1381,10 @@ var getEnabledTools = async (agentInstance, allExuluTools, disabledTools = [], a
|
|
|
1381
1381
|
};
|
|
1382
1382
|
var loadAgentCache = /* @__PURE__ */ new Map();
|
|
1383
1383
|
var loadAgents = async () => {
|
|
1384
|
-
const { db:
|
|
1385
|
-
const agents = await
|
|
1384
|
+
const { db: db3 } = await postgresClient();
|
|
1385
|
+
const agents = await db3.from("agents");
|
|
1386
1386
|
for (const agent of agents) {
|
|
1387
|
-
const agentRbac = await RBACResolver(
|
|
1387
|
+
const agentRbac = await RBACResolver(db3, "agent", agent.id, agent.rights_mode || "private");
|
|
1388
1388
|
agent.RBAC = agentRbac;
|
|
1389
1389
|
loadAgentCache.set(agent.id, {
|
|
1390
1390
|
agent,
|
|
@@ -1399,11 +1399,11 @@ var loadAgent = async (id) => {
|
|
|
1399
1399
|
if (cachedAgent && cachedAgent.expiresAt > /* @__PURE__ */ new Date()) {
|
|
1400
1400
|
return cachedAgent.agent;
|
|
1401
1401
|
}
|
|
1402
|
-
const { db:
|
|
1403
|
-
const agentInstance = await
|
|
1402
|
+
const { db: db3 } = await postgresClient();
|
|
1403
|
+
const agentInstance = await db3.from("agents").where({
|
|
1404
1404
|
id
|
|
1405
1405
|
}).first();
|
|
1406
|
-
const agentRbac = await RBACResolver(
|
|
1406
|
+
const agentRbac = await RBACResolver(db3, "agent", agentInstance.id, agentInstance.rights_mode || "private");
|
|
1407
1407
|
agentInstance.RBAC = agentRbac;
|
|
1408
1408
|
if (!agentInstance) {
|
|
1409
1409
|
throw new Error("Agent instance not found.");
|
|
@@ -1489,6 +1489,59 @@ var checkRecordAccess = async (record, request, user) => {
|
|
|
1489
1489
|
return false;
|
|
1490
1490
|
};
|
|
1491
1491
|
|
|
1492
|
+
// src/auth/generate-key.ts
|
|
1493
|
+
import bcrypt2 from "bcryptjs";
|
|
1494
|
+
var SALT_ROUNDS = 12;
|
|
1495
|
+
async function encryptString(string) {
|
|
1496
|
+
const hash = await bcrypt2.hash(string, SALT_ROUNDS);
|
|
1497
|
+
return hash;
|
|
1498
|
+
}
|
|
1499
|
+
var generateApiKey = async (name, email) => {
|
|
1500
|
+
const { db: db3 } = await postgresClient();
|
|
1501
|
+
console.log("[EXULU] Inserting default user and admin role.");
|
|
1502
|
+
const existingRole = await db3.from("roles").where({ name: "admin" }).first();
|
|
1503
|
+
let roleId;
|
|
1504
|
+
if (!existingRole) {
|
|
1505
|
+
console.log("[EXULU] Creating default admin role.");
|
|
1506
|
+
const role = await db3.from("roles").insert({
|
|
1507
|
+
name: "admin",
|
|
1508
|
+
agents: "write",
|
|
1509
|
+
workflows: "write",
|
|
1510
|
+
variables: "write",
|
|
1511
|
+
users: "write"
|
|
1512
|
+
}).returning("id");
|
|
1513
|
+
roleId = role[0].id;
|
|
1514
|
+
} else {
|
|
1515
|
+
roleId = existingRole.id;
|
|
1516
|
+
}
|
|
1517
|
+
const newKeyName = name;
|
|
1518
|
+
const plainKey = `sk_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
|
|
1519
|
+
const postFix = `/${newKeyName.toLowerCase().trim().replaceAll(" ", "_")}`;
|
|
1520
|
+
const encryptedKey = await encryptString(plainKey);
|
|
1521
|
+
const existingApiUser = await db3.from("users").where({ email }).first();
|
|
1522
|
+
if (!existingApiUser) {
|
|
1523
|
+
console.log("[EXULU] Creating default api user.");
|
|
1524
|
+
await db3.from("users").insert({
|
|
1525
|
+
name,
|
|
1526
|
+
email,
|
|
1527
|
+
super_admin: true,
|
|
1528
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1529
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
1530
|
+
type: "api",
|
|
1531
|
+
emailVerified: /* @__PURE__ */ new Date(),
|
|
1532
|
+
apikey: `${encryptedKey}${postFix}`,
|
|
1533
|
+
// password: "admin", todo add this again when we implement password auth / encryption as alternative to OTP
|
|
1534
|
+
role: roleId
|
|
1535
|
+
});
|
|
1536
|
+
console.log("[EXULU] Default api user created. Key: ", `${plainKey}${postFix}`);
|
|
1537
|
+
} else {
|
|
1538
|
+
console.log("[EXULU] API user with that name already exists.");
|
|
1539
|
+
}
|
|
1540
|
+
return {
|
|
1541
|
+
key: `${plainKey}${postFix}`
|
|
1542
|
+
};
|
|
1543
|
+
};
|
|
1544
|
+
|
|
1492
1545
|
// src/registry/utils/graphql.ts
|
|
1493
1546
|
var GraphQLDate = new GraphQLScalarType({
|
|
1494
1547
|
name: "Date",
|
|
@@ -1710,10 +1763,10 @@ var getRequestedFields = (info) => {
|
|
|
1710
1763
|
}, {}));
|
|
1711
1764
|
return fields.filter((field) => field !== "pageInfo" && field !== "items" && field !== "RBAC");
|
|
1712
1765
|
};
|
|
1713
|
-
var handleRBACUpdate = async (
|
|
1766
|
+
var handleRBACUpdate = async (db3, entityName, resourceId, rbacData, existingRbacRecords) => {
|
|
1714
1767
|
const { users = [], roles = [], projects = [] } = rbacData;
|
|
1715
1768
|
if (!existingRbacRecords) {
|
|
1716
|
-
existingRbacRecords = await
|
|
1769
|
+
existingRbacRecords = await db3.from("rbac").where({
|
|
1717
1770
|
entity: entityName,
|
|
1718
1771
|
target_resource_id: resourceId
|
|
1719
1772
|
}).select("*");
|
|
@@ -1731,13 +1784,13 @@ var handleRBACUpdate = async (db4, entityName, resourceId, rbacData, existingRba
|
|
|
1731
1784
|
const rolesToRemove = existingRbacRecords.filter((r) => r.access_type === "Role" && !newRoleRecords.has(`${r.role_id}:${r.rights}`));
|
|
1732
1785
|
const projectsToRemove = existingRbacRecords.filter((r) => r.access_type === "Project" && !newProjectRecords.has(`${r.project_id}:${r.rights}`));
|
|
1733
1786
|
if (usersToRemove.length > 0) {
|
|
1734
|
-
await
|
|
1787
|
+
await db3.from("rbac").whereIn("id", usersToRemove.map((r) => r.id)).del();
|
|
1735
1788
|
}
|
|
1736
1789
|
if (rolesToRemove.length > 0) {
|
|
1737
|
-
await
|
|
1790
|
+
await db3.from("rbac").whereIn("id", rolesToRemove.map((r) => r.id)).del();
|
|
1738
1791
|
}
|
|
1739
1792
|
if (projectsToRemove.length > 0) {
|
|
1740
|
-
await
|
|
1793
|
+
await db3.from("rbac").whereIn("id", projectsToRemove.map((r) => r.id)).del();
|
|
1741
1794
|
}
|
|
1742
1795
|
const recordsToInsert = [];
|
|
1743
1796
|
usersToCreate.forEach((user) => {
|
|
@@ -1774,14 +1827,14 @@ var handleRBACUpdate = async (db4, entityName, resourceId, rbacData, existingRba
|
|
|
1774
1827
|
});
|
|
1775
1828
|
});
|
|
1776
1829
|
if (recordsToInsert.length > 0) {
|
|
1777
|
-
await
|
|
1830
|
+
await db3.from("rbac").insert(recordsToInsert);
|
|
1778
1831
|
}
|
|
1779
1832
|
};
|
|
1780
1833
|
function createMutations(table, agents, contexts, tools, config) {
|
|
1781
1834
|
const tableNamePlural = table.name.plural.toLowerCase();
|
|
1782
1835
|
const validateWriteAccess = async (id, context) => {
|
|
1783
1836
|
try {
|
|
1784
|
-
const { db:
|
|
1837
|
+
const { db: db3, req, user } = context;
|
|
1785
1838
|
if (user.super_admin === true) {
|
|
1786
1839
|
return true;
|
|
1787
1840
|
}
|
|
@@ -1793,7 +1846,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1793
1846
|
if (!hasRBAC) {
|
|
1794
1847
|
return true;
|
|
1795
1848
|
}
|
|
1796
|
-
const record = await
|
|
1849
|
+
const record = await db3.from(tableNamePlural).select(["rights_mode", "created_by"]).where({ id }).first();
|
|
1797
1850
|
if (!record) {
|
|
1798
1851
|
throw new Error("Record not found");
|
|
1799
1852
|
}
|
|
@@ -1812,7 +1865,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1812
1865
|
throw new Error("Only the creator can edit this private record");
|
|
1813
1866
|
}
|
|
1814
1867
|
if (record.rights_mode === "users") {
|
|
1815
|
-
const rbacRecord = await
|
|
1868
|
+
const rbacRecord = await db3.from("rbac").where({
|
|
1816
1869
|
entity: table.name.singular,
|
|
1817
1870
|
target_resource_id: id,
|
|
1818
1871
|
access_type: "User",
|
|
@@ -1825,7 +1878,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1825
1878
|
throw new Error("Insufficient user permissions to edit this record");
|
|
1826
1879
|
}
|
|
1827
1880
|
if (record.rights_mode === "roles" && user.role) {
|
|
1828
|
-
const rbacRecord = await
|
|
1881
|
+
const rbacRecord = await db3.from("rbac").where({
|
|
1829
1882
|
entity: table.name.singular,
|
|
1830
1883
|
target_resource_id: id,
|
|
1831
1884
|
access_type: "Role",
|
|
@@ -1838,7 +1891,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1838
1891
|
throw new Error("Insufficient role permissions to edit this record");
|
|
1839
1892
|
}
|
|
1840
1893
|
if (record.rights_mode === "projects") {
|
|
1841
|
-
const projects = await
|
|
1894
|
+
const projects = await db3.from("rbac").where({
|
|
1842
1895
|
entity: table.name.singular,
|
|
1843
1896
|
target_resource_id: id,
|
|
1844
1897
|
access_type: "Project",
|
|
@@ -1852,7 +1905,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1852
1905
|
return false;
|
|
1853
1906
|
}
|
|
1854
1907
|
if (project.rights_mode === "users") {
|
|
1855
|
-
const rbacRecord = await
|
|
1908
|
+
const rbacRecord = await db3.from("rbac").where({
|
|
1856
1909
|
entity: "project",
|
|
1857
1910
|
target_resource_id: project.id,
|
|
1858
1911
|
access_type: "User",
|
|
@@ -1865,7 +1918,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1865
1918
|
return false;
|
|
1866
1919
|
}
|
|
1867
1920
|
if (record.rights_mode === "roles" && user.role) {
|
|
1868
|
-
const rbacRecord = await
|
|
1921
|
+
const rbacRecord = await db3.from("rbac").where({
|
|
1869
1922
|
entity: "project",
|
|
1870
1923
|
target_resource_id: project.id,
|
|
1871
1924
|
access_type: "Role",
|
|
@@ -1891,9 +1944,8 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1891
1944
|
};
|
|
1892
1945
|
const mutations = {
|
|
1893
1946
|
[`${tableNamePlural}CreateOne`]: async (_, args, context, info) => {
|
|
1894
|
-
const { db:
|
|
1947
|
+
const { db: db3 } = context;
|
|
1895
1948
|
const requestedFields = getRequestedFields(info);
|
|
1896
|
-
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
1897
1949
|
let { input } = args;
|
|
1898
1950
|
const rbacData = input.RBAC;
|
|
1899
1951
|
delete input.RBAC;
|
|
@@ -1906,7 +1958,9 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1906
1958
|
throw new Error("You are not authorized to create users");
|
|
1907
1959
|
}
|
|
1908
1960
|
if (table.name.singular === "user" && input.password) {
|
|
1909
|
-
|
|
1961
|
+
console.log("[EXULU] Hashing password", input.password);
|
|
1962
|
+
input.password = await bcrypt3.hash(input.password, SALT_ROUNDS);
|
|
1963
|
+
console.log("[EXULU] Hashed password", input.password);
|
|
1910
1964
|
}
|
|
1911
1965
|
Object.keys(input).forEach((key) => {
|
|
1912
1966
|
if (table.fields.find((field) => field.name === key)?.type === "json") {
|
|
@@ -1916,10 +1970,13 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1916
1970
|
}
|
|
1917
1971
|
});
|
|
1918
1972
|
if (!input.id) {
|
|
1919
|
-
|
|
1973
|
+
const idField = table.fields.find((field) => field.name === "id");
|
|
1974
|
+
if (!idField || idField?.type !== "number") {
|
|
1975
|
+
input.id = db3.fn.uuid();
|
|
1976
|
+
}
|
|
1920
1977
|
}
|
|
1921
|
-
const columns = await
|
|
1922
|
-
const insert =
|
|
1978
|
+
const columns = await db3(tableNamePlural).columnInfo();
|
|
1979
|
+
const insert = db3(tableNamePlural).insert({
|
|
1923
1980
|
...input,
|
|
1924
1981
|
...table.RBAC ? { rights_mode: "private" } : {}
|
|
1925
1982
|
}).returning(Object.keys(columns));
|
|
@@ -1928,7 +1985,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1928
1985
|
}
|
|
1929
1986
|
let results = await insert;
|
|
1930
1987
|
if (table.RBAC && rbacData && results[0]) {
|
|
1931
|
-
await handleRBACUpdate(
|
|
1988
|
+
await handleRBACUpdate(db3, table.name.singular, results[0].id, rbacData, []);
|
|
1932
1989
|
}
|
|
1933
1990
|
const { job } = await postprocessUpdate({
|
|
1934
1991
|
table,
|
|
@@ -1948,7 +2005,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1948
2005
|
};
|
|
1949
2006
|
},
|
|
1950
2007
|
[`${tableNamePlural}UpdateOne`]: async (_, args, context, info) => {
|
|
1951
|
-
const { db:
|
|
2008
|
+
const { db: db3, req } = context;
|
|
1952
2009
|
let { where, input } = args;
|
|
1953
2010
|
await validateCreateOrRemoveSuperAdminPermission(tableNamePlural, input, req);
|
|
1954
2011
|
const rbacData = input.RBAC;
|
|
@@ -1964,13 +2021,13 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1964
2021
|
});
|
|
1965
2022
|
const requestedFields = getRequestedFields(info);
|
|
1966
2023
|
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
1967
|
-
const item = await
|
|
2024
|
+
const item = await db3.from(tableNamePlural).select(sanitizedFields).where(where).first();
|
|
1968
2025
|
if (!item) {
|
|
1969
2026
|
throw new Error("Record not found");
|
|
1970
2027
|
}
|
|
1971
2028
|
await validateWriteAccess(item.id, context);
|
|
1972
|
-
const columns = await
|
|
1973
|
-
const result = await
|
|
2029
|
+
const columns = await db3(tableNamePlural).columnInfo();
|
|
2030
|
+
const result = await db3(tableNamePlural).where({ id: item.id }).update({
|
|
1974
2031
|
...input,
|
|
1975
2032
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1976
2033
|
}).returning(Object.keys(columns));
|
|
@@ -1978,11 +2035,11 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1978
2035
|
throw new Error("Something went wrong with the update, no id returned.");
|
|
1979
2036
|
}
|
|
1980
2037
|
if (table.RBAC && rbacData && result.id) {
|
|
1981
|
-
const existingRbacRecords = await
|
|
2038
|
+
const existingRbacRecords = await db3.from("rbac").where({
|
|
1982
2039
|
entity: table.name.singular,
|
|
1983
2040
|
target_resource_id: result.id
|
|
1984
2041
|
}).select("*");
|
|
1985
|
-
await handleRBACUpdate(
|
|
2042
|
+
await handleRBACUpdate(db3, table.name.singular, result.id, rbacData, existingRbacRecords);
|
|
1986
2043
|
}
|
|
1987
2044
|
const { job } = await postprocessUpdate({ table, requestedFields, agents, contexts, tools, result, user: context.user.id, role: context.user.role?.id });
|
|
1988
2045
|
return {
|
|
@@ -1991,7 +2048,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
1991
2048
|
};
|
|
1992
2049
|
},
|
|
1993
2050
|
[`${tableNamePlural}UpdateOneById`]: async (_, args, context, info) => {
|
|
1994
|
-
const { db:
|
|
2051
|
+
const { db: db3, req } = context;
|
|
1995
2052
|
let { id, input } = args;
|
|
1996
2053
|
await validateCreateOrRemoveSuperAdminPermission(tableNamePlural, input, req);
|
|
1997
2054
|
await validateWriteAccess(id, context);
|
|
@@ -2006,20 +2063,20 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2006
2063
|
}
|
|
2007
2064
|
}
|
|
2008
2065
|
});
|
|
2009
|
-
await
|
|
2066
|
+
await db3(tableNamePlural).where({ id }).update({
|
|
2010
2067
|
...input,
|
|
2011
2068
|
updatedAt: /* @__PURE__ */ new Date()
|
|
2012
2069
|
});
|
|
2013
2070
|
if (table.RBAC && rbacData) {
|
|
2014
|
-
const existingRbacRecords = await
|
|
2071
|
+
const existingRbacRecords = await db3.from("rbac").where({
|
|
2015
2072
|
entity: table.name.singular,
|
|
2016
2073
|
target_resource_id: id
|
|
2017
2074
|
}).select("*");
|
|
2018
|
-
await handleRBACUpdate(
|
|
2075
|
+
await handleRBACUpdate(db3, table.name.singular, id, rbacData, existingRbacRecords);
|
|
2019
2076
|
}
|
|
2020
2077
|
const requestedFields = getRequestedFields(info);
|
|
2021
|
-
const columns = await
|
|
2022
|
-
const result = await
|
|
2078
|
+
const columns = await db3(tableNamePlural).columnInfo();
|
|
2079
|
+
const result = await db3.from(tableNamePlural).select(Object.keys(columns)).where({ id }).first();
|
|
2023
2080
|
const { job } = await postprocessUpdate({ table, requestedFields, agents, contexts, tools, result, user: context.user.id, role: context.user.role?.id });
|
|
2024
2081
|
return {
|
|
2025
2082
|
item: finalizeRequestedFields({ table, requestedFields, agents, contexts, tools, result, user: context.user.id }),
|
|
@@ -2028,11 +2085,11 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2028
2085
|
},
|
|
2029
2086
|
[`${tableNamePlural}RemoveOneById`]: async (_, args, context, info) => {
|
|
2030
2087
|
const { id } = args;
|
|
2031
|
-
const { db:
|
|
2088
|
+
const { db: db3 } = context;
|
|
2032
2089
|
await validateWriteAccess(id, context);
|
|
2033
2090
|
const requestedFields = getRequestedFields(info);
|
|
2034
2091
|
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
2035
|
-
const result = await
|
|
2092
|
+
const result = await db3.from(tableNamePlural).select(sanitizedFields).where({ id }).first();
|
|
2036
2093
|
if (!result) {
|
|
2037
2094
|
throw new Error("Record not found");
|
|
2038
2095
|
}
|
|
@@ -2043,12 +2100,12 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2043
2100
|
}
|
|
2044
2101
|
const chunksTableExists = await context2.chunksTableExists();
|
|
2045
2102
|
if (chunksTableExists) {
|
|
2046
|
-
await
|
|
2103
|
+
await db3.from(getChunksTableName(context2.id)).where({ source: result.id }).del();
|
|
2047
2104
|
}
|
|
2048
2105
|
}
|
|
2049
|
-
await
|
|
2106
|
+
await db3(tableNamePlural).where({ id }).del();
|
|
2050
2107
|
if (table.RBAC) {
|
|
2051
|
-
await
|
|
2108
|
+
await db3.from("rbac").where({
|
|
2052
2109
|
entity: table.name.singular,
|
|
2053
2110
|
target_resource_id: id
|
|
2054
2111
|
}).del();
|
|
@@ -2058,10 +2115,10 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2058
2115
|
},
|
|
2059
2116
|
[`${tableNamePlural}RemoveOne`]: async (_, args, context, info) => {
|
|
2060
2117
|
const { where } = args;
|
|
2061
|
-
const { db:
|
|
2118
|
+
const { db: db3 } = context;
|
|
2062
2119
|
const requestedFields = getRequestedFields(info);
|
|
2063
2120
|
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
2064
|
-
const result = await
|
|
2121
|
+
const result = await db3.from(tableNamePlural).select(sanitizedFields).where(where).first();
|
|
2065
2122
|
if (!result) {
|
|
2066
2123
|
throw new Error("Record not found");
|
|
2067
2124
|
}
|
|
@@ -2073,10 +2130,10 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2073
2130
|
}
|
|
2074
2131
|
const chunksTableExists = await context2.chunksTableExists();
|
|
2075
2132
|
if (chunksTableExists) {
|
|
2076
|
-
await
|
|
2133
|
+
await db3.from(getChunksTableName(context2.id)).where({ source: result.id }).del();
|
|
2077
2134
|
}
|
|
2078
2135
|
}
|
|
2079
|
-
await
|
|
2136
|
+
await db3(tableNamePlural).where(where).del();
|
|
2080
2137
|
await postprocessDeletion({ table, requestedFields, agents, contexts, tools, result });
|
|
2081
2138
|
return finalizeRequestedFields({ table, requestedFields, agents, contexts, tools, result, user: context.user.id });
|
|
2082
2139
|
}
|
|
@@ -2106,8 +2163,8 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2106
2163
|
if (!field.processor) {
|
|
2107
2164
|
throw new Error(`Processor not set for field ${args.field} in context ${exists.id}.`);
|
|
2108
2165
|
}
|
|
2109
|
-
const { db:
|
|
2110
|
-
let query =
|
|
2166
|
+
const { db: db3 } = context;
|
|
2167
|
+
let query = db3.from(tableNamePlural).select("*").where({ id: args.item });
|
|
2111
2168
|
query = applyAccessControl(table, context.user, query);
|
|
2112
2169
|
const item = await query.first();
|
|
2113
2170
|
if (!item) {
|
|
@@ -2132,15 +2189,15 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2132
2189
|
if (!context.user?.super_admin) {
|
|
2133
2190
|
throw new Error("You are not authorized to delete chunks via API, user must be super admin.");
|
|
2134
2191
|
}
|
|
2135
|
-
const { db:
|
|
2192
|
+
const { db: db3 } = await postgresClient();
|
|
2136
2193
|
const exists = contexts.find((context2) => context2.id === table.id);
|
|
2137
2194
|
if (!exists) {
|
|
2138
2195
|
throw new Error(`Context ${table.id} not found.`);
|
|
2139
2196
|
}
|
|
2140
2197
|
const { id, embeddings } = exists;
|
|
2141
2198
|
const mainTable = getTableName(id);
|
|
2142
|
-
const columns = await
|
|
2143
|
-
let query =
|
|
2199
|
+
const columns = await db3(mainTable).columnInfo();
|
|
2200
|
+
let query = db3.from(mainTable).select(Object.keys(columns));
|
|
2144
2201
|
if (!args.where) {
|
|
2145
2202
|
const {
|
|
2146
2203
|
jobs: jobs2,
|
|
@@ -2183,12 +2240,12 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2183
2240
|
if (!context.user?.super_admin) {
|
|
2184
2241
|
throw new Error("You are not authorized to delete chunks via API, user must be super admin.");
|
|
2185
2242
|
}
|
|
2186
|
-
const { db:
|
|
2243
|
+
const { db: db3 } = await postgresClient();
|
|
2187
2244
|
const id = contexts.find((context2) => context2.id === table.id)?.id;
|
|
2188
2245
|
if (!id) {
|
|
2189
2246
|
throw new Error(`Context ${table.id} not found.`);
|
|
2190
2247
|
}
|
|
2191
|
-
let query =
|
|
2248
|
+
let query = db3.from(getTableName(id)).select("id");
|
|
2192
2249
|
if (args.where) {
|
|
2193
2250
|
query = applyFilters(query, args.where);
|
|
2194
2251
|
}
|
|
@@ -2197,7 +2254,7 @@ function createMutations(table, agents, contexts, tools, config) {
|
|
|
2197
2254
|
throw new Error("No items found to delete chunks for.");
|
|
2198
2255
|
}
|
|
2199
2256
|
for (const item of items) {
|
|
2200
|
-
await
|
|
2257
|
+
await db3.from(getChunksTableName(id)).where({ source: item.id }).delete();
|
|
2201
2258
|
}
|
|
2202
2259
|
return {
|
|
2203
2260
|
message: "Chunks deleted successfully.",
|
|
@@ -2400,9 +2457,9 @@ var postprocessUpdate = async ({
|
|
|
2400
2457
|
if (!context.embedder) {
|
|
2401
2458
|
return result;
|
|
2402
2459
|
}
|
|
2403
|
-
const { db:
|
|
2460
|
+
const { db: db3 } = await postgresClient();
|
|
2404
2461
|
console.log("[EXULU] Deleting chunks for item", result.id);
|
|
2405
|
-
await
|
|
2462
|
+
await db3.from(getChunksTableName(context.id)).where({ source: result.id }).delete();
|
|
2406
2463
|
console.log("[EXULU] Deleted chunks for item", result.id);
|
|
2407
2464
|
console.log("[EXULU] Embedder", context.embedder);
|
|
2408
2465
|
console.log("[EXULU] Configuration", context.configuration);
|
|
@@ -2452,11 +2509,11 @@ var postprocessDeletion = async ({
|
|
|
2452
2509
|
if (!context.embedder) {
|
|
2453
2510
|
return result;
|
|
2454
2511
|
}
|
|
2455
|
-
const { db:
|
|
2512
|
+
const { db: db3 } = await postgresClient();
|
|
2456
2513
|
console.log("[EXULU] Deleting chunks for item", result.id);
|
|
2457
|
-
const chunks = await
|
|
2514
|
+
const chunks = await db3.from(getChunksTableName(context.id)).where({ source: result.id }).select("id");
|
|
2458
2515
|
if (chunks.length > 0) {
|
|
2459
|
-
await
|
|
2516
|
+
await db3.from(getChunksTableName(context.id)).where({ source: result.id }).delete();
|
|
2460
2517
|
}
|
|
2461
2518
|
return result;
|
|
2462
2519
|
}
|
|
@@ -2503,10 +2560,10 @@ var finalizeRequestedFields = async ({
|
|
|
2503
2560
|
result.chunks = [];
|
|
2504
2561
|
return result;
|
|
2505
2562
|
}
|
|
2506
|
-
const { db:
|
|
2507
|
-
const query =
|
|
2563
|
+
const { db: db3 } = await postgresClient();
|
|
2564
|
+
const query = db3.from(getChunksTableName(context.id)).where({ source: result.id }).select("id", "content", "source", "chunk_index", "createdAt", "updatedAt");
|
|
2508
2565
|
query.select(
|
|
2509
|
-
|
|
2566
|
+
db3.raw("vector_dims(??) as embedding_size", [`embedding`])
|
|
2510
2567
|
);
|
|
2511
2568
|
const chunks = await query;
|
|
2512
2569
|
result.chunks = chunks.map((chunk) => ({
|
|
@@ -2557,29 +2614,29 @@ function createQueries(table, agents, tools, contexts) {
|
|
|
2557
2614
|
const tableNameSingular = table.name.singular.toLowerCase();
|
|
2558
2615
|
const queries = {
|
|
2559
2616
|
[`${tableNameSingular}ById`]: async (_, args, context, info) => {
|
|
2560
|
-
const { db:
|
|
2617
|
+
const { db: db3 } = context;
|
|
2561
2618
|
const requestedFields = getRequestedFields(info);
|
|
2562
2619
|
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
2563
|
-
let query =
|
|
2620
|
+
let query = db3.from(tableNamePlural).select(sanitizedFields).where({ id: args.id });
|
|
2564
2621
|
query = applyAccessControl(table, context.user, query);
|
|
2565
2622
|
let result = await query.first();
|
|
2566
2623
|
return finalizeRequestedFields({ table, requestedFields, agents, contexts, tools, result, user: context.user });
|
|
2567
2624
|
},
|
|
2568
2625
|
[`${tableNameSingular}ByIds`]: async (_, args, context, info) => {
|
|
2569
|
-
const { db:
|
|
2626
|
+
const { db: db3 } = context;
|
|
2570
2627
|
const requestedFields = getRequestedFields(info);
|
|
2571
2628
|
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
2572
|
-
let query =
|
|
2629
|
+
let query = db3.from(tableNamePlural).select(sanitizedFields).whereIn("id", args.ids);
|
|
2573
2630
|
query = applyAccessControl(table, context.user, query);
|
|
2574
2631
|
let result = await query;
|
|
2575
2632
|
return finalizeRequestedFields({ table, requestedFields, agents, contexts, tools, result, user: context.user });
|
|
2576
2633
|
},
|
|
2577
2634
|
[`${tableNameSingular}One`]: async (_, args, context, info) => {
|
|
2578
2635
|
const { filters = [], sort } = args;
|
|
2579
|
-
const { db:
|
|
2636
|
+
const { db: db3 } = context;
|
|
2580
2637
|
const requestedFields = getRequestedFields(info);
|
|
2581
2638
|
const sanitizedFields = sanitizeRequestedFields(table, requestedFields);
|
|
2582
|
-
let query =
|
|
2639
|
+
let query = db3.from(tableNamePlural).select(sanitizedFields);
|
|
2583
2640
|
query = applyFilters(query, filters);
|
|
2584
2641
|
query = applyAccessControl(table, context.user, query);
|
|
2585
2642
|
query = applySorting(query, sort);
|
|
@@ -2588,11 +2645,11 @@ function createQueries(table, agents, tools, contexts) {
|
|
|
2588
2645
|
},
|
|
2589
2646
|
[`${tableNamePlural}Pagination`]: async (_, args, context, info) => {
|
|
2590
2647
|
const { limit = 10, page = 0, filters = [], sort } = args;
|
|
2591
|
-
const { db:
|
|
2648
|
+
const { db: db3 } = context;
|
|
2592
2649
|
if (limit > 500) {
|
|
2593
2650
|
throw new Error("Limit cannot be greater than 500.");
|
|
2594
2651
|
}
|
|
2595
|
-
let countQuery =
|
|
2652
|
+
let countQuery = db3(tableNamePlural);
|
|
2596
2653
|
countQuery = applyFilters(countQuery, filters);
|
|
2597
2654
|
countQuery = applyAccessControl(table, context.user, countQuery);
|
|
2598
2655
|
const countResult = await countQuery.count("* as count");
|
|
@@ -2601,7 +2658,7 @@ function createQueries(table, agents, tools, contexts) {
|
|
|
2601
2658
|
const currentPage = page;
|
|
2602
2659
|
const hasPreviousPage = currentPage > 1;
|
|
2603
2660
|
const hasNextPage = currentPage < pageCount - 1;
|
|
2604
|
-
let dataQuery =
|
|
2661
|
+
let dataQuery = db3(tableNamePlural);
|
|
2605
2662
|
dataQuery = applyFilters(dataQuery, filters);
|
|
2606
2663
|
dataQuery = applyAccessControl(table, context.user, dataQuery);
|
|
2607
2664
|
const requestedFields = getRequestedFields(info);
|
|
@@ -2625,8 +2682,8 @@ function createQueries(table, agents, tools, contexts) {
|
|
|
2625
2682
|
// Add generic statistics query for all tables
|
|
2626
2683
|
[`${tableNamePlural}Statistics`]: async (_, args, context, info) => {
|
|
2627
2684
|
const { filters = [], groupBy } = args;
|
|
2628
|
-
const { db:
|
|
2629
|
-
let query =
|
|
2685
|
+
const { db: db3 } = context;
|
|
2686
|
+
let query = db3(tableNamePlural);
|
|
2630
2687
|
query = applyFilters(query, filters);
|
|
2631
2688
|
query = applyAccessControl(table, context.user, query);
|
|
2632
2689
|
if (groupBy) {
|
|
@@ -2689,7 +2746,7 @@ var vectorSearch = async ({
|
|
|
2689
2746
|
filters,
|
|
2690
2747
|
sort,
|
|
2691
2748
|
context,
|
|
2692
|
-
db:
|
|
2749
|
+
db: db3,
|
|
2693
2750
|
query,
|
|
2694
2751
|
method,
|
|
2695
2752
|
user,
|
|
@@ -2726,11 +2783,11 @@ var vectorSearch = async ({
|
|
|
2726
2783
|
}
|
|
2727
2784
|
const mainTable = getTableName(id);
|
|
2728
2785
|
const chunksTable = getChunksTableName(id);
|
|
2729
|
-
let countQuery =
|
|
2786
|
+
let countQuery = db3(mainTable);
|
|
2730
2787
|
countQuery = applyFilters(countQuery, filters);
|
|
2731
2788
|
countQuery = applyAccessControl(table, user, countQuery);
|
|
2732
|
-
const columns = await
|
|
2733
|
-
let itemsQuery =
|
|
2789
|
+
const columns = await db3(mainTable).columnInfo();
|
|
2790
|
+
let itemsQuery = db3(mainTable).select(Object.keys(columns).map((column) => mainTable + "." + column));
|
|
2734
2791
|
itemsQuery = applyFilters(itemsQuery, filters);
|
|
2735
2792
|
itemsQuery = applyAccessControl(table, user, itemsQuery);
|
|
2736
2793
|
itemsQuery = applySorting(itemsQuery, sort);
|
|
@@ -2747,7 +2804,7 @@ var vectorSearch = async ({
|
|
|
2747
2804
|
itemsQuery.select(chunksTable + ".chunk_index");
|
|
2748
2805
|
itemsQuery.select(chunksTable + ".createdAt as chunk_created_at");
|
|
2749
2806
|
itemsQuery.select(chunksTable + ".updatedAt as chunk_updated_at");
|
|
2750
|
-
itemsQuery.select(
|
|
2807
|
+
itemsQuery.select(db3.raw("vector_dims(??) as embedding_size", [`${chunksTable}.embedding`]));
|
|
2751
2808
|
const { chunks } = await embedder.generateFromQuery(query, {
|
|
2752
2809
|
label: table.name.singular,
|
|
2753
2810
|
trigger
|
|
@@ -2762,7 +2819,7 @@ var vectorSearch = async ({
|
|
|
2762
2819
|
let items = [];
|
|
2763
2820
|
switch (method) {
|
|
2764
2821
|
case "tsvector":
|
|
2765
|
-
itemsQuery.select(
|
|
2822
|
+
itemsQuery.select(db3.raw(
|
|
2766
2823
|
`ts_rank(${chunksTable}.fts, websearch_to_tsquery(?, ?)) as fts_rank`,
|
|
2767
2824
|
[language, query]
|
|
2768
2825
|
)).whereRaw(
|
|
@@ -2775,7 +2832,7 @@ var vectorSearch = async ({
|
|
|
2775
2832
|
default:
|
|
2776
2833
|
itemsQuery.whereNotNull(`${chunksTable}.embedding`);
|
|
2777
2834
|
itemsQuery.select(
|
|
2778
|
-
|
|
2835
|
+
db3.raw(`1 - (${chunksTable}.embedding <=> ${vectorExpr}) AS cosine_distance`)
|
|
2779
2836
|
);
|
|
2780
2837
|
itemsQuery.orderByRaw(
|
|
2781
2838
|
`${chunksTable}.embedding <=> ${vectorExpr} ASC NULLS LAST`
|
|
@@ -2865,7 +2922,7 @@ var vectorSearch = async ({
|
|
|
2865
2922
|
matchCount
|
|
2866
2923
|
// final limit
|
|
2867
2924
|
];
|
|
2868
|
-
items = await
|
|
2925
|
+
items = await db3.raw(hybridSQL, bindings).then((r) => r.rows ?? r);
|
|
2869
2926
|
}
|
|
2870
2927
|
const seenSources = /* @__PURE__ */ new Map();
|
|
2871
2928
|
items = items.reduce((acc, item) => {
|
|
@@ -2961,8 +3018,8 @@ var vectorSearch = async ({
|
|
|
2961
3018
|
items
|
|
2962
3019
|
};
|
|
2963
3020
|
};
|
|
2964
|
-
var RBACResolver = async (
|
|
2965
|
-
const rbacRecords = await
|
|
3021
|
+
var RBACResolver = async (db3, entityName, resourceId, rights_mode) => {
|
|
3022
|
+
const rbacRecords = await db3.from("rbac").where({
|
|
2966
3023
|
entity: entityName,
|
|
2967
3024
|
target_resource_id: resourceId
|
|
2968
3025
|
}).select("*");
|
|
@@ -3239,11 +3296,11 @@ type PageInfo {
|
|
|
3239
3296
|
resolvers[rbacResolverName] = {};
|
|
3240
3297
|
}
|
|
3241
3298
|
resolvers[rbacResolverName].RBAC = async (parent, args, context) => {
|
|
3242
|
-
const { db:
|
|
3299
|
+
const { db: db3 } = context;
|
|
3243
3300
|
const resourceId = parent.id;
|
|
3244
3301
|
const entityName = table.name.singular;
|
|
3245
3302
|
const rights_mode = parent.rights_mode;
|
|
3246
|
-
return RBACResolver(
|
|
3303
|
+
return RBACResolver(db3, entityName, resourceId, rights_mode);
|
|
3247
3304
|
};
|
|
3248
3305
|
}
|
|
3249
3306
|
}
|
|
@@ -3629,7 +3686,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3629
3686
|
app.delete("/s3/delete", async (req, res, next) => {
|
|
3630
3687
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
3631
3688
|
const internalkey = req.headers["internal-key"] || null;
|
|
3632
|
-
const { db:
|
|
3689
|
+
const { db: db3 } = await postgresClient();
|
|
3633
3690
|
let authtoken = null;
|
|
3634
3691
|
if (typeof apikey !== "string" && typeof internalkey !== "string") {
|
|
3635
3692
|
authtoken = await getToken(req.headers.authorization ?? "");
|
|
@@ -3638,7 +3695,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3638
3695
|
authtoken,
|
|
3639
3696
|
apikey,
|
|
3640
3697
|
internalkey,
|
|
3641
|
-
db:
|
|
3698
|
+
db: db3
|
|
3642
3699
|
});
|
|
3643
3700
|
if (!authenticationResult.user?.id) {
|
|
3644
3701
|
res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
|
|
@@ -3675,7 +3732,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3675
3732
|
app.get("/s3/download", async (req, res, next) => {
|
|
3676
3733
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
3677
3734
|
const internalkey = req.headers["internal-key"] || null;
|
|
3678
|
-
const { db:
|
|
3735
|
+
const { db: db3 } = await postgresClient();
|
|
3679
3736
|
let authtoken = null;
|
|
3680
3737
|
if (typeof apikey !== "string" && typeof internalkey !== "string") {
|
|
3681
3738
|
authtoken = await getToken(req.headers.authorization ?? "");
|
|
@@ -3684,7 +3741,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3684
3741
|
authtoken,
|
|
3685
3742
|
apikey,
|
|
3686
3743
|
internalkey,
|
|
3687
|
-
db:
|
|
3744
|
+
db: db3
|
|
3688
3745
|
});
|
|
3689
3746
|
if (!authenticationResult.user?.id) {
|
|
3690
3747
|
res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
|
|
@@ -3719,7 +3776,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3719
3776
|
app.post("/s3/object", async (req, res, next) => {
|
|
3720
3777
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
3721
3778
|
const internalkey = req.headers["internal-key"] || null;
|
|
3722
|
-
const { db:
|
|
3779
|
+
const { db: db3 } = await postgresClient();
|
|
3723
3780
|
let authtoken = null;
|
|
3724
3781
|
if (typeof apikey !== "string" && typeof internalkey !== "string") {
|
|
3725
3782
|
authtoken = await getToken(req.headers.authorization ?? "");
|
|
@@ -3728,7 +3785,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3728
3785
|
authtoken,
|
|
3729
3786
|
apikey,
|
|
3730
3787
|
internalkey,
|
|
3731
|
-
db:
|
|
3788
|
+
db: db3
|
|
3732
3789
|
});
|
|
3733
3790
|
if (!authenticationResult.user?.id) {
|
|
3734
3791
|
res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
|
|
@@ -3749,7 +3806,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3749
3806
|
app.get("/s3/list", async (req, res, next) => {
|
|
3750
3807
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
3751
3808
|
const internalkey = req.headers["internal-key"] || null;
|
|
3752
|
-
const { db:
|
|
3809
|
+
const { db: db3 } = await postgresClient();
|
|
3753
3810
|
let authtoken = null;
|
|
3754
3811
|
if (typeof apikey !== "string" && typeof internalkey !== "string") {
|
|
3755
3812
|
authtoken = await getToken(req.headers.authorization ?? "");
|
|
@@ -3758,7 +3815,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3758
3815
|
authtoken,
|
|
3759
3816
|
apikey,
|
|
3760
3817
|
internalkey,
|
|
3761
|
-
db:
|
|
3818
|
+
db: db3
|
|
3762
3819
|
});
|
|
3763
3820
|
if (!authenticationResult.user?.id) {
|
|
3764
3821
|
res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
|
|
@@ -3816,7 +3873,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3816
3873
|
const generateS3Key2 = (filename) => `${randomUUID()}-_EXULU_${filename}`;
|
|
3817
3874
|
const signOnServer = async (req, res, next) => {
|
|
3818
3875
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
3819
|
-
const { db:
|
|
3876
|
+
const { db: db3 } = await postgresClient();
|
|
3820
3877
|
let authtoken = null;
|
|
3821
3878
|
if (typeof apikey !== "string") {
|
|
3822
3879
|
authtoken = await getToken(req.headers.authorization ?? "");
|
|
@@ -3824,7 +3881,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3824
3881
|
const authenticationResult = await authentication({
|
|
3825
3882
|
authtoken,
|
|
3826
3883
|
apikey,
|
|
3827
|
-
db:
|
|
3884
|
+
db: db3
|
|
3828
3885
|
});
|
|
3829
3886
|
if (!authenticationResult.user?.id) {
|
|
3830
3887
|
res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
|
|
@@ -3861,7 +3918,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3861
3918
|
});
|
|
3862
3919
|
app.post("/s3/multipart", async (req, res, next) => {
|
|
3863
3920
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
3864
|
-
const { db:
|
|
3921
|
+
const { db: db3 } = await postgresClient();
|
|
3865
3922
|
let authtoken = null;
|
|
3866
3923
|
if (typeof apikey !== "string") {
|
|
3867
3924
|
authtoken = await getToken(req.headers.authorization ?? "");
|
|
@@ -3869,7 +3926,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
3869
3926
|
const authenticationResult = await authentication({
|
|
3870
3927
|
authtoken,
|
|
3871
3928
|
apikey,
|
|
3872
|
-
db:
|
|
3929
|
+
db: db3
|
|
3873
3930
|
});
|
|
3874
3931
|
if (!authenticationResult.user?.id) {
|
|
3875
3932
|
res.status(authenticationResult.code || 500).json({ detail: `${authenticationResult.message}` });
|
|
@@ -4149,10 +4206,10 @@ var convertToolsArrayToObject = (currentTools, allExuluTools, configs, providera
|
|
|
4149
4206
|
};
|
|
4150
4207
|
};
|
|
4151
4208
|
var hydrateVariables = async (tool2) => {
|
|
4152
|
-
const { db:
|
|
4209
|
+
const { db: db3 } = await postgresClient();
|
|
4153
4210
|
const promises = tool2.config.map(async (toolConfig) => {
|
|
4154
4211
|
const variableName = toolConfig.variable;
|
|
4155
|
-
const variable = await
|
|
4212
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
4156
4213
|
if (!variable) {
|
|
4157
4214
|
console.error("[EXULU] Variable " + variableName + " not found.");
|
|
4158
4215
|
throw new Error("Variable " + variableName + " not found.");
|
|
@@ -4288,8 +4345,8 @@ var ExuluAgent2 = class {
|
|
|
4288
4345
|
if (!variableName) {
|
|
4289
4346
|
throw new Error("Provider API key variable not set for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool.");
|
|
4290
4347
|
}
|
|
4291
|
-
const { db:
|
|
4292
|
-
const variable = await
|
|
4348
|
+
const { db: db3 } = await postgresClient();
|
|
4349
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
4293
4350
|
if (!variable) {
|
|
4294
4351
|
throw new Error("Provider API key variable not found for agent: " + agentInstance.name + " (" + agentInstance.id + ") being called as a tool.");
|
|
4295
4352
|
}
|
|
@@ -4657,9 +4714,9 @@ var ExuluAgent2 = class {
|
|
|
4657
4714
|
};
|
|
4658
4715
|
};
|
|
4659
4716
|
var getAgentMessages = async ({ session, user, limit, page }) => {
|
|
4660
|
-
const { db:
|
|
4717
|
+
const { db: db3 } = await postgresClient();
|
|
4661
4718
|
console.log("[EXULU] getting agent messages for session: " + session + " and user: " + user + " and page: " + page);
|
|
4662
|
-
const query =
|
|
4719
|
+
const query = db3.from("agent_messages").where({ session, user }).limit(limit);
|
|
4663
4720
|
if (page > 0) {
|
|
4664
4721
|
query.offset((page - 1) * limit);
|
|
4665
4722
|
}
|
|
@@ -4667,9 +4724,9 @@ var getAgentMessages = async ({ session, user, limit, page }) => {
|
|
|
4667
4724
|
return messages;
|
|
4668
4725
|
};
|
|
4669
4726
|
var saveChat = async ({ session, user, messages }) => {
|
|
4670
|
-
const { db:
|
|
4727
|
+
const { db: db3 } = await postgresClient();
|
|
4671
4728
|
const promises = messages.map((message) => {
|
|
4672
|
-
return
|
|
4729
|
+
return db3.from("agent_messages").insert({
|
|
4673
4730
|
session,
|
|
4674
4731
|
user,
|
|
4675
4732
|
content: JSON.stringify(message),
|
|
@@ -4880,25 +4937,25 @@ var ExuluContext = class {
|
|
|
4880
4937
|
};
|
|
4881
4938
|
};
|
|
4882
4939
|
deleteAll = async () => {
|
|
4883
|
-
const { db:
|
|
4884
|
-
await
|
|
4885
|
-
await
|
|
4940
|
+
const { db: db3 } = await postgresClient();
|
|
4941
|
+
await db3.from(getTableName(this.id)).delete();
|
|
4942
|
+
await db3.from(getChunksTableName(this.id)).delete();
|
|
4886
4943
|
return {
|
|
4887
4944
|
count: 0,
|
|
4888
4945
|
results: []
|
|
4889
4946
|
};
|
|
4890
4947
|
};
|
|
4891
4948
|
tableExists = async () => {
|
|
4892
|
-
const { db:
|
|
4949
|
+
const { db: db3 } = await postgresClient();
|
|
4893
4950
|
const tableName = getTableName(this.id);
|
|
4894
4951
|
console.log("[EXULU] checking if table exists.", tableName);
|
|
4895
|
-
const tableExists = await
|
|
4952
|
+
const tableExists = await db3.schema.hasTable(tableName);
|
|
4896
4953
|
return tableExists;
|
|
4897
4954
|
};
|
|
4898
4955
|
chunksTableExists = async () => {
|
|
4899
|
-
const { db:
|
|
4956
|
+
const { db: db3 } = await postgresClient();
|
|
4900
4957
|
const chunksTableName = getChunksTableName(this.id);
|
|
4901
|
-
const chunksTableExists = await
|
|
4958
|
+
const chunksTableExists = await db3.schema.hasTable(chunksTableName);
|
|
4902
4959
|
return chunksTableExists;
|
|
4903
4960
|
};
|
|
4904
4961
|
createAndUpsertEmbeddings = async (item, config, user, statistics, role, job) => {
|
|
@@ -4908,7 +4965,7 @@ var ExuluContext = class {
|
|
|
4908
4965
|
if (!item.id) {
|
|
4909
4966
|
throw new Error("Item id is required for generating embeddings.");
|
|
4910
4967
|
}
|
|
4911
|
-
const { db:
|
|
4968
|
+
const { db: db3 } = await postgresClient();
|
|
4912
4969
|
const { id: source, chunks } = await this.embedder.generateFromDocument(
|
|
4913
4970
|
{
|
|
4914
4971
|
...item,
|
|
@@ -4922,14 +4979,14 @@ var ExuluContext = class {
|
|
|
4922
4979
|
user,
|
|
4923
4980
|
role
|
|
4924
4981
|
);
|
|
4925
|
-
await
|
|
4926
|
-
await
|
|
4982
|
+
await db3.from(getChunksTableName(this.id)).where({ source }).delete();
|
|
4983
|
+
await db3.from(getChunksTableName(this.id)).insert(chunks.map((chunk) => ({
|
|
4927
4984
|
source,
|
|
4928
4985
|
content: chunk.content,
|
|
4929
4986
|
chunk_index: chunk.index,
|
|
4930
4987
|
embedding: pgvector2.toSql(chunk.vector)
|
|
4931
4988
|
})));
|
|
4932
|
-
await
|
|
4989
|
+
await db3.from(getTableName(this.id)).where({ id: item.id }).update({
|
|
4933
4990
|
embeddings_updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4934
4991
|
}).returning("id");
|
|
4935
4992
|
return {
|
|
@@ -4939,8 +4996,8 @@ var ExuluContext = class {
|
|
|
4939
4996
|
};
|
|
4940
4997
|
};
|
|
4941
4998
|
createItem = async (item, config, user, role, upsert) => {
|
|
4942
|
-
const { db:
|
|
4943
|
-
const mutation =
|
|
4999
|
+
const { db: db3 } = await postgresClient();
|
|
5000
|
+
const mutation = db3.from(getTableName(
|
|
4944
5001
|
this.id
|
|
4945
5002
|
)).insert(
|
|
4946
5003
|
{
|
|
@@ -4974,11 +5031,11 @@ var ExuluContext = class {
|
|
|
4974
5031
|
};
|
|
4975
5032
|
};
|
|
4976
5033
|
updateItem = async (item, config, user, role) => {
|
|
4977
|
-
const { db:
|
|
5034
|
+
const { db: db3 } = await postgresClient();
|
|
4978
5035
|
if (item.field) {
|
|
4979
5036
|
delete item.field;
|
|
4980
5037
|
}
|
|
4981
|
-
const record = await
|
|
5038
|
+
const record = await db3.from(
|
|
4982
5039
|
getTableName(this.id)
|
|
4983
5040
|
).where(
|
|
4984
5041
|
{ id: item.id }
|
|
@@ -4986,7 +5043,7 @@ var ExuluContext = class {
|
|
|
4986
5043
|
if (!record) {
|
|
4987
5044
|
throw new Error("Item not found.");
|
|
4988
5045
|
}
|
|
4989
|
-
const mutation =
|
|
5046
|
+
const mutation = db3.from(
|
|
4990
5047
|
getTableName(this.id)
|
|
4991
5048
|
).where(
|
|
4992
5049
|
{ id: record.id }
|
|
@@ -5020,17 +5077,17 @@ var ExuluContext = class {
|
|
|
5020
5077
|
if (!item.id) {
|
|
5021
5078
|
throw new Error("Item id is required for deleting item.");
|
|
5022
5079
|
}
|
|
5023
|
-
const { db:
|
|
5024
|
-
await
|
|
5080
|
+
const { db: db3 } = await postgresClient();
|
|
5081
|
+
await db3.from(getTableName(this.id)).where({ id: item.id }).delete();
|
|
5025
5082
|
if (!this.embedder) {
|
|
5026
5083
|
return {
|
|
5027
5084
|
id: item.id,
|
|
5028
5085
|
job: void 0
|
|
5029
5086
|
};
|
|
5030
5087
|
}
|
|
5031
|
-
const chunks = await
|
|
5088
|
+
const chunks = await db3.from(getChunksTableName(this.id)).where({ source: item.id }).select("id");
|
|
5032
5089
|
if (chunks.length > 0) {
|
|
5033
|
-
await
|
|
5090
|
+
await db3.from(getChunksTableName(this.id)).where({ source: item.id }).delete();
|
|
5034
5091
|
}
|
|
5035
5092
|
return {
|
|
5036
5093
|
id: item.id,
|
|
@@ -5079,8 +5136,8 @@ var ExuluContext = class {
|
|
|
5079
5136
|
}, role, void 0);
|
|
5080
5137
|
},
|
|
5081
5138
|
all: async (config, userId, roleId) => {
|
|
5082
|
-
const { db:
|
|
5083
|
-
const items = await
|
|
5139
|
+
const { db: db3 } = await postgresClient();
|
|
5140
|
+
const items = await db3.from(getTableName(this.id)).select("*");
|
|
5084
5141
|
const jobs = [];
|
|
5085
5142
|
const queue = await this.embedder?.queue;
|
|
5086
5143
|
if (!queue?.queue.name && items.length > 2e3) {
|
|
@@ -5109,12 +5166,12 @@ var ExuluContext = class {
|
|
|
5109
5166
|
}
|
|
5110
5167
|
};
|
|
5111
5168
|
createItemsTable = async () => {
|
|
5112
|
-
const { db:
|
|
5169
|
+
const { db: db3 } = await postgresClient();
|
|
5113
5170
|
const tableName = getTableName(this.id);
|
|
5114
5171
|
console.log("[EXULU] Creating table: " + tableName);
|
|
5115
|
-
return await
|
|
5172
|
+
return await db3.schema.createTable(tableName, (table) => {
|
|
5116
5173
|
console.log("[EXULU] Creating fields for table.", this.fields);
|
|
5117
|
-
table.uuid("id").primary().defaultTo(
|
|
5174
|
+
table.uuid("id").primary().defaultTo(db3.fn.uuid());
|
|
5118
5175
|
table.text("name");
|
|
5119
5176
|
table.text("description");
|
|
5120
5177
|
table.text("tags");
|
|
@@ -5137,19 +5194,19 @@ var ExuluContext = class {
|
|
|
5137
5194
|
}
|
|
5138
5195
|
mapType(table, type, sanitizeName(name), void 0, unique);
|
|
5139
5196
|
}
|
|
5140
|
-
table.timestamp("createdAt").defaultTo(
|
|
5141
|
-
table.timestamp("updatedAt").defaultTo(
|
|
5197
|
+
table.timestamp("createdAt").defaultTo(db3.fn.now());
|
|
5198
|
+
table.timestamp("updatedAt").defaultTo(db3.fn.now());
|
|
5142
5199
|
});
|
|
5143
5200
|
};
|
|
5144
5201
|
createChunksTable = async () => {
|
|
5145
|
-
const { db:
|
|
5202
|
+
const { db: db3 } = await refreshPostgresClient();
|
|
5146
5203
|
const tableName = getChunksTableName(this.id);
|
|
5147
5204
|
console.log("[EXULU] Creating table: " + tableName);
|
|
5148
|
-
await
|
|
5205
|
+
await db3.schema.createTable(tableName, (table) => {
|
|
5149
5206
|
if (!this.embedder) {
|
|
5150
5207
|
throw new Error("Embedder must be set for context " + this.name + " to create chunks table.");
|
|
5151
5208
|
}
|
|
5152
|
-
table.uuid("id").primary().defaultTo(
|
|
5209
|
+
table.uuid("id").primary().defaultTo(db3.fn.uuid());
|
|
5153
5210
|
table.uuid("source").references("id").inTable(getTableName(this.id));
|
|
5154
5211
|
table.text("content");
|
|
5155
5212
|
table.jsonb("metadata");
|
|
@@ -5161,10 +5218,10 @@ var ExuluContext = class {
|
|
|
5161
5218
|
);
|
|
5162
5219
|
table.index(["fts"], `${tableName}_fts_gin_idx`, "gin");
|
|
5163
5220
|
table.index(["source"], `${tableName}_source_idx`);
|
|
5164
|
-
table.timestamp("createdAt").defaultTo(
|
|
5165
|
-
table.timestamp("updatedAt").defaultTo(
|
|
5221
|
+
table.timestamp("createdAt").defaultTo(db3.fn.now());
|
|
5222
|
+
table.timestamp("updatedAt").defaultTo(db3.fn.now());
|
|
5166
5223
|
});
|
|
5167
|
-
await
|
|
5224
|
+
await db3.raw(`
|
|
5168
5225
|
CREATE INDEX IF NOT EXISTS ${tableName}_embedding_hnsw_cosine
|
|
5169
5226
|
ON ${tableName}
|
|
5170
5227
|
USING hnsw (embedding vector_cosine_ops)
|
|
@@ -5185,7 +5242,7 @@ var ExuluContext = class {
|
|
|
5185
5242
|
config: [],
|
|
5186
5243
|
description: `Gets information from the context called: ${this.name}. The context description is: ${this.description}.`,
|
|
5187
5244
|
execute: async ({ query, user, role }) => {
|
|
5188
|
-
const { db:
|
|
5245
|
+
const { db: db3 } = await postgresClient();
|
|
5189
5246
|
const result = await vectorSearch({
|
|
5190
5247
|
page: 1,
|
|
5191
5248
|
limit: 10,
|
|
@@ -5195,7 +5252,7 @@ var ExuluContext = class {
|
|
|
5195
5252
|
role,
|
|
5196
5253
|
method: "hybridSearch",
|
|
5197
5254
|
context: this,
|
|
5198
|
-
db:
|
|
5255
|
+
db: db3,
|
|
5199
5256
|
sort: void 0,
|
|
5200
5257
|
trigger: "agent"
|
|
5201
5258
|
});
|
|
@@ -5218,8 +5275,8 @@ var ExuluContext = class {
|
|
|
5218
5275
|
var updateStatistic = async (statistic) => {
|
|
5219
5276
|
console.log("[EXULU] Updating statistic", statistic);
|
|
5220
5277
|
const currentDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5221
|
-
const { db:
|
|
5222
|
-
const existing = await
|
|
5278
|
+
const { db: db3 } = await postgresClient();
|
|
5279
|
+
const existing = await db3.from("tracking").where({
|
|
5223
5280
|
...statistic.user ? { user: statistic.user } : {},
|
|
5224
5281
|
...statistic.role ? { role: statistic.role } : {},
|
|
5225
5282
|
name: statistic.name,
|
|
@@ -5229,7 +5286,7 @@ var updateStatistic = async (statistic) => {
|
|
|
5229
5286
|
}).first();
|
|
5230
5287
|
console.log("[EXULU] Existing", existing);
|
|
5231
5288
|
if (!existing) {
|
|
5232
|
-
await
|
|
5289
|
+
await db3.from("tracking").insert({
|
|
5233
5290
|
name: statistic.name,
|
|
5234
5291
|
label: statistic.label,
|
|
5235
5292
|
type: statistic.type,
|
|
@@ -5239,8 +5296,8 @@ var updateStatistic = async (statistic) => {
|
|
|
5239
5296
|
...statistic.role ? { role: statistic.role } : {}
|
|
5240
5297
|
});
|
|
5241
5298
|
} else {
|
|
5242
|
-
await
|
|
5243
|
-
total:
|
|
5299
|
+
await db3.from("tracking").update({
|
|
5300
|
+
total: db3.raw("total + ?", [statistic.count ?? 1])
|
|
5244
5301
|
}).where({
|
|
5245
5302
|
name: statistic.name,
|
|
5246
5303
|
label: statistic.label,
|
|
@@ -5525,10 +5582,10 @@ var createExpressRoutes = async (app, agents, tools, contexts, config, tracer) =
|
|
|
5525
5582
|
if (!authenticationResult.user?.id) {
|
|
5526
5583
|
throw new Error(authenticationResult.message);
|
|
5527
5584
|
}
|
|
5528
|
-
const { db:
|
|
5585
|
+
const { db: db3 } = await postgresClient();
|
|
5529
5586
|
return {
|
|
5530
5587
|
req,
|
|
5531
|
-
db:
|
|
5588
|
+
db: db3,
|
|
5532
5589
|
user: authenticationResult.user
|
|
5533
5590
|
};
|
|
5534
5591
|
}
|
|
@@ -5548,8 +5605,8 @@ var createExpressRoutes = async (app, agents, tools, contexts, config, tracer) =
|
|
|
5548
5605
|
});
|
|
5549
5606
|
return;
|
|
5550
5607
|
}
|
|
5551
|
-
const { db:
|
|
5552
|
-
const variable = await
|
|
5608
|
+
const { db: db3 } = await postgresClient();
|
|
5609
|
+
const variable = await db3.from("variables").where({ name: "OPENAI_IMAGE_GENERATION_API_KEY" }).first();
|
|
5553
5610
|
if (!variable) {
|
|
5554
5611
|
res.status(400).json({
|
|
5555
5612
|
message: "Provider API key variable not found."
|
|
@@ -5640,8 +5697,8 @@ Mood: friendly and intelligent.
|
|
|
5640
5697
|
});
|
|
5641
5698
|
return;
|
|
5642
5699
|
}
|
|
5643
|
-
const { db:
|
|
5644
|
-
const evalRun = await
|
|
5700
|
+
const { db: db3 } = await postgresClient();
|
|
5701
|
+
const evalRun = await db3.from("eval_runs").where({ id: evalRunId }).first();
|
|
5645
5702
|
if (!evalRun) {
|
|
5646
5703
|
res.status(404).json({
|
|
5647
5704
|
message: "Eval run not found."
|
|
@@ -5669,7 +5726,7 @@ Mood: friendly and intelligent.
|
|
|
5669
5726
|
});
|
|
5670
5727
|
return;
|
|
5671
5728
|
}
|
|
5672
|
-
const testCases = await
|
|
5729
|
+
const testCases = await db3.from("test_cases").whereIn("id", testCaseIds);
|
|
5673
5730
|
if (testCases.length === 0) {
|
|
5674
5731
|
res.status(404).json({
|
|
5675
5732
|
message: "No test cases found."
|
|
@@ -5735,8 +5792,8 @@ Mood: friendly and intelligent.
|
|
|
5735
5792
|
});
|
|
5736
5793
|
});
|
|
5737
5794
|
app.get("/theme", async (req, res) => {
|
|
5738
|
-
const { db:
|
|
5739
|
-
const themeConfig = await
|
|
5795
|
+
const { db: db3 } = await postgresClient();
|
|
5796
|
+
const themeConfig = await db3.from("platform_configurations").where({ config_key: "theme_config" }).first();
|
|
5740
5797
|
if (!themeConfig) {
|
|
5741
5798
|
res.status(200).json({
|
|
5742
5799
|
theme: {
|
|
@@ -5752,6 +5809,7 @@ Mood: friendly and intelligent.
|
|
|
5752
5809
|
});
|
|
5753
5810
|
app.get("/config", async (req, res) => {
|
|
5754
5811
|
res.status(200).json({
|
|
5812
|
+
authMode: process.env.AUTH_MODE,
|
|
5755
5813
|
MCP: {
|
|
5756
5814
|
enabled: config?.MCP.enabled
|
|
5757
5815
|
},
|
|
@@ -5787,7 +5845,7 @@ Mood: friendly and intelligent.
|
|
|
5787
5845
|
});
|
|
5788
5846
|
return;
|
|
5789
5847
|
}
|
|
5790
|
-
const { db:
|
|
5848
|
+
const { db: db3 } = await postgresClient();
|
|
5791
5849
|
const agentInstance = await loadAgent(instance);
|
|
5792
5850
|
const requestValidationResult = requestValidators.agents(req);
|
|
5793
5851
|
if (requestValidationResult.error) {
|
|
@@ -5808,7 +5866,7 @@ Mood: friendly and intelligent.
|
|
|
5808
5866
|
return;
|
|
5809
5867
|
}
|
|
5810
5868
|
if (headers.session) {
|
|
5811
|
-
const session = await
|
|
5869
|
+
const session = await db3.from("agent_sessions").where({
|
|
5812
5870
|
id: headers.session
|
|
5813
5871
|
}).first();
|
|
5814
5872
|
let hasAccessToSession = await checkRecordAccess(session, "write", user);
|
|
@@ -5830,7 +5888,7 @@ Mood: friendly and intelligent.
|
|
|
5830
5888
|
let enabledTools = await getEnabledTools(agentInstance, tools, disabledTools, agents, user);
|
|
5831
5889
|
console.log("[EXULU] enabled tools", enabledTools?.map((x) => x.name + " (" + x.id + ")"));
|
|
5832
5890
|
const variableName = agentInstance.providerapikey;
|
|
5833
|
-
const variable = await
|
|
5891
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
5834
5892
|
if (!variable) {
|
|
5835
5893
|
res.status(400).json({
|
|
5836
5894
|
message: "Provider API key variable not found."
|
|
@@ -5933,8 +5991,8 @@ Mood: friendly and intelligent.
|
|
|
5933
5991
|
return;
|
|
5934
5992
|
}
|
|
5935
5993
|
console.log("[EXULU] Authenticated call", authenticationResult.user?.email);
|
|
5936
|
-
const { db:
|
|
5937
|
-
let query =
|
|
5994
|
+
const { db: db3 } = await postgresClient();
|
|
5995
|
+
let query = db3("agents");
|
|
5938
5996
|
query.select("*");
|
|
5939
5997
|
query = applyAccessControl(agentsSchema2(), authenticationResult.user, query);
|
|
5940
5998
|
query.where({ id: srcReq.params.id });
|
|
@@ -5954,7 +6012,7 @@ Mood: friendly and intelligent.
|
|
|
5954
6012
|
return;
|
|
5955
6013
|
}
|
|
5956
6014
|
const variableName = agent.providerapikey;
|
|
5957
|
-
const variable = await
|
|
6015
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
5958
6016
|
console.log("[EXULU] Variable loaded", variable);
|
|
5959
6017
|
let providerapikey = variable.value;
|
|
5960
6018
|
if (!variable.encrypted) {
|
|
@@ -6004,8 +6062,8 @@ Mood: friendly and intelligent.
|
|
|
6004
6062
|
return;
|
|
6005
6063
|
}
|
|
6006
6064
|
const user = authenticationResult.user;
|
|
6007
|
-
const { db:
|
|
6008
|
-
let query =
|
|
6065
|
+
const { db: db3 } = await postgresClient();
|
|
6066
|
+
let query = db3("agents");
|
|
6009
6067
|
query.select("*");
|
|
6010
6068
|
query = applyAccessControl(agentsSchema2(), authenticationResult.user, query);
|
|
6011
6069
|
query.where({ id: req.params.id });
|
|
@@ -6032,7 +6090,7 @@ Mood: friendly and intelligent.
|
|
|
6032
6090
|
return;
|
|
6033
6091
|
}
|
|
6034
6092
|
const variableName = agent.providerapikey;
|
|
6035
|
-
const variable = await
|
|
6093
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
6036
6094
|
if (!variable) {
|
|
6037
6095
|
const arrayBuffer = createCustomAnthropicStreamingMessage(CLAUDE_MESSAGES.anthropic_token_variable_not_found);
|
|
6038
6096
|
res.setHeader("Content-Type", "application/json");
|
|
@@ -6172,7 +6230,7 @@ var createWorkers = async (queues2, config, contexts, tracer) => {
|
|
|
6172
6230
|
const worker = new Worker(
|
|
6173
6231
|
`${queue}`,
|
|
6174
6232
|
async (bullmqJob) => {
|
|
6175
|
-
const { db:
|
|
6233
|
+
const { db: db3 } = await postgresClient();
|
|
6176
6234
|
try {
|
|
6177
6235
|
const data = bullmqJob.data;
|
|
6178
6236
|
bullmq.validate(bullmqJob.id, data);
|
|
@@ -6228,7 +6286,7 @@ var createWorkers = async (queues2, config, contexts, tracer) => {
|
|
|
6228
6286
|
return result;
|
|
6229
6287
|
}
|
|
6230
6288
|
} catch (error) {
|
|
6231
|
-
await
|
|
6289
|
+
await db3.from("jobs").where({ redis: bullmqJob.id }).update({
|
|
6232
6290
|
status: "failed",
|
|
6233
6291
|
finishedAt: /* @__PURE__ */ new Date(),
|
|
6234
6292
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -6967,8 +7025,8 @@ var ExuluApp = class {
|
|
|
6967
7025
|
context: contextId,
|
|
6968
7026
|
item: itemId
|
|
6969
7027
|
}) => {
|
|
6970
|
-
const { db:
|
|
6971
|
-
const item = await
|
|
7028
|
+
const { db: db3 } = await postgresClient();
|
|
7029
|
+
const item = await db3.from(getTableName(contextId)).where({ id: itemId }).select("*").first();
|
|
6972
7030
|
const context = this.contexts.find((x) => contextId === x.id);
|
|
6973
7031
|
if (!context) {
|
|
6974
7032
|
throw new Error(`Context ${contextId} not found in registry.`);
|
|
@@ -8268,59 +8326,6 @@ var SentenceChunker = class _SentenceChunker extends BaseChunker {
|
|
|
8268
8326
|
}
|
|
8269
8327
|
};
|
|
8270
8328
|
|
|
8271
|
-
// src/auth/generate-key.ts
|
|
8272
|
-
import bcrypt3 from "bcryptjs";
|
|
8273
|
-
var SALT_ROUNDS = 12;
|
|
8274
|
-
async function encryptString(string) {
|
|
8275
|
-
const hash = await bcrypt3.hash(string, SALT_ROUNDS);
|
|
8276
|
-
return hash;
|
|
8277
|
-
}
|
|
8278
|
-
var generateApiKey = async (name, email) => {
|
|
8279
|
-
const { db: db4 } = await postgresClient();
|
|
8280
|
-
console.log("[EXULU] Inserting default user and admin role.");
|
|
8281
|
-
const existingRole = await db4.from("roles").where({ name: "admin" }).first();
|
|
8282
|
-
let roleId;
|
|
8283
|
-
if (!existingRole) {
|
|
8284
|
-
console.log("[EXULU] Creating default admin role.");
|
|
8285
|
-
const role = await db4.from("roles").insert({
|
|
8286
|
-
name: "admin",
|
|
8287
|
-
agents: "write",
|
|
8288
|
-
workflows: "write",
|
|
8289
|
-
variables: "write",
|
|
8290
|
-
users: "write"
|
|
8291
|
-
}).returning("id");
|
|
8292
|
-
roleId = role[0].id;
|
|
8293
|
-
} else {
|
|
8294
|
-
roleId = existingRole.id;
|
|
8295
|
-
}
|
|
8296
|
-
const newKeyName = name;
|
|
8297
|
-
const plainKey = `sk_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
|
|
8298
|
-
const postFix = `/${newKeyName.toLowerCase().trim().replaceAll(" ", "_")}`;
|
|
8299
|
-
const encryptedKey = await encryptString(plainKey);
|
|
8300
|
-
const existingApiUser = await db4.from("users").where({ email }).first();
|
|
8301
|
-
if (!existingApiUser) {
|
|
8302
|
-
console.log("[EXULU] Creating default api user.");
|
|
8303
|
-
await db4.from("users").insert({
|
|
8304
|
-
name,
|
|
8305
|
-
email,
|
|
8306
|
-
super_admin: true,
|
|
8307
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
8308
|
-
updatedAt: /* @__PURE__ */ new Date(),
|
|
8309
|
-
type: "api",
|
|
8310
|
-
emailVerified: /* @__PURE__ */ new Date(),
|
|
8311
|
-
apikey: `${encryptedKey}${postFix}`,
|
|
8312
|
-
// password: "admin", todo add this again when we implement password auth / encryption as alternative to OTP
|
|
8313
|
-
role: roleId
|
|
8314
|
-
});
|
|
8315
|
-
console.log("[EXULU] Default api user created. Key: ", `${plainKey}${postFix}`);
|
|
8316
|
-
} else {
|
|
8317
|
-
console.log("[EXULU] API user with that name already exists.");
|
|
8318
|
-
}
|
|
8319
|
-
return {
|
|
8320
|
-
key: `${plainKey}${postFix}`
|
|
8321
|
-
};
|
|
8322
|
-
};
|
|
8323
|
-
|
|
8324
8329
|
// src/postgres/init-db.ts
|
|
8325
8330
|
var {
|
|
8326
8331
|
agentsSchema: agentsSchema3,
|
|
@@ -8467,16 +8472,16 @@ var contextDatabases = async (contexts) => {
|
|
|
8467
8472
|
}
|
|
8468
8473
|
};
|
|
8469
8474
|
var execute = async ({ contexts }) => {
|
|
8470
|
-
const { db:
|
|
8475
|
+
const { db: db3 } = await postgresClient();
|
|
8471
8476
|
console.log("[EXULU] Checking Exulu IMP database status.");
|
|
8472
|
-
await up(
|
|
8477
|
+
await up(db3);
|
|
8473
8478
|
await contextDatabases(contexts);
|
|
8474
8479
|
console.log("[EXULU] Inserting default user and admin role.");
|
|
8475
|
-
const existingRole = await
|
|
8480
|
+
const existingRole = await db3.from("roles").where({ name: "admin" }).first();
|
|
8476
8481
|
let roleId;
|
|
8477
8482
|
if (!existingRole) {
|
|
8478
8483
|
console.log("[EXULU] Creating default admin role.");
|
|
8479
|
-
const role = await
|
|
8484
|
+
const role = await db3.from("roles").insert({
|
|
8480
8485
|
name: "admin",
|
|
8481
8486
|
agents: "write",
|
|
8482
8487
|
workflows: "write",
|
|
@@ -8487,11 +8492,11 @@ var execute = async ({ contexts }) => {
|
|
|
8487
8492
|
} else {
|
|
8488
8493
|
roleId = existingRole.id;
|
|
8489
8494
|
}
|
|
8490
|
-
const existingUser = await
|
|
8495
|
+
const existingUser = await db3.from("users").where({ email: "admin@exulu.com" }).first();
|
|
8491
8496
|
if (!existingUser) {
|
|
8492
8497
|
const password = await encryptString("admin");
|
|
8493
8498
|
console.log("[EXULU] Creating default admin user.");
|
|
8494
|
-
await
|
|
8499
|
+
await db3.from("users").insert({
|
|
8495
8500
|
name: "exulu",
|
|
8496
8501
|
email: "admin@exulu.com",
|
|
8497
8502
|
super_admin: true,
|
|
@@ -8598,8 +8603,8 @@ var ExuluDefaultAgents = {
|
|
|
8598
8603
|
};
|
|
8599
8604
|
var ExuluVariables = {
|
|
8600
8605
|
get: async (name) => {
|
|
8601
|
-
const { db:
|
|
8602
|
-
let variable = await
|
|
8606
|
+
const { db: db3 } = await postgresClient();
|
|
8607
|
+
let variable = await db3.from("variables").where({ name }).first();
|
|
8603
8608
|
if (!variable) {
|
|
8604
8609
|
throw new Error(`Variable ${name} not found.`);
|
|
8605
8610
|
}
|
|
@@ -8701,7 +8706,7 @@ var ExuluOtel = {
|
|
|
8701
8706
|
});
|
|
8702
8707
|
}
|
|
8703
8708
|
};
|
|
8704
|
-
var
|
|
8709
|
+
var db2 = {
|
|
8705
8710
|
init: async ({
|
|
8706
8711
|
contexts
|
|
8707
8712
|
}) => {
|
|
@@ -8740,5 +8745,5 @@ export {
|
|
|
8740
8745
|
ExuluTool2 as ExuluTool,
|
|
8741
8746
|
ExuluUtils,
|
|
8742
8747
|
ExuluVariables,
|
|
8743
|
-
|
|
8748
|
+
db2 as db
|
|
8744
8749
|
};
|