@exulu/backend 1.21.0 → 1.22.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 +2 -2
- package/dist/index.cjs +91 -9
- package/dist/index.d.cts +12 -11
- package/dist/index.d.ts +12 -11
- package/dist/index.js +91 -9
- package/package.json +1 -1
- package/types/models/agent-session.ts +7 -0
- package/types/models/agent.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# [1.
|
|
1
|
+
# [1.22.0](https://github.com/Qventu/exulu-backend/compare/v1.21.0...v1.22.0) (2025-09-03)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Features
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* improved UI layout for chat interface ([4802a3c](https://github.com/Qventu/exulu-backend/commit/4802a3c0ac3eb21fc6a0f492f8786de341bd7103))
|
package/dist/index.cjs
CHANGED
|
@@ -2583,7 +2583,7 @@ var vectorSearch = async ({
|
|
|
2583
2583
|
items
|
|
2584
2584
|
};
|
|
2585
2585
|
};
|
|
2586
|
-
var RBACResolver = async (db3,
|
|
2586
|
+
var RBACResolver = async (db3, entityName, resourceId, rights_mode) => {
|
|
2587
2587
|
const rbacRecords = await db3.from("rbac").where({
|
|
2588
2588
|
entity: entityName,
|
|
2589
2589
|
target_resource_id: resourceId
|
|
@@ -2821,7 +2821,7 @@ type PageInfo {
|
|
|
2821
2821
|
const resourceId = parent.id;
|
|
2822
2822
|
const entityName = table.name.singular;
|
|
2823
2823
|
const rights_mode = parent.rights_mode;
|
|
2824
|
-
return RBACResolver(db3,
|
|
2824
|
+
return RBACResolver(db3, entityName, resourceId, rights_mode);
|
|
2825
2825
|
};
|
|
2826
2826
|
}
|
|
2827
2827
|
}
|
|
@@ -3319,8 +3319,6 @@ var ExuluAgent2 = class {
|
|
|
3319
3319
|
// append the new message to the previous messages:
|
|
3320
3320
|
messages: [...previousMessagesContent, message]
|
|
3321
3321
|
});
|
|
3322
|
-
console.log("[EXULU] Model provider key", providerApiKey);
|
|
3323
|
-
console.log("[EXULU] Tool configs", toolConfigs);
|
|
3324
3322
|
const result = (0, import_ai.streamText)({
|
|
3325
3323
|
model,
|
|
3326
3324
|
// Should be a LanguageModelV1
|
|
@@ -3344,11 +3342,13 @@ var ExuluAgent2 = class {
|
|
|
3344
3342
|
"[EXULU] chat stream finished.",
|
|
3345
3343
|
messages2
|
|
3346
3344
|
);
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3345
|
+
if (session) {
|
|
3346
|
+
await saveChat({
|
|
3347
|
+
session,
|
|
3348
|
+
user,
|
|
3349
|
+
messages: messages2
|
|
3350
|
+
});
|
|
3351
|
+
}
|
|
3352
3352
|
if (statistics) {
|
|
3353
3353
|
await updateStatistic({
|
|
3354
3354
|
name: "count",
|
|
@@ -4904,6 +4904,8 @@ Mood: friendly and intelligent.
|
|
|
4904
4904
|
const agentInstance = await db3.from("agents").where({
|
|
4905
4905
|
id: instance
|
|
4906
4906
|
}).first();
|
|
4907
|
+
const agentRbac = await RBACResolver(db3, "agent", agentInstance.id, agentInstance.rights_mode || "private");
|
|
4908
|
+
agentInstance.RBAC = agentRbac;
|
|
4907
4909
|
if (!agentInstance) {
|
|
4908
4910
|
res.status(400).json({
|
|
4909
4911
|
message: "Agent instance not found."
|
|
@@ -4942,6 +4944,86 @@ Mood: friendly and intelligent.
|
|
|
4942
4944
|
return;
|
|
4943
4945
|
}
|
|
4944
4946
|
const user = authenticationResult.user;
|
|
4947
|
+
const agentIsPublic = agentInstance.rights_mode === "public";
|
|
4948
|
+
const agentByUsers = agentInstance.rights_mode === "users";
|
|
4949
|
+
const agentByRoles = agentInstance.rights_mode === "roles";
|
|
4950
|
+
const isAgentCreator = agentInstance.created_by === user.id;
|
|
4951
|
+
const isAdmin = user.super_admin;
|
|
4952
|
+
const isApi = user.type === "api";
|
|
4953
|
+
let hasAccessToAgent = "none";
|
|
4954
|
+
if (agentIsPublic || isAgentCreator || isAdmin || isApi) {
|
|
4955
|
+
hasAccessToAgent = "write";
|
|
4956
|
+
}
|
|
4957
|
+
if (agentByUsers) {
|
|
4958
|
+
hasAccessToAgent = agentInstance.RBAC?.users?.find((x) => x.id === user.id)?.rights || "none";
|
|
4959
|
+
if (!hasAccessToAgent || hasAccessToAgent === "none" || hasAccessToAgent === "read") {
|
|
4960
|
+
res.status(410).json({
|
|
4961
|
+
message: `Your current user ${user.id} does not have access to this agent.`
|
|
4962
|
+
});
|
|
4963
|
+
return;
|
|
4964
|
+
}
|
|
4965
|
+
}
|
|
4966
|
+
if (agentByRoles) {
|
|
4967
|
+
hasAccessToAgent = agentInstance.RBAC?.roles?.find((x) => x.id === user.role?.id)?.rights || "none";
|
|
4968
|
+
if (!hasAccessToAgent || hasAccessToAgent === "none" || hasAccessToAgent === "read") {
|
|
4969
|
+
res.status(410).json({
|
|
4970
|
+
message: `Your current role ${user.role?.name} does not have access to this agent.`
|
|
4971
|
+
});
|
|
4972
|
+
return;
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
let hasAccessToSession = "none";
|
|
4976
|
+
;
|
|
4977
|
+
if (headers.session) {
|
|
4978
|
+
const session = await db3.from("agents").where({
|
|
4979
|
+
id: instance
|
|
4980
|
+
}).first();
|
|
4981
|
+
const sessionIsPublic = agentInstance.rights_mode === "public";
|
|
4982
|
+
const sessionByUsers = agentInstance.rights_mode === "users";
|
|
4983
|
+
const sessionByRoles = agentInstance.rights_mode === "roles";
|
|
4984
|
+
const isSessionCreator = agentInstance.created_by === user.id;
|
|
4985
|
+
const isAdmin2 = user.super_admin;
|
|
4986
|
+
const isApi2 = user.type === "api";
|
|
4987
|
+
if (sessionIsPublic || isSessionCreator || isAdmin2 || isApi2) {
|
|
4988
|
+
hasAccessToSession = "write";
|
|
4989
|
+
}
|
|
4990
|
+
if (sessionByUsers) {
|
|
4991
|
+
hasAccessToSession = session.RBAC?.users?.find((x) => x.id === user.id)?.rights || "none";
|
|
4992
|
+
if (!hasAccessToSession || hasAccessToSession === "none" || hasAccessToSession === "read") {
|
|
4993
|
+
res.status(410).json({
|
|
4994
|
+
message: `Your current user ${user.id} does not have access to this session.`
|
|
4995
|
+
});
|
|
4996
|
+
return;
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
if (sessionByRoles) {
|
|
5000
|
+
hasAccessToSession = session.RBAC?.roles?.find((x) => x.id === user.role?.id)?.rights || "none";
|
|
5001
|
+
if (!hasAccessToSession || hasAccessToSession === "none" || hasAccessToSession === "read") {
|
|
5002
|
+
res.status(410).json({
|
|
5003
|
+
message: `Your current role ${user.role?.name} does not have access to this session.`
|
|
5004
|
+
});
|
|
5005
|
+
return;
|
|
5006
|
+
}
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
5009
|
+
if (!hasAccessToAgent || hasAccessToAgent === "none") {
|
|
5010
|
+
res.status(410).json({
|
|
5011
|
+
message: "You don't have access to this agent."
|
|
5012
|
+
});
|
|
5013
|
+
return;
|
|
5014
|
+
}
|
|
5015
|
+
if (!hasAccessToSession || hasAccessToSession === "none") {
|
|
5016
|
+
res.status(410).json({
|
|
5017
|
+
message: "You don't have access to this session."
|
|
5018
|
+
});
|
|
5019
|
+
return;
|
|
5020
|
+
}
|
|
5021
|
+
if (headers.session && !hasAccessToSession) {
|
|
5022
|
+
res.status(410).json({
|
|
5023
|
+
message: "You don't have access to this session."
|
|
5024
|
+
});
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
4945
5027
|
if (user.type !== "api" && !user.super_admin && req.body.resourceId !== user.id) {
|
|
4946
5028
|
res.status(400).json({
|
|
4947
5029
|
message: "The provided user id in the resourceId field is not the same as the authenticated user. Only super admins and API users can impersonate other users."
|
package/dist/index.d.cts
CHANGED
|
@@ -245,20 +245,21 @@ interface ExuluWorkflow {
|
|
|
245
245
|
id: string;
|
|
246
246
|
name: string;
|
|
247
247
|
description?: string;
|
|
248
|
-
rights_mode?:
|
|
249
|
-
RBAC?:
|
|
250
|
-
users?: Array<{
|
|
251
|
-
id: string;
|
|
252
|
-
rights: 'read' | 'write';
|
|
253
|
-
}>;
|
|
254
|
-
roles?: Array<{
|
|
255
|
-
id: string;
|
|
256
|
-
rights: 'read' | 'write';
|
|
257
|
-
}>;
|
|
258
|
-
};
|
|
248
|
+
rights_mode?: ExuluRightsMode;
|
|
249
|
+
RBAC?: ExuluRBAC;
|
|
259
250
|
variables?: WorkflowVariable[];
|
|
260
251
|
steps_json?: WorkflowStep[];
|
|
261
252
|
}
|
|
253
|
+
interface ExuluRBAC {
|
|
254
|
+
users?: Array<{
|
|
255
|
+
id: string;
|
|
256
|
+
rights: 'read' | 'write';
|
|
257
|
+
}>;
|
|
258
|
+
roles?: Array<{
|
|
259
|
+
id: string;
|
|
260
|
+
rights: 'read' | 'write';
|
|
261
|
+
}>;
|
|
262
|
+
}
|
|
262
263
|
type ExuluEvalRunnerInstance = {
|
|
263
264
|
name: string;
|
|
264
265
|
description: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -245,20 +245,21 @@ interface ExuluWorkflow {
|
|
|
245
245
|
id: string;
|
|
246
246
|
name: string;
|
|
247
247
|
description?: string;
|
|
248
|
-
rights_mode?:
|
|
249
|
-
RBAC?:
|
|
250
|
-
users?: Array<{
|
|
251
|
-
id: string;
|
|
252
|
-
rights: 'read' | 'write';
|
|
253
|
-
}>;
|
|
254
|
-
roles?: Array<{
|
|
255
|
-
id: string;
|
|
256
|
-
rights: 'read' | 'write';
|
|
257
|
-
}>;
|
|
258
|
-
};
|
|
248
|
+
rights_mode?: ExuluRightsMode;
|
|
249
|
+
RBAC?: ExuluRBAC;
|
|
259
250
|
variables?: WorkflowVariable[];
|
|
260
251
|
steps_json?: WorkflowStep[];
|
|
261
252
|
}
|
|
253
|
+
interface ExuluRBAC {
|
|
254
|
+
users?: Array<{
|
|
255
|
+
id: string;
|
|
256
|
+
rights: 'read' | 'write';
|
|
257
|
+
}>;
|
|
258
|
+
roles?: Array<{
|
|
259
|
+
id: string;
|
|
260
|
+
rights: 'read' | 'write';
|
|
261
|
+
}>;
|
|
262
|
+
}
|
|
262
263
|
type ExuluEvalRunnerInstance = {
|
|
263
264
|
name: string;
|
|
264
265
|
description: string;
|
package/dist/index.js
CHANGED
|
@@ -2542,7 +2542,7 @@ var vectorSearch = async ({
|
|
|
2542
2542
|
items
|
|
2543
2543
|
};
|
|
2544
2544
|
};
|
|
2545
|
-
var RBACResolver = async (db3,
|
|
2545
|
+
var RBACResolver = async (db3, entityName, resourceId, rights_mode) => {
|
|
2546
2546
|
const rbacRecords = await db3.from("rbac").where({
|
|
2547
2547
|
entity: entityName,
|
|
2548
2548
|
target_resource_id: resourceId
|
|
@@ -2780,7 +2780,7 @@ type PageInfo {
|
|
|
2780
2780
|
const resourceId = parent.id;
|
|
2781
2781
|
const entityName = table.name.singular;
|
|
2782
2782
|
const rights_mode = parent.rights_mode;
|
|
2783
|
-
return RBACResolver(db3,
|
|
2783
|
+
return RBACResolver(db3, entityName, resourceId, rights_mode);
|
|
2784
2784
|
};
|
|
2785
2785
|
}
|
|
2786
2786
|
}
|
|
@@ -3278,8 +3278,6 @@ var ExuluAgent2 = class {
|
|
|
3278
3278
|
// append the new message to the previous messages:
|
|
3279
3279
|
messages: [...previousMessagesContent, message]
|
|
3280
3280
|
});
|
|
3281
|
-
console.log("[EXULU] Model provider key", providerApiKey);
|
|
3282
|
-
console.log("[EXULU] Tool configs", toolConfigs);
|
|
3283
3281
|
const result = streamText({
|
|
3284
3282
|
model,
|
|
3285
3283
|
// Should be a LanguageModelV1
|
|
@@ -3303,11 +3301,13 @@ var ExuluAgent2 = class {
|
|
|
3303
3301
|
"[EXULU] chat stream finished.",
|
|
3304
3302
|
messages2
|
|
3305
3303
|
);
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3304
|
+
if (session) {
|
|
3305
|
+
await saveChat({
|
|
3306
|
+
session,
|
|
3307
|
+
user,
|
|
3308
|
+
messages: messages2
|
|
3309
|
+
});
|
|
3310
|
+
}
|
|
3311
3311
|
if (statistics) {
|
|
3312
3312
|
await updateStatistic({
|
|
3313
3313
|
name: "count",
|
|
@@ -4863,6 +4863,8 @@ Mood: friendly and intelligent.
|
|
|
4863
4863
|
const agentInstance = await db3.from("agents").where({
|
|
4864
4864
|
id: instance
|
|
4865
4865
|
}).first();
|
|
4866
|
+
const agentRbac = await RBACResolver(db3, "agent", agentInstance.id, agentInstance.rights_mode || "private");
|
|
4867
|
+
agentInstance.RBAC = agentRbac;
|
|
4866
4868
|
if (!agentInstance) {
|
|
4867
4869
|
res.status(400).json({
|
|
4868
4870
|
message: "Agent instance not found."
|
|
@@ -4901,6 +4903,86 @@ Mood: friendly and intelligent.
|
|
|
4901
4903
|
return;
|
|
4902
4904
|
}
|
|
4903
4905
|
const user = authenticationResult.user;
|
|
4906
|
+
const agentIsPublic = agentInstance.rights_mode === "public";
|
|
4907
|
+
const agentByUsers = agentInstance.rights_mode === "users";
|
|
4908
|
+
const agentByRoles = agentInstance.rights_mode === "roles";
|
|
4909
|
+
const isAgentCreator = agentInstance.created_by === user.id;
|
|
4910
|
+
const isAdmin = user.super_admin;
|
|
4911
|
+
const isApi = user.type === "api";
|
|
4912
|
+
let hasAccessToAgent = "none";
|
|
4913
|
+
if (agentIsPublic || isAgentCreator || isAdmin || isApi) {
|
|
4914
|
+
hasAccessToAgent = "write";
|
|
4915
|
+
}
|
|
4916
|
+
if (agentByUsers) {
|
|
4917
|
+
hasAccessToAgent = agentInstance.RBAC?.users?.find((x) => x.id === user.id)?.rights || "none";
|
|
4918
|
+
if (!hasAccessToAgent || hasAccessToAgent === "none" || hasAccessToAgent === "read") {
|
|
4919
|
+
res.status(410).json({
|
|
4920
|
+
message: `Your current user ${user.id} does not have access to this agent.`
|
|
4921
|
+
});
|
|
4922
|
+
return;
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
if (agentByRoles) {
|
|
4926
|
+
hasAccessToAgent = agentInstance.RBAC?.roles?.find((x) => x.id === user.role?.id)?.rights || "none";
|
|
4927
|
+
if (!hasAccessToAgent || hasAccessToAgent === "none" || hasAccessToAgent === "read") {
|
|
4928
|
+
res.status(410).json({
|
|
4929
|
+
message: `Your current role ${user.role?.name} does not have access to this agent.`
|
|
4930
|
+
});
|
|
4931
|
+
return;
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
let hasAccessToSession = "none";
|
|
4935
|
+
;
|
|
4936
|
+
if (headers.session) {
|
|
4937
|
+
const session = await db3.from("agents").where({
|
|
4938
|
+
id: instance
|
|
4939
|
+
}).first();
|
|
4940
|
+
const sessionIsPublic = agentInstance.rights_mode === "public";
|
|
4941
|
+
const sessionByUsers = agentInstance.rights_mode === "users";
|
|
4942
|
+
const sessionByRoles = agentInstance.rights_mode === "roles";
|
|
4943
|
+
const isSessionCreator = agentInstance.created_by === user.id;
|
|
4944
|
+
const isAdmin2 = user.super_admin;
|
|
4945
|
+
const isApi2 = user.type === "api";
|
|
4946
|
+
if (sessionIsPublic || isSessionCreator || isAdmin2 || isApi2) {
|
|
4947
|
+
hasAccessToSession = "write";
|
|
4948
|
+
}
|
|
4949
|
+
if (sessionByUsers) {
|
|
4950
|
+
hasAccessToSession = session.RBAC?.users?.find((x) => x.id === user.id)?.rights || "none";
|
|
4951
|
+
if (!hasAccessToSession || hasAccessToSession === "none" || hasAccessToSession === "read") {
|
|
4952
|
+
res.status(410).json({
|
|
4953
|
+
message: `Your current user ${user.id} does not have access to this session.`
|
|
4954
|
+
});
|
|
4955
|
+
return;
|
|
4956
|
+
}
|
|
4957
|
+
}
|
|
4958
|
+
if (sessionByRoles) {
|
|
4959
|
+
hasAccessToSession = session.RBAC?.roles?.find((x) => x.id === user.role?.id)?.rights || "none";
|
|
4960
|
+
if (!hasAccessToSession || hasAccessToSession === "none" || hasAccessToSession === "read") {
|
|
4961
|
+
res.status(410).json({
|
|
4962
|
+
message: `Your current role ${user.role?.name} does not have access to this session.`
|
|
4963
|
+
});
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4967
|
+
}
|
|
4968
|
+
if (!hasAccessToAgent || hasAccessToAgent === "none") {
|
|
4969
|
+
res.status(410).json({
|
|
4970
|
+
message: "You don't have access to this agent."
|
|
4971
|
+
});
|
|
4972
|
+
return;
|
|
4973
|
+
}
|
|
4974
|
+
if (!hasAccessToSession || hasAccessToSession === "none") {
|
|
4975
|
+
res.status(410).json({
|
|
4976
|
+
message: "You don't have access to this session."
|
|
4977
|
+
});
|
|
4978
|
+
return;
|
|
4979
|
+
}
|
|
4980
|
+
if (headers.session && !hasAccessToSession) {
|
|
4981
|
+
res.status(410).json({
|
|
4982
|
+
message: "You don't have access to this session."
|
|
4983
|
+
});
|
|
4984
|
+
return;
|
|
4985
|
+
}
|
|
4904
4986
|
if (user.type !== "api" && !user.super_admin && req.body.resourceId !== user.id) {
|
|
4905
4987
|
res.status(400).json({
|
|
4906
4988
|
message: "The provided user id in the resourceId field is not the same as the authenticated user. Only super admins and API users can impersonate other users."
|
package/package.json
CHANGED
|
@@ -6,6 +6,13 @@ export interface AgentSession {
|
|
|
6
6
|
agentId: string;
|
|
7
7
|
resourceId: string;
|
|
8
8
|
title: string;
|
|
9
|
+
created_by: string;
|
|
10
|
+
rights_mode: 'private' | 'users' | 'roles' | 'public' | 'project'
|
|
11
|
+
RBAC?: {
|
|
12
|
+
type?: string;
|
|
13
|
+
users?: Array<{ id: string; rights: 'read' | 'write' }>;
|
|
14
|
+
roles?: Array<{ id: string; rights: 'read' | 'write' }>;
|
|
15
|
+
};
|
|
9
16
|
}
|
|
10
17
|
export interface AgentMessage {
|
|
11
18
|
id: string;
|
package/types/models/agent.ts
CHANGED