@acarmisc/backstage-plugin-litellm-backend 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.d.ts +6 -0
- package/dist/index.cjs.js +13 -6
- package/dist/index.cjs.js.map +2 -2
- package/dist/opencode.d.ts +5 -0
- package/dist/opencode.js +1 -0
- package/dist/routes/opencode.js +21 -5
- package/package.json +1 -1
package/config.d.ts
CHANGED
|
@@ -216,6 +216,12 @@ export interface Config {
|
|
|
216
216
|
*/
|
|
217
217
|
maxBudget?: number;
|
|
218
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Reset period of maxBudget in LiteLLM format (e.g. "30d"). Unset, maxBudget
|
|
221
|
+
* covers the whole life of the key.
|
|
222
|
+
*/
|
|
223
|
+
budgetDuration?: string;
|
|
224
|
+
|
|
219
225
|
/**
|
|
220
226
|
* When true a team must be supplied and the user must belong to it.
|
|
221
227
|
* @default false
|
package/dist/index.cjs.js
CHANGED
|
@@ -9351,6 +9351,7 @@ function readOpencodeConfig(config) {
|
|
|
9351
9351
|
enabled,
|
|
9352
9352
|
keyDuration: config.getOptionalString("litellm.opencode.keyDuration") ?? "30d",
|
|
9353
9353
|
maxBudget: config.getOptionalNumber("litellm.opencode.maxBudget") ?? 50,
|
|
9354
|
+
budgetDuration: config.getOptionalString("litellm.opencode.budgetDuration"),
|
|
9354
9355
|
requireTeam: config.getOptionalBoolean("litellm.opencode.requireTeam") ?? false,
|
|
9355
9356
|
metadata: config.getOptional(
|
|
9356
9357
|
"litellm.opencode.metadata"
|
|
@@ -10636,6 +10637,8 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10636
10637
|
const reusable = existing.find(
|
|
10637
10638
|
(k) => k.key_alias === alias && !k.blocked && k.user_id === userId
|
|
10638
10639
|
);
|
|
10640
|
+
const teamPerm = teamId ? (await client.getTeamInfo(teamId).catch(() => void 0))?.object_permission : void 0;
|
|
10641
|
+
const mcp = teamPerm?.mcp_servers?.length || teamPerm?.mcp_access_groups?.length ? { mcp_servers: teamPerm.mcp_servers ?? [], mcp_access_groups: teamPerm.mcp_access_groups ?? [] } : void 0;
|
|
10639
10642
|
const mintNewKey = async () => {
|
|
10640
10643
|
const profile = await resolveUserProfile(
|
|
10641
10644
|
tokenEntityRef,
|
|
@@ -10647,6 +10650,7 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10647
10650
|
alias,
|
|
10648
10651
|
duration: opencodeCfg.keyDuration,
|
|
10649
10652
|
max_budget: opencodeCfg.maxBudget,
|
|
10653
|
+
...opencodeCfg.budgetDuration && { budget_duration: opencodeCfg.budgetDuration },
|
|
10650
10654
|
team_id: teamId,
|
|
10651
10655
|
metadata: {
|
|
10652
10656
|
...opencodeCfg.metadata,
|
|
@@ -10655,7 +10659,8 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10655
10659
|
...profile.email && { created_by_email: profile.email },
|
|
10656
10660
|
...teamId && { opencode_team: teamId }
|
|
10657
10661
|
},
|
|
10658
|
-
user_id: userId
|
|
10662
|
+
user_id: userId,
|
|
10663
|
+
...mcp && { object_permission: mcp }
|
|
10659
10664
|
});
|
|
10660
10665
|
return result.key;
|
|
10661
10666
|
};
|
|
@@ -10666,6 +10671,7 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10666
10671
|
try {
|
|
10667
10672
|
key = (await client.regenerateKey(keyHashOrId)).key;
|
|
10668
10673
|
rotated = true;
|
|
10674
|
+
if (key && mcp) await client.updateKey({ key, object_permission: mcp });
|
|
10669
10675
|
} catch (err) {
|
|
10670
10676
|
const unsupported = err instanceof LiteLLMUpstreamError && ([400, 404, 405, 501].includes(err.status) || /enterprise|premium/i.test(err.message));
|
|
10671
10677
|
if (!unsupported) throw err;
|
|
@@ -10681,14 +10687,15 @@ function registerOpencodeRoutes(router, ctx) {
|
|
|
10681
10687
|
res.status(502).json({ error: "LiteLLM returned no key material" });
|
|
10682
10688
|
return;
|
|
10683
10689
|
}
|
|
10690
|
+
logger.info("opencode.connect", { userId, team: teamId ?? null, rotated });
|
|
10691
|
+
if (req.is("application/json")) {
|
|
10692
|
+
res.set("Cache-Control", "no-store");
|
|
10693
|
+
res.json({ key, team: teamId ?? null });
|
|
10694
|
+
return;
|
|
10695
|
+
}
|
|
10684
10696
|
const url = new URL(redirectUri);
|
|
10685
10697
|
url.searchParams.set("key", key);
|
|
10686
10698
|
if (teamId) url.searchParams.set("team", teamId);
|
|
10687
|
-
logger.info("opencode.connect", {
|
|
10688
|
-
userId,
|
|
10689
|
-
team: teamId ?? null,
|
|
10690
|
-
rotated
|
|
10691
|
-
});
|
|
10692
10699
|
res.redirect(302, url.href);
|
|
10693
10700
|
} catch (error) {
|
|
10694
10701
|
if (error instanceof ProvisioningError) {
|