@gitlab/gitlab-ai-provider 3.5.0 → 3.6.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/dist/index.mjs CHANGED
@@ -665,6 +665,7 @@ import OpenAI from "openai";
665
665
  var MODEL_MAPPINGS = {
666
666
  // Anthropic models
667
667
  "duo-chat-opus-4-6": { provider: "anthropic", model: "claude-opus-4-6" },
668
+ "duo-chat-sonnet-4-6": { provider: "anthropic", model: "claude-sonnet-4-6" },
668
669
  "duo-chat-opus-4-5": { provider: "anthropic", model: "claude-opus-4-5-20251101" },
669
670
  "duo-chat-sonnet-4-5": { provider: "anthropic", model: "claude-sonnet-4-5-20250929" },
670
671
  "duo-chat-haiku-4-5": { provider: "anthropic", model: "claude-haiku-4-5-20251001" },
@@ -1460,6 +1461,7 @@ var GitLabOpenAILanguageModel = class {
1460
1461
  };
1461
1462
 
1462
1463
  // src/gitlab-oauth-types.ts
1464
+ var OPENCODE_GITLAB_AUTH_CLIENT_ID = "1d89f9fdb23ee96d4e603201f6861dab6e143c5c3c00469a018a2d94bdc03d4e";
1463
1465
  var BUNDLED_CLIENT_ID = "36f2a70cddeb5a0889d4fd8295c241b7e9848e89cf9e599d0eed2d8e5350fbf5";
1464
1466
  var GITLAB_COM_URL = "https://gitlab.com";
1465
1467
  var TOKEN_EXPIRY_SKEW_MS = 5 * 60 * 1e3;
@@ -1533,14 +1535,21 @@ var GitLabOAuthManager = class {
1533
1535
  return this.createTokensFromResponse(tokenResponse, instanceUrl);
1534
1536
  }
1535
1537
  /**
1536
- * Get the OAuth client ID for an instance
1538
+ * Get the OAuth client ID for an instance.
1539
+ * Priority: env var > opencode-gitlab-auth default (for GitLab.com).
1540
+ * Note: callers (e.g. exchangeRefreshToken) may pass an explicit clientId
1541
+ * that bypasses this method entirely.
1537
1542
  */
1538
1543
  getClientId(instanceUrl) {
1544
+ const envClientId = process.env["GITLAB_OAUTH_CLIENT_ID"];
1545
+ if (envClientId) {
1546
+ return envClientId;
1547
+ }
1539
1548
  if (instanceUrl === GITLAB_COM_URL) {
1540
- return BUNDLED_CLIENT_ID;
1549
+ return OPENCODE_GITLAB_AUTH_CLIENT_ID;
1541
1550
  }
1542
1551
  throw new GitLabError({
1543
- message: `No OAuth client ID configured for instance ${instanceUrl}. Please provide a clientId parameter.`
1552
+ message: `No OAuth client ID configured for instance ${instanceUrl}. Please provide a clientId parameter or set GITLAB_OAUTH_CLIENT_ID environment variable.`
1544
1553
  });
1545
1554
  }
1546
1555
  /**
@@ -1622,7 +1631,7 @@ var GitLabOAuthManager = class {
1622
1631
  };
1623
1632
 
1624
1633
  // src/version.ts
1625
- var VERSION = true ? "3.4.1" : "0.0.0-dev";
1634
+ var VERSION = true ? "3.5.1" : "0.0.0-dev";
1626
1635
 
1627
1636
  // src/gitlab-provider.ts
1628
1637
  import * as fs from "fs";
@@ -1675,20 +1684,26 @@ async function loadApiKey(options, instanceUrl, clientId) {
1675
1684
  });
1676
1685
  const authPath = getOpenCodeAuthPath();
1677
1686
  const authData = JSON.parse(fs.readFileSync(authPath, "utf-8"));
1678
- const normalizedUrl = instanceUrl.replace(/\/$/, "");
1679
- authData[normalizedUrl] = {
1687
+ authData.gitlab = {
1680
1688
  type: "oauth",
1681
1689
  refresh: refreshed.refreshToken,
1682
1690
  access: refreshed.accessToken,
1683
1691
  expires: refreshed.expiresAt,
1684
- instanceUrl
1692
+ enterpriseUrl: instanceUrl
1693
+ // Use enterpriseUrl to match auth plugin format
1685
1694
  };
1686
- fs.writeFileSync(authPath, JSON.stringify(authData, null, 2));
1695
+ fs.writeFileSync(authPath, JSON.stringify(authData, null, 2), { mode: 384 });
1687
1696
  return refreshed.accessToken;
1688
1697
  } catch (error) {
1689
- console.warn(
1690
- `Failed to refresh OAuth token: ${error instanceof Error ? error.message : String(error)}`
1691
- );
1698
+ const refreshErrorMsg = error instanceof Error ? error.message : String(error);
1699
+ console.warn(`Failed to refresh OAuth token: ${refreshErrorMsg}`);
1700
+ const envApiKey = process.env[options.environmentVariableName];
1701
+ if (envApiKey) {
1702
+ return envApiKey;
1703
+ }
1704
+ throw new GitLabError({
1705
+ message: `OAuth token refresh failed and no fallback ${options.environmentVariableName} environment variable is set. Refresh error: ${refreshErrorMsg}. Re-authenticate with 'opencode auth login gitlab' or set ${options.environmentVariableName}.`
1706
+ });
1692
1707
  }
1693
1708
  } else {
1694
1709
  return auth.access;
@@ -1737,7 +1752,16 @@ function createGitLab(options = {}) {
1737
1752
  const refreshApiKey = async () => {
1738
1753
  cachedApiKey = void 0;
1739
1754
  apiKeyPromise = void 0;
1740
- cachedApiKey = await getApiKey();
1755
+ cachedApiKey = await loadApiKey(
1756
+ {
1757
+ apiKey: void 0,
1758
+ // Bypass stale options.apiKey to force auth.json read
1759
+ environmentVariableName: "GITLAB_TOKEN",
1760
+ description: "GitLab"
1761
+ },
1762
+ instanceUrl,
1763
+ options.clientId
1764
+ );
1741
1765
  };
1742
1766
  const getHeaders = () => {
1743
1767
  const apiKey = cachedApiKey || options.apiKey || process.env["GITLAB_TOKEN"] || "";
@@ -2113,6 +2137,7 @@ export {
2113
2137
  MODEL_ID_TO_ANTHROPIC_MODEL,
2114
2138
  MODEL_MAPPINGS,
2115
2139
  OAUTH_SCOPES,
2140
+ OPENCODE_GITLAB_AUTH_CLIENT_ID,
2116
2141
  TOKEN_EXPIRY_SKEW_MS,
2117
2142
  VERSION,
2118
2143
  createGitLab,