gitlab-ai-provider 6.9.1 → 6.9.3

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.mjs CHANGED
@@ -648,6 +648,9 @@ var GitLabDirectAccessClient = class {
648
648
  if (this.config.featureFlags && Object.keys(this.config.featureFlags).length > 0) {
649
649
  requestBody.feature_flags = this.config.featureFlags;
650
650
  }
651
+ if (this.config.ensureApiKey) {
652
+ await this.config.ensureApiKey();
653
+ }
651
654
  try {
652
655
  const response = await this.fetchFn(url, {
653
656
  method: "POST",
@@ -743,6 +746,7 @@ var GitLabAnthropicLanguageModel = class {
743
746
  this.directAccessClient = new GitLabDirectAccessClient({
744
747
  instanceUrl: config.instanceUrl,
745
748
  getHeaders: config.getHeaders,
749
+ ensureApiKey: config.ensureApiKey,
746
750
  refreshApiKey: config.refreshApiKey,
747
751
  fetch: config.fetch,
748
752
  featureFlags: config.featureFlags,
@@ -1476,6 +1480,7 @@ var GitLabOpenAILanguageModel = class {
1476
1480
  this.directAccessClient = new GitLabDirectAccessClient({
1477
1481
  instanceUrl: config.instanceUrl,
1478
1482
  getHeaders: config.getHeaders,
1483
+ ensureApiKey: config.ensureApiKey,
1479
1484
  refreshApiKey: config.refreshApiKey,
1480
1485
  fetch: config.fetch,
1481
1486
  featureFlags: config.featureFlags,
@@ -2417,7 +2422,7 @@ import { AsyncResource } from "async_hooks";
2417
2422
  import WebSocket from "isomorphic-ws";
2418
2423
 
2419
2424
  // src/version.ts
2420
- var VERSION = true ? "6.9.0" : "0.0.0-dev";
2425
+ var VERSION = true ? "6.9.2" : "0.0.0-dev";
2421
2426
 
2422
2427
  // src/gitlab-workflow-client.ts
2423
2428
  var WS_CONNECT_TIMEOUT_MS = 3e4;
@@ -4754,9 +4759,10 @@ var TOKEN_EXPIRY_SKEW_MS = 5 * 60 * 1e3;
4754
4759
  var OAUTH_SCOPES = ["api"];
4755
4760
 
4756
4761
  // src/gitlab-oauth-manager.ts
4762
+ var globalInFlightRefreshes = /* @__PURE__ */ new Map();
4757
4763
  var GitLabOAuthManager = class {
4758
4764
  fetch;
4759
- inFlightRefreshes = /* @__PURE__ */ new Map();
4765
+ inFlightRefreshes = globalInFlightRefreshes;
4760
4766
  constructor(fetchImpl = fetch) {
4761
4767
  this.fetch = fetchImpl;
4762
4768
  }
@@ -4969,12 +4975,15 @@ async function loadOpenCodeAuth(instanceUrl) {
4969
4975
  }
4970
4976
  const authData = JSON.parse(fs3.readFileSync(authPath, "utf-8"));
4971
4977
  const normalizedUrl = instanceUrl.replace(/\/$/, "");
4972
- if (authData.gitlab?.type === "oauth") {
4973
- const gitlabAuth = authData.gitlab;
4974
- const normalizedEnterpriseUrl = typeof gitlabAuth.enterpriseUrl === "string" ? gitlabAuth.enterpriseUrl.replace(/\/$/, "") : gitlabAuth.enterpriseUrl;
4975
- if (normalizedEnterpriseUrl === normalizedUrl) {
4978
+ const gitlabAuth = authData.gitlab;
4979
+ if (gitlabAuth?.type === "oauth") {
4980
+ const normalizedEnterpriseUrl = typeof gitlabAuth.enterpriseUrl === "string" ? gitlabAuth.enterpriseUrl.replace(/\/$/, "") : void 0;
4981
+ const matchesInstance = normalizedEnterpriseUrl === normalizedUrl || normalizedEnterpriseUrl === void 0 && normalizedUrl === GITLAB_COM_URL;
4982
+ if (matchesInstance) {
4976
4983
  return gitlabAuth;
4977
4984
  }
4985
+ } else if (gitlabAuth?.type === "api" && typeof gitlabAuth.key === "string") {
4986
+ return gitlabAuth;
4978
4987
  }
4979
4988
  const auth = authData[normalizedUrl] || authData[`${normalizedUrl}/`];
4980
4989
  return auth;
@@ -4982,32 +4991,52 @@ async function loadOpenCodeAuth(instanceUrl) {
4982
4991
  return void 0;
4983
4992
  }
4984
4993
  }
4994
+ var inFlightOAuthRefreshes = /* @__PURE__ */ new Map();
4995
+ async function refreshOAuthToken(auth, instanceUrl, clientId) {
4996
+ const existing = inFlightOAuthRefreshes.get(instanceUrl);
4997
+ if (existing) {
4998
+ return existing;
4999
+ }
5000
+ const refreshPromise = (async () => {
5001
+ const oauthManager = new GitLabOAuthManager();
5002
+ const refreshed = await oauthManager.exchangeRefreshToken({
5003
+ instanceUrl,
5004
+ refreshToken: auth.refresh,
5005
+ clientId
5006
+ });
5007
+ const authPath = getOpenCodeAuthPath();
5008
+ const authData = JSON.parse(fs3.readFileSync(authPath, "utf-8"));
5009
+ authData.gitlab = {
5010
+ type: "oauth",
5011
+ refresh: refreshed.refreshToken,
5012
+ access: refreshed.accessToken,
5013
+ expires: refreshed.expiresAt,
5014
+ enterpriseUrl: instanceUrl
5015
+ // Use enterpriseUrl to match auth plugin format
5016
+ };
5017
+ fs3.writeFileSync(authPath, JSON.stringify(authData, null, 2), { mode: 384 });
5018
+ return refreshed.accessToken;
5019
+ })();
5020
+ inFlightOAuthRefreshes.set(instanceUrl, refreshPromise);
5021
+ try {
5022
+ return await refreshPromise;
5023
+ } finally {
5024
+ inFlightOAuthRefreshes.delete(instanceUrl);
5025
+ }
5026
+ }
4985
5027
  async function loadApiKey(options, instanceUrl, clientId) {
4986
5028
  if (options.apiKey) {
4987
5029
  return options.apiKey;
4988
5030
  }
4989
5031
  const auth = await loadOpenCodeAuth(instanceUrl);
5032
+ if (auth?.type === "api") {
5033
+ return auth.key;
5034
+ }
4990
5035
  if (auth?.type === "oauth") {
4991
5036
  const oauthManager = new GitLabOAuthManager();
4992
5037
  if (oauthManager.needsRefresh(auth.expires)) {
4993
5038
  try {
4994
- const refreshed = await oauthManager.exchangeRefreshToken({
4995
- instanceUrl,
4996
- refreshToken: auth.refresh,
4997
- clientId
4998
- });
4999
- const authPath = getOpenCodeAuthPath();
5000
- const authData = JSON.parse(fs3.readFileSync(authPath, "utf-8"));
5001
- authData.gitlab = {
5002
- type: "oauth",
5003
- refresh: refreshed.refreshToken,
5004
- access: refreshed.accessToken,
5005
- expires: refreshed.expiresAt,
5006
- enterpriseUrl: instanceUrl
5007
- // Use enterpriseUrl to match auth plugin format
5008
- };
5009
- fs3.writeFileSync(authPath, JSON.stringify(authData, null, 2), { mode: 384 });
5010
- return refreshed.accessToken;
5039
+ return await refreshOAuthToken(auth, instanceUrl, clientId);
5011
5040
  } catch (error) {
5012
5041
  const refreshErrorMsg = error instanceof Error ? error.message : String(error);
5013
5042
  const envApiKey = process.env[options.environmentVariableName];
@@ -5106,6 +5135,12 @@ function createGitLab(options = {}) {
5106
5135
  `ai-sdk-gitlab/${VERSION}`
5107
5136
  );
5108
5137
  };
5138
+ const ensureApiKey = async () => {
5139
+ try {
5140
+ await getApiKey();
5141
+ } catch {
5142
+ }
5143
+ };
5109
5144
  getApiKey().catch(() => {
5110
5145
  });
5111
5146
  const createAgenticChatModel = (modelId, agenticOptions) => {
@@ -5140,6 +5175,7 @@ function createGitLab(options = {}) {
5140
5175
  provider: `${providerName}.agentic`,
5141
5176
  instanceUrl,
5142
5177
  getHeaders,
5178
+ ensureApiKey,
5143
5179
  refreshApiKey,
5144
5180
  fetch: options.fetch,
5145
5181
  maxTokens: agenticOptions?.maxTokens,