@exulu/backend 1.62.1 → 1.63.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import {
2
2
  __resetLiteLLMCatalogCacheForTesting,
3
3
  fetchLiteLLMCatalog,
4
4
  findLiteLLMModel
5
- } from "./chunk-ILAHW4UT.js";
5
+ } from "./chunk-YCE44CMU.js";
6
6
  export {
7
7
  __resetLiteLLMCatalogCacheForTesting,
8
8
  fetchLiteLLMCatalog,
@@ -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: user?.id,
624
- role: user?.role?.id,
625
- project: project?.id,
626
- agent: agent?.id
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: { id: agent.id },
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-FZ4ZCVBZ.js");
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
- _cache = { expiresAt: Date.now() + CACHE_TTL_MS, items };
50
- return items.filter((m) => m.type !== "speech_to_text" && m.type !== "text_to_speech");
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 [];
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  convertExuluToolsToAiSdkTools
3
- } from "./chunk-4TCN467I.js";
3
+ } from "./chunk-IZOD2X2F.js";
4
4
  export {
5
5
  convertExuluToolsToAiSdkTools
6
6
  };