@gitlab/gitlab-ai-provider 3.3.1 → 3.4.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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
4
4
 
5
+ ## 3.4.0 (2026-02-02)
6
+
7
+ - Merge branch 'feat/ai-gateway-headers' into 'main' ([f2d4c79](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/f2d4c79))
8
+ - feat: add custom AI Gateway headers support ([2ef662d](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/2ef662d))
9
+ - chore: added models testing script ([85dd9ba](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/85dd9ba))
10
+ - chore: bump version to 3.3.1 to fix package-lock.json sync ([6e6e9e2](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/6e6e9e2))
11
+
5
12
  ## 3.3.0 (2026-01-23)
6
13
 
7
14
  - feat: add GPT-5.2 model support (duo-chat-gpt-5-2) ([fba8c4c](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/fba8c4c))
package/README.md CHANGED
@@ -272,6 +272,33 @@ const gitlab = createGitLab({
272
272
  });
273
273
  ```
274
274
 
275
+ ### AI Gateway Headers
276
+
277
+ Custom headers can be sent to GitLab's AI Gateway (Anthropic/OpenAI proxy) for traffic identification and routing. By default, the provider sends `User-Agent: gitlab-ai-provider/{version}`.
278
+
279
+ ```typescript
280
+ // Provider-level headers (apply to all agentic models)
281
+ const gitlab = createGitLab({
282
+ apiKey: process.env.GITLAB_TOKEN,
283
+ aiGatewayHeaders: {
284
+ 'X-Custom-Routing': 'premium-tier',
285
+ },
286
+ });
287
+
288
+ // Model-level headers (override provider-level)
289
+ const model = gitlab.agenticChat('duo-chat-opus-4-5', {
290
+ aiGatewayHeaders: {
291
+ 'X-Request-Priority': 'high',
292
+ },
293
+ });
294
+ ```
295
+
296
+ **Header Precedence (lowest to highest):**
297
+
298
+ 1. Default headers (`User-Agent: gitlab-ai-provider/{version}`)
299
+ 2. Provider-level `aiGatewayHeaders`
300
+ 3. Model-level `aiGatewayHeaders`
301
+
275
302
  ## 🏗️ Architecture
276
303
 
277
304
  ### Core Components
@@ -374,7 +401,8 @@ interface GitLabProviderSettings {
374
401
  apiKey?: string; // PAT or OAuth access token
375
402
  refreshToken?: string; // OAuth refresh token
376
403
  name?: string; // Provider name prefix
377
- headers?: Record<string, string>; // Custom headers
404
+ headers?: Record<string, string>; // Custom headers for GitLab API
405
+ aiGatewayHeaders?: Record<string, string>; // Custom headers for AI Gateway proxy
378
406
  fetch?: typeof fetch; // Custom fetch implementation
379
407
  aiGatewayUrl?: string; // AI Gateway URL (default: 'https://cloud.gitlab.com')
380
408
  }
@@ -394,6 +422,7 @@ interface GitLabAgenticOptions {
394
422
  providerModel?: string; // Override the backend model (e.g., 'claude-sonnet-4-5-20250929' or 'gpt-5.1-2025-11-13')
395
423
  maxTokens?: number; // Default: 8192
396
424
  featureFlags?: Record<string, boolean>; // GitLab feature flags
425
+ aiGatewayHeaders?: Record<string, string>; // Custom headers for AI Gateway proxy (per-model)
397
426
  }
398
427
  ```
399
428
 
package/dist/index.d.mts CHANGED
@@ -34,6 +34,11 @@ interface GitLabAnthropicConfig {
34
34
  * @default 'https://cloud.gitlab.com'
35
35
  */
36
36
  aiGatewayUrl?: string;
37
+ /**
38
+ * Custom headers for AI Gateway Anthropic proxy requests.
39
+ * Merged with headers from direct_access token response.
40
+ */
41
+ aiGatewayHeaders?: Record<string, string>;
37
42
  }
38
43
  /**
39
44
  * GitLab Anthropic Language Model
@@ -154,6 +159,12 @@ interface GitLabAgenticOptions {
154
159
  * Feature flags to pass to the GitLab API
155
160
  */
156
161
  featureFlags?: Record<string, boolean>;
162
+ /**
163
+ * Custom headers for AI Gateway requests (per-model override).
164
+ * These headers are sent to the Anthropic/OpenAI proxy endpoints.
165
+ * Merged with provider-level aiGatewayHeaders (model-level takes precedence).
166
+ */
167
+ aiGatewayHeaders?: Record<string, string>;
157
168
  }
158
169
  interface GitLabProviderSettings {
159
170
  /**
@@ -200,6 +211,12 @@ interface GitLabProviderSettings {
200
211
  * @default 'https://cloud.gitlab.com'
201
212
  */
202
213
  aiGatewayUrl?: string;
214
+ /**
215
+ * Custom headers to include in AI Gateway requests (Anthropic/OpenAI proxy).
216
+ * These headers are merged with the default headers from direct_access response.
217
+ * Default User-Agent: gitlab-ai-provider/{version}
218
+ */
219
+ aiGatewayHeaders?: Record<string, string>;
203
220
  }
204
221
  declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
205
222
  /**
@@ -214,6 +231,8 @@ declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
214
231
  */
215
232
  declare const gitlab: GitLabProvider;
216
233
 
234
+ declare const VERSION: string;
235
+
217
236
  interface GitLabOpenAIConfig {
218
237
  provider: string;
219
238
  instanceUrl: string;
@@ -228,6 +247,11 @@ interface GitLabOpenAIConfig {
228
247
  aiGatewayUrl?: string;
229
248
  /** Whether to use the Responses API instead of Chat Completions API */
230
249
  useResponsesApi?: boolean;
250
+ /**
251
+ * Custom headers for AI Gateway OpenAI proxy requests.
252
+ * Merged with headers from direct_access token response.
253
+ */
254
+ aiGatewayHeaders?: Record<string, string>;
231
255
  }
232
256
  declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
233
257
  readonly specificationVersion: "v2";
@@ -641,4 +665,4 @@ declare class GitLabDirectAccessClient {
641
665
  invalidateToken(): void;
642
666
  }
643
667
 
644
- export { BUNDLED_CLIENT_ID, DEFAULT_AI_GATEWAY_URL, type DirectAccessToken, GITLAB_COM_URL, type GitLabAgenticOptions, type GitLabAnthropicConfig, GitLabAnthropicLanguageModel, GitLabDirectAccessClient, type GitLabDirectAccessConfig, GitLabError, type GitLabErrorOptions, GitLabOAuthManager, type GitLabOAuthTokenResponse, type GitLabOAuthTokens, type GitLabOpenAIConfig, GitLabOpenAILanguageModel, type GitLabProject, GitLabProjectCache, GitLabProjectDetector, type GitLabProjectDetectorConfig, type GitLabProvider, type GitLabProviderSettings, MODEL_ID_TO_ANTHROPIC_MODEL, MODEL_MAPPINGS, type ModelMapping, type ModelProvider, OAUTH_SCOPES, type OpenAIApiType, type OpenCodeAuth, type OpenCodeAuthApi, type OpenCodeAuthOAuth, TOKEN_EXPIRY_SKEW_MS, createGitLab, getAnthropicModelForModelId, getModelMapping, getOpenAIApiType, getOpenAIModelForModelId, getProviderForModelId, getValidModelsForProvider, gitlab, isResponsesApiModel };
668
+ export { BUNDLED_CLIENT_ID, DEFAULT_AI_GATEWAY_URL, type DirectAccessToken, GITLAB_COM_URL, type GitLabAgenticOptions, type GitLabAnthropicConfig, GitLabAnthropicLanguageModel, GitLabDirectAccessClient, type GitLabDirectAccessConfig, GitLabError, type GitLabErrorOptions, GitLabOAuthManager, type GitLabOAuthTokenResponse, type GitLabOAuthTokens, type GitLabOpenAIConfig, GitLabOpenAILanguageModel, type GitLabProject, GitLabProjectCache, GitLabProjectDetector, type GitLabProjectDetectorConfig, type GitLabProvider, type GitLabProviderSettings, MODEL_ID_TO_ANTHROPIC_MODEL, MODEL_MAPPINGS, type ModelMapping, type ModelProvider, OAUTH_SCOPES, type OpenAIApiType, type OpenCodeAuth, type OpenCodeAuthApi, type OpenCodeAuthOAuth, TOKEN_EXPIRY_SKEW_MS, VERSION, createGitLab, getAnthropicModelForModelId, getModelMapping, getOpenAIApiType, getOpenAIModelForModelId, getProviderForModelId, getValidModelsForProvider, gitlab, isResponsesApiModel };
package/dist/index.d.ts CHANGED
@@ -34,6 +34,11 @@ interface GitLabAnthropicConfig {
34
34
  * @default 'https://cloud.gitlab.com'
35
35
  */
36
36
  aiGatewayUrl?: string;
37
+ /**
38
+ * Custom headers for AI Gateway Anthropic proxy requests.
39
+ * Merged with headers from direct_access token response.
40
+ */
41
+ aiGatewayHeaders?: Record<string, string>;
37
42
  }
38
43
  /**
39
44
  * GitLab Anthropic Language Model
@@ -154,6 +159,12 @@ interface GitLabAgenticOptions {
154
159
  * Feature flags to pass to the GitLab API
155
160
  */
156
161
  featureFlags?: Record<string, boolean>;
162
+ /**
163
+ * Custom headers for AI Gateway requests (per-model override).
164
+ * These headers are sent to the Anthropic/OpenAI proxy endpoints.
165
+ * Merged with provider-level aiGatewayHeaders (model-level takes precedence).
166
+ */
167
+ aiGatewayHeaders?: Record<string, string>;
157
168
  }
158
169
  interface GitLabProviderSettings {
159
170
  /**
@@ -200,6 +211,12 @@ interface GitLabProviderSettings {
200
211
  * @default 'https://cloud.gitlab.com'
201
212
  */
202
213
  aiGatewayUrl?: string;
214
+ /**
215
+ * Custom headers to include in AI Gateway requests (Anthropic/OpenAI proxy).
216
+ * These headers are merged with the default headers from direct_access response.
217
+ * Default User-Agent: gitlab-ai-provider/{version}
218
+ */
219
+ aiGatewayHeaders?: Record<string, string>;
203
220
  }
204
221
  declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
205
222
  /**
@@ -214,6 +231,8 @@ declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
214
231
  */
215
232
  declare const gitlab: GitLabProvider;
216
233
 
234
+ declare const VERSION: string;
235
+
217
236
  interface GitLabOpenAIConfig {
218
237
  provider: string;
219
238
  instanceUrl: string;
@@ -228,6 +247,11 @@ interface GitLabOpenAIConfig {
228
247
  aiGatewayUrl?: string;
229
248
  /** Whether to use the Responses API instead of Chat Completions API */
230
249
  useResponsesApi?: boolean;
250
+ /**
251
+ * Custom headers for AI Gateway OpenAI proxy requests.
252
+ * Merged with headers from direct_access token response.
253
+ */
254
+ aiGatewayHeaders?: Record<string, string>;
231
255
  }
232
256
  declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
233
257
  readonly specificationVersion: "v2";
@@ -641,4 +665,4 @@ declare class GitLabDirectAccessClient {
641
665
  invalidateToken(): void;
642
666
  }
643
667
 
644
- export { BUNDLED_CLIENT_ID, DEFAULT_AI_GATEWAY_URL, type DirectAccessToken, GITLAB_COM_URL, type GitLabAgenticOptions, type GitLabAnthropicConfig, GitLabAnthropicLanguageModel, GitLabDirectAccessClient, type GitLabDirectAccessConfig, GitLabError, type GitLabErrorOptions, GitLabOAuthManager, type GitLabOAuthTokenResponse, type GitLabOAuthTokens, type GitLabOpenAIConfig, GitLabOpenAILanguageModel, type GitLabProject, GitLabProjectCache, GitLabProjectDetector, type GitLabProjectDetectorConfig, type GitLabProvider, type GitLabProviderSettings, MODEL_ID_TO_ANTHROPIC_MODEL, MODEL_MAPPINGS, type ModelMapping, type ModelProvider, OAUTH_SCOPES, type OpenAIApiType, type OpenCodeAuth, type OpenCodeAuthApi, type OpenCodeAuthOAuth, TOKEN_EXPIRY_SKEW_MS, createGitLab, getAnthropicModelForModelId, getModelMapping, getOpenAIApiType, getOpenAIModelForModelId, getProviderForModelId, getValidModelsForProvider, gitlab, isResponsesApiModel };
668
+ export { BUNDLED_CLIENT_ID, DEFAULT_AI_GATEWAY_URL, type DirectAccessToken, GITLAB_COM_URL, type GitLabAgenticOptions, type GitLabAnthropicConfig, GitLabAnthropicLanguageModel, GitLabDirectAccessClient, type GitLabDirectAccessConfig, GitLabError, type GitLabErrorOptions, GitLabOAuthManager, type GitLabOAuthTokenResponse, type GitLabOAuthTokens, type GitLabOpenAIConfig, GitLabOpenAILanguageModel, type GitLabProject, GitLabProjectCache, GitLabProjectDetector, type GitLabProjectDetectorConfig, type GitLabProvider, type GitLabProviderSettings, MODEL_ID_TO_ANTHROPIC_MODEL, MODEL_MAPPINGS, type ModelMapping, type ModelProvider, OAUTH_SCOPES, type OpenAIApiType, type OpenCodeAuth, type OpenCodeAuthApi, type OpenCodeAuthOAuth, TOKEN_EXPIRY_SKEW_MS, VERSION, createGitLab, getAnthropicModelForModelId, getModelMapping, getOpenAIApiType, getOpenAIModelForModelId, getProviderForModelId, getValidModelsForProvider, gitlab, isResponsesApiModel };
package/dist/index.js CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  MODEL_MAPPINGS: () => MODEL_MAPPINGS,
44
44
  OAUTH_SCOPES: () => OAUTH_SCOPES,
45
45
  TOKEN_EXPIRY_SKEW_MS: () => TOKEN_EXPIRY_SKEW_MS,
46
+ VERSION: () => VERSION,
46
47
  createGitLab: () => createGitLab,
47
48
  getAnthropicModelForModelId: () => getAnthropicModelForModelId,
48
49
  getModelMapping: () => getModelMapping,
@@ -238,11 +239,15 @@ var GitLabAnthropicLanguageModel = class {
238
239
  async getAnthropicClient(forceRefresh = false) {
239
240
  const tokenData = await this.directAccessClient.getDirectAccessToken(forceRefresh);
240
241
  const { "x-api-key": _removed, ...filteredHeaders } = tokenData.headers;
242
+ const mergedHeaders = {
243
+ ...filteredHeaders,
244
+ ...this.config.aiGatewayHeaders
245
+ };
241
246
  this.anthropicClient = new import_sdk.default({
242
247
  apiKey: null,
243
248
  authToken: tokenData.token,
244
249
  baseURL: this.directAccessClient.getAnthropicProxyUrl(),
245
- defaultHeaders: filteredHeaders
250
+ defaultHeaders: mergedHeaders
246
251
  });
247
252
  return this.anthropicClient;
248
253
  }
@@ -743,10 +748,14 @@ var GitLabOpenAILanguageModel = class {
743
748
  async getOpenAIClient(forceRefresh = false) {
744
749
  const tokenData = await this.directAccessClient.getDirectAccessToken(forceRefresh);
745
750
  const { "x-api-key": _removed, ...filteredHeaders } = tokenData.headers;
751
+ const mergedHeaders = {
752
+ ...filteredHeaders,
753
+ ...this.config.aiGatewayHeaders
754
+ };
746
755
  this.openaiClient = new import_openai.default({
747
756
  apiKey: tokenData.token,
748
757
  baseURL: this.directAccessClient.getOpenAIProxyUrl(),
749
- defaultHeaders: filteredHeaders
758
+ defaultHeaders: mergedHeaders
750
759
  });
751
760
  return this.openaiClient;
752
761
  }
@@ -1559,11 +1568,13 @@ var GitLabOAuthManager = class {
1559
1568
  }
1560
1569
  };
1561
1570
 
1571
+ // src/version.ts
1572
+ var VERSION = true ? "3.3.1" : "0.0.0-dev";
1573
+
1562
1574
  // src/gitlab-provider.ts
1563
1575
  var fs = __toESM(require("fs"));
1564
1576
  var path = __toESM(require("path"));
1565
1577
  var os = __toESM(require("os"));
1566
- var VERSION = "0.0.1";
1567
1578
  function getOpenCodeAuthPath() {
1568
1579
  const homeDir = os.homedir();
1569
1580
  const xdgDataHome = process.env.XDG_DATA_HOME;
@@ -1713,6 +1724,14 @@ function createGitLab(options = {}) {
1713
1724
  ...options.featureFlags,
1714
1725
  ...agenticOptions?.featureFlags
1715
1726
  };
1727
+ const defaultAiGatewayHeaders = {
1728
+ "User-Agent": `gitlab-ai-provider/${VERSION}`
1729
+ };
1730
+ const aiGatewayHeaders = {
1731
+ ...defaultAiGatewayHeaders,
1732
+ ...options.aiGatewayHeaders,
1733
+ ...agenticOptions?.aiGatewayHeaders
1734
+ };
1716
1735
  const baseConfig = {
1717
1736
  provider: `${providerName}.agentic`,
1718
1737
  instanceUrl,
@@ -1721,7 +1740,8 @@ function createGitLab(options = {}) {
1721
1740
  fetch: options.fetch,
1722
1741
  maxTokens: agenticOptions?.maxTokens,
1723
1742
  featureFlags,
1724
- aiGatewayUrl: options.aiGatewayUrl
1743
+ aiGatewayUrl: options.aiGatewayUrl,
1744
+ aiGatewayHeaders
1725
1745
  };
1726
1746
  if (mapping.provider === "openai") {
1727
1747
  return new GitLabOpenAILanguageModel(modelId, {
@@ -2042,6 +2062,7 @@ var GitLabProjectDetector = class {
2042
2062
  MODEL_MAPPINGS,
2043
2063
  OAUTH_SCOPES,
2044
2064
  TOKEN_EXPIRY_SKEW_MS,
2065
+ VERSION,
2045
2066
  createGitLab,
2046
2067
  getAnthropicModelForModelId,
2047
2068
  getModelMapping,