@exulu/backend 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -3
- package/dist/index.cjs +203 -198
- package/dist/index.d.cts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +203 -198
- package/package.json +2 -4
- package/types/models/user.ts +1 -0
package/dist/index.cjs
CHANGED
|
@@ -304,41 +304,50 @@ var bullmqDecorator = async ({
|
|
|
304
304
|
};
|
|
305
305
|
|
|
306
306
|
// src/registry/utils/map-types.ts
|
|
307
|
-
var mapType = (t, type, name, defaultValue) => {
|
|
307
|
+
var mapType = (t, type, name, defaultValue, unique) => {
|
|
308
308
|
if (type === "text") {
|
|
309
309
|
t.text(name);
|
|
310
|
+
if (unique) t.unique(name);
|
|
310
311
|
return;
|
|
311
312
|
}
|
|
312
313
|
if (type === "longText") {
|
|
313
314
|
t.text(name);
|
|
315
|
+
if (unique) t.unique(name);
|
|
314
316
|
return;
|
|
315
317
|
}
|
|
316
318
|
if (type === "shortText") {
|
|
317
319
|
t.string(name, 100);
|
|
320
|
+
if (unique) t.unique(name);
|
|
318
321
|
return;
|
|
319
322
|
}
|
|
320
323
|
if (type === "number") {
|
|
321
324
|
t.float(name);
|
|
325
|
+
if (unique) t.unique(name);
|
|
322
326
|
return;
|
|
323
327
|
}
|
|
324
328
|
if (type === "boolean") {
|
|
325
329
|
t.boolean(name).defaultTo(defaultValue || false);
|
|
330
|
+
if (unique) t.unique(name);
|
|
326
331
|
return;
|
|
327
332
|
}
|
|
328
333
|
if (type === "code") {
|
|
329
334
|
t.text(name);
|
|
335
|
+
if (unique) t.unique(name);
|
|
330
336
|
return;
|
|
331
337
|
}
|
|
332
338
|
if (type === "json") {
|
|
333
339
|
t.jsonb(name);
|
|
340
|
+
if (unique) t.unique(name);
|
|
334
341
|
return;
|
|
335
342
|
}
|
|
336
343
|
if (type === "date") {
|
|
337
344
|
t.timestamp(name);
|
|
345
|
+
if (unique) t.unique(name);
|
|
338
346
|
return;
|
|
339
347
|
}
|
|
340
348
|
if (type === "uuid") {
|
|
341
349
|
t.uuid(name);
|
|
350
|
+
if (unique) t.unique(name);
|
|
342
351
|
return;
|
|
343
352
|
}
|
|
344
353
|
throw new Error("Invalid type: " + type);
|
|
@@ -437,7 +446,39 @@ var ExuluEvalUtils = {
|
|
|
437
446
|
}
|
|
438
447
|
};
|
|
439
448
|
|
|
449
|
+
// src/registry/utils/claude-messages.ts
|
|
450
|
+
var CLAUDE_MESSAGES = {
|
|
451
|
+
anthropic_token_variable_not_encrypted: `
|
|
452
|
+
\x1B[41m -- Anthropic token variable set by your admin is not encrypted. This poses a security risk. Please contact your admin to fix the variable used for your key. --
|
|
453
|
+
\x1B[0m`,
|
|
454
|
+
anthropic_token_variable_not_found: `
|
|
455
|
+
\x1B[41m -- Anthropic token variable not found. Please contact to fix the variable used for your key. --
|
|
456
|
+
\x1B[0m`,
|
|
457
|
+
authentication_error: `
|
|
458
|
+
\x1B[41m -- Authentication error please check your IMP token and try again. --
|
|
459
|
+
\x1B[0m`,
|
|
460
|
+
missing_body: `
|
|
461
|
+
\x1B[41m -- Missing body Anthropic response. --
|
|
462
|
+
\x1B[0m`,
|
|
463
|
+
missing_nextauth_secret: `
|
|
464
|
+
\x1B[41m -- Missing NEXTAUTH_SECRET in environment variables on the server. --
|
|
465
|
+
\x1B[0m`,
|
|
466
|
+
not_enabled: `
|
|
467
|
+
\x1B[31m
|
|
468
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557
|
|
469
|
+
\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
470
|
+
\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
471
|
+
\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
472
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
473
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
|
|
474
|
+
Intelligence Management Platform
|
|
475
|
+
\x1B[0m
|
|
476
|
+
\x1B[41m -- Your account has not been enabled to use Claude Code, please contact your admin or enable Claude Code in the user settings. --
|
|
477
|
+
\x1B[0m`
|
|
478
|
+
};
|
|
479
|
+
|
|
440
480
|
// src/registry/classes.ts
|
|
481
|
+
var import_crypto_js = __toESM(require("crypto-js"), 1);
|
|
441
482
|
function sanitizeToolName(name) {
|
|
442
483
|
if (typeof name !== "string") return "";
|
|
443
484
|
let sanitized = name.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
@@ -447,7 +488,7 @@ function sanitizeToolName(name) {
|
|
|
447
488
|
}
|
|
448
489
|
return sanitized;
|
|
449
490
|
}
|
|
450
|
-
var convertToolsArrayToObject = (tools) => {
|
|
491
|
+
var convertToolsArrayToObject = (tools, configs) => {
|
|
451
492
|
if (!tools) return {};
|
|
452
493
|
const sanitizedTools = tools ? tools.map((tool2) => ({
|
|
453
494
|
...tool2,
|
|
@@ -461,12 +502,57 @@ var convertToolsArrayToObject = (tools) => {
|
|
|
461
502
|
};
|
|
462
503
|
return {
|
|
463
504
|
...sanitizedTools?.reduce(
|
|
464
|
-
(prev, cur) => ({
|
|
505
|
+
(prev, cur) => ({
|
|
506
|
+
...prev,
|
|
507
|
+
[cur.name]: {
|
|
508
|
+
...cur.tool,
|
|
509
|
+
execute: async (inputs, options) => {
|
|
510
|
+
if (!cur.tool?.execute) {
|
|
511
|
+
console.error("[EXULU] Tool execute function is undefined.", cur.tool);
|
|
512
|
+
throw new Error("Tool execute function is undefined.");
|
|
513
|
+
}
|
|
514
|
+
let config = configs?.find((config2) => config2.toolId === cur.id);
|
|
515
|
+
if (config) {
|
|
516
|
+
config = await hydrateVariables(config || []);
|
|
517
|
+
}
|
|
518
|
+
return await cur.tool.execute({
|
|
519
|
+
...inputs,
|
|
520
|
+
// Convert config to object format if a config object
|
|
521
|
+
// is available, after we added the .value property
|
|
522
|
+
// by hydrating it from the variables table.
|
|
523
|
+
config: config ? config.config.reduce((acc, curr) => {
|
|
524
|
+
acc[curr.name] = curr.value;
|
|
525
|
+
return acc;
|
|
526
|
+
}, {}) : {}
|
|
527
|
+
}, options);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}),
|
|
465
531
|
{}
|
|
466
532
|
),
|
|
467
533
|
askForConfirmation
|
|
468
534
|
};
|
|
469
535
|
};
|
|
536
|
+
var hydrateVariables = async (tool2) => {
|
|
537
|
+
const { db: db3 } = await postgresClient();
|
|
538
|
+
const promises2 = tool2.config.map(async (toolConfig) => {
|
|
539
|
+
const variableName = toolConfig.variable;
|
|
540
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
541
|
+
if (!variable) {
|
|
542
|
+
console.error("[EXULU] Variable " + variableName + " not found.");
|
|
543
|
+
throw new Error("Variable " + variableName + " not found.");
|
|
544
|
+
}
|
|
545
|
+
let value = variable.value;
|
|
546
|
+
if (variable.encrypted) {
|
|
547
|
+
const bytes = import_crypto_js.default.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
|
|
548
|
+
value = bytes.toString(import_crypto_js.default.enc.Utf8);
|
|
549
|
+
}
|
|
550
|
+
toolConfig.value = value;
|
|
551
|
+
});
|
|
552
|
+
await Promise.all(promises2);
|
|
553
|
+
console.log("[EXULU] Variable values retrieved and added to tool config.");
|
|
554
|
+
return tool2;
|
|
555
|
+
};
|
|
470
556
|
function generateSlug(name) {
|
|
471
557
|
const normalized = name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "");
|
|
472
558
|
const lowercase = normalized.toLowerCase();
|
|
@@ -523,12 +609,13 @@ var ExuluAgent = class {
|
|
|
523
609
|
tool = () => {
|
|
524
610
|
return new ExuluTool({
|
|
525
611
|
id: this.id,
|
|
526
|
-
name: `${this.name}
|
|
612
|
+
name: `${this.name}`,
|
|
527
613
|
type: "agent",
|
|
528
614
|
inputSchema: import_zod2.z.object({
|
|
529
615
|
prompt: import_zod2.z.string()
|
|
530
616
|
}),
|
|
531
617
|
description: `A function that calls an AI agent named: ${this.name}. The agent does the following: ${this.description}.`,
|
|
618
|
+
config: [],
|
|
532
619
|
execute: async ({ prompt }) => {
|
|
533
620
|
return await this.generateSync({
|
|
534
621
|
prompt,
|
|
@@ -540,7 +627,7 @@ var ExuluAgent = class {
|
|
|
540
627
|
}
|
|
541
628
|
});
|
|
542
629
|
};
|
|
543
|
-
generateSync = async ({ messages, prompt, tools, statistics }) => {
|
|
630
|
+
generateSync = async ({ messages, prompt, tools, statistics, configs }) => {
|
|
544
631
|
if (!this.model) {
|
|
545
632
|
throw new Error("Model is required for streaming.");
|
|
546
633
|
}
|
|
@@ -556,7 +643,7 @@ var ExuluAgent = class {
|
|
|
556
643
|
messages,
|
|
557
644
|
prompt,
|
|
558
645
|
maxRetries: 2,
|
|
559
|
-
tools: convertToolsArrayToObject(tools),
|
|
646
|
+
tools: convertToolsArrayToObject(tools, configs),
|
|
560
647
|
maxSteps: 5
|
|
561
648
|
});
|
|
562
649
|
if (statistics) {
|
|
@@ -570,7 +657,7 @@ var ExuluAgent = class {
|
|
|
570
657
|
}
|
|
571
658
|
return text;
|
|
572
659
|
};
|
|
573
|
-
generateStream = ({ messages, prompt, tools, statistics }) => {
|
|
660
|
+
generateStream = ({ messages, prompt, tools, statistics, configs }) => {
|
|
574
661
|
if (!this.model) {
|
|
575
662
|
throw new Error("Model is required for streaming.");
|
|
576
663
|
}
|
|
@@ -586,7 +673,7 @@ var ExuluAgent = class {
|
|
|
586
673
|
prompt,
|
|
587
674
|
system: "You are a helpful assistant. When you use a tool to answer a question do not explicitly comment on the result of the tool call unless the user has explicitly you to do something with the result.",
|
|
588
675
|
maxRetries: 2,
|
|
589
|
-
tools: convertToolsArrayToObject(tools),
|
|
676
|
+
tools: convertToolsArrayToObject(tools, configs),
|
|
590
677
|
maxSteps: 5,
|
|
591
678
|
onError: (error) => console.error("[EXULU] chat stream error.", error),
|
|
592
679
|
onFinish: async ({ response, usage }) => {
|
|
@@ -942,8 +1029,10 @@ var ExuluTool = class {
|
|
|
942
1029
|
inputSchema;
|
|
943
1030
|
type;
|
|
944
1031
|
tool;
|
|
945
|
-
|
|
1032
|
+
config;
|
|
1033
|
+
constructor({ id, name, description, inputSchema, type, execute: execute2, config }) {
|
|
946
1034
|
this.id = id;
|
|
1035
|
+
this.config = config;
|
|
947
1036
|
this.name = name;
|
|
948
1037
|
this.description = description;
|
|
949
1038
|
this.inputSchema = inputSchema;
|
|
@@ -1351,11 +1440,11 @@ var ExuluContext = class {
|
|
|
1351
1440
|
table.text("source");
|
|
1352
1441
|
table.timestamp("embeddings_updated_at");
|
|
1353
1442
|
for (const field of this.fields) {
|
|
1354
|
-
const { type, name } = field;
|
|
1443
|
+
const { type, name, unique } = field;
|
|
1355
1444
|
if (!type || !name) {
|
|
1356
1445
|
continue;
|
|
1357
1446
|
}
|
|
1358
|
-
mapType(table, type, sanitizeName(name));
|
|
1447
|
+
mapType(table, type, sanitizeName(name), void 0, unique);
|
|
1359
1448
|
}
|
|
1360
1449
|
table.timestamps(true, true);
|
|
1361
1450
|
});
|
|
@@ -1377,11 +1466,12 @@ var ExuluContext = class {
|
|
|
1377
1466
|
tool = () => {
|
|
1378
1467
|
return new ExuluTool({
|
|
1379
1468
|
id: this.id,
|
|
1380
|
-
name: `${this.name}
|
|
1469
|
+
name: `${this.name}`,
|
|
1381
1470
|
type: "context",
|
|
1382
1471
|
inputSchema: import_zod2.z.object({
|
|
1383
1472
|
query: import_zod2.z.string()
|
|
1384
1473
|
}),
|
|
1474
|
+
config: [],
|
|
1385
1475
|
description: `Gets information from the context called: ${this.name}. The context description is: ${this.description}.`,
|
|
1386
1476
|
execute: async ({ query }) => {
|
|
1387
1477
|
return await this.getItems({
|
|
@@ -1849,7 +1939,7 @@ var import_reflect_metadata = require("reflect-metadata");
|
|
|
1849
1939
|
var import_schema = require("@graphql-tools/schema");
|
|
1850
1940
|
var import_graphql_type_json = __toESM(require("graphql-type-json"), 1);
|
|
1851
1941
|
var import_graphql = require("graphql");
|
|
1852
|
-
var
|
|
1942
|
+
var import_crypto_js2 = __toESM(require("crypto-js"), 1);
|
|
1853
1943
|
var GraphQLDate = new import_graphql.GraphQLScalarType({
|
|
1854
1944
|
name: "Date",
|
|
1855
1945
|
description: "Date custom scalar type",
|
|
@@ -2015,8 +2105,9 @@ function createMutations(table) {
|
|
|
2015
2105
|
return results[0];
|
|
2016
2106
|
},
|
|
2017
2107
|
[`${tableNamePlural}UpdateOne`]: async (_, args, context, info) => {
|
|
2018
|
-
const { db: db3 } = context;
|
|
2108
|
+
const { db: db3, req } = context;
|
|
2019
2109
|
let { where, input } = args;
|
|
2110
|
+
await validateSuperAdminPermission(tableNamePlural, input, req);
|
|
2020
2111
|
input = encryptSensitiveFields(input);
|
|
2021
2112
|
await db3(tableNamePlural).where(where).update({
|
|
2022
2113
|
...input,
|
|
@@ -2027,9 +2118,10 @@ function createMutations(table) {
|
|
|
2027
2118
|
return result;
|
|
2028
2119
|
},
|
|
2029
2120
|
[`${tableNamePlural}UpdateOneById`]: async (_, args, context, info) => {
|
|
2121
|
+
const { db: db3, req } = context;
|
|
2030
2122
|
let { id, input } = args;
|
|
2123
|
+
await validateSuperAdminPermission(tableNamePlural, input, req);
|
|
2031
2124
|
input = encryptSensitiveFields(input);
|
|
2032
|
-
const { db: db3 } = context;
|
|
2033
2125
|
await db3(tableNamePlural).where({ id }).update({
|
|
2034
2126
|
...input,
|
|
2035
2127
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -2166,6 +2258,7 @@ function createQueries(table) {
|
|
|
2166
2258
|
};
|
|
2167
2259
|
}
|
|
2168
2260
|
function createSDL(tables) {
|
|
2261
|
+
console.log("[EXULU] Creating SDL");
|
|
2169
2262
|
let typeDefs = `
|
|
2170
2263
|
scalar JSON
|
|
2171
2264
|
scalar Date
|
|
@@ -2181,6 +2274,7 @@ function createSDL(tables) {
|
|
|
2181
2274
|
const tableNamePlural = table.name.plural.toLowerCase();
|
|
2182
2275
|
const tableNameSingular = table.name.singular.toLowerCase();
|
|
2183
2276
|
const tableNameSingularUpperCaseFirst = table.name.singular.charAt(0).toUpperCase() + table.name.singular.slice(1);
|
|
2277
|
+
console.log("[EXULU] Adding table >>>>>", tableNamePlural);
|
|
2184
2278
|
typeDefs += `
|
|
2185
2279
|
${tableNameSingular}ById(id: ID!): ${tableNameSingular}
|
|
2186
2280
|
${tableNamePlural}Pagination(limit: Int, page: Int, filters: [Filter${tableNameSingularUpperCaseFirst}], sort: SortBy): ${tableNameSingularUpperCaseFirst}PaginationResult
|
|
@@ -2255,15 +2349,23 @@ type JobStatistics {
|
|
|
2255
2349
|
console.log("\n");
|
|
2256
2350
|
return schema;
|
|
2257
2351
|
}
|
|
2258
|
-
var sensitiveFields = ["anthropic_token"];
|
|
2259
2352
|
var encryptSensitiveFields = (input) => {
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
}
|
|
2264
|
-
});
|
|
2353
|
+
if (input.value && input.encrypted === true) {
|
|
2354
|
+
input.value = import_crypto_js2.default.AES.encrypt(input.value, process.env.NEXTAUTH_SECRET).toString();
|
|
2355
|
+
}
|
|
2265
2356
|
return input;
|
|
2266
2357
|
};
|
|
2358
|
+
var validateSuperAdminPermission = async (tableNamePlural, input, req) => {
|
|
2359
|
+
if (tableNamePlural === "users" && input.super_admin !== void 0) {
|
|
2360
|
+
const authResult = await requestValidators.authenticate(req);
|
|
2361
|
+
if (authResult.error || !authResult.user) {
|
|
2362
|
+
throw new Error("Authentication failed");
|
|
2363
|
+
}
|
|
2364
|
+
if (!authResult.user.super_admin) {
|
|
2365
|
+
throw new Error("Only super administrators can modify super_admin status");
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
};
|
|
2267
2369
|
|
|
2268
2370
|
// src/registry/routes.ts
|
|
2269
2371
|
var import_express5 = require("@as-integrations/express5");
|
|
@@ -2601,6 +2703,29 @@ var agentsSchema = {
|
|
|
2601
2703
|
}
|
|
2602
2704
|
]
|
|
2603
2705
|
};
|
|
2706
|
+
var variablesSchema = {
|
|
2707
|
+
name: {
|
|
2708
|
+
plural: "variables",
|
|
2709
|
+
singular: "variable"
|
|
2710
|
+
},
|
|
2711
|
+
fields: [
|
|
2712
|
+
{
|
|
2713
|
+
name: "name",
|
|
2714
|
+
type: "text",
|
|
2715
|
+
index: true,
|
|
2716
|
+
unique: true
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
name: "value",
|
|
2720
|
+
type: "longText"
|
|
2721
|
+
},
|
|
2722
|
+
{
|
|
2723
|
+
name: "encrypted",
|
|
2724
|
+
type: "boolean",
|
|
2725
|
+
default: false
|
|
2726
|
+
}
|
|
2727
|
+
]
|
|
2728
|
+
};
|
|
2604
2729
|
|
|
2605
2730
|
// src/registry/uppy.ts
|
|
2606
2731
|
var import_express = require("express");
|
|
@@ -2996,34 +3121,7 @@ var createUppyRoutes = async (app) => {
|
|
|
2996
3121
|
// src/registry/routes.ts
|
|
2997
3122
|
var import_utils2 = require("@apollo/utils.keyvaluecache");
|
|
2998
3123
|
var import_body_parser = __toESM(require("body-parser"), 1);
|
|
2999
|
-
var
|
|
3000
|
-
|
|
3001
|
-
// src/registry/utils/claude-messages.ts
|
|
3002
|
-
var CLAUDE_MESSAGES = {
|
|
3003
|
-
authentication_error: `
|
|
3004
|
-
\x1B[41m -- Authentication error please check your IMP token and try again. --
|
|
3005
|
-
\x1B[0m`,
|
|
3006
|
-
missing_body: `
|
|
3007
|
-
\x1B[41m -- Missing body Anthropic response. --
|
|
3008
|
-
\x1B[0m`,
|
|
3009
|
-
missing_nextauth_secret: `
|
|
3010
|
-
\x1B[41m -- Missing NEXTAUTH_SECRET in environment variables on the server. --
|
|
3011
|
-
\x1B[0m`,
|
|
3012
|
-
not_enabled: `
|
|
3013
|
-
\x1B[31m
|
|
3014
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557
|
|
3015
|
-
\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
3016
|
-
\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
3017
|
-
\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
3018
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
3019
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
|
|
3020
|
-
Intelligence Management Platform
|
|
3021
|
-
\x1B[0m
|
|
3022
|
-
\x1B[41m -- Your account has not been enabled to use Claude Code, please contact your admin or enable Claude Code in the user settings. --
|
|
3023
|
-
\x1B[0m`
|
|
3024
|
-
};
|
|
3025
|
-
|
|
3026
|
-
// src/registry/routes.ts
|
|
3124
|
+
var import_crypto_js3 = __toESM(require("crypto-js"), 1);
|
|
3027
3125
|
var REQUEST_SIZE_LIMIT = "50mb";
|
|
3028
3126
|
var global_queues = {
|
|
3029
3127
|
logs_cleaner: "logs-cleaner"
|
|
@@ -3130,7 +3228,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
|
|
|
3130
3228
|
} else {
|
|
3131
3229
|
console.log("===========================", "[EXULU] no redis server configured, not setting up recurring jobs.", "===========================");
|
|
3132
3230
|
}
|
|
3133
|
-
const schema = createSDL([usersSchema, rolesSchema, agentsSchema, jobsSchema, workflowSchema, evalResultsSchema, agentSessionsSchema, agentMessagesSchema]);
|
|
3231
|
+
const schema = createSDL([usersSchema, rolesSchema, agentsSchema, jobsSchema, workflowSchema, evalResultsSchema, agentSessionsSchema, agentMessagesSchema, variablesSchema]);
|
|
3134
3232
|
console.log("[EXULU] graphql server");
|
|
3135
3233
|
const server = new import_server3.ApolloServer({
|
|
3136
3234
|
cache: new import_utils2.InMemoryLRUCache(),
|
|
@@ -3965,6 +4063,7 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
|
|
|
3965
4063
|
const result = agent.generateStream({
|
|
3966
4064
|
messages: req.body.messages,
|
|
3967
4065
|
tools: enabledTools,
|
|
4066
|
+
configs: agentInstance.tools,
|
|
3968
4067
|
statistics: {
|
|
3969
4068
|
label: agent.name,
|
|
3970
4069
|
trigger: "agent"
|
|
@@ -3975,7 +4074,8 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
|
|
|
3975
4074
|
} else {
|
|
3976
4075
|
const response = await agent.generateSync({
|
|
3977
4076
|
messages: req.body.messages,
|
|
3978
|
-
tools: enabledTools.map(),
|
|
4077
|
+
tools: enabledTools.map((tool2) => tool2.tool),
|
|
4078
|
+
configs: agentInstance.tools,
|
|
3979
4079
|
statistics: {
|
|
3980
4080
|
label: agent.name,
|
|
3981
4081
|
trigger: "agent"
|
|
@@ -4092,8 +4192,25 @@ var createExpressRoutes = async (app, agents, tools, workflows, contexts) => {
|
|
|
4092
4192
|
res.end(Buffer.from(arrayBuffer));
|
|
4093
4193
|
return;
|
|
4094
4194
|
}
|
|
4095
|
-
const
|
|
4096
|
-
const
|
|
4195
|
+
const variableName = authenticationResult.user.anthropic_token;
|
|
4196
|
+
const variable = await db3.from("variables").where({ name: variableName }).first();
|
|
4197
|
+
if (!variable) {
|
|
4198
|
+
const arrayBuffer = createCustomAnthropicStreamingMessage(CLAUDE_MESSAGES.anthropic_token_variable_not_found);
|
|
4199
|
+
res.setHeader("Content-Type", "application/json");
|
|
4200
|
+
res.end(Buffer.from(arrayBuffer));
|
|
4201
|
+
return;
|
|
4202
|
+
}
|
|
4203
|
+
let anthropicApiKey = variable.value;
|
|
4204
|
+
if (!variable.encrypted) {
|
|
4205
|
+
const arrayBuffer = createCustomAnthropicStreamingMessage(CLAUDE_MESSAGES.anthropic_token_variable_not_encrypted);
|
|
4206
|
+
res.setHeader("Content-Type", "application/json");
|
|
4207
|
+
res.end(Buffer.from(arrayBuffer));
|
|
4208
|
+
return;
|
|
4209
|
+
}
|
|
4210
|
+
if (variable.encrypted) {
|
|
4211
|
+
const bytes = import_crypto_js3.default.AES.decrypt(variable.value, process.env.NEXTAUTH_SECRET);
|
|
4212
|
+
anthropicApiKey = bytes.toString(import_crypto_js3.default.enc.Utf8);
|
|
4213
|
+
}
|
|
4097
4214
|
const headers = {
|
|
4098
4215
|
"x-api-key": anthropicApiKey,
|
|
4099
4216
|
"anthropic-version": "2023-06-01",
|
|
@@ -4605,129 +4722,6 @@ var defaultAgent = new ExuluAgent({
|
|
|
4605
4722
|
}
|
|
4606
4723
|
});
|
|
4607
4724
|
|
|
4608
|
-
// src/templates/tools/browserbase.ts
|
|
4609
|
-
var import_zod5 = require("zod");
|
|
4610
|
-
var import_stagehand = require("@browserbasehq/stagehand");
|
|
4611
|
-
var import_sdk = require("@browserbasehq/sdk");
|
|
4612
|
-
var PROJECT_ID = "811444dd-6e6d-40b5-bd90-541c93e44be6";
|
|
4613
|
-
process.env.BROWSERBASE_PROJECT_ID = PROJECT_ID;
|
|
4614
|
-
var BB_API_KEY = "bb_live_LwMwNgZB5cIEKcBwMuAugrgNkFM";
|
|
4615
|
-
async function createContext() {
|
|
4616
|
-
const bb = new import_sdk.Browserbase({ apiKey: BB_API_KEY });
|
|
4617
|
-
const context = await bb.contexts.create({
|
|
4618
|
-
projectId: PROJECT_ID
|
|
4619
|
-
});
|
|
4620
|
-
return context;
|
|
4621
|
-
}
|
|
4622
|
-
async function createAuthSession(contextId) {
|
|
4623
|
-
const bb = new import_sdk.Browserbase({ apiKey: BB_API_KEY });
|
|
4624
|
-
const session = await bb.sessions.create({
|
|
4625
|
-
projectId: PROJECT_ID,
|
|
4626
|
-
browserSettings: {
|
|
4627
|
-
context: {
|
|
4628
|
-
id: contextId,
|
|
4629
|
-
persist: true
|
|
4630
|
-
}
|
|
4631
|
-
}
|
|
4632
|
-
/* proxies: [{ // not included in the free tier
|
|
4633
|
-
type: "browserbase",
|
|
4634
|
-
geolocation: {
|
|
4635
|
-
city: CITY,
|
|
4636
|
-
country: COUNTRY
|
|
4637
|
-
}
|
|
4638
|
-
}] */
|
|
4639
|
-
});
|
|
4640
|
-
const liveViewLinks = await bb.sessions.debug(session.id);
|
|
4641
|
-
const liveViewLink = liveViewLinks.debuggerFullscreenUrl;
|
|
4642
|
-
console.log(`\u{1F50D} Live View Link: ${liveViewLink}`);
|
|
4643
|
-
console.log("Session URL: https://browserbase.com/sessions/" + session.id);
|
|
4644
|
-
return {
|
|
4645
|
-
url: liveViewLink,
|
|
4646
|
-
id: session.id
|
|
4647
|
-
};
|
|
4648
|
-
}
|
|
4649
|
-
var createSession = new ExuluTool({
|
|
4650
|
-
id: `1234-5178-9423-4267`,
|
|
4651
|
-
type: "function",
|
|
4652
|
-
name: "Create a browserbase session.",
|
|
4653
|
-
description: `
|
|
4654
|
-
Creates a browserbase session and returns the live view url as well as
|
|
4655
|
-
the session id as a JSON object. A browserbase session is a headless browser
|
|
4656
|
-
that can be used to to visit websites and perform actions.
|
|
4657
|
-
`,
|
|
4658
|
-
execute: async () => {
|
|
4659
|
-
const { id } = await createContext();
|
|
4660
|
-
return await createAuthSession(id);
|
|
4661
|
-
}
|
|
4662
|
-
});
|
|
4663
|
-
var askChatgpt = new ExuluTool({
|
|
4664
|
-
id: `1234-5178-9423-4268`,
|
|
4665
|
-
type: "function",
|
|
4666
|
-
name: "ChatGPT browserbase operation.",
|
|
4667
|
-
inputSchema: import_zod5.z.object({
|
|
4668
|
-
session: import_zod5.z.string().describe("The session id of the browserbase session."),
|
|
4669
|
-
question: import_zod5.z.string().describe("The question to ask ChatGPT.")
|
|
4670
|
-
}),
|
|
4671
|
-
description: `Uses an existing, authenticated browserbase session to visit ChatGPT and perform actions such as asking questions.`,
|
|
4672
|
-
execute: async ({ session, question }) => {
|
|
4673
|
-
const stagehand = new import_stagehand.Stagehand({
|
|
4674
|
-
// With npx create-browser-app, this config is found
|
|
4675
|
-
// in a separate stagehand.config.ts file
|
|
4676
|
-
env: "BROWSERBASE",
|
|
4677
|
-
// set to "LOCAL" for local development
|
|
4678
|
-
apiKey: BB_API_KEY,
|
|
4679
|
-
// todo make this a config variable the admin can set in the UI
|
|
4680
|
-
modelName: "openai/gpt-4.1-mini",
|
|
4681
|
-
// todo change to claude || optionally make configurable?
|
|
4682
|
-
browserbaseSessionID: session,
|
|
4683
|
-
modelClientOptions: {
|
|
4684
|
-
apiKey: process.env.OPENAI_API_KEY
|
|
4685
|
-
// todo make this a config variable the admin can set in the UI
|
|
4686
|
-
}
|
|
4687
|
-
});
|
|
4688
|
-
await stagehand.init();
|
|
4689
|
-
const page = stagehand.page;
|
|
4690
|
-
await page.goto("https://chatgpt.com");
|
|
4691
|
-
await page.act(`Type in '${question}' into the search bar`);
|
|
4692
|
-
const { answer } = await page.extract({
|
|
4693
|
-
instruction: "The answer to the question generated by ChatGPT.",
|
|
4694
|
-
schema: import_zod5.z.object({
|
|
4695
|
-
answer: import_zod5.z.string()
|
|
4696
|
-
})
|
|
4697
|
-
});
|
|
4698
|
-
console.log(answer);
|
|
4699
|
-
await stagehand.close();
|
|
4700
|
-
return {
|
|
4701
|
-
answer
|
|
4702
|
-
};
|
|
4703
|
-
}
|
|
4704
|
-
});
|
|
4705
|
-
|
|
4706
|
-
// src/templates/tools/jira.ts
|
|
4707
|
-
var import_zod6 = require("zod");
|
|
4708
|
-
var getTicket = new ExuluTool({
|
|
4709
|
-
id: `1414-5179-1423-1269`,
|
|
4710
|
-
name: "JIRA ticket retrieval.",
|
|
4711
|
-
type: "function",
|
|
4712
|
-
inputSchema: import_zod6.z.object({
|
|
4713
|
-
ticketId: import_zod6.z.string().describe("The id of the ticket to retrieve.")
|
|
4714
|
-
}),
|
|
4715
|
-
description: `Retrieves a ticket from Jira.`,
|
|
4716
|
-
execute: async ({ session, question }) => {
|
|
4717
|
-
return {
|
|
4718
|
-
name: "BYD-1234",
|
|
4719
|
-
id: "12345678",
|
|
4720
|
-
status: "Open",
|
|
4721
|
-
description: "This is a test ticket",
|
|
4722
|
-
assignee: "John Doe",
|
|
4723
|
-
createdAt: "2021-01-01",
|
|
4724
|
-
updatedAt: "2021-01-01",
|
|
4725
|
-
dueDate: "2021-01-01",
|
|
4726
|
-
priority: "High"
|
|
4727
|
-
};
|
|
4728
|
-
}
|
|
4729
|
-
});
|
|
4730
|
-
|
|
4731
4725
|
// src/registry/index.ts
|
|
4732
4726
|
var ExuluApp = class {
|
|
4733
4727
|
_agents = [];
|
|
@@ -4755,12 +4749,7 @@ var ExuluApp = class {
|
|
|
4755
4749
|
// Add contexts as tools
|
|
4756
4750
|
...Object.values(contexts || {}).map((context) => context.tool()),
|
|
4757
4751
|
// Add agents as tools
|
|
4758
|
-
...(agents || []).map((agent) => agent.tool())
|
|
4759
|
-
...[
|
|
4760
|
-
createSession,
|
|
4761
|
-
askChatgpt,
|
|
4762
|
-
getTicket
|
|
4763
|
-
]
|
|
4752
|
+
...(agents || []).map((agent) => agent.tool())
|
|
4764
4753
|
];
|
|
4765
4754
|
const contextsArray = Object.values(contexts || {});
|
|
4766
4755
|
const queues2 = [
|
|
@@ -6096,6 +6085,7 @@ var generateApiKey = async (name, email) => {
|
|
|
6096
6085
|
|
|
6097
6086
|
// src/postgres/init-db.ts
|
|
6098
6087
|
var up = async function(knex) {
|
|
6088
|
+
console.log("[EXULU] Database up.");
|
|
6099
6089
|
if (!await knex.schema.hasTable("agent_sessions")) {
|
|
6100
6090
|
console.log("[EXULU] Creating agent_sessions table.");
|
|
6101
6091
|
await knex.schema.createTable("agent_sessions", (table) => {
|
|
@@ -6103,11 +6093,11 @@ var up = async function(knex) {
|
|
|
6103
6093
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6104
6094
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6105
6095
|
for (const field of agentSessionsSchema.fields) {
|
|
6106
|
-
const { type, name, default: defaultValue } = field;
|
|
6096
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6107
6097
|
if (!type || !name) {
|
|
6108
6098
|
continue;
|
|
6109
6099
|
}
|
|
6110
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6100
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6111
6101
|
}
|
|
6112
6102
|
});
|
|
6113
6103
|
}
|
|
@@ -6118,11 +6108,11 @@ var up = async function(knex) {
|
|
|
6118
6108
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6119
6109
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6120
6110
|
for (const field of agentMessagesSchema.fields) {
|
|
6121
|
-
const { type, name, default: defaultValue } = field;
|
|
6111
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6122
6112
|
if (!type || !name) {
|
|
6123
6113
|
continue;
|
|
6124
6114
|
}
|
|
6125
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6115
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6126
6116
|
}
|
|
6127
6117
|
});
|
|
6128
6118
|
}
|
|
@@ -6133,11 +6123,11 @@ var up = async function(knex) {
|
|
|
6133
6123
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6134
6124
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6135
6125
|
for (const field of rolesSchema.fields) {
|
|
6136
|
-
const { type, name, default: defaultValue } = field;
|
|
6126
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6137
6127
|
if (!type || !name) {
|
|
6138
6128
|
continue;
|
|
6139
6129
|
}
|
|
6140
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6130
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6141
6131
|
}
|
|
6142
6132
|
});
|
|
6143
6133
|
}
|
|
@@ -6148,11 +6138,11 @@ var up = async function(knex) {
|
|
|
6148
6138
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6149
6139
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6150
6140
|
for (const field of evalResultsSchema.fields) {
|
|
6151
|
-
const { type, name, default: defaultValue } = field;
|
|
6141
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6152
6142
|
if (!type || !name) {
|
|
6153
6143
|
continue;
|
|
6154
6144
|
}
|
|
6155
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6145
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6156
6146
|
}
|
|
6157
6147
|
});
|
|
6158
6148
|
}
|
|
@@ -6163,11 +6153,11 @@ var up = async function(knex) {
|
|
|
6163
6153
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6164
6154
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6165
6155
|
for (const field of statisticsSchema.fields) {
|
|
6166
|
-
const { type, name, default: defaultValue } = field;
|
|
6156
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6167
6157
|
if (!type || !name) {
|
|
6168
6158
|
continue;
|
|
6169
6159
|
}
|
|
6170
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6160
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6171
6161
|
}
|
|
6172
6162
|
});
|
|
6173
6163
|
}
|
|
@@ -6178,11 +6168,11 @@ var up = async function(knex) {
|
|
|
6178
6168
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6179
6169
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6180
6170
|
for (const field of jobsSchema.fields) {
|
|
6181
|
-
const { type, name, default: defaultValue } = field;
|
|
6171
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6182
6172
|
if (!type || !name) {
|
|
6183
6173
|
continue;
|
|
6184
6174
|
}
|
|
6185
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6175
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6186
6176
|
}
|
|
6187
6177
|
});
|
|
6188
6178
|
}
|
|
@@ -6193,11 +6183,26 @@ var up = async function(knex) {
|
|
|
6193
6183
|
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6194
6184
|
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6195
6185
|
for (const field of agentsSchema.fields) {
|
|
6196
|
-
const { type, name, default: defaultValue } = field;
|
|
6186
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6187
|
+
if (!type || !name) {
|
|
6188
|
+
continue;
|
|
6189
|
+
}
|
|
6190
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6191
|
+
}
|
|
6192
|
+
});
|
|
6193
|
+
}
|
|
6194
|
+
if (!await knex.schema.hasTable("variables")) {
|
|
6195
|
+
console.log("[EXULU] Creating variables table.");
|
|
6196
|
+
await knex.schema.createTable("variables", (table) => {
|
|
6197
|
+
table.uuid("id").primary().defaultTo(knex.fn.uuid());
|
|
6198
|
+
table.timestamp("createdAt").defaultTo(knex.fn.now());
|
|
6199
|
+
table.timestamp("updatedAt").defaultTo(knex.fn.now());
|
|
6200
|
+
for (const field of variablesSchema.fields) {
|
|
6201
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6197
6202
|
if (!type || !name) {
|
|
6198
6203
|
continue;
|
|
6199
6204
|
}
|
|
6200
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6205
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6201
6206
|
}
|
|
6202
6207
|
});
|
|
6203
6208
|
}
|
|
@@ -6223,14 +6228,14 @@ var up = async function(knex) {
|
|
|
6223
6228
|
table.text("image");
|
|
6224
6229
|
for (const field of usersSchema.fields) {
|
|
6225
6230
|
console.log("[EXULU] field", field);
|
|
6226
|
-
const { type, name, default: defaultValue } = field;
|
|
6231
|
+
const { type, name, default: defaultValue, unique } = field;
|
|
6227
6232
|
if (name === "id" || name === "name" || name === "email" || name === "emailVerified" || name === "image") {
|
|
6228
6233
|
continue;
|
|
6229
6234
|
}
|
|
6230
6235
|
if (!type || !name) {
|
|
6231
6236
|
continue;
|
|
6232
6237
|
}
|
|
6233
|
-
mapType(table, type, sanitizeName(name), defaultValue);
|
|
6238
|
+
mapType(table, type, sanitizeName(name), defaultValue, unique);
|
|
6234
6239
|
}
|
|
6235
6240
|
});
|
|
6236
6241
|
}
|