@gitlab/gitlab-ai-provider 3.3.1 → 3.4.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/CHANGELOG.md +12 -0
- package/README.md +30 -1
- package/dist/gitlab-gitlab-ai-provider-3.4.1.tgz +0 -0
- package/dist/index.d.mts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +135 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +134 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
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
|
+
## <small>3.4.1 (2026-02-06)</small>
|
|
6
|
+
|
|
7
|
+
- Merge branch 'vg/token_refresh_fix' into 'main' ([8c1f2c4](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/8c1f2c4))
|
|
8
|
+
- fix: detect context overflow errors before token refresh ([ce272cd](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/ce272cd))
|
|
9
|
+
|
|
10
|
+
## 3.4.0 (2026-02-02)
|
|
11
|
+
|
|
12
|
+
- Merge branch 'feat/ai-gateway-headers' into 'main' ([f2d4c79](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/f2d4c79))
|
|
13
|
+
- feat: add custom AI Gateway headers support ([2ef662d](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/2ef662d))
|
|
14
|
+
- chore: added models testing script ([85dd9ba](https://gitlab.com/gitlab-org/editor-extensions/gitlab-ai-provider/commit/85dd9ba))
|
|
15
|
+
- 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))
|
|
16
|
+
|
|
5
17
|
## 3.3.0 (2026-01-23)
|
|
6
18
|
|
|
7
19
|
- 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
|
|
|
Binary file
|
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
|
|
@@ -60,6 +65,11 @@ declare class GitLabAnthropicLanguageModel implements LanguageModelV2 {
|
|
|
60
65
|
* Check if an error is a token-related authentication error that can be retried
|
|
61
66
|
*/
|
|
62
67
|
private isTokenError;
|
|
68
|
+
/**
|
|
69
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
70
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
71
|
+
*/
|
|
72
|
+
private isContextOverflowError;
|
|
63
73
|
/**
|
|
64
74
|
* Convert AI SDK tools to Anthropic tool format
|
|
65
75
|
*/
|
|
@@ -154,6 +164,12 @@ interface GitLabAgenticOptions {
|
|
|
154
164
|
* Feature flags to pass to the GitLab API
|
|
155
165
|
*/
|
|
156
166
|
featureFlags?: Record<string, boolean>;
|
|
167
|
+
/**
|
|
168
|
+
* Custom headers for AI Gateway requests (per-model override).
|
|
169
|
+
* These headers are sent to the Anthropic/OpenAI proxy endpoints.
|
|
170
|
+
* Merged with provider-level aiGatewayHeaders (model-level takes precedence).
|
|
171
|
+
*/
|
|
172
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
157
173
|
}
|
|
158
174
|
interface GitLabProviderSettings {
|
|
159
175
|
/**
|
|
@@ -200,6 +216,12 @@ interface GitLabProviderSettings {
|
|
|
200
216
|
* @default 'https://cloud.gitlab.com'
|
|
201
217
|
*/
|
|
202
218
|
aiGatewayUrl?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Custom headers to include in AI Gateway requests (Anthropic/OpenAI proxy).
|
|
221
|
+
* These headers are merged with the default headers from direct_access response.
|
|
222
|
+
* Default User-Agent: gitlab-ai-provider/{version}
|
|
223
|
+
*/
|
|
224
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
203
225
|
}
|
|
204
226
|
declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
|
|
205
227
|
/**
|
|
@@ -214,6 +236,8 @@ declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
|
|
|
214
236
|
*/
|
|
215
237
|
declare const gitlab: GitLabProvider;
|
|
216
238
|
|
|
239
|
+
declare const VERSION: string;
|
|
240
|
+
|
|
217
241
|
interface GitLabOpenAIConfig {
|
|
218
242
|
provider: string;
|
|
219
243
|
instanceUrl: string;
|
|
@@ -228,6 +252,11 @@ interface GitLabOpenAIConfig {
|
|
|
228
252
|
aiGatewayUrl?: string;
|
|
229
253
|
/** Whether to use the Responses API instead of Chat Completions API */
|
|
230
254
|
useResponsesApi?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Custom headers for AI Gateway OpenAI proxy requests.
|
|
257
|
+
* Merged with headers from direct_access token response.
|
|
258
|
+
*/
|
|
259
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
231
260
|
}
|
|
232
261
|
declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
|
|
233
262
|
readonly specificationVersion: "v2";
|
|
@@ -241,6 +270,11 @@ declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
|
|
|
241
270
|
get provider(): string;
|
|
242
271
|
private getOpenAIClient;
|
|
243
272
|
private isTokenError;
|
|
273
|
+
/**
|
|
274
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
275
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
276
|
+
*/
|
|
277
|
+
private isContextOverflowError;
|
|
244
278
|
private convertTools;
|
|
245
279
|
private convertToolChoice;
|
|
246
280
|
private convertPrompt;
|
|
@@ -318,6 +352,11 @@ declare class GitLabError extends Error {
|
|
|
318
352
|
isRateLimitError(): boolean;
|
|
319
353
|
isForbiddenError(): boolean;
|
|
320
354
|
isServerError(): boolean;
|
|
355
|
+
/**
|
|
356
|
+
* Check if this error is a context overflow error (prompt too long).
|
|
357
|
+
* These errors occur when the conversation exceeds the model's token limit.
|
|
358
|
+
*/
|
|
359
|
+
isContextOverflowError(): boolean;
|
|
321
360
|
}
|
|
322
361
|
|
|
323
362
|
declare const gitlabOAuthTokenResponseSchema: z.ZodObject<{
|
|
@@ -641,4 +680,4 @@ declare class GitLabDirectAccessClient {
|
|
|
641
680
|
invalidateToken(): void;
|
|
642
681
|
}
|
|
643
682
|
|
|
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 };
|
|
683
|
+
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
|
|
@@ -60,6 +65,11 @@ declare class GitLabAnthropicLanguageModel implements LanguageModelV2 {
|
|
|
60
65
|
* Check if an error is a token-related authentication error that can be retried
|
|
61
66
|
*/
|
|
62
67
|
private isTokenError;
|
|
68
|
+
/**
|
|
69
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
70
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
71
|
+
*/
|
|
72
|
+
private isContextOverflowError;
|
|
63
73
|
/**
|
|
64
74
|
* Convert AI SDK tools to Anthropic tool format
|
|
65
75
|
*/
|
|
@@ -154,6 +164,12 @@ interface GitLabAgenticOptions {
|
|
|
154
164
|
* Feature flags to pass to the GitLab API
|
|
155
165
|
*/
|
|
156
166
|
featureFlags?: Record<string, boolean>;
|
|
167
|
+
/**
|
|
168
|
+
* Custom headers for AI Gateway requests (per-model override).
|
|
169
|
+
* These headers are sent to the Anthropic/OpenAI proxy endpoints.
|
|
170
|
+
* Merged with provider-level aiGatewayHeaders (model-level takes precedence).
|
|
171
|
+
*/
|
|
172
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
157
173
|
}
|
|
158
174
|
interface GitLabProviderSettings {
|
|
159
175
|
/**
|
|
@@ -200,6 +216,12 @@ interface GitLabProviderSettings {
|
|
|
200
216
|
* @default 'https://cloud.gitlab.com'
|
|
201
217
|
*/
|
|
202
218
|
aiGatewayUrl?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Custom headers to include in AI Gateway requests (Anthropic/OpenAI proxy).
|
|
221
|
+
* These headers are merged with the default headers from direct_access response.
|
|
222
|
+
* Default User-Agent: gitlab-ai-provider/{version}
|
|
223
|
+
*/
|
|
224
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
203
225
|
}
|
|
204
226
|
declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
|
|
205
227
|
/**
|
|
@@ -214,6 +236,8 @@ declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
|
|
|
214
236
|
*/
|
|
215
237
|
declare const gitlab: GitLabProvider;
|
|
216
238
|
|
|
239
|
+
declare const VERSION: string;
|
|
240
|
+
|
|
217
241
|
interface GitLabOpenAIConfig {
|
|
218
242
|
provider: string;
|
|
219
243
|
instanceUrl: string;
|
|
@@ -228,6 +252,11 @@ interface GitLabOpenAIConfig {
|
|
|
228
252
|
aiGatewayUrl?: string;
|
|
229
253
|
/** Whether to use the Responses API instead of Chat Completions API */
|
|
230
254
|
useResponsesApi?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Custom headers for AI Gateway OpenAI proxy requests.
|
|
257
|
+
* Merged with headers from direct_access token response.
|
|
258
|
+
*/
|
|
259
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
231
260
|
}
|
|
232
261
|
declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
|
|
233
262
|
readonly specificationVersion: "v2";
|
|
@@ -241,6 +270,11 @@ declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
|
|
|
241
270
|
get provider(): string;
|
|
242
271
|
private getOpenAIClient;
|
|
243
272
|
private isTokenError;
|
|
273
|
+
/**
|
|
274
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
275
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
276
|
+
*/
|
|
277
|
+
private isContextOverflowError;
|
|
244
278
|
private convertTools;
|
|
245
279
|
private convertToolChoice;
|
|
246
280
|
private convertPrompt;
|
|
@@ -318,6 +352,11 @@ declare class GitLabError extends Error {
|
|
|
318
352
|
isRateLimitError(): boolean;
|
|
319
353
|
isForbiddenError(): boolean;
|
|
320
354
|
isServerError(): boolean;
|
|
355
|
+
/**
|
|
356
|
+
* Check if this error is a context overflow error (prompt too long).
|
|
357
|
+
* These errors occur when the conversation exceeds the model's token limit.
|
|
358
|
+
*/
|
|
359
|
+
isContextOverflowError(): boolean;
|
|
321
360
|
}
|
|
322
361
|
|
|
323
362
|
declare const gitlabOAuthTokenResponseSchema: z.ZodObject<{
|
|
@@ -641,4 +680,4 @@ declare class GitLabDirectAccessClient {
|
|
|
641
680
|
invalidateToken(): void;
|
|
642
681
|
}
|
|
643
682
|
|
|
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 };
|
|
683
|
+
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,
|
|
@@ -95,6 +96,17 @@ var GitLabError = class _GitLabError extends Error {
|
|
|
95
96
|
isServerError() {
|
|
96
97
|
return this.statusCode !== void 0 && this.statusCode >= 500;
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if this error is a context overflow error (prompt too long).
|
|
101
|
+
* These errors occur when the conversation exceeds the model's token limit.
|
|
102
|
+
*/
|
|
103
|
+
isContextOverflowError() {
|
|
104
|
+
if (this.statusCode !== 400) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const message = this.message?.toLowerCase() || "";
|
|
108
|
+
return message.includes("context overflow") || message.includes("prompt is too long") || message.includes("prompt too long") || message.includes("tokens") && message.includes("maximum");
|
|
109
|
+
}
|
|
98
110
|
};
|
|
99
111
|
|
|
100
112
|
// src/gitlab-direct-access.ts
|
|
@@ -238,11 +250,15 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
238
250
|
async getAnthropicClient(forceRefresh = false) {
|
|
239
251
|
const tokenData = await this.directAccessClient.getDirectAccessToken(forceRefresh);
|
|
240
252
|
const { "x-api-key": _removed, ...filteredHeaders } = tokenData.headers;
|
|
253
|
+
const mergedHeaders = {
|
|
254
|
+
...filteredHeaders,
|
|
255
|
+
...this.config.aiGatewayHeaders
|
|
256
|
+
};
|
|
241
257
|
this.anthropicClient = new import_sdk.default({
|
|
242
258
|
apiKey: null,
|
|
243
259
|
authToken: tokenData.token,
|
|
244
260
|
baseURL: this.directAccessClient.getAnthropicProxyUrl(),
|
|
245
|
-
defaultHeaders:
|
|
261
|
+
defaultHeaders: mergedHeaders
|
|
246
262
|
});
|
|
247
263
|
return this.anthropicClient;
|
|
248
264
|
}
|
|
@@ -261,6 +277,21 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
261
277
|
}
|
|
262
278
|
return false;
|
|
263
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
282
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
283
|
+
*/
|
|
284
|
+
isContextOverflowError(error) {
|
|
285
|
+
if (error instanceof import_sdk.default.APIError) {
|
|
286
|
+
if (error.status === 400) {
|
|
287
|
+
const message = error.message?.toLowerCase() || "";
|
|
288
|
+
if (message.includes("prompt is too long") || message.includes("prompt too long") || message.includes("tokens") && message.includes("maximum")) {
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
264
295
|
/**
|
|
265
296
|
* Convert AI SDK tools to Anthropic tool format
|
|
266
297
|
*/
|
|
@@ -438,6 +469,14 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
438
469
|
warnings: []
|
|
439
470
|
};
|
|
440
471
|
} catch (error) {
|
|
472
|
+
if (this.isContextOverflowError(error)) {
|
|
473
|
+
const apiError = error;
|
|
474
|
+
throw new GitLabError({
|
|
475
|
+
message: `Context overflow: ${apiError.message}. Please start a new session or use /compact to reduce context.`,
|
|
476
|
+
statusCode: 400,
|
|
477
|
+
cause: error
|
|
478
|
+
});
|
|
479
|
+
}
|
|
441
480
|
if (!isRetry && this.isTokenError(error)) {
|
|
442
481
|
this.directAccessClient.invalidateToken();
|
|
443
482
|
return this.doGenerateWithRetry(options, true);
|
|
@@ -445,6 +484,7 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
445
484
|
if (error instanceof import_sdk.default.APIError) {
|
|
446
485
|
throw new GitLabError({
|
|
447
486
|
message: `Anthropic API error: ${error.message}`,
|
|
487
|
+
statusCode: error.status,
|
|
448
488
|
cause: error
|
|
449
489
|
});
|
|
450
490
|
}
|
|
@@ -625,6 +665,19 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
625
665
|
});
|
|
626
666
|
}
|
|
627
667
|
}
|
|
668
|
+
if (self.isContextOverflowError(error)) {
|
|
669
|
+
const apiError = error;
|
|
670
|
+
controller.enqueue({
|
|
671
|
+
type: "error",
|
|
672
|
+
error: new GitLabError({
|
|
673
|
+
message: `Context overflow: ${apiError.message}. Please start a new session or use /compact to reduce context.`,
|
|
674
|
+
statusCode: 400,
|
|
675
|
+
cause: error
|
|
676
|
+
})
|
|
677
|
+
});
|
|
678
|
+
controller.close();
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
628
681
|
if (!isRetry && self.isTokenError(error)) {
|
|
629
682
|
self.directAccessClient.invalidateToken();
|
|
630
683
|
controller.enqueue({
|
|
@@ -642,6 +695,7 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
642
695
|
type: "error",
|
|
643
696
|
error: new GitLabError({
|
|
644
697
|
message: `Anthropic API error: ${error.message}`,
|
|
698
|
+
statusCode: error.status,
|
|
645
699
|
cause: error
|
|
646
700
|
})
|
|
647
701
|
});
|
|
@@ -743,10 +797,14 @@ var GitLabOpenAILanguageModel = class {
|
|
|
743
797
|
async getOpenAIClient(forceRefresh = false) {
|
|
744
798
|
const tokenData = await this.directAccessClient.getDirectAccessToken(forceRefresh);
|
|
745
799
|
const { "x-api-key": _removed, ...filteredHeaders } = tokenData.headers;
|
|
800
|
+
const mergedHeaders = {
|
|
801
|
+
...filteredHeaders,
|
|
802
|
+
...this.config.aiGatewayHeaders
|
|
803
|
+
};
|
|
746
804
|
this.openaiClient = new import_openai.default({
|
|
747
805
|
apiKey: tokenData.token,
|
|
748
806
|
baseURL: this.directAccessClient.getOpenAIProxyUrl(),
|
|
749
|
-
defaultHeaders:
|
|
807
|
+
defaultHeaders: mergedHeaders
|
|
750
808
|
});
|
|
751
809
|
return this.openaiClient;
|
|
752
810
|
}
|
|
@@ -762,6 +820,21 @@ var GitLabOpenAILanguageModel = class {
|
|
|
762
820
|
}
|
|
763
821
|
return false;
|
|
764
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
825
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
826
|
+
*/
|
|
827
|
+
isContextOverflowError(error) {
|
|
828
|
+
if (error instanceof import_openai.default.APIError) {
|
|
829
|
+
if (error.status === 400) {
|
|
830
|
+
const message = error.message?.toLowerCase() || "";
|
|
831
|
+
if (message.includes("prompt is too long") || message.includes("prompt too long") || message.includes("tokens") && message.includes("maximum")) {
|
|
832
|
+
return true;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return false;
|
|
837
|
+
}
|
|
765
838
|
convertTools(tools) {
|
|
766
839
|
if (!tools || tools.length === 0) {
|
|
767
840
|
return void 0;
|
|
@@ -1042,6 +1115,14 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1042
1115
|
warnings: []
|
|
1043
1116
|
};
|
|
1044
1117
|
} catch (error) {
|
|
1118
|
+
if (this.isContextOverflowError(error)) {
|
|
1119
|
+
const apiError = error;
|
|
1120
|
+
throw new GitLabError({
|
|
1121
|
+
message: `Context overflow: ${apiError.message}. Please start a new session or use /compact to reduce context.`,
|
|
1122
|
+
statusCode: 400,
|
|
1123
|
+
cause: error
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1045
1126
|
if (!isRetry && this.isTokenError(error)) {
|
|
1046
1127
|
this.directAccessClient.invalidateToken();
|
|
1047
1128
|
return this.doGenerateWithChatApi(options, true);
|
|
@@ -1049,6 +1130,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1049
1130
|
if (error instanceof import_openai.default.APIError) {
|
|
1050
1131
|
throw new GitLabError({
|
|
1051
1132
|
message: `OpenAI API error: ${error.message}`,
|
|
1133
|
+
statusCode: error.status,
|
|
1052
1134
|
cause: error
|
|
1053
1135
|
});
|
|
1054
1136
|
}
|
|
@@ -1104,6 +1186,14 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1104
1186
|
warnings: []
|
|
1105
1187
|
};
|
|
1106
1188
|
} catch (error) {
|
|
1189
|
+
if (this.isContextOverflowError(error)) {
|
|
1190
|
+
const apiError = error;
|
|
1191
|
+
throw new GitLabError({
|
|
1192
|
+
message: `Context overflow: ${apiError.message}. Please start a new session or use /compact to reduce context.`,
|
|
1193
|
+
statusCode: 400,
|
|
1194
|
+
cause: error
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1107
1197
|
if (!isRetry && this.isTokenError(error)) {
|
|
1108
1198
|
this.directAccessClient.invalidateToken();
|
|
1109
1199
|
return this.doGenerateWithResponsesApi(options, true);
|
|
@@ -1111,6 +1201,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1111
1201
|
if (error instanceof import_openai.default.APIError) {
|
|
1112
1202
|
throw new GitLabError({
|
|
1113
1203
|
message: `OpenAI API error: ${error.message}`,
|
|
1204
|
+
statusCode: error.status,
|
|
1114
1205
|
cause: error
|
|
1115
1206
|
});
|
|
1116
1207
|
}
|
|
@@ -1229,6 +1320,19 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1229
1320
|
controller.enqueue({ type: "finish", finishReason, usage });
|
|
1230
1321
|
controller.close();
|
|
1231
1322
|
} catch (error) {
|
|
1323
|
+
if (self.isContextOverflowError(error)) {
|
|
1324
|
+
const apiError = error;
|
|
1325
|
+
controller.enqueue({
|
|
1326
|
+
type: "error",
|
|
1327
|
+
error: new GitLabError({
|
|
1328
|
+
message: `Context overflow: ${apiError.message}. Please start a new session or use /compact to reduce context.`,
|
|
1329
|
+
statusCode: 400,
|
|
1330
|
+
cause: error
|
|
1331
|
+
})
|
|
1332
|
+
});
|
|
1333
|
+
controller.close();
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1232
1336
|
if (!isRetry && self.isTokenError(error)) {
|
|
1233
1337
|
self.directAccessClient.invalidateToken();
|
|
1234
1338
|
controller.enqueue({
|
|
@@ -1243,6 +1347,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1243
1347
|
type: "error",
|
|
1244
1348
|
error: new GitLabError({
|
|
1245
1349
|
message: `OpenAI API error: ${error.message}`,
|
|
1350
|
+
statusCode: error.status,
|
|
1246
1351
|
cause: error
|
|
1247
1352
|
})
|
|
1248
1353
|
});
|
|
@@ -1369,6 +1474,19 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1369
1474
|
controller.enqueue({ type: "finish", finishReason, usage });
|
|
1370
1475
|
controller.close();
|
|
1371
1476
|
} catch (error) {
|
|
1477
|
+
if (self.isContextOverflowError(error)) {
|
|
1478
|
+
const apiError = error;
|
|
1479
|
+
controller.enqueue({
|
|
1480
|
+
type: "error",
|
|
1481
|
+
error: new GitLabError({
|
|
1482
|
+
message: `Context overflow: ${apiError.message}. Please start a new session or use /compact to reduce context.`,
|
|
1483
|
+
statusCode: 400,
|
|
1484
|
+
cause: error
|
|
1485
|
+
})
|
|
1486
|
+
});
|
|
1487
|
+
controller.close();
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1372
1490
|
if (!isRetry && self.isTokenError(error)) {
|
|
1373
1491
|
self.directAccessClient.invalidateToken();
|
|
1374
1492
|
controller.enqueue({
|
|
@@ -1383,6 +1501,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1383
1501
|
type: "error",
|
|
1384
1502
|
error: new GitLabError({
|
|
1385
1503
|
message: `OpenAI API error: ${error.message}`,
|
|
1504
|
+
statusCode: error.status,
|
|
1386
1505
|
cause: error
|
|
1387
1506
|
})
|
|
1388
1507
|
});
|
|
@@ -1559,11 +1678,13 @@ var GitLabOAuthManager = class {
|
|
|
1559
1678
|
}
|
|
1560
1679
|
};
|
|
1561
1680
|
|
|
1681
|
+
// src/version.ts
|
|
1682
|
+
var VERSION = true ? "3.4.0" : "0.0.0-dev";
|
|
1683
|
+
|
|
1562
1684
|
// src/gitlab-provider.ts
|
|
1563
1685
|
var fs = __toESM(require("fs"));
|
|
1564
1686
|
var path = __toESM(require("path"));
|
|
1565
1687
|
var os = __toESM(require("os"));
|
|
1566
|
-
var VERSION = "0.0.1";
|
|
1567
1688
|
function getOpenCodeAuthPath() {
|
|
1568
1689
|
const homeDir = os.homedir();
|
|
1569
1690
|
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
@@ -1713,6 +1834,14 @@ function createGitLab(options = {}) {
|
|
|
1713
1834
|
...options.featureFlags,
|
|
1714
1835
|
...agenticOptions?.featureFlags
|
|
1715
1836
|
};
|
|
1837
|
+
const defaultAiGatewayHeaders = {
|
|
1838
|
+
"User-Agent": `gitlab-ai-provider/${VERSION}`
|
|
1839
|
+
};
|
|
1840
|
+
const aiGatewayHeaders = {
|
|
1841
|
+
...defaultAiGatewayHeaders,
|
|
1842
|
+
...options.aiGatewayHeaders,
|
|
1843
|
+
...agenticOptions?.aiGatewayHeaders
|
|
1844
|
+
};
|
|
1716
1845
|
const baseConfig = {
|
|
1717
1846
|
provider: `${providerName}.agentic`,
|
|
1718
1847
|
instanceUrl,
|
|
@@ -1721,7 +1850,8 @@ function createGitLab(options = {}) {
|
|
|
1721
1850
|
fetch: options.fetch,
|
|
1722
1851
|
maxTokens: agenticOptions?.maxTokens,
|
|
1723
1852
|
featureFlags,
|
|
1724
|
-
aiGatewayUrl: options.aiGatewayUrl
|
|
1853
|
+
aiGatewayUrl: options.aiGatewayUrl,
|
|
1854
|
+
aiGatewayHeaders
|
|
1725
1855
|
};
|
|
1726
1856
|
if (mapping.provider === "openai") {
|
|
1727
1857
|
return new GitLabOpenAILanguageModel(modelId, {
|
|
@@ -2042,6 +2172,7 @@ var GitLabProjectDetector = class {
|
|
|
2042
2172
|
MODEL_MAPPINGS,
|
|
2043
2173
|
OAUTH_SCOPES,
|
|
2044
2174
|
TOKEN_EXPIRY_SKEW_MS,
|
|
2175
|
+
VERSION,
|
|
2045
2176
|
createGitLab,
|
|
2046
2177
|
getAnthropicModelForModelId,
|
|
2047
2178
|
getModelMapping,
|