@acarmisc/backstage-plugin-litellm-backend 0.31.0 → 0.32.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/config.d.ts +18 -2
- package/dist/index.cjs.js +92 -68
- package/dist/index.cjs.js.map +4 -4
- package/dist/openapi.js +1 -0
- package/dist/provisioning.d.ts +5 -0
- package/dist/provisioning.js +15 -4
- package/dist/router.js +3 -1
- package/dist/routes/config.js +5 -1
- package/dist/services/keyService.js +13 -3
- package/dist/types.cjs.js.map +1 -1
- package/dist/types.d.ts +12 -2
- package/package.json +2 -2
package/config.d.ts
CHANGED
|
@@ -44,16 +44,29 @@ export interface Config {
|
|
|
44
44
|
enabled?: boolean;
|
|
45
45
|
|
|
46
46
|
defaults?: {
|
|
47
|
+
/**
|
|
48
|
+
* Leave first-visit user budgets to LiteLLM. When true, maxBudget and
|
|
49
|
+
* budgetDuration have no built-in fallback: each is sent on /user/new
|
|
50
|
+
* only if set here or on the matching roles[] entry. Otherwise LiteLLM's
|
|
51
|
+
* litellm_settings.max_internal_user_budget /
|
|
52
|
+
* internal_user_budget_duration apply (LiteLLM applies those to
|
|
53
|
+
* user_role internal_user only).
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
useGatewayBudgetDefaults?: boolean;
|
|
57
|
+
|
|
47
58
|
/**
|
|
48
59
|
* Max lifetime spend in USD before the account is blocked.
|
|
49
|
-
* Set a conservative value
|
|
60
|
+
* Set a conservative value. When unset, 10 is used unless
|
|
61
|
+
* useGatewayBudgetDefaults is true (a YAML null counts as unset).
|
|
50
62
|
* @default 10
|
|
51
63
|
*/
|
|
52
64
|
maxBudget?: number;
|
|
53
65
|
|
|
54
66
|
/**
|
|
55
67
|
* Spend-reset period for maxBudget (e.g. "30d", "7d", "1h").
|
|
56
|
-
* After this period the spend counter resets.
|
|
68
|
+
* After this period the spend counter resets. When unset, "30d" is
|
|
69
|
+
* used unless useGatewayBudgetDefaults is true.
|
|
57
70
|
* @default "30d"
|
|
58
71
|
*/
|
|
59
72
|
budgetDuration?: string;
|
|
@@ -167,6 +180,9 @@ export interface Config {
|
|
|
167
180
|
* Allowed duration presets for keys (e.g. "1d", "7d", "30d", "90d").
|
|
168
181
|
* Requests with a duration not in this list are rejected with a 400 error.
|
|
169
182
|
* An empty array allows any duration matching the format /^\d+[smhdwy]$/.
|
|
183
|
+
* List "never" to offer keys that never expire: such a key is sent to
|
|
184
|
+
* LiteLLM with no duration. "never" is never the default and is only
|
|
185
|
+
* accepted when listed here.
|
|
170
186
|
* @default ["1d", "7d", "30d", "90d"]
|
|
171
187
|
*/
|
|
172
188
|
allowedDurations?: string[];
|
package/dist/index.cjs.js
CHANGED
|
@@ -7986,20 +7986,20 @@ __export(index_exports, {
|
|
|
7986
7986
|
getOrProvisionUser: () => getOrProvisionUser,
|
|
7987
7987
|
getOrProvisionUserFromClaims: () => getOrProvisionUserFromClaims,
|
|
7988
7988
|
isTeamManagementEnabled: () => isTeamManagementEnabled,
|
|
7989
|
-
litellmAuditReadPermission: () =>
|
|
7990
|
-
litellmKeyCreatePermission: () =>
|
|
7991
|
-
litellmKeyManagePermission: () =>
|
|
7992
|
-
litellmKeyResetSpendPermission: () =>
|
|
7993
|
-
litellmKeyRevokePermission: () =>
|
|
7994
|
-
litellmKeyUnblockPermission: () =>
|
|
7995
|
-
litellmPermissions: () =>
|
|
7989
|
+
litellmAuditReadPermission: () => import_backstage_plugin_litellm_common14.litellmAuditReadPermission,
|
|
7990
|
+
litellmKeyCreatePermission: () => import_backstage_plugin_litellm_common14.litellmKeyCreatePermission,
|
|
7991
|
+
litellmKeyManagePermission: () => import_backstage_plugin_litellm_common14.litellmKeyManagePermission,
|
|
7992
|
+
litellmKeyResetSpendPermission: () => import_backstage_plugin_litellm_common14.litellmKeyResetSpendPermission,
|
|
7993
|
+
litellmKeyRevokePermission: () => import_backstage_plugin_litellm_common14.litellmKeyRevokePermission,
|
|
7994
|
+
litellmKeyUnblockPermission: () => import_backstage_plugin_litellm_common14.litellmKeyUnblockPermission,
|
|
7995
|
+
litellmPermissions: () => import_backstage_plugin_litellm_common14.litellmPermissions,
|
|
7996
7996
|
litellmPlugin: () => litellmPlugin,
|
|
7997
|
-
litellmTeamCreatePermission: () =>
|
|
7998
|
-
litellmTeamDeletePermission: () =>
|
|
7999
|
-
litellmTeamKnowledgebaseManagePermission: () =>
|
|
8000
|
-
litellmTeamManagePermission: () =>
|
|
8001
|
-
litellmTeamMcpManagePermission: () =>
|
|
8002
|
-
litellmTeamMembersManagePermission: () =>
|
|
7997
|
+
litellmTeamCreatePermission: () => import_backstage_plugin_litellm_common14.litellmTeamCreatePermission,
|
|
7998
|
+
litellmTeamDeletePermission: () => import_backstage_plugin_litellm_common14.litellmTeamDeletePermission,
|
|
7999
|
+
litellmTeamKnowledgebaseManagePermission: () => import_backstage_plugin_litellm_common14.litellmTeamKnowledgebaseManagePermission,
|
|
8000
|
+
litellmTeamManagePermission: () => import_backstage_plugin_litellm_common14.litellmTeamManagePermission,
|
|
8001
|
+
litellmTeamMcpManagePermission: () => import_backstage_plugin_litellm_common14.litellmTeamMcpManagePermission,
|
|
8002
|
+
litellmTeamMembersManagePermission: () => import_backstage_plugin_litellm_common14.litellmTeamMembersManagePermission,
|
|
8003
8003
|
newDefaultVerifier: () => newDefaultVerifier,
|
|
8004
8004
|
provisionUser: () => provisionUser,
|
|
8005
8005
|
readBridgeConfig: () => readBridgeConfig,
|
|
@@ -8889,11 +8889,18 @@ function applyRoleOverrides(defaults, role) {
|
|
|
8889
8889
|
}
|
|
8890
8890
|
function readProvisioningDefaults(config) {
|
|
8891
8891
|
const enabled = config.getOptionalBoolean("litellm.provisioning.enabled") ?? false;
|
|
8892
|
+
const useGatewayBudgetDefaults = config.getOptionalBoolean(
|
|
8893
|
+
"litellm.provisioning.defaults.useGatewayBudgetDefaults"
|
|
8894
|
+
) ?? false;
|
|
8895
|
+
const maxBudget = config.getOptionalNumber(
|
|
8896
|
+
"litellm.provisioning.defaults.maxBudget"
|
|
8897
|
+
);
|
|
8898
|
+
const budgetDuration = config.getOptionalString(
|
|
8899
|
+
"litellm.provisioning.defaults.budgetDuration"
|
|
8900
|
+
);
|
|
8892
8901
|
const defaults = {
|
|
8893
|
-
maxBudget:
|
|
8894
|
-
budgetDuration:
|
|
8895
|
-
"litellm.provisioning.defaults.budgetDuration"
|
|
8896
|
-
) ?? "30d",
|
|
8902
|
+
maxBudget: maxBudget ?? (useGatewayBudgetDefaults ? void 0 : 10),
|
|
8903
|
+
budgetDuration: budgetDuration ?? (useGatewayBudgetDefaults ? void 0 : "30d"),
|
|
8897
8904
|
models: config.getOptionalStringArray("litellm.provisioning.defaults.models") ?? [],
|
|
8898
8905
|
teams: config.getOptionalStringArray("litellm.provisioning.defaults.teams") ?? [],
|
|
8899
8906
|
tpmLimit: config.getOptionalNumber(
|
|
@@ -8958,8 +8965,11 @@ async function provisionUser(client, userId, defaults, profile, backstageEntity,
|
|
|
8958
8965
|
user_id: userId,
|
|
8959
8966
|
...profile.email && { user_email: profile.email },
|
|
8960
8967
|
...profile.displayName && { user_alias: profile.displayName },
|
|
8961
|
-
|
|
8962
|
-
|
|
8968
|
+
// Undefined = left out, so LiteLLM's internal-user defaults apply.
|
|
8969
|
+
...defaults.maxBudget !== void 0 && { max_budget: defaults.maxBudget },
|
|
8970
|
+
...defaults.budgetDuration !== void 0 && {
|
|
8971
|
+
budget_duration: defaults.budgetDuration
|
|
8972
|
+
},
|
|
8963
8973
|
models: defaults.models,
|
|
8964
8974
|
teams: defaults.teams,
|
|
8965
8975
|
...defaults.tpmLimit !== void 0 && { tpm_limit: defaults.tpmLimit },
|
|
@@ -9192,7 +9202,7 @@ function parseKeySnippetTabs(raw) {
|
|
|
9192
9202
|
}
|
|
9193
9203
|
|
|
9194
9204
|
// src/router.ts
|
|
9195
|
-
var
|
|
9205
|
+
var import_backstage_plugin_litellm_common12 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
9196
9206
|
|
|
9197
9207
|
// src/teamAdmin.ts
|
|
9198
9208
|
var import_plugin_permission_common = __toESM(require_index_cjs2());
|
|
@@ -9805,6 +9815,7 @@ var openApiSpec = {
|
|
|
9805
9815
|
content: { "application/json": { schema: { type: "object", properties: {
|
|
9806
9816
|
baseUrl: { type: "string" },
|
|
9807
9817
|
keyGeneration: { type: "object", properties: {
|
|
9818
|
+
allowedDurations: { type: "array", items: { type: "string" }, description: 'Durations a new key may have (litellm.keys.allowedDurations); "never" means no expiry' },
|
|
9808
9819
|
allowUnlimitedBudget: { type: "boolean" },
|
|
9809
9820
|
teamRequired: { type: "boolean" }
|
|
9810
9821
|
} },
|
|
@@ -10064,7 +10075,11 @@ function registerConfigRoutes(router, ctx) {
|
|
|
10064
10075
|
res.json({
|
|
10065
10076
|
baseUrl: ctx.publicBaseUrl,
|
|
10066
10077
|
supportContact: ctx.supportContact,
|
|
10067
|
-
keyGeneration: {
|
|
10078
|
+
keyGeneration: {
|
|
10079
|
+
allowUnlimitedBudget: ctx.allowUnlimitedBudget,
|
|
10080
|
+
teamRequired: ctx.teamRequired,
|
|
10081
|
+
allowedDurations: ctx.keyValidationConfig.allowedDurations
|
|
10082
|
+
},
|
|
10068
10083
|
keyActions: { allowOwnerResetSpend: ctx.allowOwnerResetSpend },
|
|
10069
10084
|
opencode: { enabled: ctx.opencodeCfg.enabled },
|
|
10070
10085
|
teamManagement: {
|
|
@@ -10139,6 +10154,9 @@ function registerConfigRoutes(router, ctx) {
|
|
|
10139
10154
|
}
|
|
10140
10155
|
|
|
10141
10156
|
// src/routes/keys.ts
|
|
10157
|
+
var import_backstage_plugin_litellm_common5 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
10158
|
+
|
|
10159
|
+
// src/services/keyService.ts
|
|
10142
10160
|
var import_backstage_plugin_litellm_common4 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
10143
10161
|
|
|
10144
10162
|
// src/services/modelAccess.ts
|
|
@@ -10281,8 +10299,14 @@ async function createKeyForUser(user, input, ctx) {
|
|
|
10281
10299
|
upstreamRequest.models = input.models;
|
|
10282
10300
|
}
|
|
10283
10301
|
const durations = ctx.keyValidationConfig.allowedDurations;
|
|
10284
|
-
const defaultDuration = durations.length === 0 || durations.includes("30d") ? "30d" : durations
|
|
10285
|
-
|
|
10302
|
+
const defaultDuration = durations.length === 0 || durations.includes("30d") ? "30d" : durations.find((d) => d !== import_backstage_plugin_litellm_common4.NEVER_KEY_DURATION);
|
|
10303
|
+
const duration = input.duration ?? defaultDuration;
|
|
10304
|
+
if (duration === void 0) {
|
|
10305
|
+
throw new KeyServiceError(400, { error: "duration is required" });
|
|
10306
|
+
}
|
|
10307
|
+
if (duration !== import_backstage_plugin_litellm_common4.NEVER_KEY_DURATION) {
|
|
10308
|
+
upstreamRequest.duration = duration;
|
|
10309
|
+
}
|
|
10286
10310
|
if (input.max_budget !== void 0) {
|
|
10287
10311
|
upstreamRequest.max_budget = input.max_budget ?? void 0;
|
|
10288
10312
|
}
|
|
@@ -10328,8 +10352,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10328
10352
|
assertPermission,
|
|
10329
10353
|
sendPermissionDenied
|
|
10330
10354
|
} = ctx;
|
|
10331
|
-
const generateKeyInputSchema = (0,
|
|
10332
|
-
const updateKeyInputSchema = (0,
|
|
10355
|
+
const generateKeyInputSchema = (0, import_backstage_plugin_litellm_common5.createGenerateKeyInputSchema)(keyValidationConfig);
|
|
10356
|
+
const updateKeyInputSchema = (0, import_backstage_plugin_litellm_common5.createUpdateKeyInputSchema)(keyValidationConfig);
|
|
10333
10357
|
router.get("/user/info", async (_req, res) => {
|
|
10334
10358
|
try {
|
|
10335
10359
|
const tokenEntityRef = res.locals.tokenEntityRef;
|
|
@@ -10366,8 +10390,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10366
10390
|
});
|
|
10367
10391
|
router.post("/keys/prune-expired", async (_req, res) => {
|
|
10368
10392
|
try {
|
|
10369
|
-
if (!await assertPermission(_req,
|
|
10370
|
-
sendPermissionDenied(res,
|
|
10393
|
+
if (!await assertPermission(_req, import_backstage_plugin_litellm_common5.litellmKeyRevokePermission)) {
|
|
10394
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyRevokePermission);
|
|
10371
10395
|
return;
|
|
10372
10396
|
}
|
|
10373
10397
|
await getProvisionedUser(ctx, res);
|
|
@@ -10431,8 +10455,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10431
10455
|
return;
|
|
10432
10456
|
}
|
|
10433
10457
|
const input = parseResult.data;
|
|
10434
|
-
if (!await assertPermission(req,
|
|
10435
|
-
sendPermissionDenied(res,
|
|
10458
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmKeyCreatePermission)) {
|
|
10459
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyCreatePermission);
|
|
10436
10460
|
return;
|
|
10437
10461
|
}
|
|
10438
10462
|
const tokenEntityRef = res.locals.tokenEntityRef;
|
|
@@ -10481,8 +10505,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10481
10505
|
res.status(400).json({ error: "keyId is required" });
|
|
10482
10506
|
return;
|
|
10483
10507
|
}
|
|
10484
|
-
if (!await assertPermission(req,
|
|
10485
|
-
sendPermissionDenied(res,
|
|
10508
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmKeyManagePermission)) {
|
|
10509
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyManagePermission);
|
|
10486
10510
|
return;
|
|
10487
10511
|
}
|
|
10488
10512
|
const { tokenEntityRef, userId, key } = await authorizeKeyAction(req, keyId);
|
|
@@ -10559,8 +10583,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10559
10583
|
res.status(400).json({ error: "keyId is required" });
|
|
10560
10584
|
return;
|
|
10561
10585
|
}
|
|
10562
|
-
if (!await assertPermission(req,
|
|
10563
|
-
sendPermissionDenied(res,
|
|
10586
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmKeyRevokePermission)) {
|
|
10587
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyRevokePermission);
|
|
10564
10588
|
return;
|
|
10565
10589
|
}
|
|
10566
10590
|
const { tokenEntityRef } = await authorizeKeyAction(req, keyId);
|
|
@@ -10574,8 +10598,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10574
10598
|
router.post("/keys/:keyId/block", async (req, res) => {
|
|
10575
10599
|
try {
|
|
10576
10600
|
const { keyId } = req.params;
|
|
10577
|
-
if (!await assertPermission(req,
|
|
10578
|
-
sendPermissionDenied(res,
|
|
10601
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmKeyManagePermission)) {
|
|
10602
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyManagePermission);
|
|
10579
10603
|
return;
|
|
10580
10604
|
}
|
|
10581
10605
|
const { tokenEntityRef, key } = await authorizeKeyAction(req, keyId);
|
|
@@ -10603,8 +10627,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10603
10627
|
try {
|
|
10604
10628
|
const { keyId } = req.params;
|
|
10605
10629
|
const { tokenEntityRef, key } = await authorizeKeyAction(req, keyId);
|
|
10606
|
-
if (!await assertPermission(req,
|
|
10607
|
-
sendPermissionDenied(res,
|
|
10630
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmKeyUnblockPermission)) {
|
|
10631
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyUnblockPermission);
|
|
10608
10632
|
return;
|
|
10609
10633
|
}
|
|
10610
10634
|
await client.unblockKey(keyId);
|
|
@@ -10632,8 +10656,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10632
10656
|
});
|
|
10633
10657
|
return;
|
|
10634
10658
|
}
|
|
10635
|
-
if (!await assertPermission(req,
|
|
10636
|
-
sendPermissionDenied(res,
|
|
10659
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmKeyResetSpendPermission)) {
|
|
10660
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmKeyResetSpendPermission);
|
|
10637
10661
|
return;
|
|
10638
10662
|
}
|
|
10639
10663
|
const { tokenEntityRef } = await authorizeKeyAction(req, keyId);
|
|
@@ -10665,8 +10689,8 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10665
10689
|
res.status(403).json({ error: "Access denied: not a member of the audit group" });
|
|
10666
10690
|
return;
|
|
10667
10691
|
}
|
|
10668
|
-
if (!await assertPermission(req,
|
|
10669
|
-
sendPermissionDenied(res,
|
|
10692
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common5.litellmAuditReadPermission)) {
|
|
10693
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common5.litellmAuditReadPermission);
|
|
10670
10694
|
return;
|
|
10671
10695
|
}
|
|
10672
10696
|
try {
|
|
@@ -10718,7 +10742,7 @@ function registerKeysRoutes(router, ctx) {
|
|
|
10718
10742
|
}
|
|
10719
10743
|
|
|
10720
10744
|
// src/routes/opencode.ts
|
|
10721
|
-
var
|
|
10745
|
+
var import_backstage_plugin_litellm_common6 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
10722
10746
|
function isValidRedirectUri(uri) {
|
|
10723
10747
|
if (!uri) return false;
|
|
10724
10748
|
try {
|
|
@@ -10760,8 +10784,8 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10760
10784
|
return null;
|
|
10761
10785
|
}
|
|
10762
10786
|
const redirectUri = redirectUriParam;
|
|
10763
|
-
if (!await assertPermission(req,
|
|
10764
|
-
sendPermissionDenied(res,
|
|
10787
|
+
if (!await assertPermission(req, import_backstage_plugin_litellm_common6.litellmKeyCreatePermission)) {
|
|
10788
|
+
sendPermissionDenied(res, import_backstage_plugin_litellm_common6.litellmKeyCreatePermission);
|
|
10765
10789
|
return null;
|
|
10766
10790
|
}
|
|
10767
10791
|
const computedUserId = toLiteLLMUserId(tokenEntityRef, userIdDomain);
|
|
@@ -10929,7 +10953,7 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10929
10953
|
}
|
|
10930
10954
|
|
|
10931
10955
|
// src/routes/teams.ts
|
|
10932
|
-
var
|
|
10956
|
+
var import_backstage_plugin_litellm_common7 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
10933
10957
|
|
|
10934
10958
|
// src/http/respondTeam.ts
|
|
10935
10959
|
function respondTeam(res, team, ctx, caller) {
|
|
@@ -11024,7 +11048,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11024
11048
|
permissions,
|
|
11025
11049
|
catalogClient,
|
|
11026
11050
|
teamAdminGroup: teamAdminCfg.group,
|
|
11027
|
-
permission:
|
|
11051
|
+
permission: import_backstage_plugin_litellm_common7.litellmTeamCreatePermission,
|
|
11028
11052
|
logger
|
|
11029
11053
|
});
|
|
11030
11054
|
if (!check.ok) {
|
|
@@ -11098,7 +11122,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11098
11122
|
const authz = await authorizeTeamSubresource(
|
|
11099
11123
|
req,
|
|
11100
11124
|
res,
|
|
11101
|
-
|
|
11125
|
+
import_backstage_plugin_litellm_common7.litellmTeamManagePermission
|
|
11102
11126
|
);
|
|
11103
11127
|
if (!authz) return;
|
|
11104
11128
|
const { teamId, owningGroup, actor, team: existing } = authz;
|
|
@@ -11139,7 +11163,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11139
11163
|
const authz = await authorizeTeamSubresource(
|
|
11140
11164
|
req,
|
|
11141
11165
|
res,
|
|
11142
|
-
|
|
11166
|
+
import_backstage_plugin_litellm_common7.litellmTeamDeletePermission
|
|
11143
11167
|
);
|
|
11144
11168
|
if (!authz) return;
|
|
11145
11169
|
const { teamId, owningGroup, actor } = authz;
|
|
@@ -11180,7 +11204,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11180
11204
|
permissions,
|
|
11181
11205
|
catalogClient,
|
|
11182
11206
|
teamAdminGroup: teamAdminCfg.group,
|
|
11183
|
-
permission:
|
|
11207
|
+
permission: import_backstage_plugin_litellm_common7.litellmTeamManagePermission,
|
|
11184
11208
|
logger
|
|
11185
11209
|
});
|
|
11186
11210
|
if (!check.ok) {
|
|
@@ -11203,7 +11227,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11203
11227
|
const authz = await authorizeTeamSubresource(
|
|
11204
11228
|
req,
|
|
11205
11229
|
res,
|
|
11206
|
-
|
|
11230
|
+
import_backstage_plugin_litellm_common7.litellmTeamMembersManagePermission,
|
|
11207
11231
|
{ allowTeamRole: true }
|
|
11208
11232
|
);
|
|
11209
11233
|
if (!authz) return;
|
|
@@ -11308,7 +11332,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11308
11332
|
const authz = await authorizeTeamSubresource(
|
|
11309
11333
|
req,
|
|
11310
11334
|
res,
|
|
11311
|
-
|
|
11335
|
+
import_backstage_plugin_litellm_common7.litellmTeamMembersManagePermission,
|
|
11312
11336
|
{ allowTeamRole: true }
|
|
11313
11337
|
);
|
|
11314
11338
|
if (!authz) return;
|
|
@@ -11356,7 +11380,7 @@ function registerTeamsRoutes(router, ctx) {
|
|
|
11356
11380
|
}
|
|
11357
11381
|
|
|
11358
11382
|
// src/routes/objectPermissions.ts
|
|
11359
|
-
var
|
|
11383
|
+
var import_backstage_plugin_litellm_common8 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
11360
11384
|
function registerObjectPermissionsRoutes(router, ctx) {
|
|
11361
11385
|
const {
|
|
11362
11386
|
client,
|
|
@@ -11391,7 +11415,7 @@ function registerObjectPermissionsRoutes(router, ctx) {
|
|
|
11391
11415
|
permissions,
|
|
11392
11416
|
catalogClient,
|
|
11393
11417
|
teamAdminGroup: teamAdminCfg.group,
|
|
11394
|
-
permission:
|
|
11418
|
+
permission: import_backstage_plugin_litellm_common8.litellmTeamKnowledgebaseManagePermission,
|
|
11395
11419
|
logger
|
|
11396
11420
|
});
|
|
11397
11421
|
if (!check.ok) {
|
|
@@ -11413,7 +11437,7 @@ function registerObjectPermissionsRoutes(router, ctx) {
|
|
|
11413
11437
|
const authz = await authorizeTeamSubresource(
|
|
11414
11438
|
req,
|
|
11415
11439
|
res,
|
|
11416
|
-
|
|
11440
|
+
import_backstage_plugin_litellm_common8.litellmTeamKnowledgebaseManagePermission
|
|
11417
11441
|
);
|
|
11418
11442
|
if (!authz) return;
|
|
11419
11443
|
const { teamId, owningGroup, actor, team } = authz;
|
|
@@ -11473,7 +11497,7 @@ function registerObjectPermissionsRoutes(router, ctx) {
|
|
|
11473
11497
|
permissions,
|
|
11474
11498
|
catalogClient,
|
|
11475
11499
|
teamAdminGroup: teamAdminCfg.group,
|
|
11476
|
-
permission:
|
|
11500
|
+
permission: import_backstage_plugin_litellm_common8.litellmTeamMcpManagePermission,
|
|
11477
11501
|
logger
|
|
11478
11502
|
});
|
|
11479
11503
|
if (!check.ok) {
|
|
@@ -11495,7 +11519,7 @@ function registerObjectPermissionsRoutes(router, ctx) {
|
|
|
11495
11519
|
const authz = await authorizeTeamSubresource(
|
|
11496
11520
|
req,
|
|
11497
11521
|
res,
|
|
11498
|
-
|
|
11522
|
+
import_backstage_plugin_litellm_common8.litellmTeamMcpManagePermission
|
|
11499
11523
|
);
|
|
11500
11524
|
if (!authz) return;
|
|
11501
11525
|
const { teamId, owningGroup, actor, team } = authz;
|
|
@@ -11548,7 +11572,7 @@ function registerObjectPermissionsRoutes(router, ctx) {
|
|
|
11548
11572
|
}
|
|
11549
11573
|
|
|
11550
11574
|
// src/routes/teamUsage.ts
|
|
11551
|
-
var
|
|
11575
|
+
var import_backstage_plugin_litellm_common9 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
11552
11576
|
function registerTeamUsageRoutes(router, ctx) {
|
|
11553
11577
|
const {
|
|
11554
11578
|
client,
|
|
@@ -11651,7 +11675,7 @@ function registerTeamUsageRoutes(router, ctx) {
|
|
|
11651
11675
|
}
|
|
11652
11676
|
const role = team.members_with_roles?.find((m) => m.user_id === callerId)?.role;
|
|
11653
11677
|
const viaRole = isMember && !!role && cfg.viewerRoles.includes(role);
|
|
11654
|
-
const allowed = isManager || viaRole || isMember && cfg.permissionEnabled && await ctx.assertPermission(req,
|
|
11678
|
+
const allowed = isManager || viaRole || isMember && cfg.permissionEnabled && await ctx.assertPermission(req, import_backstage_plugin_litellm_common9.litellmTeamUsageReadPermission);
|
|
11655
11679
|
if (!allowed) {
|
|
11656
11680
|
res.status(403).json({
|
|
11657
11681
|
error: "Access denied: viewing per-member usage needs a team role or permission"
|
|
@@ -13475,8 +13499,8 @@ async function bridgeListKeys(client, claims, provisioningEnabled, provisioningD
|
|
|
13475
13499
|
}
|
|
13476
13500
|
|
|
13477
13501
|
// src/routes/bridge.ts
|
|
13478
|
-
var import_backstage_plugin_litellm_common9 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
13479
13502
|
var import_backstage_plugin_litellm_common10 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
13503
|
+
var import_backstage_plugin_litellm_common11 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
13480
13504
|
function registerBridgeRoutes(router, ctx, bridgeOpts) {
|
|
13481
13505
|
const {
|
|
13482
13506
|
client,
|
|
@@ -13489,7 +13513,7 @@ function registerBridgeRoutes(router, ctx, bridgeOpts) {
|
|
|
13489
13513
|
keyValidationConfig
|
|
13490
13514
|
} = ctx;
|
|
13491
13515
|
const { config } = bridgeOpts;
|
|
13492
|
-
const generateKeyInputSchema = (0,
|
|
13516
|
+
const generateKeyInputSchema = (0, import_backstage_plugin_litellm_common11.createGenerateKeyInputSchema)(ctx.keyValidationConfig);
|
|
13493
13517
|
const bridgeCfg = readBridgeConfig(config);
|
|
13494
13518
|
const bridgeIdentity = {
|
|
13495
13519
|
userIdDomain,
|
|
@@ -13650,11 +13674,11 @@ function registerBridgeRoutes(router, ctx, bridgeOpts) {
|
|
|
13650
13674
|
}
|
|
13651
13675
|
const team = await client.getTeamInfo(teamId);
|
|
13652
13676
|
const allowed = team.models;
|
|
13653
|
-
if (!allowed || allowed.length === 0 || allowed.includes(
|
|
13677
|
+
if (!allowed || allowed.length === 0 || allowed.includes(import_backstage_plugin_litellm_common10.ALL_PROXY_MODELS)) {
|
|
13654
13678
|
res.json(models);
|
|
13655
13679
|
return;
|
|
13656
13680
|
}
|
|
13657
|
-
res.json(models.filter((m) => (0,
|
|
13681
|
+
res.json(models.filter((m) => (0, import_backstage_plugin_litellm_common10.isModelAllowed)(m, allowed)));
|
|
13658
13682
|
} catch (error) {
|
|
13659
13683
|
handleBridgeError(error, res);
|
|
13660
13684
|
}
|
|
@@ -13720,13 +13744,13 @@ async function createRouter(options) {
|
|
|
13720
13744
|
const keyMaxBudget = config.getOptionalNumber("litellm.keys.maxBudget") ?? 100;
|
|
13721
13745
|
const keyMaxTpm = config.getOptionalNumber("litellm.keys.maxTpm") ?? 1e5;
|
|
13722
13746
|
const keyMaxRpm = config.getOptionalNumber("litellm.keys.maxRpm") ?? 1e3;
|
|
13723
|
-
const keyAllowedDurations = config.getOptionalStringArray("litellm.keys.allowedDurations") ??
|
|
13747
|
+
const keyAllowedDurations = config.getOptionalStringArray("litellm.keys.allowedDurations") ?? import_backstage_plugin_litellm_common12.DEFAULT_KEY_DURATIONS;
|
|
13724
13748
|
const keyValidationConfig = {
|
|
13725
13749
|
maxBudget: keyMaxBudget,
|
|
13726
13750
|
maxTpm: keyMaxTpm,
|
|
13727
13751
|
maxRpm: keyMaxRpm,
|
|
13728
13752
|
allowedDurations: keyAllowedDurations,
|
|
13729
|
-
allowedBudgetDurations: config.getOptionalStringArray("litellm.keys.allowedBudgetDurations") ??
|
|
13753
|
+
allowedBudgetDurations: config.getOptionalStringArray("litellm.keys.allowedBudgetDurations") ?? import_backstage_plugin_litellm_common12.DEFAULT_KEY_BUDGET_DURATIONS
|
|
13730
13754
|
};
|
|
13731
13755
|
const teamMgmtEnabled = isTeamManagementEnabled(config);
|
|
13732
13756
|
const objectPermsEnabled = isObjectPermissionsEnabled(config);
|
|
@@ -13738,7 +13762,7 @@ async function createRouter(options) {
|
|
|
13738
13762
|
const catalogClient = options.catalogClient ?? new import_catalog_client.CatalogClient({ discoveryApi: discovery });
|
|
13739
13763
|
if (provisioningEnabled) {
|
|
13740
13764
|
logger.info(
|
|
13741
|
-
`LiteLLM auto-provisioning enabled \u2014 defaults: budget
|
|
13765
|
+
`LiteLLM auto-provisioning enabled \u2014 defaults: budget=${provisioningDefaults.maxBudget === void 0 ? "gateway default" : `$${provisioningDefaults.maxBudget}`}/${provisioningDefaults.budgetDuration ?? "gateway default"}, models=${provisioningDefaults.models.length ? provisioningDefaults.models.join(",") : "all"}, teams=[${provisioningDefaults.teams.join(",")}]`
|
|
13742
13766
|
);
|
|
13743
13767
|
}
|
|
13744
13768
|
if (config.getOptional("litellm.teamAdmin") && !teamMgmtEnabled) {
|
|
@@ -13941,7 +13965,7 @@ async function createRouter(options) {
|
|
|
13941
13965
|
}
|
|
13942
13966
|
|
|
13943
13967
|
// src/plugin.ts
|
|
13944
|
-
var
|
|
13968
|
+
var import_backstage_plugin_litellm_common13 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
13945
13969
|
var BRIDGE_UNAUTHENTICATED_PATHS = [
|
|
13946
13970
|
"/bridge/health",
|
|
13947
13971
|
"/bridge/keys",
|
|
@@ -13971,7 +13995,7 @@ var litellmPlugin = (0, import_backend_plugin_api.createBackendPlugin)({
|
|
|
13971
13995
|
permissions,
|
|
13972
13996
|
permissionsRegistry
|
|
13973
13997
|
}) {
|
|
13974
|
-
permissionsRegistry.addPermissions(
|
|
13998
|
+
permissionsRegistry.addPermissions(import_backstage_plugin_litellm_common13.litellmPermissions);
|
|
13975
13999
|
const router = await createRouter({
|
|
13976
14000
|
config,
|
|
13977
14001
|
logger,
|
|
@@ -13991,7 +14015,7 @@ var litellmPlugin = (0, import_backend_plugin_api.createBackendPlugin)({
|
|
|
13991
14015
|
});
|
|
13992
14016
|
|
|
13993
14017
|
// src/index.ts
|
|
13994
|
-
var
|
|
14018
|
+
var import_backstage_plugin_litellm_common14 = require("@acarmisc/backstage-plugin-litellm-common");
|
|
13995
14019
|
// Annotate the CommonJS export names for ESM import in node:
|
|
13996
14020
|
0 && (module.exports = {
|
|
13997
14021
|
KeycloakJWTVerifier,
|