@exulu/backend 1.30.0 → 1.30.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 +3 -3
- package/dist/index.cjs +21 -26
- package/dist/index.js +13 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
## [1.30.1](https://github.com/Qventu/exulu-backend/compare/v1.30.0...v1.30.1) (2025-11-04)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
* add
|
|
6
|
+
* dont add eval tools if redis not configured ([4ebbb5c](https://github.com/Qventu/exulu-backend/commit/4ebbb5ce44aaf07072adaf6b6963e6eac376e022))
|
package/dist/index.cjs
CHANGED
|
@@ -437,7 +437,8 @@ var sanitizeName = (name) => {
|
|
|
437
437
|
|
|
438
438
|
// src/registry/classes.ts
|
|
439
439
|
var import_crypto_js2 = __toESM(require("crypto-js"), 1);
|
|
440
|
-
var
|
|
440
|
+
var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
441
|
+
var import_mcp_stdio = require("ai/mcp-stdio");
|
|
441
442
|
|
|
442
443
|
// src/registry/utils/graphql.ts
|
|
443
444
|
var import_schema = require("@graphql-tools/schema");
|
|
@@ -2428,7 +2429,7 @@ var applyAccessControl = (table, user, query) => {
|
|
|
2428
2429
|
console.log("[EXULU] table.name.plural", table.name.plural);
|
|
2429
2430
|
if (!user.super_admin && (!user.role || !(table.name.plural === "agents" && (user.role.agents === "read" || user.role.agents === "write")) && !(table.name.plural === "workflow_templates" && (user.role.workflows === "read" || user.role.workflows === "write")) && !(table.name.plural === "variables" && (user.role.variables === "read" || user.role.variables === "write")) && !(table.name.plural === "users" && (user.role.users === "read" || user.role.users === "write")) && !((table.name.plural === "test_cases" || table.name.plural === "eval_sets" || table.name.plural === "eval_runs") && (user.role.evals === "read" || user.role.evals === "write")))) {
|
|
2430
2431
|
console.error("==== Access control error: no role found or no access to entity type. ====");
|
|
2431
|
-
|
|
2432
|
+
throw new Error("Access control error: no role found or no access to entity type.");
|
|
2432
2433
|
}
|
|
2433
2434
|
const hasRBAC = table.RBAC === true;
|
|
2434
2435
|
console.log("[EXULU] hasRBAC", hasRBAC);
|
|
@@ -4631,6 +4632,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
4631
4632
|
};
|
|
4632
4633
|
|
|
4633
4634
|
// src/registry/classes.ts
|
|
4635
|
+
var import_streamableHttp2 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
4634
4636
|
var s3Client2;
|
|
4635
4637
|
function sanitizeToolName(name) {
|
|
4636
4638
|
if (typeof name !== "string") return "";
|
|
@@ -4649,12 +4651,6 @@ var convertToolsArrayToObject = (currentTools, allExuluTools, configs, providera
|
|
|
4649
4651
|
name: sanitizeToolName(tool2.name)
|
|
4650
4652
|
})) : [];
|
|
4651
4653
|
console.log("[EXULU] Sanitized tools", sanitizedTools.map((x) => x.name + " (" + x.id + ")"));
|
|
4652
|
-
const askForConfirmation = {
|
|
4653
|
-
description: "Ask the user for confirmation.",
|
|
4654
|
-
inputSchema: import_zod.z.object({
|
|
4655
|
-
message: import_zod.z.string().describe("The message to ask for confirmation.")
|
|
4656
|
-
})
|
|
4657
|
-
};
|
|
4658
4654
|
return {
|
|
4659
4655
|
...sanitizedTools?.reduce(
|
|
4660
4656
|
(prev, cur) => ({
|
|
@@ -4753,8 +4749,8 @@ var convertToolsArrayToObject = (currentTools, allExuluTools, configs, providera
|
|
|
4753
4749
|
}
|
|
4754
4750
|
}),
|
|
4755
4751
|
{}
|
|
4756
|
-
)
|
|
4757
|
-
askForConfirmation
|
|
4752
|
+
)
|
|
4753
|
+
// askForConfirmation
|
|
4758
4754
|
};
|
|
4759
4755
|
};
|
|
4760
4756
|
var hydrateVariables = async (tool2) => {
|
|
@@ -5792,7 +5788,6 @@ var ExuluContext = class {
|
|
|
5792
5788
|
};
|
|
5793
5789
|
};
|
|
5794
5790
|
var updateStatistic = async (statistic) => {
|
|
5795
|
-
console.log("[EXULU] Updating statistic", statistic);
|
|
5796
5791
|
const currentDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5797
5792
|
const { db: db3 } = await postgresClient();
|
|
5798
5793
|
const existing = await db3.from("tracking").where({
|
|
@@ -5803,7 +5798,6 @@ var updateStatistic = async (statistic) => {
|
|
|
5803
5798
|
type: statistic.type,
|
|
5804
5799
|
createdAt: currentDate
|
|
5805
5800
|
}).first();
|
|
5806
|
-
console.log("[EXULU] Existing", existing);
|
|
5807
5801
|
if (!existing) {
|
|
5808
5802
|
await db3.from("tracking").insert({
|
|
5809
5803
|
name: statistic.name,
|
|
@@ -5874,11 +5868,11 @@ var getMimeType = (type) => {
|
|
|
5874
5868
|
};
|
|
5875
5869
|
|
|
5876
5870
|
// src/registry/index.ts
|
|
5877
|
-
var
|
|
5871
|
+
var import_express6 = require("express");
|
|
5878
5872
|
|
|
5879
5873
|
// src/registry/routes.ts
|
|
5880
|
-
var
|
|
5881
|
-
var
|
|
5874
|
+
var import_express2 = require("express");
|
|
5875
|
+
var import_express3 = __toESM(require("express"), 1);
|
|
5882
5876
|
var import_server2 = require("@apollo/server");
|
|
5883
5877
|
var import_cors = __toESM(require("cors"), 1);
|
|
5884
5878
|
var import_reflect_metadata = require("reflect-metadata");
|
|
@@ -5945,7 +5939,7 @@ var createExpressRoutes = async (app, agents, tools, contexts, config, evals, tr
|
|
|
5945
5939
|
optionsSuccessStatus: 200
|
|
5946
5940
|
// some legacy browsers (IE11, various SmartTVs) choke on 204
|
|
5947
5941
|
};
|
|
5948
|
-
app.use(
|
|
5942
|
+
app.use(import_express3.default.json({ limit: REQUEST_SIZE_LIMIT }));
|
|
5949
5943
|
app.use((0, import_cors.default)(corsOptions));
|
|
5950
5944
|
app.use(import_body_parser.default.urlencoded({ extended: true, limit: REQUEST_SIZE_LIMIT }));
|
|
5951
5945
|
app.use(import_body_parser.default.json({ limit: REQUEST_SIZE_LIMIT }));
|
|
@@ -5985,7 +5979,7 @@ var createExpressRoutes = async (app, agents, tools, contexts, config, evals, tr
|
|
|
5985
5979
|
app.use(
|
|
5986
5980
|
"/graphql",
|
|
5987
5981
|
(0, import_cors.default)(corsOptions),
|
|
5988
|
-
|
|
5982
|
+
import_express3.default.json({ limit: REQUEST_SIZE_LIMIT }),
|
|
5989
5983
|
(0, import_express5.expressMiddleware)(server, {
|
|
5990
5984
|
context: async ({ req }) => {
|
|
5991
5985
|
console.info("[EXULU] Incoming graphql request", {
|
|
@@ -6361,7 +6355,7 @@ Mood: friendly and intelligent.
|
|
|
6361
6355
|
}
|
|
6362
6356
|
});
|
|
6363
6357
|
});
|
|
6364
|
-
app.use("/gateway/anthropic/:id",
|
|
6358
|
+
app.use("/gateway/anthropic/:id", import_express3.default.raw({ type: "*/*", limit: REQUEST_SIZE_LIMIT }), async (req, res) => {
|
|
6365
6359
|
try {
|
|
6366
6360
|
if (!req.body.tools) {
|
|
6367
6361
|
req.body.tools = [];
|
|
@@ -6502,7 +6496,7 @@ data: ${JSON.stringify(event)}
|
|
|
6502
6496
|
}
|
|
6503
6497
|
}
|
|
6504
6498
|
});
|
|
6505
|
-
app.use(
|
|
6499
|
+
app.use(import_express3.default.static("public"));
|
|
6506
6500
|
return app;
|
|
6507
6501
|
};
|
|
6508
6502
|
var createCustomAnthropicStreamingMessage = (message) => {
|
|
@@ -7204,10 +7198,10 @@ function getAverage(arr) {
|
|
|
7204
7198
|
// src/mcp/index.ts
|
|
7205
7199
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
7206
7200
|
var import_node_crypto4 = require("crypto");
|
|
7207
|
-
var
|
|
7201
|
+
var import_streamableHttp3 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
7208
7202
|
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
7209
7203
|
var import_zod2 = require("zod");
|
|
7210
|
-
var
|
|
7204
|
+
var import_express4 = require("express");
|
|
7211
7205
|
var import_api3 = require("@opentelemetry/api");
|
|
7212
7206
|
var SESSION_ID_HEADER = "mcp-session-id";
|
|
7213
7207
|
var ExuluMCP = class {
|
|
@@ -7294,7 +7288,7 @@ ${code}`
|
|
|
7294
7288
|
if (sessionId && this.transports[sessionId]) {
|
|
7295
7289
|
transport = this.transports[sessionId];
|
|
7296
7290
|
} else if (!sessionId && (0, import_types.isInitializeRequest)(req.body)) {
|
|
7297
|
-
transport = new
|
|
7291
|
+
transport = new import_streamableHttp3.StreamableHTTPServerTransport({
|
|
7298
7292
|
sessionIdGenerator: () => (0, import_node_crypto4.randomUUID)(),
|
|
7299
7293
|
onsessioninitialized: (sessionId2) => {
|
|
7300
7294
|
this.transports[sessionId2] = transport;
|
|
@@ -7335,7 +7329,7 @@ ${code}`
|
|
|
7335
7329
|
};
|
|
7336
7330
|
|
|
7337
7331
|
// src/registry/index.ts
|
|
7338
|
-
var
|
|
7332
|
+
var import_express7 = __toESM(require("express"), 1);
|
|
7339
7333
|
|
|
7340
7334
|
// src/templates/agents/anthropic/claude.ts
|
|
7341
7335
|
var import_anthropic = require("@ai-sdk/anthropic");
|
|
@@ -8539,10 +8533,10 @@ var ExuluApp = class {
|
|
|
8539
8533
|
// Factory function so we can async
|
|
8540
8534
|
// initialize the MCP server if needed.
|
|
8541
8535
|
create = async ({ contexts, agents, config, tools, evals }) => {
|
|
8542
|
-
this._evals = [
|
|
8536
|
+
this._evals = redisServer.host?.length && redisServer.port?.length ? [
|
|
8543
8537
|
llmAsJudgeEval,
|
|
8544
8538
|
...evals ?? []
|
|
8545
|
-
];
|
|
8539
|
+
] : [];
|
|
8546
8540
|
this._contexts = {
|
|
8547
8541
|
...contexts,
|
|
8548
8542
|
codeStandardsContext,
|
|
@@ -8572,6 +8566,7 @@ var ExuluApp = class {
|
|
|
8572
8566
|
// Because agents are stored in the database, we add those as tools
|
|
8573
8567
|
// at request time, not during ExuluApp initialization. We add them
|
|
8574
8568
|
// in the grahql tools resolver.
|
|
8569
|
+
// ...mcpTools
|
|
8575
8570
|
];
|
|
8576
8571
|
const checks = [
|
|
8577
8572
|
...Object.keys(this._contexts || {}).map((x) => ({
|
|
@@ -8610,7 +8605,7 @@ var ExuluApp = class {
|
|
|
8610
8605
|
express = {
|
|
8611
8606
|
init: async () => {
|
|
8612
8607
|
if (!this._expressApp) {
|
|
8613
|
-
this._expressApp = (0,
|
|
8608
|
+
this._expressApp = (0, import_express7.default)();
|
|
8614
8609
|
await this.server.express.init();
|
|
8615
8610
|
console.log("[EXULU] Express app initialized.");
|
|
8616
8611
|
}
|
package/dist/index.js
CHANGED
|
@@ -385,7 +385,8 @@ var sanitizeName = (name) => {
|
|
|
385
385
|
|
|
386
386
|
// src/registry/classes.ts
|
|
387
387
|
import CryptoJS2 from "crypto-js";
|
|
388
|
-
import "
|
|
388
|
+
import "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
389
|
+
import "ai/mcp-stdio";
|
|
389
390
|
|
|
390
391
|
// src/registry/utils/graphql.ts
|
|
391
392
|
import { makeExecutableSchema } from "@graphql-tools/schema";
|
|
@@ -2376,7 +2377,7 @@ var applyAccessControl = (table, user, query) => {
|
|
|
2376
2377
|
console.log("[EXULU] table.name.plural", table.name.plural);
|
|
2377
2378
|
if (!user.super_admin && (!user.role || !(table.name.plural === "agents" && (user.role.agents === "read" || user.role.agents === "write")) && !(table.name.plural === "workflow_templates" && (user.role.workflows === "read" || user.role.workflows === "write")) && !(table.name.plural === "variables" && (user.role.variables === "read" || user.role.variables === "write")) && !(table.name.plural === "users" && (user.role.users === "read" || user.role.users === "write")) && !((table.name.plural === "test_cases" || table.name.plural === "eval_sets" || table.name.plural === "eval_runs") && (user.role.evals === "read" || user.role.evals === "write")))) {
|
|
2378
2379
|
console.error("==== Access control error: no role found or no access to entity type. ====");
|
|
2379
|
-
|
|
2380
|
+
throw new Error("Access control error: no role found or no access to entity type.");
|
|
2380
2381
|
}
|
|
2381
2382
|
const hasRBAC = table.RBAC === true;
|
|
2382
2383
|
console.log("[EXULU] hasRBAC", hasRBAC);
|
|
@@ -4598,6 +4599,7 @@ var createUppyRoutes = async (app, config) => {
|
|
|
4598
4599
|
};
|
|
4599
4600
|
|
|
4600
4601
|
// src/registry/classes.ts
|
|
4602
|
+
import "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4601
4603
|
var s3Client2;
|
|
4602
4604
|
function sanitizeToolName(name) {
|
|
4603
4605
|
if (typeof name !== "string") return "";
|
|
@@ -4616,12 +4618,6 @@ var convertToolsArrayToObject = (currentTools, allExuluTools, configs, providera
|
|
|
4616
4618
|
name: sanitizeToolName(tool2.name)
|
|
4617
4619
|
})) : [];
|
|
4618
4620
|
console.log("[EXULU] Sanitized tools", sanitizedTools.map((x) => x.name + " (" + x.id + ")"));
|
|
4619
|
-
const askForConfirmation = {
|
|
4620
|
-
description: "Ask the user for confirmation.",
|
|
4621
|
-
inputSchema: z.object({
|
|
4622
|
-
message: z.string().describe("The message to ask for confirmation.")
|
|
4623
|
-
})
|
|
4624
|
-
};
|
|
4625
4621
|
return {
|
|
4626
4622
|
...sanitizedTools?.reduce(
|
|
4627
4623
|
(prev, cur) => ({
|
|
@@ -4720,8 +4716,8 @@ var convertToolsArrayToObject = (currentTools, allExuluTools, configs, providera
|
|
|
4720
4716
|
}
|
|
4721
4717
|
}),
|
|
4722
4718
|
{}
|
|
4723
|
-
)
|
|
4724
|
-
askForConfirmation
|
|
4719
|
+
)
|
|
4720
|
+
// askForConfirmation
|
|
4725
4721
|
};
|
|
4726
4722
|
};
|
|
4727
4723
|
var hydrateVariables = async (tool2) => {
|
|
@@ -5759,7 +5755,6 @@ var ExuluContext = class {
|
|
|
5759
5755
|
};
|
|
5760
5756
|
};
|
|
5761
5757
|
var updateStatistic = async (statistic) => {
|
|
5762
|
-
console.log("[EXULU] Updating statistic", statistic);
|
|
5763
5758
|
const currentDate = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5764
5759
|
const { db: db3 } = await postgresClient();
|
|
5765
5760
|
const existing = await db3.from("tracking").where({
|
|
@@ -5770,7 +5765,6 @@ var updateStatistic = async (statistic) => {
|
|
|
5770
5765
|
type: statistic.type,
|
|
5771
5766
|
createdAt: currentDate
|
|
5772
5767
|
}).first();
|
|
5773
|
-
console.log("[EXULU] Existing", existing);
|
|
5774
5768
|
if (!existing) {
|
|
5775
5769
|
await db3.from("tracking").insert({
|
|
5776
5770
|
name: statistic.name,
|
|
@@ -5882,7 +5876,7 @@ var CLAUDE_MESSAGES = {
|
|
|
5882
5876
|
};
|
|
5883
5877
|
|
|
5884
5878
|
// src/registry/routes.ts
|
|
5885
|
-
import { createIdGenerator
|
|
5879
|
+
import { createIdGenerator } from "ai";
|
|
5886
5880
|
var REQUEST_SIZE_LIMIT = "50mb";
|
|
5887
5881
|
var global_queues = {
|
|
5888
5882
|
eval_runs: "eval_runs"
|
|
@@ -6237,7 +6231,7 @@ Mood: friendly and intelligent.
|
|
|
6237
6231
|
console.error("[EXULU] chat response error.", error);
|
|
6238
6232
|
return errorHandler(error);
|
|
6239
6233
|
},
|
|
6240
|
-
generateMessageId:
|
|
6234
|
+
generateMessageId: createIdGenerator({
|
|
6241
6235
|
prefix: "msg_",
|
|
6242
6236
|
size: 16
|
|
6243
6237
|
}),
|
|
@@ -7171,7 +7165,7 @@ function getAverage(arr) {
|
|
|
7171
7165
|
// src/mcp/index.ts
|
|
7172
7166
|
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7173
7167
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
7174
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
7168
|
+
import { StreamableHTTPServerTransport as StreamableHTTPServerTransport2 } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
7175
7169
|
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
7176
7170
|
import { z as z2 } from "zod";
|
|
7177
7171
|
import "express";
|
|
@@ -7261,7 +7255,7 @@ ${code}`
|
|
|
7261
7255
|
if (sessionId && this.transports[sessionId]) {
|
|
7262
7256
|
transport = this.transports[sessionId];
|
|
7263
7257
|
} else if (!sessionId && isInitializeRequest(req.body)) {
|
|
7264
|
-
transport = new
|
|
7258
|
+
transport = new StreamableHTTPServerTransport2({
|
|
7265
7259
|
sessionIdGenerator: () => randomUUID4(),
|
|
7266
7260
|
onsessioninitialized: (sessionId2) => {
|
|
7267
7261
|
this.transports[sessionId2] = transport;
|
|
@@ -8506,10 +8500,10 @@ var ExuluApp = class {
|
|
|
8506
8500
|
// Factory function so we can async
|
|
8507
8501
|
// initialize the MCP server if needed.
|
|
8508
8502
|
create = async ({ contexts, agents, config, tools, evals }) => {
|
|
8509
|
-
this._evals = [
|
|
8503
|
+
this._evals = redisServer.host?.length && redisServer.port?.length ? [
|
|
8510
8504
|
llmAsJudgeEval,
|
|
8511
8505
|
...evals ?? []
|
|
8512
|
-
];
|
|
8506
|
+
] : [];
|
|
8513
8507
|
this._contexts = {
|
|
8514
8508
|
...contexts,
|
|
8515
8509
|
codeStandardsContext,
|
|
@@ -8539,6 +8533,7 @@ var ExuluApp = class {
|
|
|
8539
8533
|
// Because agents are stored in the database, we add those as tools
|
|
8540
8534
|
// at request time, not during ExuluApp initialization. We add them
|
|
8541
8535
|
// in the grahql tools resolver.
|
|
8536
|
+
// ...mcpTools
|
|
8542
8537
|
];
|
|
8543
8538
|
const checks = [
|
|
8544
8539
|
...Object.keys(this._contexts || {}).map((x) => ({
|