@exulu/backend 1.62.1 → 1.63.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/dist/{catalog-BWE6SLE2.js → catalog-TBSPSN2N.js} +1 -1
- package/dist/{chunk-4TCN467I.js → chunk-IZOD2X2F.js} +88 -11
- package/dist/{chunk-ILAHW4UT.js → chunk-YCE44CMU.js} +14 -2
- package/dist/{convert-exulu-tools-to-ai-sdk-tools-FZ4ZCVBZ.js → convert-exulu-tools-to-ai-sdk-tools-THDKPKF3.js} +1 -1
- package/dist/index.cjs +183 -42
- package/dist/index.d.cts +17 -10
- package/dist/index.d.ts +17 -10
- package/dist/index.js +84 -32
- package/ee/rbac-resolver.ts +9 -1
- package/ee/rbac-update.ts +32 -1
- package/ee/schemas.ts +25 -0
- package/ee/workers.ts +1 -1
- package/package.json +1 -1
|
@@ -164,6 +164,7 @@ var checkRecordAccess = async (record, request, user) => {
|
|
|
164
164
|
const isPublic = record.rights_mode === "public";
|
|
165
165
|
const byUsers = record.rights_mode === "users";
|
|
166
166
|
const byRoles = record.rights_mode === "roles";
|
|
167
|
+
const byTeams = record.rights_mode === "teams";
|
|
167
168
|
const createdBy = typeof record.created_by === "string" ? record.created_by : record.created_by?.toString();
|
|
168
169
|
const isCreator = user ? createdBy === user.id.toString() : false;
|
|
169
170
|
const isAdmin = user ? user.super_admin : false;
|
|
@@ -209,6 +210,23 @@ var checkRecordAccess = async (record, request, user) => {
|
|
|
209
210
|
return true;
|
|
210
211
|
}
|
|
211
212
|
}
|
|
213
|
+
if (byTeams) {
|
|
214
|
+
if (!user) {
|
|
215
|
+
setRecordAccessCache(false);
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
hasAccess = record.RBAC?.teams?.find((x) => x.id === user.team?.id)?.rights || "none";
|
|
219
|
+
if (!hasAccess || hasAccess === "none" || hasAccess !== request) {
|
|
220
|
+
console.error(
|
|
221
|
+
`[EXULU] Your current team ${user.team?.name} does not have access to this record, current access type is: ${hasAccess}.`
|
|
222
|
+
);
|
|
223
|
+
setRecordAccessCache(false);
|
|
224
|
+
return false;
|
|
225
|
+
} else {
|
|
226
|
+
setRecordAccessCache(true);
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
212
230
|
setRecordAccessCache(false);
|
|
213
231
|
return false;
|
|
214
232
|
};
|
|
@@ -468,6 +486,12 @@ function buildTags(input) {
|
|
|
468
486
|
if (input.agent_name) {
|
|
469
487
|
candidates.push("agent_name_" + input.agent_name);
|
|
470
488
|
}
|
|
489
|
+
if (input.team_id) {
|
|
490
|
+
candidates.push("team_id_" + input.team_id);
|
|
491
|
+
}
|
|
492
|
+
if (input.team_name) {
|
|
493
|
+
candidates.push("team_name_" + input.team_name);
|
|
494
|
+
}
|
|
471
495
|
console.log("[EXULU] Candidates", candidates);
|
|
472
496
|
const out = [];
|
|
473
497
|
for (const candidate of candidates) {
|
|
@@ -571,17 +595,24 @@ var getLiteLLMProvider = ({
|
|
|
571
595
|
user,
|
|
572
596
|
role,
|
|
573
597
|
project,
|
|
574
|
-
agent
|
|
598
|
+
agent,
|
|
599
|
+
team
|
|
575
600
|
}) => {
|
|
576
601
|
if (_litellmProvider) return _litellmProvider;
|
|
577
602
|
const host = process.env.LITELLM_HOST ?? "127.0.0.1";
|
|
578
603
|
const port = process.env.LITELLM_PORT ?? "4000";
|
|
579
604
|
const masterKey = process.env.LITELLM_MASTER_KEY;
|
|
580
605
|
const tags = buildTags({
|
|
581
|
-
user,
|
|
582
|
-
role,
|
|
583
|
-
project,
|
|
584
|
-
agent
|
|
606
|
+
user_id: user?.id,
|
|
607
|
+
role_id: role?.id,
|
|
608
|
+
project_id: project?.id,
|
|
609
|
+
agent_id: agent?.id,
|
|
610
|
+
user_name: !user ? void 0 : user.type === "api" ? user.firstname ?? user.email : user.email,
|
|
611
|
+
role_name: role?.name,
|
|
612
|
+
project_name: project?.name,
|
|
613
|
+
agent_name: agent?.name,
|
|
614
|
+
team_id: team?.id,
|
|
615
|
+
team_name: team?.name
|
|
585
616
|
});
|
|
586
617
|
if (!masterKey) {
|
|
587
618
|
throw new ResolveModelError(
|
|
@@ -620,10 +651,11 @@ async function resolveModel(input) {
|
|
|
620
651
|
);
|
|
621
652
|
}
|
|
622
653
|
const litellm = getLiteLLMProvider({
|
|
623
|
-
user
|
|
624
|
-
role: user?.role
|
|
625
|
-
project
|
|
626
|
-
agent
|
|
654
|
+
user,
|
|
655
|
+
role: user?.role,
|
|
656
|
+
project,
|
|
657
|
+
agent,
|
|
658
|
+
team: user?.team
|
|
627
659
|
});
|
|
628
660
|
const languageModel2 = litellm(modelId);
|
|
629
661
|
const syntheticModel = {
|
|
@@ -765,12 +797,12 @@ var ExuluTool = class {
|
|
|
765
797
|
modelId: agent.model,
|
|
766
798
|
user,
|
|
767
799
|
providers,
|
|
768
|
-
agent
|
|
800
|
+
agent,
|
|
769
801
|
rbacBypass: true
|
|
770
802
|
});
|
|
771
803
|
providerapikey = resolved.apiKey;
|
|
772
804
|
}
|
|
773
|
-
const { convertExuluToolsToAiSdkTools: convertExuluToolsToAiSdkTools2 } = await import("./convert-exulu-tools-to-ai-sdk-tools-
|
|
805
|
+
const { convertExuluToolsToAiSdkTools: convertExuluToolsToAiSdkTools2 } = await import("./convert-exulu-tools-to-ai-sdk-tools-THDKPKF3.js");
|
|
774
806
|
const tools = await convertExuluToolsToAiSdkTools2(
|
|
775
807
|
[this],
|
|
776
808
|
[],
|
|
@@ -1233,6 +1265,12 @@ var authentication = async ({
|
|
|
1233
1265
|
user.role = role;
|
|
1234
1266
|
}
|
|
1235
1267
|
}
|
|
1268
|
+
if (user?.team) {
|
|
1269
|
+
const team = await db2.from("teams").select("*").where("id", user?.team).first();
|
|
1270
|
+
if (team) {
|
|
1271
|
+
user.team = team;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1236
1274
|
if (!user) {
|
|
1237
1275
|
return {
|
|
1238
1276
|
error: true,
|
|
@@ -2334,6 +2372,16 @@ var applyAccessControl = (table, query, user, field_prefix) => {
|
|
|
2334
2372
|
});
|
|
2335
2373
|
});
|
|
2336
2374
|
}
|
|
2375
|
+
if (user?.team) {
|
|
2376
|
+
const userTeamId = user.team.id;
|
|
2377
|
+
this.orWhere(function() {
|
|
2378
|
+
this.where(`${prefix}rights_mode`, "teams").whereExists(function() {
|
|
2379
|
+
this.select("*").from("rbac").whereRaw(
|
|
2380
|
+
"rbac.target_resource_id = " + (prefix ? prefix.slice(0, -1) : tableNamePlural) + ".id"
|
|
2381
|
+
).where("rbac.entity", table.name.singular).where("rbac.access_type", "Team").where("rbac.team_id", userTeamId);
|
|
2382
|
+
});
|
|
2383
|
+
});
|
|
2384
|
+
}
|
|
2337
2385
|
});
|
|
2338
2386
|
} catch (error) {
|
|
2339
2387
|
console.error("Access control error:", error);
|
|
@@ -2546,6 +2594,26 @@ var rolesSchema = {
|
|
|
2546
2594
|
}
|
|
2547
2595
|
]
|
|
2548
2596
|
};
|
|
2597
|
+
var teamsSchema = {
|
|
2598
|
+
type: "teams",
|
|
2599
|
+
name: {
|
|
2600
|
+
plural: "teams",
|
|
2601
|
+
singular: "team"
|
|
2602
|
+
},
|
|
2603
|
+
fields: [
|
|
2604
|
+
{
|
|
2605
|
+
name: "name",
|
|
2606
|
+
type: "text",
|
|
2607
|
+
index: true,
|
|
2608
|
+
unique: true,
|
|
2609
|
+
required: true
|
|
2610
|
+
},
|
|
2611
|
+
{
|
|
2612
|
+
name: "description",
|
|
2613
|
+
type: "text"
|
|
2614
|
+
}
|
|
2615
|
+
]
|
|
2616
|
+
};
|
|
2549
2617
|
var statisticsSchema = {
|
|
2550
2618
|
type: "tracking",
|
|
2551
2619
|
name: {
|
|
@@ -2766,6 +2834,10 @@ var rbacSchema = {
|
|
|
2766
2834
|
name: "role_id",
|
|
2767
2835
|
type: "uuid"
|
|
2768
2836
|
},
|
|
2837
|
+
{
|
|
2838
|
+
name: "team_id",
|
|
2839
|
+
type: "uuid"
|
|
2840
|
+
},
|
|
2769
2841
|
{
|
|
2770
2842
|
name: "user_id",
|
|
2771
2843
|
type: "number"
|
|
@@ -3224,6 +3296,10 @@ var usersSchema = {
|
|
|
3224
3296
|
{
|
|
3225
3297
|
name: "role",
|
|
3226
3298
|
type: "uuid"
|
|
3299
|
+
},
|
|
3300
|
+
{
|
|
3301
|
+
name: "team",
|
|
3302
|
+
type: "uuid"
|
|
3227
3303
|
}
|
|
3228
3304
|
]
|
|
3229
3305
|
};
|
|
@@ -3502,6 +3578,7 @@ var coreSchemas = {
|
|
|
3502
3578
|
}
|
|
3503
3579
|
if (license["rbac"]) {
|
|
3504
3580
|
schemas.rolesSchema = () => addCoreFields(rolesSchema);
|
|
3581
|
+
schemas.teamsSchema = () => addCoreFields(teamsSchema);
|
|
3505
3582
|
schemas.rbacSchema = () => addCoreFields(rbacSchema);
|
|
3506
3583
|
}
|
|
3507
3584
|
if (license["evals"]) {
|
|
@@ -35,6 +35,8 @@ var fetchLiteLLMCatalog = async () => {
|
|
|
35
35
|
region: m.model_info?.region ?? null,
|
|
36
36
|
max_tokens: m.model_info?.max_tokens ?? null,
|
|
37
37
|
max_input_tokens: m.model_info?.max_input_tokens ?? null,
|
|
38
|
+
input_cost_per_million_tokens: m.model_info?.input_cost_per_token * 1e6,
|
|
39
|
+
output_cost_per_million_tokens: m.model_info?.output_cost_per_token * 1e6,
|
|
38
40
|
active: m.model_info?.active ?? true,
|
|
39
41
|
max_output_tokens: m.model_info?.max_output_tokens ?? null,
|
|
40
42
|
supports_vision: !!m.model_info?.supports_vision,
|
|
@@ -46,8 +48,18 @@ var fetchLiteLLMCatalog = async () => {
|
|
|
46
48
|
supports_edit: !!m.model_info?.supports_edit,
|
|
47
49
|
max_n: typeof m.model_info?.max_n === "number" ? m.model_info.max_n : null
|
|
48
50
|
}));
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const map = /* @__PURE__ */ new Map();
|
|
52
|
+
for (const item of items) {
|
|
53
|
+
const key = `${item.model_name}-${item.upstream_model}`;
|
|
54
|
+
if (map.has(key)) {
|
|
55
|
+
map.get(key).tags.push(...item.tags);
|
|
56
|
+
} else {
|
|
57
|
+
map.set(key, item);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const uniqueItems = Array.from(map.values());
|
|
61
|
+
_cache = { expiresAt: Date.now() + CACHE_TTL_MS, items: uniqueItems };
|
|
62
|
+
return uniqueItems.filter((m) => m.type !== "speech_to_text" && m.type !== "text_to_speech");
|
|
51
63
|
} catch (err) {
|
|
52
64
|
console.error("[EXULU] litellmCatalog: failed to fetch /model/info:", err);
|
|
53
65
|
return [];
|
package/dist/index.cjs
CHANGED
|
@@ -267,6 +267,12 @@ var init_auth = __esm({
|
|
|
267
267
|
user.role = role;
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
+
if (user?.team) {
|
|
271
|
+
const team = await db2.from("teams").select("*").where("id", user?.team).first();
|
|
272
|
+
if (team) {
|
|
273
|
+
user.team = team;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
270
276
|
if (!user) {
|
|
271
277
|
return {
|
|
272
278
|
error: true,
|
|
@@ -637,6 +643,7 @@ var init_check_record_access = __esm({
|
|
|
637
643
|
const isPublic = record.rights_mode === "public";
|
|
638
644
|
const byUsers = record.rights_mode === "users";
|
|
639
645
|
const byRoles = record.rights_mode === "roles";
|
|
646
|
+
const byTeams = record.rights_mode === "teams";
|
|
640
647
|
const createdBy = typeof record.created_by === "string" ? record.created_by : record.created_by?.toString();
|
|
641
648
|
const isCreator = user ? createdBy === user.id.toString() : false;
|
|
642
649
|
const isAdmin = user ? user.super_admin : false;
|
|
@@ -682,6 +689,23 @@ var init_check_record_access = __esm({
|
|
|
682
689
|
return true;
|
|
683
690
|
}
|
|
684
691
|
}
|
|
692
|
+
if (byTeams) {
|
|
693
|
+
if (!user) {
|
|
694
|
+
setRecordAccessCache(false);
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
hasAccess = record.RBAC?.teams?.find((x) => x.id === user.team?.id)?.rights || "none";
|
|
698
|
+
if (!hasAccess || hasAccess === "none" || hasAccess !== request2) {
|
|
699
|
+
console.error(
|
|
700
|
+
`[EXULU] Your current team ${user.team?.name} does not have access to this record, current access type is: ${hasAccess}.`
|
|
701
|
+
);
|
|
702
|
+
setRecordAccessCache(false);
|
|
703
|
+
return false;
|
|
704
|
+
} else {
|
|
705
|
+
setRecordAccessCache(true);
|
|
706
|
+
return true;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
685
709
|
setRecordAccessCache(false);
|
|
686
710
|
return false;
|
|
687
711
|
};
|
|
@@ -784,6 +808,12 @@ function buildTags(input) {
|
|
|
784
808
|
if (input.agent_name) {
|
|
785
809
|
candidates.push("agent_name_" + input.agent_name);
|
|
786
810
|
}
|
|
811
|
+
if (input.team_id) {
|
|
812
|
+
candidates.push("team_id_" + input.team_id);
|
|
813
|
+
}
|
|
814
|
+
if (input.team_name) {
|
|
815
|
+
candidates.push("team_name_" + input.team_name);
|
|
816
|
+
}
|
|
787
817
|
console.log("[EXULU] Candidates", candidates);
|
|
788
818
|
const out = [];
|
|
789
819
|
for (const candidate of candidates) {
|
|
@@ -881,10 +911,11 @@ async function resolveModel(input) {
|
|
|
881
911
|
);
|
|
882
912
|
}
|
|
883
913
|
const litellm = getLiteLLMProvider({
|
|
884
|
-
user
|
|
885
|
-
role: user?.role
|
|
886
|
-
project
|
|
887
|
-
agent
|
|
914
|
+
user,
|
|
915
|
+
role: user?.role,
|
|
916
|
+
project,
|
|
917
|
+
agent,
|
|
918
|
+
team: user?.team
|
|
888
919
|
});
|
|
889
920
|
const languageModel2 = litellm(modelId);
|
|
890
921
|
const syntheticModel = {
|
|
@@ -996,17 +1027,24 @@ var init_resolve_model = __esm({
|
|
|
996
1027
|
user,
|
|
997
1028
|
role,
|
|
998
1029
|
project,
|
|
999
|
-
agent
|
|
1030
|
+
agent,
|
|
1031
|
+
team
|
|
1000
1032
|
}) => {
|
|
1001
1033
|
if (_litellmProvider) return _litellmProvider;
|
|
1002
1034
|
const host = process.env.LITELLM_HOST ?? "127.0.0.1";
|
|
1003
1035
|
const port = process.env.LITELLM_PORT ?? "4000";
|
|
1004
1036
|
const masterKey = process.env.LITELLM_MASTER_KEY;
|
|
1005
1037
|
const tags = buildTags({
|
|
1006
|
-
user,
|
|
1007
|
-
role,
|
|
1008
|
-
project,
|
|
1009
|
-
agent
|
|
1038
|
+
user_id: user?.id,
|
|
1039
|
+
role_id: role?.id,
|
|
1040
|
+
project_id: project?.id,
|
|
1041
|
+
agent_id: agent?.id,
|
|
1042
|
+
user_name: !user ? void 0 : user.type === "api" ? user.firstname ?? user.email : user.email,
|
|
1043
|
+
role_name: role?.name,
|
|
1044
|
+
project_name: project?.name,
|
|
1045
|
+
agent_name: agent?.name,
|
|
1046
|
+
team_id: team?.id,
|
|
1047
|
+
team_name: team?.name
|
|
1010
1048
|
});
|
|
1011
1049
|
if (!masterKey) {
|
|
1012
1050
|
throw new ResolveModelError(
|
|
@@ -3328,7 +3366,7 @@ var init_tool = __esm({
|
|
|
3328
3366
|
modelId: agent.model,
|
|
3329
3367
|
user,
|
|
3330
3368
|
providers,
|
|
3331
|
-
agent
|
|
3369
|
+
agent,
|
|
3332
3370
|
rbacBypass: true
|
|
3333
3371
|
});
|
|
3334
3372
|
providerapikey = resolved.apiKey;
|
|
@@ -3698,6 +3736,16 @@ var init_access_control = __esm({
|
|
|
3698
3736
|
});
|
|
3699
3737
|
});
|
|
3700
3738
|
}
|
|
3739
|
+
if (user?.team) {
|
|
3740
|
+
const userTeamId = user.team.id;
|
|
3741
|
+
this.orWhere(function() {
|
|
3742
|
+
this.where(`${prefix}rights_mode`, "teams").whereExists(function() {
|
|
3743
|
+
this.select("*").from("rbac").whereRaw(
|
|
3744
|
+
"rbac.target_resource_id = " + (prefix ? prefix.slice(0, -1) : tableNamePlural) + ".id"
|
|
3745
|
+
).where("rbac.entity", table.name.singular).where("rbac.access_type", "Team").where("rbac.team_id", userTeamId);
|
|
3746
|
+
});
|
|
3747
|
+
});
|
|
3748
|
+
}
|
|
3701
3749
|
});
|
|
3702
3750
|
} catch (error) {
|
|
3703
3751
|
console.error("Access control error:", error);
|
|
@@ -3840,7 +3888,7 @@ var init_vector_methods = __esm({
|
|
|
3840
3888
|
});
|
|
3841
3889
|
|
|
3842
3890
|
// ee/schemas.ts
|
|
3843
|
-
var feedbackSchema, rolesSchema, statisticsSchema, testCasesSchema, evalSetsSchema, jobResultsSchema, evalRunsSchema, rbacSchema, workflowTemplatesSchema;
|
|
3891
|
+
var feedbackSchema, rolesSchema, teamsSchema, statisticsSchema, testCasesSchema, evalSetsSchema, jobResultsSchema, evalRunsSchema, rbacSchema, workflowTemplatesSchema;
|
|
3844
3892
|
var init_schemas = __esm({
|
|
3845
3893
|
"ee/schemas.ts"() {
|
|
3846
3894
|
"use strict";
|
|
@@ -3924,6 +3972,26 @@ var init_schemas = __esm({
|
|
|
3924
3972
|
}
|
|
3925
3973
|
]
|
|
3926
3974
|
};
|
|
3975
|
+
teamsSchema = {
|
|
3976
|
+
type: "teams",
|
|
3977
|
+
name: {
|
|
3978
|
+
plural: "teams",
|
|
3979
|
+
singular: "team"
|
|
3980
|
+
},
|
|
3981
|
+
fields: [
|
|
3982
|
+
{
|
|
3983
|
+
name: "name",
|
|
3984
|
+
type: "text",
|
|
3985
|
+
index: true,
|
|
3986
|
+
unique: true,
|
|
3987
|
+
required: true
|
|
3988
|
+
},
|
|
3989
|
+
{
|
|
3990
|
+
name: "description",
|
|
3991
|
+
type: "text"
|
|
3992
|
+
}
|
|
3993
|
+
]
|
|
3994
|
+
};
|
|
3927
3995
|
statisticsSchema = {
|
|
3928
3996
|
type: "tracking",
|
|
3929
3997
|
name: {
|
|
@@ -4144,6 +4212,10 @@ var init_schemas = __esm({
|
|
|
4144
4212
|
name: "role_id",
|
|
4145
4213
|
type: "uuid"
|
|
4146
4214
|
},
|
|
4215
|
+
{
|
|
4216
|
+
name: "team_id",
|
|
4217
|
+
type: "uuid"
|
|
4218
|
+
},
|
|
4147
4219
|
{
|
|
4148
4220
|
name: "user_id",
|
|
4149
4221
|
type: "number"
|
|
@@ -4611,6 +4683,10 @@ var init_core_schema = __esm({
|
|
|
4611
4683
|
{
|
|
4612
4684
|
name: "role",
|
|
4613
4685
|
type: "uuid"
|
|
4686
|
+
},
|
|
4687
|
+
{
|
|
4688
|
+
name: "team",
|
|
4689
|
+
type: "uuid"
|
|
4614
4690
|
}
|
|
4615
4691
|
]
|
|
4616
4692
|
};
|
|
@@ -4889,6 +4965,7 @@ var init_core_schema = __esm({
|
|
|
4889
4965
|
}
|
|
4890
4966
|
if (license["rbac"]) {
|
|
4891
4967
|
schemas.rolesSchema = () => addCoreFields(rolesSchema);
|
|
4968
|
+
schemas.teamsSchema = () => addCoreFields(teamsSchema);
|
|
4892
4969
|
schemas.rbacSchema = () => addCoreFields(rbacSchema);
|
|
4893
4970
|
}
|
|
4894
4971
|
if (license["evals"]) {
|
|
@@ -7779,6 +7856,8 @@ var init_catalog = __esm({
|
|
|
7779
7856
|
region: m.model_info?.region ?? null,
|
|
7780
7857
|
max_tokens: m.model_info?.max_tokens ?? null,
|
|
7781
7858
|
max_input_tokens: m.model_info?.max_input_tokens ?? null,
|
|
7859
|
+
input_cost_per_million_tokens: m.model_info?.input_cost_per_token * 1e6,
|
|
7860
|
+
output_cost_per_million_tokens: m.model_info?.output_cost_per_token * 1e6,
|
|
7782
7861
|
active: m.model_info?.active ?? true,
|
|
7783
7862
|
max_output_tokens: m.model_info?.max_output_tokens ?? null,
|
|
7784
7863
|
supports_vision: !!m.model_info?.supports_vision,
|
|
@@ -7790,8 +7869,18 @@ var init_catalog = __esm({
|
|
|
7790
7869
|
supports_edit: !!m.model_info?.supports_edit,
|
|
7791
7870
|
max_n: typeof m.model_info?.max_n === "number" ? m.model_info.max_n : null
|
|
7792
7871
|
}));
|
|
7793
|
-
|
|
7794
|
-
|
|
7872
|
+
const map = /* @__PURE__ */ new Map();
|
|
7873
|
+
for (const item of items) {
|
|
7874
|
+
const key2 = `${item.model_name}-${item.upstream_model}`;
|
|
7875
|
+
if (map.has(key2)) {
|
|
7876
|
+
map.get(key2).tags.push(...item.tags);
|
|
7877
|
+
} else {
|
|
7878
|
+
map.set(key2, item);
|
|
7879
|
+
}
|
|
7880
|
+
}
|
|
7881
|
+
const uniqueItems = Array.from(map.values());
|
|
7882
|
+
_cache = { expiresAt: Date.now() + CACHE_TTL_MS2, items: uniqueItems };
|
|
7883
|
+
return uniqueItems.filter((m) => m.type !== "speech_to_text" && m.type !== "text_to_speech");
|
|
7795
7884
|
} catch (err) {
|
|
7796
7885
|
console.error("[EXULU] litellmCatalog: failed to fetch /model/info:", err);
|
|
7797
7886
|
return [];
|
|
@@ -8313,7 +8402,8 @@ var RBACResolver = async (db2, entityName, resourceId, rights_mode) => {
|
|
|
8313
8402
|
return {
|
|
8314
8403
|
type: "public",
|
|
8315
8404
|
users: [],
|
|
8316
|
-
roles: []
|
|
8405
|
+
roles: [],
|
|
8406
|
+
teams: []
|
|
8317
8407
|
};
|
|
8318
8408
|
}
|
|
8319
8409
|
const rbacRecords = await db2.from("rbac").where({
|
|
@@ -8322,13 +8412,16 @@ var RBACResolver = async (db2, entityName, resourceId, rights_mode) => {
|
|
|
8322
8412
|
}).select("*");
|
|
8323
8413
|
const users = rbacRecords.filter((r) => r.access_type === "User")?.map((r) => ({ id: r.user_id, rights: r.rights }));
|
|
8324
8414
|
const roles = rbacRecords.filter((r) => r.access_type === "Role")?.map((r) => ({ id: r.role_id, rights: r.rights }));
|
|
8415
|
+
const teams = rbacRecords.filter((r) => r.access_type === "Team")?.map((r) => ({ id: r.team_id, rights: r.rights }));
|
|
8325
8416
|
let type = rights_mode || "private";
|
|
8326
8417
|
if (type === "users" && users.length === 0) type = "private";
|
|
8327
8418
|
if (type === "roles" && roles.length === 0) type = "private";
|
|
8419
|
+
if (type === "teams" && teams.length === 0) type = "private";
|
|
8328
8420
|
return {
|
|
8329
8421
|
type,
|
|
8330
8422
|
users,
|
|
8331
|
-
roles
|
|
8423
|
+
roles,
|
|
8424
|
+
teams
|
|
8332
8425
|
};
|
|
8333
8426
|
};
|
|
8334
8427
|
|
|
@@ -9085,7 +9178,8 @@ var handleRBACUpdate = async (db2, entityName, resourceId, rbacData, existingRba
|
|
|
9085
9178
|
}
|
|
9086
9179
|
const {
|
|
9087
9180
|
users = [],
|
|
9088
|
-
roles = []
|
|
9181
|
+
roles = [],
|
|
9182
|
+
teams = []
|
|
9089
9183
|
/* projects = [] */
|
|
9090
9184
|
} = rbacData;
|
|
9091
9185
|
if (!existingRbacRecords) {
|
|
@@ -9096,20 +9190,28 @@ var handleRBACUpdate = async (db2, entityName, resourceId, rbacData, existingRba
|
|
|
9096
9190
|
}
|
|
9097
9191
|
const newUserRecords = new Set(users.map((u) => `${u.id}:${u.rights}`));
|
|
9098
9192
|
const newRoleRecords = new Set(roles.map((r) => `${r.id}:${r.rights}`));
|
|
9193
|
+
const newTeamRecords = new Set(teams.map((t) => `${t.id}:${t.rights}`));
|
|
9099
9194
|
const existingUserRecords = new Set(
|
|
9100
9195
|
existingRbacRecords.filter((r) => r.access_type === "User").map((r) => `${r.user_id}:${r.rights}`)
|
|
9101
9196
|
);
|
|
9102
9197
|
const existingRoleRecords = new Set(
|
|
9103
9198
|
existingRbacRecords.filter((r) => r.access_type === "Role").map((r) => `${r.role_id}:${r.rights}`)
|
|
9104
9199
|
);
|
|
9200
|
+
const existingTeamRecords = new Set(
|
|
9201
|
+
existingRbacRecords.filter((r) => r.access_type === "Team").map((r) => `${r.team_id}:${r.rights}`)
|
|
9202
|
+
);
|
|
9105
9203
|
const usersToCreate = users.filter((u) => !existingUserRecords.has(`${u.id}:${u.rights}`));
|
|
9106
9204
|
const rolesToCreate = roles.filter((r) => !existingRoleRecords.has(`${r.id}:${r.rights}`));
|
|
9205
|
+
const teamsToCreate = teams.filter((t) => !existingTeamRecords.has(`${t.id}:${t.rights}`));
|
|
9107
9206
|
const usersToRemove = existingRbacRecords.filter(
|
|
9108
9207
|
(r) => r.access_type === "User" && !newUserRecords.has(`${r.user_id}:${r.rights}`)
|
|
9109
9208
|
);
|
|
9110
9209
|
const rolesToRemove = existingRbacRecords.filter(
|
|
9111
9210
|
(r) => r.access_type === "Role" && !newRoleRecords.has(`${r.role_id}:${r.rights}`)
|
|
9112
9211
|
);
|
|
9212
|
+
const teamsToRemove = existingRbacRecords.filter(
|
|
9213
|
+
(r) => r.access_type === "Team" && !newTeamRecords.has(`${r.team_id}:${r.rights}`)
|
|
9214
|
+
);
|
|
9113
9215
|
if (usersToRemove.length > 0) {
|
|
9114
9216
|
await db2.from("rbac").whereIn(
|
|
9115
9217
|
"id",
|
|
@@ -9122,6 +9224,12 @@ var handleRBACUpdate = async (db2, entityName, resourceId, rbacData, existingRba
|
|
|
9122
9224
|
rolesToRemove.map((r) => r.id)
|
|
9123
9225
|
).del();
|
|
9124
9226
|
}
|
|
9227
|
+
if (teamsToRemove.length > 0) {
|
|
9228
|
+
await db2.from("rbac").whereIn(
|
|
9229
|
+
"id",
|
|
9230
|
+
teamsToRemove.map((r) => r.id)
|
|
9231
|
+
).del();
|
|
9232
|
+
}
|
|
9125
9233
|
const recordsToInsert = [];
|
|
9126
9234
|
usersToCreate.forEach((user) => {
|
|
9127
9235
|
recordsToInsert.push({
|
|
@@ -9145,6 +9253,17 @@ var handleRBACUpdate = async (db2, entityName, resourceId, rbacData, existingRba
|
|
|
9145
9253
|
updatedAt: /* @__PURE__ */ new Date()
|
|
9146
9254
|
});
|
|
9147
9255
|
});
|
|
9256
|
+
teamsToCreate.forEach((team) => {
|
|
9257
|
+
recordsToInsert.push({
|
|
9258
|
+
entity: entityName,
|
|
9259
|
+
access_type: "Team",
|
|
9260
|
+
target_resource_id: resourceId,
|
|
9261
|
+
team_id: team.id,
|
|
9262
|
+
rights: team.rights,
|
|
9263
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
9264
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
9265
|
+
});
|
|
9266
|
+
});
|
|
9148
9267
|
if (recordsToInsert.length > 0) {
|
|
9149
9268
|
await db2.from("rbac").insert(recordsToInsert);
|
|
9150
9269
|
}
|
|
@@ -9343,6 +9462,19 @@ function createMutations(table, providers, contexts, rerankers, tools, config) {
|
|
|
9343
9462
|
}
|
|
9344
9463
|
throw new Error("Insufficient role permissions to edit this record");
|
|
9345
9464
|
}
|
|
9465
|
+
if (record.rights_mode === "teams" && user.team) {
|
|
9466
|
+
const rbacRecord = await db2.from("rbac").where({
|
|
9467
|
+
entity: table.name.singular,
|
|
9468
|
+
target_resource_id: id,
|
|
9469
|
+
access_type: "Team",
|
|
9470
|
+
team_id: user.team,
|
|
9471
|
+
rights: "write"
|
|
9472
|
+
}).first();
|
|
9473
|
+
if (rbacRecord) {
|
|
9474
|
+
return true;
|
|
9475
|
+
}
|
|
9476
|
+
throw new Error("Insufficient team permissions to edit this record");
|
|
9477
|
+
}
|
|
9346
9478
|
throw new Error("Insufficient permissions to edit this record");
|
|
9347
9479
|
} catch (error) {
|
|
9348
9480
|
console.error("Write access validation error:", error);
|
|
@@ -11046,7 +11178,7 @@ var processUiMessagesFlow = async ({
|
|
|
11046
11178
|
modelId: agent.model,
|
|
11047
11179
|
user,
|
|
11048
11180
|
providers,
|
|
11049
|
-
agent
|
|
11181
|
+
agent
|
|
11050
11182
|
});
|
|
11051
11183
|
const providerapikey = resolved.apiKey;
|
|
11052
11184
|
const resolvedLanguageModel = resolved.languageModel;
|
|
@@ -12087,6 +12219,8 @@ type LiteLLMModel {
|
|
|
12087
12219
|
supports_function_calling: Boolean
|
|
12088
12220
|
supports_pdf_input: Boolean
|
|
12089
12221
|
supports_audio_input: Boolean
|
|
12222
|
+
input_cost_per_million_tokens: Float
|
|
12223
|
+
output_cost_per_million_tokens: Float
|
|
12090
12224
|
}
|
|
12091
12225
|
`;
|
|
12092
12226
|
resolvers.Query["agentRateLimitUsage"] = async (_, args, context) => {
|
|
@@ -13678,7 +13812,7 @@ var ExuluProvider = class {
|
|
|
13678
13812
|
modelId: agent.model,
|
|
13679
13813
|
user,
|
|
13680
13814
|
providers,
|
|
13681
|
-
agent
|
|
13815
|
+
agent
|
|
13682
13816
|
});
|
|
13683
13817
|
const providerapikey = resolved.apiKey;
|
|
13684
13818
|
console.log(
|
|
@@ -15386,7 +15520,7 @@ var registerOpenAIGatewayRoutes = async (app, providers, tools, contexts, config
|
|
|
15386
15520
|
});
|
|
15387
15521
|
return;
|
|
15388
15522
|
}
|
|
15389
|
-
let project =
|
|
15523
|
+
let project = void 0;
|
|
15390
15524
|
if (projectName) {
|
|
15391
15525
|
let projectQuery = db2("projects").select("*");
|
|
15392
15526
|
projectQuery = applyAccessControl(projectsSchema4(), projectQuery, user);
|
|
@@ -15409,8 +15543,8 @@ var registerOpenAIGatewayRoutes = async (app, providers, tools, contexts, config
|
|
|
15409
15543
|
modelId: agent.model,
|
|
15410
15544
|
user,
|
|
15411
15545
|
providers,
|
|
15412
|
-
agent
|
|
15413
|
-
project
|
|
15546
|
+
agent,
|
|
15547
|
+
project
|
|
15414
15548
|
});
|
|
15415
15549
|
} catch (err) {
|
|
15416
15550
|
if (err instanceof ResolveModelError) {
|
|
@@ -15587,6 +15721,7 @@ var {
|
|
|
15587
15721
|
rbacSchema: rbacSchema2,
|
|
15588
15722
|
promptLibrarySchema: promptLibrarySchema2,
|
|
15589
15723
|
contextPresetsSchema: contextPresetsSchema2,
|
|
15724
|
+
teamsSchema: teamsSchema2,
|
|
15590
15725
|
embedderSettingsSchema: embedderSettingsSchema2,
|
|
15591
15726
|
promptFavoritesSchema: promptFavoritesSchema2,
|
|
15592
15727
|
statisticsSchema: statisticsSchema2,
|
|
@@ -15636,6 +15771,7 @@ var createExpressRoutes = async (app, providers, tools, contexts, config, evals,
|
|
|
15636
15771
|
jobResultsSchema2(),
|
|
15637
15772
|
promptLibrarySchema2(),
|
|
15638
15773
|
contextPresetsSchema2(),
|
|
15774
|
+
teamsSchema2(),
|
|
15639
15775
|
embedderSettingsSchema2(),
|
|
15640
15776
|
promptFavoritesSchema2(),
|
|
15641
15777
|
evalRunsSchema2(),
|
|
@@ -16022,7 +16158,7 @@ Mood: friendly and intelligent.
|
|
|
16022
16158
|
modelId,
|
|
16023
16159
|
user,
|
|
16024
16160
|
providers,
|
|
16025
|
-
agent
|
|
16161
|
+
agent
|
|
16026
16162
|
});
|
|
16027
16163
|
} catch (err) {
|
|
16028
16164
|
if (err instanceof ResolveModelError) {
|
|
@@ -16283,7 +16419,7 @@ ${customInstructions}` : agent.instructions;
|
|
|
16283
16419
|
modelId: agent.model,
|
|
16284
16420
|
user,
|
|
16285
16421
|
providers,
|
|
16286
|
-
agent
|
|
16422
|
+
agent
|
|
16287
16423
|
});
|
|
16288
16424
|
} catch (err) {
|
|
16289
16425
|
if (err instanceof ResolveModelError) {
|
|
@@ -17095,7 +17231,9 @@ ${style.markdown}` : params.prompt;
|
|
|
17095
17231
|
project_id: project?.id,
|
|
17096
17232
|
user_name: user.email,
|
|
17097
17233
|
role_name: user.role?.name,
|
|
17098
|
-
project_name: project?.name
|
|
17234
|
+
project_name: project?.name,
|
|
17235
|
+
team_id: user.team?.id,
|
|
17236
|
+
team_name: user.team?.name
|
|
17099
17237
|
});
|
|
17100
17238
|
if (tags?.length) {
|
|
17101
17239
|
upstreamHeaders["x-litellm-tags"] = tags.join(",");
|
|
@@ -18140,7 +18278,7 @@ var ExuluMCP = class {
|
|
|
18140
18278
|
modelId: agent.model,
|
|
18141
18279
|
user,
|
|
18142
18280
|
providers: allProviders,
|
|
18143
|
-
agent
|
|
18281
|
+
agent
|
|
18144
18282
|
});
|
|
18145
18283
|
const providerapikey = resolved.apiKey;
|
|
18146
18284
|
if (!isLiteLLMEnabled()) {
|
|
@@ -19386,6 +19524,7 @@ var ExuluEval = class {
|
|
|
19386
19524
|
init_resolve_model();
|
|
19387
19525
|
init_singleton();
|
|
19388
19526
|
var import_zod14 = require("zod");
|
|
19527
|
+
var import_ai14 = require("ai");
|
|
19389
19528
|
var llmAsJudgeEval = () => {
|
|
19390
19529
|
if (process.env.REDIS_HOST?.length && process.env.REDIS_PORT?.length) {
|
|
19391
19530
|
return new ExuluEval({
|
|
@@ -19426,27 +19565,27 @@ var llmAsJudgeEval = () => {
|
|
|
19426
19565
|
const resolved = await resolveModel({
|
|
19427
19566
|
modelId: agent.model,
|
|
19428
19567
|
providers: exuluApp.get().providers,
|
|
19429
|
-
agent
|
|
19568
|
+
agent,
|
|
19430
19569
|
rbacBypass: true
|
|
19431
19570
|
});
|
|
19432
|
-
const providerapikey = resolved.apiKey;
|
|
19433
19571
|
console.log("[EXULU] prompt", prompt);
|
|
19434
|
-
const
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19572
|
+
const { output } = await (0, import_ai14.generateText)({
|
|
19573
|
+
temperature: 0,
|
|
19574
|
+
model: resolved.languageModel,
|
|
19575
|
+
system: "",
|
|
19438
19576
|
prompt,
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19577
|
+
maxRetries: 2,
|
|
19578
|
+
output: import_ai14.Output.object({
|
|
19579
|
+
schema: import_zod14.z.object({
|
|
19580
|
+
score: import_zod14.z.number().min(0).max(100).describe("The score between 0 and 100.")
|
|
19581
|
+
})
|
|
19582
|
+
})
|
|
19444
19583
|
});
|
|
19445
|
-
console.log("[EXULU]
|
|
19446
|
-
const score =
|
|
19584
|
+
console.log("[EXULU] output", output);
|
|
19585
|
+
const score = output.score;
|
|
19447
19586
|
if (isNaN(score)) {
|
|
19448
19587
|
throw new Error(
|
|
19449
|
-
`Generated score from llm as a judge eval is not a number: ${
|
|
19588
|
+
`Generated score from llm as a judge eval is not a number: ${output.score}`
|
|
19450
19589
|
);
|
|
19451
19590
|
}
|
|
19452
19591
|
return score;
|
|
@@ -22853,6 +22992,7 @@ var {
|
|
|
22853
22992
|
agentMessagesSchema: agentMessagesSchema3,
|
|
22854
22993
|
modelsSchema: modelsSchema3,
|
|
22855
22994
|
rolesSchema: rolesSchema3,
|
|
22995
|
+
teamsSchema: teamsSchema3,
|
|
22856
22996
|
usersSchema: usersSchema3,
|
|
22857
22997
|
skillsSchema: skillsSchema3,
|
|
22858
22998
|
statisticsSchema: statisticsSchema3,
|
|
@@ -22895,6 +23035,7 @@ var up = async function(knex) {
|
|
|
22895
23035
|
agentMessagesSchema3(),
|
|
22896
23036
|
modelsSchema3(),
|
|
22897
23037
|
rolesSchema3(),
|
|
23038
|
+
teamsSchema3(),
|
|
22898
23039
|
testCasesSchema3(),
|
|
22899
23040
|
evalSetsSchema3(),
|
|
22900
23041
|
evalRunsSchema3(),
|
|
@@ -23922,7 +24063,7 @@ var MarkdownChunker = class {
|
|
|
23922
24063
|
init_cjs_shims();
|
|
23923
24064
|
var fs5 = __toESM(require("fs"), 1);
|
|
23924
24065
|
var path2 = __toESM(require("path"), 1);
|
|
23925
|
-
var
|
|
24066
|
+
var import_ai15 = require("ai");
|
|
23926
24067
|
var import_zod22 = require("zod");
|
|
23927
24068
|
var import_p_limit = __toESM(require("p-limit"), 1);
|
|
23928
24069
|
var import_crypto = require("crypto");
|
|
@@ -24275,9 +24416,9 @@ If the page contains a flow-chart, schematic, technical drawing or control board
|
|
|
24275
24416
|
|
|
24276
24417
|
### 7. Only populate \`corrected_text\` when \`needs_correction\` is true. If the OCR output is accurate, return \`needs_correction: false\` and \`corrected_content: null\`.
|
|
24277
24418
|
`;
|
|
24278
|
-
const result = await (0,
|
|
24419
|
+
const result = await (0, import_ai15.generateText)({
|
|
24279
24420
|
model,
|
|
24280
|
-
output:
|
|
24421
|
+
output: import_ai15.Output.object({
|
|
24281
24422
|
schema: import_zod22.z.object({
|
|
24282
24423
|
needs_correction: import_zod22.z.boolean(),
|
|
24283
24424
|
corrected_text: import_zod22.z.string().nullable(),
|
package/dist/index.d.cts
CHANGED
|
@@ -24,15 +24,22 @@ type User = {
|
|
|
24
24
|
favourite_agents?: string[];
|
|
25
25
|
scope_mode?: ApiKeyScopeMode;
|
|
26
26
|
agent_ids?: string[];
|
|
27
|
-
role:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
role: UserRole;
|
|
28
|
+
team?: ExuluTeam;
|
|
29
|
+
};
|
|
30
|
+
type UserRole = {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
agents: "read" | "write";
|
|
34
|
+
evals: "read" | "write";
|
|
35
|
+
workflows: "read" | "write";
|
|
36
|
+
variables: "read" | "write";
|
|
37
|
+
users: "read" | "write";
|
|
38
|
+
};
|
|
39
|
+
type ExuluTeam = {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
description?: string;
|
|
36
43
|
};
|
|
37
44
|
|
|
38
45
|
declare function redisClient(): Promise<{
|
|
@@ -789,7 +796,7 @@ declare class ExuluProvider {
|
|
|
789
796
|
get providerName(): string;
|
|
790
797
|
get modelName(): string;
|
|
791
798
|
tool: (instance: string, providers: ExuluProvider[], contexts: ExuluContext[], rerankers: ExuluReranker[]) => Promise<ExuluTool | null>;
|
|
792
|
-
generateSync: ({ prompt, req, user, session, inputMessages, approvedTools, currentTools, currentSkills, allExuluTools, statistics, toolConfigs, providerapikey, languageModel, contexts, rerankers, exuluConfig, agent, instructions, maxStepCount, onTokenUsage
|
|
799
|
+
generateSync: ({ prompt, req, user, session, inputMessages, approvedTools, currentTools, currentSkills, allExuluTools, statistics, toolConfigs, providerapikey, languageModel, contexts, rerankers, exuluConfig, agent, instructions, maxStepCount, onTokenUsage }: {
|
|
793
800
|
prompt?: string;
|
|
794
801
|
user?: User;
|
|
795
802
|
maxStepCount?: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -24,15 +24,22 @@ type User = {
|
|
|
24
24
|
favourite_agents?: string[];
|
|
25
25
|
scope_mode?: ApiKeyScopeMode;
|
|
26
26
|
agent_ids?: string[];
|
|
27
|
-
role:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
role: UserRole;
|
|
28
|
+
team?: ExuluTeam;
|
|
29
|
+
};
|
|
30
|
+
type UserRole = {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
agents: "read" | "write";
|
|
34
|
+
evals: "read" | "write";
|
|
35
|
+
workflows: "read" | "write";
|
|
36
|
+
variables: "read" | "write";
|
|
37
|
+
users: "read" | "write";
|
|
38
|
+
};
|
|
39
|
+
type ExuluTeam = {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
description?: string;
|
|
36
43
|
};
|
|
37
44
|
|
|
38
45
|
declare function redisClient(): Promise<{
|
|
@@ -789,7 +796,7 @@ declare class ExuluProvider {
|
|
|
789
796
|
get providerName(): string;
|
|
790
797
|
get modelName(): string;
|
|
791
798
|
tool: (instance: string, providers: ExuluProvider[], contexts: ExuluContext[], rerankers: ExuluReranker[]) => Promise<ExuluTool | null>;
|
|
792
|
-
generateSync: ({ prompt, req, user, session, inputMessages, approvedTools, currentTools, currentSkills, allExuluTools, statistics, toolConfigs, providerapikey, languageModel, contexts, rerankers, exuluConfig, agent, instructions, maxStepCount, onTokenUsage
|
|
799
|
+
generateSync: ({ prompt, req, user, session, inputMessages, approvedTools, currentTools, currentSkills, allExuluTools, statistics, toolConfigs, providerapikey, languageModel, contexts, rerankers, exuluConfig, agent, instructions, maxStepCount, onTokenUsage }: {
|
|
793
800
|
prompt?: string;
|
|
794
801
|
user?: User;
|
|
795
802
|
maxStepCount?: number;
|
package/dist/index.js
CHANGED
|
@@ -53,10 +53,10 @@ import {
|
|
|
53
53
|
vectorSearch,
|
|
54
54
|
waitForLiteLLMReady,
|
|
55
55
|
withRetry
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-IZOD2X2F.js";
|
|
57
57
|
import {
|
|
58
58
|
findLiteLLMModel
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-YCE44CMU.js";
|
|
60
60
|
|
|
61
61
|
// src/index.ts
|
|
62
62
|
import "dotenv/config";
|
|
@@ -504,7 +504,8 @@ var RBACResolver = async (db, entityName, resourceId, rights_mode) => {
|
|
|
504
504
|
return {
|
|
505
505
|
type: "public",
|
|
506
506
|
users: [],
|
|
507
|
-
roles: []
|
|
507
|
+
roles: [],
|
|
508
|
+
teams: []
|
|
508
509
|
};
|
|
509
510
|
}
|
|
510
511
|
const rbacRecords = await db.from("rbac").where({
|
|
@@ -513,13 +514,16 @@ var RBACResolver = async (db, entityName, resourceId, rights_mode) => {
|
|
|
513
514
|
}).select("*");
|
|
514
515
|
const users = rbacRecords.filter((r) => r.access_type === "User")?.map((r) => ({ id: r.user_id, rights: r.rights }));
|
|
515
516
|
const roles = rbacRecords.filter((r) => r.access_type === "Role")?.map((r) => ({ id: r.role_id, rights: r.rights }));
|
|
517
|
+
const teams = rbacRecords.filter((r) => r.access_type === "Team")?.map((r) => ({ id: r.team_id, rights: r.rights }));
|
|
516
518
|
let type = rights_mode || "private";
|
|
517
519
|
if (type === "users" && users.length === 0) type = "private";
|
|
518
520
|
if (type === "roles" && roles.length === 0) type = "private";
|
|
521
|
+
if (type === "teams" && teams.length === 0) type = "private";
|
|
519
522
|
return {
|
|
520
523
|
type,
|
|
521
524
|
users,
|
|
522
|
-
roles
|
|
525
|
+
roles,
|
|
526
|
+
teams
|
|
523
527
|
};
|
|
524
528
|
};
|
|
525
529
|
|
|
@@ -1233,7 +1237,8 @@ var handleRBACUpdate = async (db, entityName, resourceId, rbacData, existingRbac
|
|
|
1233
1237
|
}
|
|
1234
1238
|
const {
|
|
1235
1239
|
users = [],
|
|
1236
|
-
roles = []
|
|
1240
|
+
roles = [],
|
|
1241
|
+
teams = []
|
|
1237
1242
|
/* projects = [] */
|
|
1238
1243
|
} = rbacData;
|
|
1239
1244
|
if (!existingRbacRecords) {
|
|
@@ -1244,20 +1249,28 @@ var handleRBACUpdate = async (db, entityName, resourceId, rbacData, existingRbac
|
|
|
1244
1249
|
}
|
|
1245
1250
|
const newUserRecords = new Set(users.map((u) => `${u.id}:${u.rights}`));
|
|
1246
1251
|
const newRoleRecords = new Set(roles.map((r) => `${r.id}:${r.rights}`));
|
|
1252
|
+
const newTeamRecords = new Set(teams.map((t) => `${t.id}:${t.rights}`));
|
|
1247
1253
|
const existingUserRecords = new Set(
|
|
1248
1254
|
existingRbacRecords.filter((r) => r.access_type === "User").map((r) => `${r.user_id}:${r.rights}`)
|
|
1249
1255
|
);
|
|
1250
1256
|
const existingRoleRecords = new Set(
|
|
1251
1257
|
existingRbacRecords.filter((r) => r.access_type === "Role").map((r) => `${r.role_id}:${r.rights}`)
|
|
1252
1258
|
);
|
|
1259
|
+
const existingTeamRecords = new Set(
|
|
1260
|
+
existingRbacRecords.filter((r) => r.access_type === "Team").map((r) => `${r.team_id}:${r.rights}`)
|
|
1261
|
+
);
|
|
1253
1262
|
const usersToCreate = users.filter((u) => !existingUserRecords.has(`${u.id}:${u.rights}`));
|
|
1254
1263
|
const rolesToCreate = roles.filter((r) => !existingRoleRecords.has(`${r.id}:${r.rights}`));
|
|
1264
|
+
const teamsToCreate = teams.filter((t) => !existingTeamRecords.has(`${t.id}:${t.rights}`));
|
|
1255
1265
|
const usersToRemove = existingRbacRecords.filter(
|
|
1256
1266
|
(r) => r.access_type === "User" && !newUserRecords.has(`${r.user_id}:${r.rights}`)
|
|
1257
1267
|
);
|
|
1258
1268
|
const rolesToRemove = existingRbacRecords.filter(
|
|
1259
1269
|
(r) => r.access_type === "Role" && !newRoleRecords.has(`${r.role_id}:${r.rights}`)
|
|
1260
1270
|
);
|
|
1271
|
+
const teamsToRemove = existingRbacRecords.filter(
|
|
1272
|
+
(r) => r.access_type === "Team" && !newTeamRecords.has(`${r.team_id}:${r.rights}`)
|
|
1273
|
+
);
|
|
1261
1274
|
if (usersToRemove.length > 0) {
|
|
1262
1275
|
await db.from("rbac").whereIn(
|
|
1263
1276
|
"id",
|
|
@@ -1270,6 +1283,12 @@ var handleRBACUpdate = async (db, entityName, resourceId, rbacData, existingRbac
|
|
|
1270
1283
|
rolesToRemove.map((r) => r.id)
|
|
1271
1284
|
).del();
|
|
1272
1285
|
}
|
|
1286
|
+
if (teamsToRemove.length > 0) {
|
|
1287
|
+
await db.from("rbac").whereIn(
|
|
1288
|
+
"id",
|
|
1289
|
+
teamsToRemove.map((r) => r.id)
|
|
1290
|
+
).del();
|
|
1291
|
+
}
|
|
1273
1292
|
const recordsToInsert = [];
|
|
1274
1293
|
usersToCreate.forEach((user) => {
|
|
1275
1294
|
recordsToInsert.push({
|
|
@@ -1293,6 +1312,17 @@ var handleRBACUpdate = async (db, entityName, resourceId, rbacData, existingRbac
|
|
|
1293
1312
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1294
1313
|
});
|
|
1295
1314
|
});
|
|
1315
|
+
teamsToCreate.forEach((team) => {
|
|
1316
|
+
recordsToInsert.push({
|
|
1317
|
+
entity: entityName,
|
|
1318
|
+
access_type: "Team",
|
|
1319
|
+
target_resource_id: resourceId,
|
|
1320
|
+
team_id: team.id,
|
|
1321
|
+
rights: team.rights,
|
|
1322
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1323
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1296
1326
|
if (recordsToInsert.length > 0) {
|
|
1297
1327
|
await db.from("rbac").insert(recordsToInsert);
|
|
1298
1328
|
}
|
|
@@ -1491,6 +1521,19 @@ function createMutations(table, providers, contexts, rerankers, tools, config) {
|
|
|
1491
1521
|
}
|
|
1492
1522
|
throw new Error("Insufficient role permissions to edit this record");
|
|
1493
1523
|
}
|
|
1524
|
+
if (record.rights_mode === "teams" && user.team) {
|
|
1525
|
+
const rbacRecord = await db.from("rbac").where({
|
|
1526
|
+
entity: table.name.singular,
|
|
1527
|
+
target_resource_id: id,
|
|
1528
|
+
access_type: "Team",
|
|
1529
|
+
team_id: user.team,
|
|
1530
|
+
rights: "write"
|
|
1531
|
+
}).first();
|
|
1532
|
+
if (rbacRecord) {
|
|
1533
|
+
return true;
|
|
1534
|
+
}
|
|
1535
|
+
throw new Error("Insufficient team permissions to edit this record");
|
|
1536
|
+
}
|
|
1494
1537
|
throw new Error("Insufficient permissions to edit this record");
|
|
1495
1538
|
} catch (error) {
|
|
1496
1539
|
console.error("Write access validation error:", error);
|
|
@@ -3177,7 +3220,7 @@ var processUiMessagesFlow = async ({
|
|
|
3177
3220
|
modelId: agent.model,
|
|
3178
3221
|
user,
|
|
3179
3222
|
providers,
|
|
3180
|
-
agent
|
|
3223
|
+
agent
|
|
3181
3224
|
});
|
|
3182
3225
|
const providerapikey = resolved.apiKey;
|
|
3183
3226
|
const resolvedLanguageModel = resolved.languageModel;
|
|
@@ -4209,6 +4252,8 @@ type LiteLLMModel {
|
|
|
4209
4252
|
supports_function_calling: Boolean
|
|
4210
4253
|
supports_pdf_input: Boolean
|
|
4211
4254
|
supports_audio_input: Boolean
|
|
4255
|
+
input_cost_per_million_tokens: Float
|
|
4256
|
+
output_cost_per_million_tokens: Float
|
|
4212
4257
|
}
|
|
4213
4258
|
`;
|
|
4214
4259
|
resolvers.Query["agentRateLimitUsage"] = async (_, args, context) => {
|
|
@@ -4264,7 +4309,7 @@ type LiteLLMModel {
|
|
|
4264
4309
|
};
|
|
4265
4310
|
};
|
|
4266
4311
|
resolvers.Query["litellmCatalog"] = async () => {
|
|
4267
|
-
const { fetchLiteLLMCatalog } = await import("./catalog-
|
|
4312
|
+
const { fetchLiteLLMCatalog } = await import("./catalog-TBSPSN2N.js");
|
|
4268
4313
|
return fetchLiteLLMCatalog();
|
|
4269
4314
|
};
|
|
4270
4315
|
resolvers.Query["workflowSchedule"] = async (_, args, context, info) => {
|
|
@@ -5781,7 +5826,7 @@ var ExuluProvider = class {
|
|
|
5781
5826
|
modelId: agent.model,
|
|
5782
5827
|
user,
|
|
5783
5828
|
providers,
|
|
5784
|
-
agent
|
|
5829
|
+
agent
|
|
5785
5830
|
});
|
|
5786
5831
|
const providerapikey = resolved.apiKey;
|
|
5787
5832
|
console.log(
|
|
@@ -7476,7 +7521,7 @@ var registerOpenAIGatewayRoutes = async (app, providers, tools, contexts, config
|
|
|
7476
7521
|
});
|
|
7477
7522
|
return;
|
|
7478
7523
|
}
|
|
7479
|
-
let project =
|
|
7524
|
+
let project = void 0;
|
|
7480
7525
|
if (projectName) {
|
|
7481
7526
|
let projectQuery = db("projects").select("*");
|
|
7482
7527
|
projectQuery = applyAccessControl(projectsSchema3(), projectQuery, user);
|
|
@@ -7499,8 +7544,8 @@ var registerOpenAIGatewayRoutes = async (app, providers, tools, contexts, config
|
|
|
7499
7544
|
modelId: agent.model,
|
|
7500
7545
|
user,
|
|
7501
7546
|
providers,
|
|
7502
|
-
agent
|
|
7503
|
-
project
|
|
7547
|
+
agent,
|
|
7548
|
+
project
|
|
7504
7549
|
});
|
|
7505
7550
|
} catch (err) {
|
|
7506
7551
|
if (err instanceof ResolveModelError) {
|
|
@@ -7672,6 +7717,7 @@ var {
|
|
|
7672
7717
|
rbacSchema,
|
|
7673
7718
|
promptLibrarySchema,
|
|
7674
7719
|
contextPresetsSchema,
|
|
7720
|
+
teamsSchema,
|
|
7675
7721
|
embedderSettingsSchema,
|
|
7676
7722
|
promptFavoritesSchema,
|
|
7677
7723
|
statisticsSchema,
|
|
@@ -7721,6 +7767,7 @@ var createExpressRoutes = async (app, providers, tools, contexts, config, evals,
|
|
|
7721
7767
|
jobResultsSchema(),
|
|
7722
7768
|
promptLibrarySchema(),
|
|
7723
7769
|
contextPresetsSchema(),
|
|
7770
|
+
teamsSchema(),
|
|
7724
7771
|
embedderSettingsSchema(),
|
|
7725
7772
|
promptFavoritesSchema(),
|
|
7726
7773
|
evalRunsSchema(),
|
|
@@ -8107,7 +8154,7 @@ Mood: friendly and intelligent.
|
|
|
8107
8154
|
modelId,
|
|
8108
8155
|
user,
|
|
8109
8156
|
providers,
|
|
8110
|
-
agent
|
|
8157
|
+
agent
|
|
8111
8158
|
});
|
|
8112
8159
|
} catch (err) {
|
|
8113
8160
|
if (err instanceof ResolveModelError) {
|
|
@@ -8368,7 +8415,7 @@ ${customInstructions}` : agent.instructions;
|
|
|
8368
8415
|
modelId: agent.model,
|
|
8369
8416
|
user,
|
|
8370
8417
|
providers,
|
|
8371
|
-
agent
|
|
8418
|
+
agent
|
|
8372
8419
|
});
|
|
8373
8420
|
} catch (err) {
|
|
8374
8421
|
if (err instanceof ResolveModelError) {
|
|
@@ -9180,7 +9227,9 @@ ${style.markdown}` : params.prompt;
|
|
|
9180
9227
|
project_id: project?.id,
|
|
9181
9228
|
user_name: user.email,
|
|
9182
9229
|
role_name: user.role?.name,
|
|
9183
|
-
project_name: project?.name
|
|
9230
|
+
project_name: project?.name,
|
|
9231
|
+
team_id: user.team?.id,
|
|
9232
|
+
team_name: user.team?.name
|
|
9184
9233
|
});
|
|
9185
9234
|
if (tags?.length) {
|
|
9186
9235
|
upstreamHeaders["x-litellm-tags"] = tags.join(",");
|
|
@@ -10217,7 +10266,7 @@ var ExuluMCP = class {
|
|
|
10217
10266
|
modelId: agent.model,
|
|
10218
10267
|
user,
|
|
10219
10268
|
providers: allProviders,
|
|
10220
|
-
agent
|
|
10269
|
+
agent
|
|
10221
10270
|
});
|
|
10222
10271
|
const providerapikey = resolved.apiKey;
|
|
10223
10272
|
if (!isLiteLLMEnabled()) {
|
|
@@ -11449,6 +11498,7 @@ var ExuluEval = class {
|
|
|
11449
11498
|
|
|
11450
11499
|
// src/templates/evals/index.ts
|
|
11451
11500
|
import { z as z4 } from "zod";
|
|
11501
|
+
import { generateText as generateText5, Output as Output2 } from "ai";
|
|
11452
11502
|
var llmAsJudgeEval = () => {
|
|
11453
11503
|
if (process.env.REDIS_HOST?.length && process.env.REDIS_PORT?.length) {
|
|
11454
11504
|
return new ExuluEval({
|
|
@@ -11489,27 +11539,27 @@ var llmAsJudgeEval = () => {
|
|
|
11489
11539
|
const resolved = await resolveModel({
|
|
11490
11540
|
modelId: agent.model,
|
|
11491
11541
|
providers: exuluApp.get().providers,
|
|
11492
|
-
agent
|
|
11542
|
+
agent,
|
|
11493
11543
|
rbacBypass: true
|
|
11494
11544
|
});
|
|
11495
|
-
const providerapikey = resolved.apiKey;
|
|
11496
11545
|
console.log("[EXULU] prompt", prompt);
|
|
11497
|
-
const
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11546
|
+
const { output } = await generateText5({
|
|
11547
|
+
temperature: 0,
|
|
11548
|
+
model: resolved.languageModel,
|
|
11549
|
+
system: "",
|
|
11501
11550
|
prompt,
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
|
|
11551
|
+
maxRetries: 2,
|
|
11552
|
+
output: Output2.object({
|
|
11553
|
+
schema: z4.object({
|
|
11554
|
+
score: z4.number().min(0).max(100).describe("The score between 0 and 100.")
|
|
11555
|
+
})
|
|
11556
|
+
})
|
|
11507
11557
|
});
|
|
11508
|
-
console.log("[EXULU]
|
|
11509
|
-
const score =
|
|
11558
|
+
console.log("[EXULU] output", output);
|
|
11559
|
+
const score = output.score;
|
|
11510
11560
|
if (isNaN(score)) {
|
|
11511
11561
|
throw new Error(
|
|
11512
|
-
`Generated score from llm as a judge eval is not a number: ${
|
|
11562
|
+
`Generated score from llm as a judge eval is not a number: ${output.score}`
|
|
11513
11563
|
);
|
|
11514
11564
|
}
|
|
11515
11565
|
return score;
|
|
@@ -14634,6 +14684,7 @@ var {
|
|
|
14634
14684
|
agentMessagesSchema: agentMessagesSchema2,
|
|
14635
14685
|
modelsSchema: modelsSchema2,
|
|
14636
14686
|
rolesSchema: rolesSchema2,
|
|
14687
|
+
teamsSchema: teamsSchema2,
|
|
14637
14688
|
usersSchema: usersSchema2,
|
|
14638
14689
|
skillsSchema: skillsSchema2,
|
|
14639
14690
|
statisticsSchema: statisticsSchema2,
|
|
@@ -14676,6 +14727,7 @@ var up = async function(knex) {
|
|
|
14676
14727
|
agentMessagesSchema2(),
|
|
14677
14728
|
modelsSchema2(),
|
|
14678
14729
|
rolesSchema2(),
|
|
14730
|
+
teamsSchema2(),
|
|
14679
14731
|
testCasesSchema2(),
|
|
14680
14732
|
evalSetsSchema2(),
|
|
14681
14733
|
evalRunsSchema2(),
|
|
@@ -15691,7 +15743,7 @@ var MarkdownChunker = class {
|
|
|
15691
15743
|
// ee/python/documents/processing/doc_processor.ts
|
|
15692
15744
|
import * as fs4 from "fs";
|
|
15693
15745
|
import * as path from "path";
|
|
15694
|
-
import { generateText as
|
|
15746
|
+
import { generateText as generateText6, Output as Output3 } from "ai";
|
|
15695
15747
|
import { z as z12 } from "zod";
|
|
15696
15748
|
import pLimit from "p-limit";
|
|
15697
15749
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
@@ -16041,9 +16093,9 @@ If the page contains a flow-chart, schematic, technical drawing or control board
|
|
|
16041
16093
|
|
|
16042
16094
|
### 7. Only populate \`corrected_text\` when \`needs_correction\` is true. If the OCR output is accurate, return \`needs_correction: false\` and \`corrected_content: null\`.
|
|
16043
16095
|
`;
|
|
16044
|
-
const result = await
|
|
16096
|
+
const result = await generateText6({
|
|
16045
16097
|
model,
|
|
16046
|
-
output:
|
|
16098
|
+
output: Output3.object({
|
|
16047
16099
|
schema: z12.object({
|
|
16048
16100
|
needs_correction: z12.boolean(),
|
|
16049
16101
|
corrected_text: z12.string().nullable(),
|
package/ee/rbac-resolver.ts
CHANGED
|
@@ -9,6 +9,7 @@ export const RBACResolver = async (
|
|
|
9
9
|
type: string;
|
|
10
10
|
users: any[];
|
|
11
11
|
roles: any[];
|
|
12
|
+
teams: any[];
|
|
12
13
|
}> => {
|
|
13
14
|
|
|
14
15
|
// If RBAC is not available
|
|
@@ -18,7 +19,8 @@ export const RBACResolver = async (
|
|
|
18
19
|
return {
|
|
19
20
|
type: "public",
|
|
20
21
|
users: [],
|
|
21
|
-
roles: []
|
|
22
|
+
roles: [],
|
|
23
|
+
teams: []
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
// Get RBAC records for this resource
|
|
@@ -38,14 +40,20 @@ export const RBACResolver = async (
|
|
|
38
40
|
.filter((r) => r.access_type === "Role")
|
|
39
41
|
?.map((r) => ({ id: r.role_id, rights: r.rights }));
|
|
40
42
|
|
|
43
|
+
const teams = rbacRecords
|
|
44
|
+
.filter((r) => r.access_type === "Team")
|
|
45
|
+
?.map((r) => ({ id: r.team_id, rights: r.rights }));
|
|
46
|
+
|
|
41
47
|
// Determine the type based on rights_mode or presence of records
|
|
42
48
|
let type = rights_mode || "private";
|
|
43
49
|
if (type === "users" && users.length === 0) type = "private";
|
|
44
50
|
if (type === "roles" && roles.length === 0) type = "private";
|
|
51
|
+
if (type === "teams" && teams.length === 0) type = "private";
|
|
45
52
|
|
|
46
53
|
return {
|
|
47
54
|
type,
|
|
48
55
|
users,
|
|
49
56
|
roles,
|
|
57
|
+
teams,
|
|
50
58
|
};
|
|
51
59
|
};
|
package/ee/rbac-update.ts
CHANGED
|
@@ -15,7 +15,7 @@ export const handleRBACUpdate = async (
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const { users = [], roles = [] /* projects = [] */ } = rbacData;
|
|
18
|
+
const { users = [], roles = [], teams = [] /* projects = [] */ } = rbacData;
|
|
19
19
|
|
|
20
20
|
// Get existing RBAC records if not provided
|
|
21
21
|
if (!existingRbacRecords) {
|
|
@@ -31,6 +31,7 @@ export const handleRBACUpdate = async (
|
|
|
31
31
|
// Create sets for comparison
|
|
32
32
|
const newUserRecords = new Set(users.map((u: any) => `${u.id}:${u.rights}`));
|
|
33
33
|
const newRoleRecords = new Set(roles.map((r: any) => `${r.id}:${r.rights}`));
|
|
34
|
+
const newTeamRecords = new Set(teams.map((t: any) => `${t.id}:${t.rights}`));
|
|
34
35
|
// const newProjectRecords = new Set(projects.map((p: any) => `${p.id}:${p.rights}`));
|
|
35
36
|
const existingUserRecords = new Set(
|
|
36
37
|
existingRbacRecords
|
|
@@ -42,10 +43,16 @@ export const handleRBACUpdate = async (
|
|
|
42
43
|
.filter((r) => r.access_type === "Role")
|
|
43
44
|
.map((r) => `${r.role_id}:${r.rights}`),
|
|
44
45
|
);
|
|
46
|
+
const existingTeamRecords = new Set(
|
|
47
|
+
existingRbacRecords
|
|
48
|
+
.filter((r) => r.access_type === "Team")
|
|
49
|
+
.map((r) => `${r.team_id}:${r.rights}`),
|
|
50
|
+
);
|
|
45
51
|
|
|
46
52
|
// Records to create
|
|
47
53
|
const usersToCreate = users.filter((u: any) => !existingUserRecords.has(`${u.id}:${u.rights}`));
|
|
48
54
|
const rolesToCreate = roles.filter((r: any) => !existingRoleRecords.has(`${r.id}:${r.rights}`));
|
|
55
|
+
const teamsToCreate = teams.filter((t: any) => !existingTeamRecords.has(`${t.id}:${t.rights}`));
|
|
49
56
|
// const projectsToCreate = projects.filter((p: any) => !existingProjectRecords.has(`${p.id}:${p.rights}`));
|
|
50
57
|
|
|
51
58
|
// Records to remove
|
|
@@ -55,6 +62,9 @@ export const handleRBACUpdate = async (
|
|
|
55
62
|
const rolesToRemove = existingRbacRecords.filter(
|
|
56
63
|
(r) => r.access_type === "Role" && !newRoleRecords.has(`${r.role_id}:${r.rights}`),
|
|
57
64
|
);
|
|
65
|
+
const teamsToRemove = existingRbacRecords.filter(
|
|
66
|
+
(r) => r.access_type === "Team" && !newTeamRecords.has(`${r.team_id}:${r.rights}`),
|
|
67
|
+
);
|
|
58
68
|
// const projectsToRemove = existingRbacRecords
|
|
59
69
|
// .filter(r => r.access_type === 'Project' && !newProjectRecords.has(`${r.project_id}:${r.rights}`));
|
|
60
70
|
|
|
@@ -77,6 +87,15 @@ export const handleRBACUpdate = async (
|
|
|
77
87
|
)
|
|
78
88
|
.del();
|
|
79
89
|
}
|
|
90
|
+
if (teamsToRemove.length > 0) {
|
|
91
|
+
await db
|
|
92
|
+
.from("rbac")
|
|
93
|
+
.whereIn(
|
|
94
|
+
"id",
|
|
95
|
+
teamsToRemove.map((r) => r.id),
|
|
96
|
+
)
|
|
97
|
+
.del();
|
|
98
|
+
}
|
|
80
99
|
|
|
81
100
|
// Create new records
|
|
82
101
|
const recordsToInsert: any[] = [];
|
|
@@ -105,6 +124,18 @@ export const handleRBACUpdate = async (
|
|
|
105
124
|
});
|
|
106
125
|
});
|
|
107
126
|
|
|
127
|
+
teamsToCreate.forEach((team: any) => {
|
|
128
|
+
recordsToInsert.push({
|
|
129
|
+
entity: entityName,
|
|
130
|
+
access_type: "Team",
|
|
131
|
+
target_resource_id: resourceId,
|
|
132
|
+
team_id: team.id,
|
|
133
|
+
rights: team.rights,
|
|
134
|
+
createdAt: new Date(),
|
|
135
|
+
updatedAt: new Date(),
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
108
139
|
if (recordsToInsert.length > 0) {
|
|
109
140
|
await db.from("rbac").insert(recordsToInsert);
|
|
110
141
|
}
|
package/ee/schemas.ts
CHANGED
|
@@ -76,6 +76,27 @@ export const rolesSchema: ExuluTableDefinition = {
|
|
|
76
76
|
],
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
+
export const teamsSchema: ExuluTableDefinition = {
|
|
80
|
+
type: "teams",
|
|
81
|
+
name: {
|
|
82
|
+
plural: "teams",
|
|
83
|
+
singular: "team",
|
|
84
|
+
},
|
|
85
|
+
fields: [
|
|
86
|
+
{
|
|
87
|
+
name: "name",
|
|
88
|
+
type: "text",
|
|
89
|
+
index: true,
|
|
90
|
+
unique: true,
|
|
91
|
+
required: true,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "description",
|
|
95
|
+
type: "text",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
|
|
79
100
|
export const statisticsSchema: ExuluTableDefinition = {
|
|
80
101
|
type: "tracking",
|
|
81
102
|
name: {
|
|
@@ -301,6 +322,10 @@ export const rbacSchema: ExuluTableDefinition = {
|
|
|
301
322
|
name: "role_id",
|
|
302
323
|
type: "uuid",
|
|
303
324
|
},
|
|
325
|
+
{
|
|
326
|
+
name: "team_id",
|
|
327
|
+
type: "uuid",
|
|
328
|
+
},
|
|
304
329
|
{
|
|
305
330
|
name: "user_id",
|
|
306
331
|
type: "number",
|
package/ee/workers.ts
CHANGED
|
@@ -1390,7 +1390,7 @@ export const processUiMessagesFlow = async ({
|
|
|
1390
1390
|
modelId: agent.model,
|
|
1391
1391
|
user,
|
|
1392
1392
|
providers,
|
|
1393
|
-
agent:
|
|
1393
|
+
agent: agent
|
|
1394
1394
|
});
|
|
1395
1395
|
const providerapikey = resolved.apiKey;
|
|
1396
1396
|
const resolvedLanguageModel = resolved.languageModel;
|