@acarmisc/backstage-plugin-litellm-backend 0.17.0 → 0.17.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.
package/dist/index.cjs.js CHANGED
@@ -568,9 +568,9 @@ var require_index_cjs = __commonJS({
568
568
  }
569
569
  });
570
570
 
571
- // ../../node_modules/webidl-conversions/lib/index.js
571
+ // ../../node_modules/node-fetch/node_modules/webidl-conversions/lib/index.js
572
572
  var require_lib = __commonJS({
573
- "../../node_modules/webidl-conversions/lib/index.js"(exports2, module2) {
573
+ "../../node_modules/node-fetch/node_modules/webidl-conversions/lib/index.js"(exports2, module2) {
574
574
  "use strict";
575
575
  var conversions = {};
576
576
  module2.exports = conversions;
@@ -721,9 +721,9 @@ var require_lib = __commonJS({
721
721
  }
722
722
  });
723
723
 
724
- // ../../node_modules/whatwg-url/lib/utils.js
724
+ // ../../node_modules/node-fetch/node_modules/whatwg-url/lib/utils.js
725
725
  var require_utils = __commonJS({
726
- "../../node_modules/whatwg-url/lib/utils.js"(exports2, module2) {
726
+ "../../node_modules/node-fetch/node_modules/whatwg-url/lib/utils.js"(exports2, module2) {
727
727
  "use strict";
728
728
  module2.exports.mixin = function mixin(target, source) {
729
729
  const keys = Object.getOwnPropertyNames(source);
@@ -910,9 +910,9 @@ var require_tr46 = __commonJS({
910
910
  }
911
911
  });
912
912
 
913
- // ../../node_modules/whatwg-url/lib/url-state-machine.js
913
+ // ../../node_modules/node-fetch/node_modules/whatwg-url/lib/url-state-machine.js
914
914
  var require_url_state_machine = __commonJS({
915
- "../../node_modules/whatwg-url/lib/url-state-machine.js"(exports2, module2) {
915
+ "../../node_modules/node-fetch/node_modules/whatwg-url/lib/url-state-machine.js"(exports2, module2) {
916
916
  "use strict";
917
917
  var punycode = require("punycode");
918
918
  var tr46 = require_tr46();
@@ -1982,9 +1982,9 @@ var require_url_state_machine = __commonJS({
1982
1982
  }
1983
1983
  });
1984
1984
 
1985
- // ../../node_modules/whatwg-url/lib/URL-impl.js
1985
+ // ../../node_modules/node-fetch/node_modules/whatwg-url/lib/URL-impl.js
1986
1986
  var require_URL_impl = __commonJS({
1987
- "../../node_modules/whatwg-url/lib/URL-impl.js"(exports2) {
1987
+ "../../node_modules/node-fetch/node_modules/whatwg-url/lib/URL-impl.js"(exports2) {
1988
1988
  "use strict";
1989
1989
  var usm = require_url_state_machine();
1990
1990
  exports2.implementation = class URLImpl {
@@ -2139,9 +2139,9 @@ var require_URL_impl = __commonJS({
2139
2139
  }
2140
2140
  });
2141
2141
 
2142
- // ../../node_modules/whatwg-url/lib/URL.js
2142
+ // ../../node_modules/node-fetch/node_modules/whatwg-url/lib/URL.js
2143
2143
  var require_URL = __commonJS({
2144
- "../../node_modules/whatwg-url/lib/URL.js"(exports2, module2) {
2144
+ "../../node_modules/node-fetch/node_modules/whatwg-url/lib/URL.js"(exports2, module2) {
2145
2145
  "use strict";
2146
2146
  var conversions = require_lib();
2147
2147
  var utils = require_utils();
@@ -2321,9 +2321,9 @@ var require_URL = __commonJS({
2321
2321
  }
2322
2322
  });
2323
2323
 
2324
- // ../../node_modules/whatwg-url/lib/public-api.js
2324
+ // ../../node_modules/node-fetch/node_modules/whatwg-url/lib/public-api.js
2325
2325
  var require_public_api = __commonJS({
2326
- "../../node_modules/whatwg-url/lib/public-api.js"(exports2) {
2326
+ "../../node_modules/node-fetch/node_modules/whatwg-url/lib/public-api.js"(exports2) {
2327
2327
  "use strict";
2328
2328
  exports2.URL = require_URL().interface;
2329
2329
  exports2.serializeURL = require_url_state_machine().serializeURL;
@@ -8123,6 +8123,48 @@ var LiteLLMClient = class {
8123
8123
  throw err;
8124
8124
  }
8125
8125
  }
8126
+ /**
8127
+ * Searches for an existing user by email address. Returns the first matching
8128
+ * user or null if none found. Handles both response shapes: a bare array
8129
+ * or `{ users: [...] }`. Matching is case-insensitive on the email address.
8130
+ */
8131
+ async getUserByEmail(email) {
8132
+ try {
8133
+ const raw = await this.request(
8134
+ `/user/list?user_email=${encodeURIComponent(email)}`
8135
+ );
8136
+ let users = [];
8137
+ if (Array.isArray(raw)) {
8138
+ users = raw;
8139
+ } else if (Array.isArray(raw?.users)) {
8140
+ users = raw.users;
8141
+ }
8142
+ if (!users.length) return null;
8143
+ const found = users.find(
8144
+ (u) => (u.user_email ?? u.email ?? "").toLowerCase() === email.toLowerCase()
8145
+ );
8146
+ if (!found) return null;
8147
+ const inner = found.user_info ?? {};
8148
+ const teamIds = Array.isArray(found.teams) ? found.teams.map((t) => typeof t === "string" ? t : t?.team_id).filter((t) => typeof t === "string") : [];
8149
+ return {
8150
+ user_id: found.user_id ?? inner.user_id ?? "",
8151
+ user_email: inner.user_email ?? found.user_email,
8152
+ email: inner.email ?? found.email,
8153
+ teams: teamIds,
8154
+ models: inner.models ?? found.models,
8155
+ max_budget: inner.max_budget ?? found.max_budget,
8156
+ budget_duration: inner.budget_duration ?? found.budget_duration,
8157
+ budget_reset_at: inner.budget_reset_at ?? found.budget_reset_at,
8158
+ spend: inner.spend ?? found.spend,
8159
+ current_spend: inner.current_spend ?? found.current_spend,
8160
+ soft_limit: inner.soft_limit ?? found.soft_limit,
8161
+ hard_limit: inner.hard_limit ?? found.hard_limit
8162
+ };
8163
+ } catch (err) {
8164
+ if (err instanceof LiteLLMUpstreamError && err.status === 404) return null;
8165
+ throw err;
8166
+ }
8167
+ }
8126
8168
  async createUser(payload) {
8127
8169
  return this.request("/user/new", {
8128
8170
  method: "POST",
@@ -11272,10 +11314,10 @@ function registerTeamUsageRoutes(router, ctx) {
11272
11314
  });
11273
11315
  }
11274
11316
 
11275
- // node_modules/jose/dist/node/esm/runtime/base64url.js
11317
+ // ../../node_modules/jose/dist/node/esm/runtime/base64url.js
11276
11318
  var import_node_buffer = require("node:buffer");
11277
11319
 
11278
- // node_modules/jose/dist/node/esm/lib/buffer_utils.js
11320
+ // ../../node_modules/jose/dist/node/esm/lib/buffer_utils.js
11279
11321
  var encoder = new TextEncoder();
11280
11322
  var decoder = new TextDecoder();
11281
11323
  var MAX_INT32 = 2 ** 32;
@@ -11290,7 +11332,7 @@ function concat(...buffers) {
11290
11332
  return buf;
11291
11333
  }
11292
11334
 
11293
- // node_modules/jose/dist/node/esm/runtime/base64url.js
11335
+ // ../../node_modules/jose/dist/node/esm/runtime/base64url.js
11294
11336
  function normalize(input) {
11295
11337
  let encoded = input;
11296
11338
  if (encoded instanceof Uint8Array) {
@@ -11300,7 +11342,7 @@ function normalize(input) {
11300
11342
  }
11301
11343
  var decode = (input) => new Uint8Array(import_node_buffer.Buffer.from(normalize(input), "base64url"));
11302
11344
 
11303
- // node_modules/jose/dist/node/esm/util/errors.js
11345
+ // ../../node_modules/jose/dist/node/esm/util/errors.js
11304
11346
  var JOSEError = class extends Error {
11305
11347
  static code = "ERR_JOSE_GENERIC";
11306
11348
  code = "ERR_JOSE_GENERIC";
@@ -11386,18 +11428,18 @@ var JWSSignatureVerificationFailed = class extends JOSEError {
11386
11428
  }
11387
11429
  };
11388
11430
 
11389
- // node_modules/jose/dist/node/esm/runtime/is_key_object.js
11431
+ // ../../node_modules/jose/dist/node/esm/runtime/is_key_object.js
11390
11432
  var util = __toESM(require("node:util"), 1);
11391
11433
  var is_key_object_default = (obj) => util.types.isKeyObject(obj);
11392
11434
 
11393
- // node_modules/jose/dist/node/esm/runtime/webcrypto.js
11435
+ // ../../node_modules/jose/dist/node/esm/runtime/webcrypto.js
11394
11436
  var crypto = __toESM(require("node:crypto"), 1);
11395
11437
  var util2 = __toESM(require("node:util"), 1);
11396
11438
  var webcrypto2 = crypto.webcrypto;
11397
11439
  var webcrypto_default = webcrypto2;
11398
11440
  var isCryptoKey = (key) => util2.types.isCryptoKey(key);
11399
11441
 
11400
- // node_modules/jose/dist/node/esm/lib/crypto_key.js
11442
+ // ../../node_modules/jose/dist/node/esm/lib/crypto_key.js
11401
11443
  function unusable(name, prop = "algorithm.name") {
11402
11444
  return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
11403
11445
  }
@@ -11496,7 +11538,7 @@ function checkSigCryptoKey(key, alg, ...usages) {
11496
11538
  checkUsage(key, usages);
11497
11539
  }
11498
11540
 
11499
- // node_modules/jose/dist/node/esm/lib/invalid_key_input.js
11541
+ // ../../node_modules/jose/dist/node/esm/lib/invalid_key_input.js
11500
11542
  function message(msg, actual, ...types4) {
11501
11543
  types4 = types4.filter(Boolean);
11502
11544
  if (types4.length > 2) {
@@ -11525,14 +11567,14 @@ function withAlg(alg, actual, ...types4) {
11525
11567
  return message(`Key for the ${alg} algorithm must be `, actual, ...types4);
11526
11568
  }
11527
11569
 
11528
- // node_modules/jose/dist/node/esm/runtime/is_key_like.js
11570
+ // ../../node_modules/jose/dist/node/esm/runtime/is_key_like.js
11529
11571
  var is_key_like_default = (key) => is_key_object_default(key) || isCryptoKey(key);
11530
11572
  var types3 = ["KeyObject"];
11531
11573
  if (globalThis.CryptoKey || webcrypto_default?.CryptoKey) {
11532
11574
  types3.push("CryptoKey");
11533
11575
  }
11534
11576
 
11535
- // node_modules/jose/dist/node/esm/lib/is_disjoint.js
11577
+ // ../../node_modules/jose/dist/node/esm/lib/is_disjoint.js
11536
11578
  var isDisjoint = (...headers) => {
11537
11579
  const sources = headers.filter(Boolean);
11538
11580
  if (sources.length === 0 || sources.length === 1) {
@@ -11556,7 +11598,7 @@ var isDisjoint = (...headers) => {
11556
11598
  };
11557
11599
  var is_disjoint_default = isDisjoint;
11558
11600
 
11559
- // node_modules/jose/dist/node/esm/lib/is_object.js
11601
+ // ../../node_modules/jose/dist/node/esm/lib/is_object.js
11560
11602
  function isObjectLike(value) {
11561
11603
  return typeof value === "object" && value !== null;
11562
11604
  }
@@ -11574,10 +11616,10 @@ function isObject(input) {
11574
11616
  return Object.getPrototypeOf(input) === proto;
11575
11617
  }
11576
11618
 
11577
- // node_modules/jose/dist/node/esm/runtime/get_named_curve.js
11619
+ // ../../node_modules/jose/dist/node/esm/runtime/get_named_curve.js
11578
11620
  var import_node_crypto = require("node:crypto");
11579
11621
 
11580
- // node_modules/jose/dist/node/esm/lib/is_jwk.js
11622
+ // ../../node_modules/jose/dist/node/esm/lib/is_jwk.js
11581
11623
  function isJWK(key) {
11582
11624
  return isObject(key) && typeof key.kty === "string";
11583
11625
  }
@@ -11591,7 +11633,7 @@ function isSecretJWK(key) {
11591
11633
  return isJWK(key) && key.kty === "oct" && typeof key.k === "string";
11592
11634
  }
11593
11635
 
11594
- // node_modules/jose/dist/node/esm/runtime/get_named_curve.js
11636
+ // ../../node_modules/jose/dist/node/esm/runtime/get_named_curve.js
11595
11637
  var namedCurveToJOSE = (namedCurve) => {
11596
11638
  switch (namedCurve) {
11597
11639
  case "prime256v1":
@@ -11640,7 +11682,7 @@ var getNamedCurve2 = (kee, raw) => {
11640
11682
  };
11641
11683
  var get_named_curve_default = getNamedCurve2;
11642
11684
 
11643
- // node_modules/jose/dist/node/esm/runtime/check_key_length.js
11685
+ // ../../node_modules/jose/dist/node/esm/runtime/check_key_length.js
11644
11686
  var import_node_crypto2 = require("node:crypto");
11645
11687
  var check_key_length_default = (key, alg) => {
11646
11688
  let modulusLength;
@@ -11657,7 +11699,7 @@ var check_key_length_default = (key, alg) => {
11657
11699
  }
11658
11700
  };
11659
11701
 
11660
- // node_modules/jose/dist/node/esm/runtime/jwk_to_key.js
11702
+ // ../../node_modules/jose/dist/node/esm/runtime/jwk_to_key.js
11661
11703
  var import_node_crypto3 = require("node:crypto");
11662
11704
  var parse = (key) => {
11663
11705
  if (key.d) {
@@ -11667,7 +11709,7 @@ var parse = (key) => {
11667
11709
  };
11668
11710
  var jwk_to_key_default = parse;
11669
11711
 
11670
- // node_modules/jose/dist/node/esm/key/import.js
11712
+ // ../../node_modules/jose/dist/node/esm/key/import.js
11671
11713
  async function importJWK(jwk, alg) {
11672
11714
  if (!isObject(jwk)) {
11673
11715
  throw new TypeError("JWK must be an object");
@@ -11691,7 +11733,7 @@ async function importJWK(jwk, alg) {
11691
11733
  }
11692
11734
  }
11693
11735
 
11694
- // node_modules/jose/dist/node/esm/lib/check_key_type.js
11736
+ // ../../node_modules/jose/dist/node/esm/lib/check_key_type.js
11695
11737
  var tag = (key) => key?.[Symbol.toStringTag];
11696
11738
  var jwkMatchesOp = (alg, key, usage) => {
11697
11739
  if (key.use !== void 0 && key.use !== "sig") {
@@ -11763,7 +11805,7 @@ function checkKeyType(allowJwk, alg, key, usage) {
11763
11805
  var check_key_type_default = checkKeyType.bind(void 0, false);
11764
11806
  var checkKeyTypeWithJwk = checkKeyType.bind(void 0, true);
11765
11807
 
11766
- // node_modules/jose/dist/node/esm/lib/validate_crit.js
11808
+ // ../../node_modules/jose/dist/node/esm/lib/validate_crit.js
11767
11809
  function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
11768
11810
  if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
11769
11811
  throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
@@ -11795,7 +11837,7 @@ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader,
11795
11837
  }
11796
11838
  var validate_crit_default = validateCrit;
11797
11839
 
11798
- // node_modules/jose/dist/node/esm/lib/validate_algorithms.js
11840
+ // ../../node_modules/jose/dist/node/esm/lib/validate_algorithms.js
11799
11841
  var validateAlgorithms = (option, algorithms) => {
11800
11842
  if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
11801
11843
  throw new TypeError(`"${option}" option must be an array of strings`);
@@ -11807,11 +11849,11 @@ var validateAlgorithms = (option, algorithms) => {
11807
11849
  };
11808
11850
  var validate_algorithms_default = validateAlgorithms;
11809
11851
 
11810
- // node_modules/jose/dist/node/esm/runtime/verify.js
11852
+ // ../../node_modules/jose/dist/node/esm/runtime/verify.js
11811
11853
  var crypto3 = __toESM(require("node:crypto"), 1);
11812
11854
  var import_node_util2 = require("node:util");
11813
11855
 
11814
- // node_modules/jose/dist/node/esm/runtime/dsa_digest.js
11856
+ // ../../node_modules/jose/dist/node/esm/runtime/dsa_digest.js
11815
11857
  function dsaDigest(alg) {
11816
11858
  switch (alg) {
11817
11859
  case "PS256":
@@ -11835,7 +11877,7 @@ function dsaDigest(alg) {
11835
11877
  }
11836
11878
  }
11837
11879
 
11838
- // node_modules/jose/dist/node/esm/runtime/node_key.js
11880
+ // ../../node_modules/jose/dist/node/esm/runtime/node_key.js
11839
11881
  var import_node_crypto4 = require("node:crypto");
11840
11882
  var ecCurveAlgMap = /* @__PURE__ */ new Map([
11841
11883
  ["ES256", "P-256"],
@@ -11939,11 +11981,11 @@ function keyForCrypto(alg, key) {
11939
11981
  return options ? { ...options, key } : key;
11940
11982
  }
11941
11983
 
11942
- // node_modules/jose/dist/node/esm/runtime/sign.js
11984
+ // ../../node_modules/jose/dist/node/esm/runtime/sign.js
11943
11985
  var crypto2 = __toESM(require("node:crypto"), 1);
11944
11986
  var import_node_util = require("node:util");
11945
11987
 
11946
- // node_modules/jose/dist/node/esm/runtime/hmac_digest.js
11988
+ // ../../node_modules/jose/dist/node/esm/runtime/hmac_digest.js
11947
11989
  function hmacDigest(alg) {
11948
11990
  switch (alg) {
11949
11991
  case "HS256":
@@ -11957,7 +11999,7 @@ function hmacDigest(alg) {
11957
11999
  }
11958
12000
  }
11959
12001
 
11960
- // node_modules/jose/dist/node/esm/runtime/get_sign_verify_key.js
12002
+ // ../../node_modules/jose/dist/node/esm/runtime/get_sign_verify_key.js
11961
12003
  var import_node_crypto5 = require("node:crypto");
11962
12004
  function getSignVerifyKey(alg, key, usage) {
11963
12005
  if (key instanceof Uint8Array) {
@@ -11982,7 +12024,7 @@ function getSignVerifyKey(alg, key, usage) {
11982
12024
  throw new TypeError(invalid_key_input_default(key, ...types3, "Uint8Array", "JSON Web Key"));
11983
12025
  }
11984
12026
 
11985
- // node_modules/jose/dist/node/esm/runtime/sign.js
12027
+ // ../../node_modules/jose/dist/node/esm/runtime/sign.js
11986
12028
  var oneShotSign = (0, import_node_util.promisify)(crypto2.sign);
11987
12029
  var sign2 = async (alg, key, data) => {
11988
12030
  const k = getSignVerifyKey(alg, key, "sign");
@@ -11995,7 +12037,7 @@ var sign2 = async (alg, key, data) => {
11995
12037
  };
11996
12038
  var sign_default = sign2;
11997
12039
 
11998
- // node_modules/jose/dist/node/esm/runtime/verify.js
12040
+ // ../../node_modules/jose/dist/node/esm/runtime/verify.js
11999
12041
  var oneShotVerify = (0, import_node_util2.promisify)(crypto3.verify);
12000
12042
  var verify2 = async (alg, key, signature, data) => {
12001
12043
  const k = getSignVerifyKey(alg, key, "verify");
@@ -12018,7 +12060,7 @@ var verify2 = async (alg, key, signature, data) => {
12018
12060
  };
12019
12061
  var verify_default = verify2;
12020
12062
 
12021
- // node_modules/jose/dist/node/esm/jws/flattened/verify.js
12063
+ // ../../node_modules/jose/dist/node/esm/jws/flattened/verify.js
12022
12064
  async function flattenedVerify(jws, key, options) {
12023
12065
  if (!isObject(jws)) {
12024
12066
  throw new JWSInvalid("Flattened JWS must be an object");
@@ -12124,7 +12166,7 @@ async function flattenedVerify(jws, key, options) {
12124
12166
  return result;
12125
12167
  }
12126
12168
 
12127
- // node_modules/jose/dist/node/esm/jws/compact/verify.js
12169
+ // ../../node_modules/jose/dist/node/esm/jws/compact/verify.js
12128
12170
  async function compactVerify(jws, key, options) {
12129
12171
  if (jws instanceof Uint8Array) {
12130
12172
  jws = decoder.decode(jws);
@@ -12144,10 +12186,10 @@ async function compactVerify(jws, key, options) {
12144
12186
  return result;
12145
12187
  }
12146
12188
 
12147
- // node_modules/jose/dist/node/esm/lib/epoch.js
12189
+ // ../../node_modules/jose/dist/node/esm/lib/epoch.js
12148
12190
  var epoch_default = (date) => Math.floor(date.getTime() / 1e3);
12149
12191
 
12150
- // node_modules/jose/dist/node/esm/lib/secs.js
12192
+ // ../../node_modules/jose/dist/node/esm/lib/secs.js
12151
12193
  var minute = 60;
12152
12194
  var hour = minute * 60;
12153
12195
  var day = hour * 24;
@@ -12204,7 +12246,7 @@ var secs_default = (str) => {
12204
12246
  return numericDate;
12205
12247
  };
12206
12248
 
12207
- // node_modules/jose/dist/node/esm/lib/jwt_claims_set.js
12249
+ // ../../node_modules/jose/dist/node/esm/lib/jwt_claims_set.js
12208
12250
  var normalizeTyp = (value) => value.toLowerCase().replace(/^application\//, "");
12209
12251
  var checkAudiencePresence = (audPayload, audOption) => {
12210
12252
  if (typeof audPayload === "string") {
@@ -12300,7 +12342,7 @@ var jwt_claims_set_default = (protectedHeader, encodedPayload, options = {}) =>
12300
12342
  return payload;
12301
12343
  };
12302
12344
 
12303
- // node_modules/jose/dist/node/esm/jwt/verify.js
12345
+ // ../../node_modules/jose/dist/node/esm/jwt/verify.js
12304
12346
  async function jwtVerify(jwt, key, options) {
12305
12347
  const verified = await compactVerify(jwt, key, options);
12306
12348
  if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
@@ -12314,7 +12356,7 @@ async function jwtVerify(jwt, key, options) {
12314
12356
  return result;
12315
12357
  }
12316
12358
 
12317
- // node_modules/jose/dist/node/esm/jwks/local.js
12359
+ // ../../node_modules/jose/dist/node/esm/jwks/local.js
12318
12360
  function getKtyFromAlg(alg) {
12319
12361
  switch (typeof alg === "string" && alg.slice(0, 2)) {
12320
12362
  case "RS":
@@ -12435,7 +12477,7 @@ function createLocalJWKSet(jwks) {
12435
12477
  return localJWKSet;
12436
12478
  }
12437
12479
 
12438
- // node_modules/jose/dist/node/esm/runtime/fetch_jwks.js
12480
+ // ../../node_modules/jose/dist/node/esm/runtime/fetch_jwks.js
12439
12481
  var http = __toESM(require("node:http"), 1);
12440
12482
  var https = __toESM(require("node:https"), 1);
12441
12483
  var import_node_events = require("node:events");
@@ -12477,7 +12519,7 @@ var fetchJwks = async (url, timeout, options) => {
12477
12519
  };
12478
12520
  var fetch_jwks_default = fetchJwks;
12479
12521
 
12480
- // node_modules/jose/dist/node/esm/jwks/remote.js
12522
+ // ../../node_modules/jose/dist/node/esm/jwks/remote.js
12481
12523
  function isCloudflareWorkers() {
12482
12524
  return typeof WebSocketPair !== "undefined" || typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers" || typeof EdgeRuntime !== "undefined" && EdgeRuntime === "vercel";
12483
12525
  }
@@ -12718,13 +12760,32 @@ function resolveBridgeUserId(claims, identity) {
12718
12760
  `email domain mismatch: "${domain}" is not allowed for this deployment`
12719
12761
  );
12720
12762
  }
12721
- const name = claims.preferred_username?.trim() || emailLocalPart;
12763
+ let name = claims.preferred_username?.trim();
12764
+ if (name && name.includes("@")) {
12765
+ const usernameParts = name.split("@");
12766
+ if (usernameParts.length === 2 && usernameParts[0]) {
12767
+ const [userLocal, userDomain] = usernameParts;
12768
+ if (trusted.includes(userDomain.toLowerCase())) {
12769
+ name = userLocal;
12770
+ }
12771
+ }
12772
+ }
12773
+ name = name || emailLocalPart;
12722
12774
  return toLiteLLMUserId(name, userIdDomain);
12723
12775
  }
12724
12776
  async function getOrProvisionUserFromClaims(client, claims, provisioningEnabled, provisioningDefaults, logger, userIdDomain) {
12725
12777
  const userId = resolveBridgeUserId(claims, userIdDomain);
12726
12778
  const existing = await client.getUserInfo(userId);
12727
12779
  if (existing) return existing;
12780
+ if (claims.email) {
12781
+ const byEmail = await client.getUserByEmail(claims.email);
12782
+ if (byEmail) {
12783
+ logger.info(
12784
+ `Found existing LiteLLM user ${byEmail.user_id} by email ${claims.email}, reusing for ${userId}`
12785
+ );
12786
+ return byEmail;
12787
+ }
12788
+ }
12728
12789
  if (!provisioningEnabled) {
12729
12790
  throw new ProvisioningError(
12730
12791
  "User not found in LiteLLM",
@@ -12755,7 +12816,7 @@ async function getOrProvisionUserFromClaims(client, claims, provisioningEnabled,
12755
12816
  return created;
12756
12817
  }
12757
12818
  async function bridgeListKeys(client, claims, provisioningEnabled, provisioningDefaults, logger, userIdDomain) {
12758
- await getOrProvisionUserFromClaims(
12819
+ const user = await getOrProvisionUserFromClaims(
12759
12820
  client,
12760
12821
  claims,
12761
12822
  provisioningEnabled,
@@ -12763,10 +12824,10 @@ async function bridgeListKeys(client, claims, provisioningEnabled, provisioningD
12763
12824
  logger,
12764
12825
  userIdDomain
12765
12826
  );
12766
- return client.listKeys(resolveBridgeUserId(claims, userIdDomain));
12827
+ return client.listKeys(user.user_id);
12767
12828
  }
12768
12829
  async function bridgeGenerateKey(client, claims, provisioningEnabled, provisioningDefaults, logger, request, userIdDomain) {
12769
- await getOrProvisionUserFromClaims(
12830
+ const user = await getOrProvisionUserFromClaims(
12770
12831
  client,
12771
12832
  claims,
12772
12833
  provisioningEnabled,
@@ -12774,14 +12835,13 @@ async function bridgeGenerateKey(client, claims, provisioningEnabled, provisioni
12774
12835
  logger,
12775
12836
  userIdDomain
12776
12837
  );
12777
- const userId = resolveBridgeUserId(claims, userIdDomain);
12778
12838
  const enriched = {
12779
12839
  ...request,
12780
- user_id: userId,
12840
+ user_id: user.user_id,
12781
12841
  metadata: {
12782
12842
  ...request.metadata ?? {},
12783
12843
  created_via: "abby-cli",
12784
- created_by: userId,
12844
+ created_by: user.user_id,
12785
12845
  created_at_iso: (/* @__PURE__ */ new Date()).toISOString()
12786
12846
  }
12787
12847
  };