@exulu/backend 0.3.10 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +129 -30
- package/dist/index.d.cts +5 -6
- package/dist/index.d.ts +5 -6
- package/dist/index.js +129 -30
- package/package.json +4 -1
package/dist/index.cjs
CHANGED
|
@@ -1038,7 +1038,7 @@ var ExuluAgent = class {
|
|
|
1038
1038
|
streaming = false;
|
|
1039
1039
|
rateLimit;
|
|
1040
1040
|
config;
|
|
1041
|
-
// private memory: Memory | undefined; // TODO
|
|
1041
|
+
// private memory: Memory | undefined; // TODO do own implementation
|
|
1042
1042
|
tools;
|
|
1043
1043
|
evals;
|
|
1044
1044
|
model;
|
|
@@ -1798,13 +1798,13 @@ var ExuluContext = class {
|
|
|
1798
1798
|
return await db2.schema.createTable(tableName, (table) => {
|
|
1799
1799
|
console.log("[EXULU] Creating fields for table.", this.fields);
|
|
1800
1800
|
table.uuid("id").primary().defaultTo(db2.fn.uuid());
|
|
1801
|
-
table.
|
|
1801
|
+
table.text("name");
|
|
1802
1802
|
table.text("description");
|
|
1803
|
-
table.
|
|
1803
|
+
table.text("tags");
|
|
1804
1804
|
table.boolean("archived").defaultTo(false);
|
|
1805
|
-
table.string("external_id",
|
|
1805
|
+
table.string("external_id", 255);
|
|
1806
1806
|
table.integer("textLength");
|
|
1807
|
-
table.
|
|
1807
|
+
table.text("source");
|
|
1808
1808
|
for (const field of this.fields) {
|
|
1809
1809
|
const { type, name } = field;
|
|
1810
1810
|
if (!type || !name) {
|
|
@@ -2617,7 +2617,6 @@ var import_express5 = require("@as-integrations/express5");
|
|
|
2617
2617
|
|
|
2618
2618
|
// src/registry/uppy.ts
|
|
2619
2619
|
var import_express = require("express");
|
|
2620
|
-
var import_body_parser = __toESM(require("body-parser"), 1);
|
|
2621
2620
|
var createUppyRoutes = async (app) => {
|
|
2622
2621
|
const {
|
|
2623
2622
|
S3Client,
|
|
@@ -2678,7 +2677,6 @@ var createUppyRoutes = async (app) => {
|
|
|
2678
2677
|
});
|
|
2679
2678
|
return stsClient;
|
|
2680
2679
|
}
|
|
2681
|
-
app.use(import_body_parser.default.urlencoded({ extended: true }), import_body_parser.default.json());
|
|
2682
2680
|
app.get("/s3/list", async (req, res, next) => {
|
|
2683
2681
|
req.accepts;
|
|
2684
2682
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
@@ -3010,6 +3008,8 @@ var createUppyRoutes = async (app) => {
|
|
|
3010
3008
|
|
|
3011
3009
|
// src/registry/routes.ts
|
|
3012
3010
|
var import_utils2 = require("@apollo/utils.keyvaluecache");
|
|
3011
|
+
var import_body_parser = __toESM(require("body-parser"), 1);
|
|
3012
|
+
var REQUEST_SIZE_LIMIT = "50mb";
|
|
3013
3013
|
var global_queues = {
|
|
3014
3014
|
logs_cleaner: "logs-cleaner"
|
|
3015
3015
|
};
|
|
@@ -3054,7 +3054,10 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3054
3054
|
optionsSuccessStatus: 200
|
|
3055
3055
|
// some legacy browsers (IE11, various SmartTVs) choke on 204
|
|
3056
3056
|
};
|
|
3057
|
+
app.use(import_express3.default.json({ limit: REQUEST_SIZE_LIMIT }));
|
|
3057
3058
|
app.use((0, import_cors.default)(corsOptions));
|
|
3059
|
+
app.use(import_body_parser.default.urlencoded({ extended: true, limit: REQUEST_SIZE_LIMIT }));
|
|
3060
|
+
app.use(import_body_parser.default.json({ limit: REQUEST_SIZE_LIMIT }));
|
|
3058
3061
|
console.log(`
|
|
3059
3062
|
\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
|
|
3060
3063
|
\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
|
|
@@ -3062,6 +3065,7 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3062
3065
|
\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
|
|
3063
3066
|
\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
|
|
3064
3067
|
\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
|
|
3068
|
+
|
|
3065
3069
|
`);
|
|
3066
3070
|
console.log("Agents:");
|
|
3067
3071
|
console.table(agents.map((agent) => {
|
|
@@ -3122,7 +3126,7 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3122
3126
|
app.use(
|
|
3123
3127
|
"/graphql",
|
|
3124
3128
|
(0, import_cors.default)(corsOptions),
|
|
3125
|
-
import_express3.default.json(),
|
|
3129
|
+
import_express3.default.json({ limit: REQUEST_SIZE_LIMIT }),
|
|
3126
3130
|
(0, import_express5.expressMiddleware)(server, {
|
|
3127
3131
|
context: async ({ req }) => {
|
|
3128
3132
|
const authenticationResult = await requestValidators.authenticate(req);
|
|
@@ -3974,6 +3978,73 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3974
3978
|
}
|
|
3975
3979
|
console.log("Routes:");
|
|
3976
3980
|
console.table(routeLogs);
|
|
3981
|
+
const TARGET_API = "https://api.anthropic.com";
|
|
3982
|
+
app.use("/gateway/anthropic", import_express3.default.raw({ type: "*/*", limit: REQUEST_SIZE_LIMIT }), async (req, res) => {
|
|
3983
|
+
const path3 = req.url;
|
|
3984
|
+
const url = `${TARGET_API}${path3}`;
|
|
3985
|
+
console.log("[PROXY] Manual proxy to:", url);
|
|
3986
|
+
console.log("[PROXY] Method:", req.method);
|
|
3987
|
+
console.log("[PROXY] Headers:", Object.keys(req.headers));
|
|
3988
|
+
console.log("[PROXY] Request body length:", req.body ? req.body.length : 0);
|
|
3989
|
+
console.log("[PROXY] Request model name:", req.body.model);
|
|
3990
|
+
console.log("[PROXY] Request stream:", req.body.stream);
|
|
3991
|
+
console.log("[PROXY] API key:", req.headers["x-api-key"]);
|
|
3992
|
+
console.log("[PROXY] Request messages:", req.body.messages?.length);
|
|
3993
|
+
try {
|
|
3994
|
+
const headers = {
|
|
3995
|
+
"x-api-key": process.env.ANTHROPIC_API_KEY,
|
|
3996
|
+
"anthropic-version": "2023-06-01",
|
|
3997
|
+
"content-type": req.headers["content-type"] || "application/json"
|
|
3998
|
+
};
|
|
3999
|
+
if (req.headers["accept"]) headers["accept"] = req.headers["accept"];
|
|
4000
|
+
if (req.headers["user-agent"]) headers["user-agent"] = req.headers["user-agent"];
|
|
4001
|
+
console.log("[PROXY] Request body tools array length:", req.body.tools?.length);
|
|
4002
|
+
if (!req.body.tools) {
|
|
4003
|
+
req.body.tools = [];
|
|
4004
|
+
}
|
|
4005
|
+
if (req.headers["x-api-key"] === "PLACEHOLDER") {
|
|
4006
|
+
res.write(JSON.stringify({
|
|
4007
|
+
"type": "content_block_delta",
|
|
4008
|
+
"index": 0,
|
|
4009
|
+
"delta": {
|
|
4010
|
+
"type": "text_delta",
|
|
4011
|
+
"text": "Hello, world!"
|
|
4012
|
+
}
|
|
4013
|
+
}));
|
|
4014
|
+
res.end();
|
|
4015
|
+
return;
|
|
4016
|
+
}
|
|
4017
|
+
const response = await fetch(url, {
|
|
4018
|
+
method: req.method,
|
|
4019
|
+
headers,
|
|
4020
|
+
body: req.method !== "GET" ? JSON.stringify(req.body) : void 0
|
|
4021
|
+
});
|
|
4022
|
+
console.log("[PROXY] Response status:", response.status);
|
|
4023
|
+
response.headers.forEach((value, key) => {
|
|
4024
|
+
res.setHeader(key, value);
|
|
4025
|
+
});
|
|
4026
|
+
res.status(response.status);
|
|
4027
|
+
if (response.headers.get("content-type")?.includes("text/event-stream")) {
|
|
4028
|
+
const reader = response.body.getReader();
|
|
4029
|
+
const decoder = new TextDecoder();
|
|
4030
|
+
while (true) {
|
|
4031
|
+
const { done, value } = await reader.read();
|
|
4032
|
+
if (done) break;
|
|
4033
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
4034
|
+
res.write(chunk);
|
|
4035
|
+
}
|
|
4036
|
+
res.end();
|
|
4037
|
+
} else {
|
|
4038
|
+
const data = await response.arrayBuffer();
|
|
4039
|
+
res.end(Buffer.from(data));
|
|
4040
|
+
}
|
|
4041
|
+
} catch (error) {
|
|
4042
|
+
console.error("[PROXY] Manual proxy error:", error);
|
|
4043
|
+
if (!res.headersSent) {
|
|
4044
|
+
res.status(500).json({ error: error.message });
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
});
|
|
3977
4048
|
return app;
|
|
3978
4049
|
};
|
|
3979
4050
|
var preprocessInputs = async (data) => {
|
|
@@ -4231,14 +4302,15 @@ var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamable
|
|
|
4231
4302
|
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
4232
4303
|
var import_zod3 = require("zod");
|
|
4233
4304
|
var import_express4 = require("express");
|
|
4305
|
+
var SESSION_ID_HEADER = "mcp-session-id";
|
|
4234
4306
|
var ExuluMCP = class {
|
|
4235
4307
|
server;
|
|
4236
4308
|
transports = {};
|
|
4237
4309
|
express;
|
|
4238
4310
|
constructor() {
|
|
4239
4311
|
}
|
|
4240
|
-
create = async ({ express:
|
|
4241
|
-
this.express =
|
|
4312
|
+
create = async ({ express: express3, contexts, embedders, agents, workflows, config, tools }) => {
|
|
4313
|
+
this.express = express3;
|
|
4242
4314
|
if (!this.server) {
|
|
4243
4315
|
console.log("[EXULU] Creating MCP server.");
|
|
4244
4316
|
this.server = new import_mcp.McpServer({
|
|
@@ -4247,14 +4319,21 @@ var ExuluMCP = class {
|
|
|
4247
4319
|
});
|
|
4248
4320
|
}
|
|
4249
4321
|
this.server.registerTool(
|
|
4250
|
-
"
|
|
4322
|
+
"getAgents",
|
|
4251
4323
|
{
|
|
4252
|
-
title: "
|
|
4253
|
-
description: "
|
|
4254
|
-
inputSchema: { a: import_zod3.z.number(), b: import_zod3.z.number() }
|
|
4324
|
+
title: "Get agents",
|
|
4325
|
+
description: "Retrieves a list of all available agents"
|
|
4255
4326
|
},
|
|
4256
|
-
async (
|
|
4257
|
-
content:
|
|
4327
|
+
async () => ({
|
|
4328
|
+
content: agents ? agents.map((agent) => {
|
|
4329
|
+
return {
|
|
4330
|
+
type: "text",
|
|
4331
|
+
text: `${agent.name} - ${agent.description}`
|
|
4332
|
+
};
|
|
4333
|
+
}) : [{
|
|
4334
|
+
type: "text",
|
|
4335
|
+
text: "No agents found."
|
|
4336
|
+
}]
|
|
4258
4337
|
})
|
|
4259
4338
|
);
|
|
4260
4339
|
this.server.registerResource(
|
|
@@ -4303,7 +4382,12 @@ ${code}`
|
|
|
4303
4382
|
}
|
|
4304
4383
|
console.log("[EXULU] Wiring up MCP server routes to express app.");
|
|
4305
4384
|
this.express.post("/mcp", async (req, res) => {
|
|
4306
|
-
|
|
4385
|
+
if (!this.server) {
|
|
4386
|
+
throw new Error("MCP server not initialized.");
|
|
4387
|
+
}
|
|
4388
|
+
const sessionId = req.headers[SESSION_ID_HEADER];
|
|
4389
|
+
console.log("sessionId!!", sessionId);
|
|
4390
|
+
console.log("req.headers!!", req.headers);
|
|
4307
4391
|
let transport;
|
|
4308
4392
|
if (sessionId && this.transports[sessionId]) {
|
|
4309
4393
|
transport = this.transports[sessionId];
|
|
@@ -4323,27 +4407,20 @@ ${code}`
|
|
|
4323
4407
|
delete this.transports[transport.sessionId];
|
|
4324
4408
|
}
|
|
4325
4409
|
};
|
|
4326
|
-
|
|
4327
|
-
name: "example-server",
|
|
4328
|
-
version: "1.0.0"
|
|
4329
|
-
});
|
|
4330
|
-
await server.connect(transport);
|
|
4410
|
+
await this.server.connect(transport);
|
|
4331
4411
|
} else {
|
|
4332
4412
|
res.status(400).json({
|
|
4333
|
-
|
|
4334
|
-
error: {
|
|
4335
|
-
code: -32e3,
|
|
4336
|
-
message: "Bad Request: No valid session ID provided"
|
|
4337
|
-
},
|
|
4338
|
-
id: null
|
|
4413
|
+
error: "Bad Request: No valid session ID provided"
|
|
4339
4414
|
});
|
|
4340
4415
|
return;
|
|
4341
4416
|
}
|
|
4342
4417
|
await transport.handleRequest(req, res, req.body);
|
|
4343
4418
|
});
|
|
4344
4419
|
const handleSessionRequest = async (req, res) => {
|
|
4345
|
-
|
|
4420
|
+
console.log("handleSessionRequest", req.body);
|
|
4421
|
+
const sessionId = req.headers[SESSION_ID_HEADER];
|
|
4346
4422
|
if (!sessionId || !this.transports[sessionId]) {
|
|
4423
|
+
console.log("Invalid or missing session ID");
|
|
4347
4424
|
res.status(400).send("Invalid or missing session ID");
|
|
4348
4425
|
return;
|
|
4349
4426
|
}
|
|
@@ -4365,6 +4442,7 @@ ${code}`
|
|
|
4365
4442
|
};
|
|
4366
4443
|
|
|
4367
4444
|
// src/registry/index.ts
|
|
4445
|
+
var import_express7 = __toESM(require("express"), 1);
|
|
4368
4446
|
var ExuluApp = class {
|
|
4369
4447
|
_agents = [];
|
|
4370
4448
|
_workflows = [];
|
|
@@ -4373,6 +4451,7 @@ var ExuluApp = class {
|
|
|
4373
4451
|
_queues = [];
|
|
4374
4452
|
_contexts = {};
|
|
4375
4453
|
_tools = [];
|
|
4454
|
+
_expressApp = null;
|
|
4376
4455
|
constructor() {
|
|
4377
4456
|
}
|
|
4378
4457
|
// Factory function so we can async initialize the
|
|
@@ -4389,7 +4468,19 @@ var ExuluApp = class {
|
|
|
4389
4468
|
...workflows?.length ? workflows.map((workflow) => workflow.queue?.name || null) : []
|
|
4390
4469
|
];
|
|
4391
4470
|
this._queues = [...new Set(queues2.filter((o) => !!o))];
|
|
4471
|
+
if (!this._expressApp) {
|
|
4472
|
+
this._expressApp = (0, import_express7.default)();
|
|
4473
|
+
await this.server.express.init();
|
|
4474
|
+
console.log("[EXULU] Express app initialized.");
|
|
4475
|
+
}
|
|
4476
|
+
return this._expressApp;
|
|
4392
4477
|
};
|
|
4478
|
+
get expressApp() {
|
|
4479
|
+
if (!this._expressApp) {
|
|
4480
|
+
throw new Error("Express app not initialized, initialize it by calling await ExuluApp.create() first.");
|
|
4481
|
+
}
|
|
4482
|
+
return this._expressApp;
|
|
4483
|
+
}
|
|
4393
4484
|
embedder(id) {
|
|
4394
4485
|
return this._embedders.find((x) => x.id === id);
|
|
4395
4486
|
}
|
|
@@ -4435,7 +4526,11 @@ var ExuluApp = class {
|
|
|
4435
4526
|
};
|
|
4436
4527
|
server = {
|
|
4437
4528
|
express: {
|
|
4438
|
-
init: async (
|
|
4529
|
+
init: async () => {
|
|
4530
|
+
if (!this._expressApp) {
|
|
4531
|
+
throw new Error("Express app not initialized");
|
|
4532
|
+
}
|
|
4533
|
+
const app = this._expressApp;
|
|
4439
4534
|
await createExpressRoutes(
|
|
4440
4535
|
app,
|
|
4441
4536
|
this._agents,
|
|
@@ -5681,6 +5776,10 @@ var nav = [
|
|
|
5681
5776
|
label: "Agents",
|
|
5682
5777
|
value: "agents"
|
|
5683
5778
|
},
|
|
5779
|
+
{
|
|
5780
|
+
label: "Start Claude Code",
|
|
5781
|
+
value: "claude-code"
|
|
5782
|
+
},
|
|
5684
5783
|
{
|
|
5685
5784
|
label: "Exit",
|
|
5686
5785
|
value: "exit"
|
package/dist/index.d.cts
CHANGED
|
@@ -92,6 +92,7 @@ type ExuluAgentConfig = {
|
|
|
92
92
|
instructions: string;
|
|
93
93
|
model: LanguageModelV1;
|
|
94
94
|
outputSchema?: ZodSchema;
|
|
95
|
+
custom?: ZodSchema;
|
|
95
96
|
memory?: {
|
|
96
97
|
lastMessages: number;
|
|
97
98
|
vector: boolean;
|
|
@@ -469,6 +470,7 @@ declare class ExuluApp {
|
|
|
469
470
|
private _queues;
|
|
470
471
|
private _contexts?;
|
|
471
472
|
private _tools;
|
|
473
|
+
private _expressApp;
|
|
472
474
|
constructor();
|
|
473
475
|
create: ({ contexts, embedders, agents, workflows, config, tools }: {
|
|
474
476
|
contexts?: Record<string, ExuluContext>;
|
|
@@ -477,7 +479,8 @@ declare class ExuluApp {
|
|
|
477
479
|
agents?: ExuluAgent[];
|
|
478
480
|
workflows?: ExuluWorkflow[];
|
|
479
481
|
tools?: ExuluTool[];
|
|
480
|
-
}) => Promise<
|
|
482
|
+
}) => Promise<Express>;
|
|
483
|
+
get expressApp(): Express;
|
|
481
484
|
embedder(id: string): ExuluEmbedder | undefined;
|
|
482
485
|
tool(id: string): ExuluTool | undefined;
|
|
483
486
|
tools(): ExuluTool[];
|
|
@@ -493,11 +496,7 @@ declare class ExuluApp {
|
|
|
493
496
|
create: () => Promise<bullmq.Worker<any, any, string>[]>;
|
|
494
497
|
};
|
|
495
498
|
};
|
|
496
|
-
server
|
|
497
|
-
express: {
|
|
498
|
-
init: (app: Express) => Promise<Express>;
|
|
499
|
-
};
|
|
500
|
-
};
|
|
499
|
+
private server;
|
|
501
500
|
}
|
|
502
501
|
|
|
503
502
|
type User = {
|
package/dist/index.d.ts
CHANGED
|
@@ -92,6 +92,7 @@ type ExuluAgentConfig = {
|
|
|
92
92
|
instructions: string;
|
|
93
93
|
model: LanguageModelV1;
|
|
94
94
|
outputSchema?: ZodSchema;
|
|
95
|
+
custom?: ZodSchema;
|
|
95
96
|
memory?: {
|
|
96
97
|
lastMessages: number;
|
|
97
98
|
vector: boolean;
|
|
@@ -469,6 +470,7 @@ declare class ExuluApp {
|
|
|
469
470
|
private _queues;
|
|
470
471
|
private _contexts?;
|
|
471
472
|
private _tools;
|
|
473
|
+
private _expressApp;
|
|
472
474
|
constructor();
|
|
473
475
|
create: ({ contexts, embedders, agents, workflows, config, tools }: {
|
|
474
476
|
contexts?: Record<string, ExuluContext>;
|
|
@@ -477,7 +479,8 @@ declare class ExuluApp {
|
|
|
477
479
|
agents?: ExuluAgent[];
|
|
478
480
|
workflows?: ExuluWorkflow[];
|
|
479
481
|
tools?: ExuluTool[];
|
|
480
|
-
}) => Promise<
|
|
482
|
+
}) => Promise<Express>;
|
|
483
|
+
get expressApp(): Express;
|
|
481
484
|
embedder(id: string): ExuluEmbedder | undefined;
|
|
482
485
|
tool(id: string): ExuluTool | undefined;
|
|
483
486
|
tools(): ExuluTool[];
|
|
@@ -493,11 +496,7 @@ declare class ExuluApp {
|
|
|
493
496
|
create: () => Promise<bullmq.Worker<any, any, string>[]>;
|
|
494
497
|
};
|
|
495
498
|
};
|
|
496
|
-
server
|
|
497
|
-
express: {
|
|
498
|
-
init: (app: Express) => Promise<Express>;
|
|
499
|
-
};
|
|
500
|
-
};
|
|
499
|
+
private server;
|
|
501
500
|
}
|
|
502
501
|
|
|
503
502
|
type User = {
|
package/dist/index.js
CHANGED
|
@@ -994,7 +994,7 @@ var ExuluAgent = class {
|
|
|
994
994
|
streaming = false;
|
|
995
995
|
rateLimit;
|
|
996
996
|
config;
|
|
997
|
-
// private memory: Memory | undefined; // TODO
|
|
997
|
+
// private memory: Memory | undefined; // TODO do own implementation
|
|
998
998
|
tools;
|
|
999
999
|
evals;
|
|
1000
1000
|
model;
|
|
@@ -1754,13 +1754,13 @@ var ExuluContext = class {
|
|
|
1754
1754
|
return await db2.schema.createTable(tableName, (table) => {
|
|
1755
1755
|
console.log("[EXULU] Creating fields for table.", this.fields);
|
|
1756
1756
|
table.uuid("id").primary().defaultTo(db2.fn.uuid());
|
|
1757
|
-
table.
|
|
1757
|
+
table.text("name");
|
|
1758
1758
|
table.text("description");
|
|
1759
|
-
table.
|
|
1759
|
+
table.text("tags");
|
|
1760
1760
|
table.boolean("archived").defaultTo(false);
|
|
1761
|
-
table.string("external_id",
|
|
1761
|
+
table.string("external_id", 255);
|
|
1762
1762
|
table.integer("textLength");
|
|
1763
|
-
table.
|
|
1763
|
+
table.text("source");
|
|
1764
1764
|
for (const field of this.fields) {
|
|
1765
1765
|
const { type, name } = field;
|
|
1766
1766
|
if (!type || !name) {
|
|
@@ -2573,7 +2573,6 @@ import { expressMiddleware } from "@as-integrations/express5";
|
|
|
2573
2573
|
|
|
2574
2574
|
// src/registry/uppy.ts
|
|
2575
2575
|
import "express";
|
|
2576
|
-
import bodyParser from "body-parser";
|
|
2577
2576
|
var createUppyRoutes = async (app) => {
|
|
2578
2577
|
const {
|
|
2579
2578
|
S3Client,
|
|
@@ -2634,7 +2633,6 @@ var createUppyRoutes = async (app) => {
|
|
|
2634
2633
|
});
|
|
2635
2634
|
return stsClient;
|
|
2636
2635
|
}
|
|
2637
|
-
app.use(bodyParser.urlencoded({ extended: true }), bodyParser.json());
|
|
2638
2636
|
app.get("/s3/list", async (req, res, next) => {
|
|
2639
2637
|
req.accepts;
|
|
2640
2638
|
const apikey = req.headers["exulu-api-key"] || null;
|
|
@@ -2966,6 +2964,8 @@ var createUppyRoutes = async (app) => {
|
|
|
2966
2964
|
|
|
2967
2965
|
// src/registry/routes.ts
|
|
2968
2966
|
import { InMemoryLRUCache } from "@apollo/utils.keyvaluecache";
|
|
2967
|
+
import bodyParser from "body-parser";
|
|
2968
|
+
var REQUEST_SIZE_LIMIT = "50mb";
|
|
2969
2969
|
var global_queues = {
|
|
2970
2970
|
logs_cleaner: "logs-cleaner"
|
|
2971
2971
|
};
|
|
@@ -3010,7 +3010,10 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3010
3010
|
optionsSuccessStatus: 200
|
|
3011
3011
|
// some legacy browsers (IE11, various SmartTVs) choke on 204
|
|
3012
3012
|
};
|
|
3013
|
+
app.use(express.json({ limit: REQUEST_SIZE_LIMIT }));
|
|
3013
3014
|
app.use(cors(corsOptions));
|
|
3015
|
+
app.use(bodyParser.urlencoded({ extended: true, limit: REQUEST_SIZE_LIMIT }));
|
|
3016
|
+
app.use(bodyParser.json({ limit: REQUEST_SIZE_LIMIT }));
|
|
3014
3017
|
console.log(`
|
|
3015
3018
|
\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
|
|
3016
3019
|
\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
|
|
@@ -3018,6 +3021,7 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3018
3021
|
\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
|
|
3019
3022
|
\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
|
|
3020
3023
|
\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
|
|
3024
|
+
|
|
3021
3025
|
`);
|
|
3022
3026
|
console.log("Agents:");
|
|
3023
3027
|
console.table(agents.map((agent) => {
|
|
@@ -3078,7 +3082,7 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3078
3082
|
app.use(
|
|
3079
3083
|
"/graphql",
|
|
3080
3084
|
cors(corsOptions),
|
|
3081
|
-
express.json(),
|
|
3085
|
+
express.json({ limit: REQUEST_SIZE_LIMIT }),
|
|
3082
3086
|
expressMiddleware(server, {
|
|
3083
3087
|
context: async ({ req }) => {
|
|
3084
3088
|
const authenticationResult = await requestValidators.authenticate(req);
|
|
@@ -3930,6 +3934,73 @@ var createExpressRoutes = async (app, agents, embedders, tools, workflows, conte
|
|
|
3930
3934
|
}
|
|
3931
3935
|
console.log("Routes:");
|
|
3932
3936
|
console.table(routeLogs);
|
|
3937
|
+
const TARGET_API = "https://api.anthropic.com";
|
|
3938
|
+
app.use("/gateway/anthropic", express.raw({ type: "*/*", limit: REQUEST_SIZE_LIMIT }), async (req, res) => {
|
|
3939
|
+
const path3 = req.url;
|
|
3940
|
+
const url = `${TARGET_API}${path3}`;
|
|
3941
|
+
console.log("[PROXY] Manual proxy to:", url);
|
|
3942
|
+
console.log("[PROXY] Method:", req.method);
|
|
3943
|
+
console.log("[PROXY] Headers:", Object.keys(req.headers));
|
|
3944
|
+
console.log("[PROXY] Request body length:", req.body ? req.body.length : 0);
|
|
3945
|
+
console.log("[PROXY] Request model name:", req.body.model);
|
|
3946
|
+
console.log("[PROXY] Request stream:", req.body.stream);
|
|
3947
|
+
console.log("[PROXY] API key:", req.headers["x-api-key"]);
|
|
3948
|
+
console.log("[PROXY] Request messages:", req.body.messages?.length);
|
|
3949
|
+
try {
|
|
3950
|
+
const headers = {
|
|
3951
|
+
"x-api-key": process.env.ANTHROPIC_API_KEY,
|
|
3952
|
+
"anthropic-version": "2023-06-01",
|
|
3953
|
+
"content-type": req.headers["content-type"] || "application/json"
|
|
3954
|
+
};
|
|
3955
|
+
if (req.headers["accept"]) headers["accept"] = req.headers["accept"];
|
|
3956
|
+
if (req.headers["user-agent"]) headers["user-agent"] = req.headers["user-agent"];
|
|
3957
|
+
console.log("[PROXY] Request body tools array length:", req.body.tools?.length);
|
|
3958
|
+
if (!req.body.tools) {
|
|
3959
|
+
req.body.tools = [];
|
|
3960
|
+
}
|
|
3961
|
+
if (req.headers["x-api-key"] === "PLACEHOLDER") {
|
|
3962
|
+
res.write(JSON.stringify({
|
|
3963
|
+
"type": "content_block_delta",
|
|
3964
|
+
"index": 0,
|
|
3965
|
+
"delta": {
|
|
3966
|
+
"type": "text_delta",
|
|
3967
|
+
"text": "Hello, world!"
|
|
3968
|
+
}
|
|
3969
|
+
}));
|
|
3970
|
+
res.end();
|
|
3971
|
+
return;
|
|
3972
|
+
}
|
|
3973
|
+
const response = await fetch(url, {
|
|
3974
|
+
method: req.method,
|
|
3975
|
+
headers,
|
|
3976
|
+
body: req.method !== "GET" ? JSON.stringify(req.body) : void 0
|
|
3977
|
+
});
|
|
3978
|
+
console.log("[PROXY] Response status:", response.status);
|
|
3979
|
+
response.headers.forEach((value, key) => {
|
|
3980
|
+
res.setHeader(key, value);
|
|
3981
|
+
});
|
|
3982
|
+
res.status(response.status);
|
|
3983
|
+
if (response.headers.get("content-type")?.includes("text/event-stream")) {
|
|
3984
|
+
const reader = response.body.getReader();
|
|
3985
|
+
const decoder = new TextDecoder();
|
|
3986
|
+
while (true) {
|
|
3987
|
+
const { done, value } = await reader.read();
|
|
3988
|
+
if (done) break;
|
|
3989
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
3990
|
+
res.write(chunk);
|
|
3991
|
+
}
|
|
3992
|
+
res.end();
|
|
3993
|
+
} else {
|
|
3994
|
+
const data = await response.arrayBuffer();
|
|
3995
|
+
res.end(Buffer.from(data));
|
|
3996
|
+
}
|
|
3997
|
+
} catch (error) {
|
|
3998
|
+
console.error("[PROXY] Manual proxy error:", error);
|
|
3999
|
+
if (!res.headersSent) {
|
|
4000
|
+
res.status(500).json({ error: error.message });
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
});
|
|
3933
4004
|
return app;
|
|
3934
4005
|
};
|
|
3935
4006
|
var preprocessInputs = async (data) => {
|
|
@@ -4187,14 +4258,15 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
|
|
|
4187
4258
|
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
4188
4259
|
import { z as z2 } from "zod";
|
|
4189
4260
|
import "express";
|
|
4261
|
+
var SESSION_ID_HEADER = "mcp-session-id";
|
|
4190
4262
|
var ExuluMCP = class {
|
|
4191
4263
|
server;
|
|
4192
4264
|
transports = {};
|
|
4193
4265
|
express;
|
|
4194
4266
|
constructor() {
|
|
4195
4267
|
}
|
|
4196
|
-
create = async ({ express:
|
|
4197
|
-
this.express =
|
|
4268
|
+
create = async ({ express: express3, contexts, embedders, agents, workflows, config, tools }) => {
|
|
4269
|
+
this.express = express3;
|
|
4198
4270
|
if (!this.server) {
|
|
4199
4271
|
console.log("[EXULU] Creating MCP server.");
|
|
4200
4272
|
this.server = new McpServer({
|
|
@@ -4203,14 +4275,21 @@ var ExuluMCP = class {
|
|
|
4203
4275
|
});
|
|
4204
4276
|
}
|
|
4205
4277
|
this.server.registerTool(
|
|
4206
|
-
"
|
|
4278
|
+
"getAgents",
|
|
4207
4279
|
{
|
|
4208
|
-
title: "
|
|
4209
|
-
description: "
|
|
4210
|
-
inputSchema: { a: z2.number(), b: z2.number() }
|
|
4280
|
+
title: "Get agents",
|
|
4281
|
+
description: "Retrieves a list of all available agents"
|
|
4211
4282
|
},
|
|
4212
|
-
async (
|
|
4213
|
-
content:
|
|
4283
|
+
async () => ({
|
|
4284
|
+
content: agents ? agents.map((agent) => {
|
|
4285
|
+
return {
|
|
4286
|
+
type: "text",
|
|
4287
|
+
text: `${agent.name} - ${agent.description}`
|
|
4288
|
+
};
|
|
4289
|
+
}) : [{
|
|
4290
|
+
type: "text",
|
|
4291
|
+
text: "No agents found."
|
|
4292
|
+
}]
|
|
4214
4293
|
})
|
|
4215
4294
|
);
|
|
4216
4295
|
this.server.registerResource(
|
|
@@ -4259,7 +4338,12 @@ ${code}`
|
|
|
4259
4338
|
}
|
|
4260
4339
|
console.log("[EXULU] Wiring up MCP server routes to express app.");
|
|
4261
4340
|
this.express.post("/mcp", async (req, res) => {
|
|
4262
|
-
|
|
4341
|
+
if (!this.server) {
|
|
4342
|
+
throw new Error("MCP server not initialized.");
|
|
4343
|
+
}
|
|
4344
|
+
const sessionId = req.headers[SESSION_ID_HEADER];
|
|
4345
|
+
console.log("sessionId!!", sessionId);
|
|
4346
|
+
console.log("req.headers!!", req.headers);
|
|
4263
4347
|
let transport;
|
|
4264
4348
|
if (sessionId && this.transports[sessionId]) {
|
|
4265
4349
|
transport = this.transports[sessionId];
|
|
@@ -4279,27 +4363,20 @@ ${code}`
|
|
|
4279
4363
|
delete this.transports[transport.sessionId];
|
|
4280
4364
|
}
|
|
4281
4365
|
};
|
|
4282
|
-
|
|
4283
|
-
name: "example-server",
|
|
4284
|
-
version: "1.0.0"
|
|
4285
|
-
});
|
|
4286
|
-
await server.connect(transport);
|
|
4366
|
+
await this.server.connect(transport);
|
|
4287
4367
|
} else {
|
|
4288
4368
|
res.status(400).json({
|
|
4289
|
-
|
|
4290
|
-
error: {
|
|
4291
|
-
code: -32e3,
|
|
4292
|
-
message: "Bad Request: No valid session ID provided"
|
|
4293
|
-
},
|
|
4294
|
-
id: null
|
|
4369
|
+
error: "Bad Request: No valid session ID provided"
|
|
4295
4370
|
});
|
|
4296
4371
|
return;
|
|
4297
4372
|
}
|
|
4298
4373
|
await transport.handleRequest(req, res, req.body);
|
|
4299
4374
|
});
|
|
4300
4375
|
const handleSessionRequest = async (req, res) => {
|
|
4301
|
-
|
|
4376
|
+
console.log("handleSessionRequest", req.body);
|
|
4377
|
+
const sessionId = req.headers[SESSION_ID_HEADER];
|
|
4302
4378
|
if (!sessionId || !this.transports[sessionId]) {
|
|
4379
|
+
console.log("Invalid or missing session ID");
|
|
4303
4380
|
res.status(400).send("Invalid or missing session ID");
|
|
4304
4381
|
return;
|
|
4305
4382
|
}
|
|
@@ -4321,6 +4398,7 @@ ${code}`
|
|
|
4321
4398
|
};
|
|
4322
4399
|
|
|
4323
4400
|
// src/registry/index.ts
|
|
4401
|
+
import express2 from "express";
|
|
4324
4402
|
var ExuluApp = class {
|
|
4325
4403
|
_agents = [];
|
|
4326
4404
|
_workflows = [];
|
|
@@ -4329,6 +4407,7 @@ var ExuluApp = class {
|
|
|
4329
4407
|
_queues = [];
|
|
4330
4408
|
_contexts = {};
|
|
4331
4409
|
_tools = [];
|
|
4410
|
+
_expressApp = null;
|
|
4332
4411
|
constructor() {
|
|
4333
4412
|
}
|
|
4334
4413
|
// Factory function so we can async initialize the
|
|
@@ -4345,7 +4424,19 @@ var ExuluApp = class {
|
|
|
4345
4424
|
...workflows?.length ? workflows.map((workflow) => workflow.queue?.name || null) : []
|
|
4346
4425
|
];
|
|
4347
4426
|
this._queues = [...new Set(queues2.filter((o) => !!o))];
|
|
4427
|
+
if (!this._expressApp) {
|
|
4428
|
+
this._expressApp = express2();
|
|
4429
|
+
await this.server.express.init();
|
|
4430
|
+
console.log("[EXULU] Express app initialized.");
|
|
4431
|
+
}
|
|
4432
|
+
return this._expressApp;
|
|
4348
4433
|
};
|
|
4434
|
+
get expressApp() {
|
|
4435
|
+
if (!this._expressApp) {
|
|
4436
|
+
throw new Error("Express app not initialized, initialize it by calling await ExuluApp.create() first.");
|
|
4437
|
+
}
|
|
4438
|
+
return this._expressApp;
|
|
4439
|
+
}
|
|
4349
4440
|
embedder(id) {
|
|
4350
4441
|
return this._embedders.find((x) => x.id === id);
|
|
4351
4442
|
}
|
|
@@ -4391,7 +4482,11 @@ var ExuluApp = class {
|
|
|
4391
4482
|
};
|
|
4392
4483
|
server = {
|
|
4393
4484
|
express: {
|
|
4394
|
-
init: async (
|
|
4485
|
+
init: async () => {
|
|
4486
|
+
if (!this._expressApp) {
|
|
4487
|
+
throw new Error("Express app not initialized");
|
|
4488
|
+
}
|
|
4489
|
+
const app = this._expressApp;
|
|
4395
4490
|
await createExpressRoutes(
|
|
4396
4491
|
app,
|
|
4397
4492
|
this._agents,
|
|
@@ -5637,6 +5732,10 @@ var nav = [
|
|
|
5637
5732
|
label: "Agents",
|
|
5638
5733
|
value: "agents"
|
|
5639
5734
|
},
|
|
5735
|
+
{
|
|
5736
|
+
label: "Start Claude Code",
|
|
5737
|
+
value: "claude-code"
|
|
5738
|
+
},
|
|
5640
5739
|
{
|
|
5641
5740
|
label: "Exit",
|
|
5642
5741
|
value: "exit"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exulu/backend",
|
|
3
3
|
"author": "Qventu Bv.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.11",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"private": false,
|
|
7
7
|
"publishConfig": {
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"typescript": "^5.8.3"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@ai-sdk/anthropic": "^1.2.12",
|
|
40
|
+
"@anthropic-ai/sdk": "^0.56.0",
|
|
39
41
|
"@as-integrations/express5": "^1.0.0",
|
|
40
42
|
"@aws-sdk/client-s3": "^3.338.0",
|
|
41
43
|
"@aws-sdk/client-sts": "^3.338.0",
|
|
@@ -62,6 +64,7 @@
|
|
|
62
64
|
"graphql": "^16.11.0",
|
|
63
65
|
"graphql-tools": "^9.0.18",
|
|
64
66
|
"graphql-type-json": "^0.3.2",
|
|
67
|
+
"http-proxy-middleware": "^3.0.5",
|
|
65
68
|
"ink": "^6.0.0",
|
|
66
69
|
"ink-big-text": "^2.0.0",
|
|
67
70
|
"ink-gradient": "^3.0.0",
|