gitlab-ai-provider 5.0.0 → 5.1.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/dist/gitlab-ai-provider-5.1.1.tgz +0 -0
- package/dist/index.d.mts +56 -1
- package/dist/index.d.ts +1214 -1296
- package/dist/index.js +319 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +316 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,52 +1,44 @@
|
|
|
1
|
-
import {
|
|
2
|
-
LanguageModelV2,
|
|
3
|
-
LanguageModelV2CallOptions,
|
|
4
|
-
LanguageModelV2Content,
|
|
5
|
-
LanguageModelV2FinishReason,
|
|
6
|
-
LanguageModelV2Usage,
|
|
7
|
-
LanguageModelV2CallWarning,
|
|
8
|
-
LanguageModelV2StreamPart,
|
|
9
|
-
} from '@ai-sdk/provider';
|
|
1
|
+
import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2StreamPart } from '@ai-sdk/provider';
|
|
10
2
|
import { z } from 'zod';
|
|
11
3
|
|
|
12
4
|
interface GitLabAnthropicConfig {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
5
|
+
provider: string;
|
|
6
|
+
instanceUrl: string;
|
|
7
|
+
getHeaders: () => Record<string, string>;
|
|
8
|
+
fetch?: typeof fetch;
|
|
9
|
+
/**
|
|
10
|
+
* Optional callback to refresh the API key when a 401 error occurs.
|
|
11
|
+
* Should clear cached credentials and re-fetch from auth provider.
|
|
12
|
+
*/
|
|
13
|
+
refreshApiKey?: () => Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* The Anthropic model to use (e.g., 'claude-sonnet-4-5-20250929')
|
|
16
|
+
* @default 'claude-sonnet-4-5-20250929'
|
|
17
|
+
*/
|
|
18
|
+
anthropicModel?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Maximum tokens to generate
|
|
21
|
+
* @default 8192
|
|
22
|
+
*/
|
|
23
|
+
maxTokens?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Feature flags to pass to the GitLab API
|
|
26
|
+
* @default { DuoAgentPlatformNext: true }
|
|
27
|
+
*/
|
|
28
|
+
featureFlags?: {
|
|
29
|
+
DuoAgentPlatformNext: true;
|
|
30
|
+
} & Record<string, boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* AI Gateway URL for the Anthropic proxy.
|
|
33
|
+
* Can also be set via GITLAB_AI_GATEWAY_URL environment variable.
|
|
34
|
+
* @default 'https://cloud.gitlab.com'
|
|
35
|
+
*/
|
|
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>;
|
|
50
42
|
}
|
|
51
43
|
/**
|
|
52
44
|
* GitLab Anthropic Language Model
|
|
@@ -56,61 +48,61 @@ interface GitLabAnthropicConfig {
|
|
|
56
48
|
* at https://cloud.gitlab.com/ai/v1/proxy/anthropic/
|
|
57
49
|
*/
|
|
58
50
|
declare class GitLabAnthropicLanguageModel implements LanguageModelV2 {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
51
|
+
readonly specificationVersion: "v2";
|
|
52
|
+
readonly modelId: string;
|
|
53
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
54
|
+
private readonly config;
|
|
55
|
+
private readonly directAccessClient;
|
|
56
|
+
private anthropicClient;
|
|
57
|
+
constructor(modelId: string, config: GitLabAnthropicConfig);
|
|
58
|
+
get provider(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Get or create an Anthropic client with valid credentials
|
|
61
|
+
* @param forceRefresh - If true, forces a token refresh before creating the client
|
|
62
|
+
*/
|
|
63
|
+
private getAnthropicClient;
|
|
64
|
+
/**
|
|
65
|
+
* Check if an error is a token-related authentication error that can be retried
|
|
66
|
+
*/
|
|
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;
|
|
73
|
+
/**
|
|
74
|
+
* Convert AI SDK tools to Anthropic tool format
|
|
75
|
+
*/
|
|
76
|
+
private convertTools;
|
|
77
|
+
/**
|
|
78
|
+
* Convert AI SDK tool choice to Anthropic format
|
|
79
|
+
*/
|
|
80
|
+
private convertToolChoice;
|
|
81
|
+
/**
|
|
82
|
+
* Convert AI SDK prompt to Anthropic messages format
|
|
83
|
+
*/
|
|
84
|
+
private convertPrompt;
|
|
85
|
+
/**
|
|
86
|
+
* Convert Anthropic finish reason to AI SDK format
|
|
87
|
+
*/
|
|
88
|
+
private convertFinishReason;
|
|
89
|
+
doGenerate(options: LanguageModelV2CallOptions): Promise<{
|
|
90
|
+
content: LanguageModelV2Content[];
|
|
91
|
+
finishReason: LanguageModelV2FinishReason;
|
|
92
|
+
usage: LanguageModelV2Usage;
|
|
93
|
+
warnings: LanguageModelV2CallWarning[];
|
|
94
|
+
}>;
|
|
95
|
+
private doGenerateWithRetry;
|
|
96
|
+
doStream(options: LanguageModelV2CallOptions): Promise<{
|
|
97
|
+
stream: ReadableStream<LanguageModelV2StreamPart>;
|
|
98
|
+
request?: {
|
|
99
|
+
body?: unknown;
|
|
100
|
+
};
|
|
101
|
+
response?: {
|
|
102
|
+
headers?: Record<string, string>;
|
|
103
|
+
};
|
|
104
|
+
}>;
|
|
105
|
+
private doStreamWithRetry;
|
|
114
106
|
}
|
|
115
107
|
|
|
116
108
|
/**
|
|
@@ -123,63 +115,63 @@ declare class GitLabAnthropicLanguageModel implements LanguageModelV2 {
|
|
|
123
115
|
* Requires GitLab 18.4+ (18.5+ for pinned model support).
|
|
124
116
|
*/
|
|
125
117
|
interface AiModel {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
/** Display name (e.g., 'Claude Sonnet 4.6') */
|
|
119
|
+
name: string;
|
|
120
|
+
/** Model reference for API use (e.g., 'claude_sonnet_4_6' or 'anthropic/claude-sonnet-4-5-20250929') */
|
|
121
|
+
ref: string;
|
|
130
122
|
}
|
|
131
123
|
interface AiChatAvailableModels {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
defaultModel: AiModel | null;
|
|
125
|
+
selectableModels: AiModel[];
|
|
126
|
+
pinnedModel: AiModel | null;
|
|
135
127
|
}
|
|
136
128
|
interface DiscoveredModels {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
129
|
+
/** The effective model (pinned > user-selected > default) */
|
|
130
|
+
defaultModel: AiModel | null;
|
|
131
|
+
/** All models the user can select from */
|
|
132
|
+
selectableModels: AiModel[];
|
|
133
|
+
/** Admin-pinned model (overrides everything) */
|
|
134
|
+
pinnedModel: AiModel | null;
|
|
135
|
+
/** Whether the ai_user_model_switching feature flag is enabled */
|
|
136
|
+
modelSwitchingEnabled: boolean;
|
|
137
|
+
/** GitLab instance version */
|
|
138
|
+
instanceVersion: string | null;
|
|
147
139
|
}
|
|
148
140
|
interface ModelDiscoveryConfig {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
141
|
+
/** GitLab instance URL */
|
|
142
|
+
instanceUrl: string;
|
|
143
|
+
/** Function returning auth headers */
|
|
144
|
+
getHeaders: () => Record<string, string>;
|
|
145
|
+
/** Custom fetch */
|
|
146
|
+
fetch?: typeof fetch;
|
|
155
147
|
}
|
|
156
148
|
declare class GitLabModelDiscovery {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
149
|
+
private readonly config;
|
|
150
|
+
private readonly fetchFn;
|
|
151
|
+
private cache;
|
|
152
|
+
constructor(config: ModelDiscoveryConfig);
|
|
153
|
+
/**
|
|
154
|
+
* Discover available models for a given root namespace.
|
|
155
|
+
*
|
|
156
|
+
* Results are cached per `rootNamespaceId` with a 10-minute TTL.
|
|
157
|
+
* Use `invalidateCache()` to force an immediate refresh.
|
|
158
|
+
*
|
|
159
|
+
* @param rootNamespaceId - GitLab group ID (e.g., 'gid://gitlab/Group/12345')
|
|
160
|
+
*/
|
|
161
|
+
discover(rootNamespaceId: string): Promise<DiscoveredModels>;
|
|
162
|
+
/**
|
|
163
|
+
* Get the effective model ref to use for a workflow.
|
|
164
|
+
*
|
|
165
|
+
* Priority: pinned > user-selected > default.
|
|
166
|
+
*
|
|
167
|
+
* @param rootNamespaceId - GitLab group ID
|
|
168
|
+
* @param userSelectedRef - Optional user preference
|
|
169
|
+
*/
|
|
170
|
+
getEffectiveModelRef(rootNamespaceId: string, userSelectedRef?: string): Promise<string | null>;
|
|
171
|
+
/**
|
|
172
|
+
* Invalidate the cached discovery results.
|
|
173
|
+
*/
|
|
174
|
+
invalidateCache(): void;
|
|
183
175
|
}
|
|
184
176
|
|
|
185
177
|
/**
|
|
@@ -200,50 +192,50 @@ declare class GitLabModelDiscovery {
|
|
|
200
192
|
*/
|
|
201
193
|
|
|
202
194
|
interface ModelCacheEntry {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
195
|
+
discovery: DiscoveredModels | null;
|
|
196
|
+
selectedModelRef: string | null;
|
|
197
|
+
selectedModelName: string | null;
|
|
198
|
+
updatedAt: string;
|
|
207
199
|
}
|
|
208
200
|
declare class GitLabModelCache {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
201
|
+
private readonly filePath;
|
|
202
|
+
private readonly key;
|
|
203
|
+
constructor(workDir: string, instanceUrl?: string);
|
|
204
|
+
private readAll;
|
|
205
|
+
private writeAll;
|
|
206
|
+
/**
|
|
207
|
+
* Load the cached entry for this workspace.
|
|
208
|
+
* Returns null if no cache exists or is unreadable.
|
|
209
|
+
*/
|
|
210
|
+
load(): ModelCacheEntry | null;
|
|
211
|
+
/**
|
|
212
|
+
* Persist the full cache entry to disk.
|
|
213
|
+
*/
|
|
214
|
+
save(entry: ModelCacheEntry): void;
|
|
215
|
+
/**
|
|
216
|
+
* Update only the discovery portion of the cache, preserving selection.
|
|
217
|
+
*/
|
|
218
|
+
saveDiscovery(discovery: DiscoveredModels): void;
|
|
219
|
+
/**
|
|
220
|
+
* Update only the selected model, preserving the discovery data.
|
|
221
|
+
*/
|
|
222
|
+
saveSelection(ref: string | null, name: string | null): void;
|
|
223
|
+
/**
|
|
224
|
+
* Remove the entry for this workspace from the cache file.
|
|
225
|
+
*/
|
|
226
|
+
clear(): void;
|
|
227
|
+
/**
|
|
228
|
+
* Convenience: get the cached selected model ref (or null).
|
|
229
|
+
*/
|
|
230
|
+
getSelectedModelRef(): string | null;
|
|
231
|
+
/**
|
|
232
|
+
* Convenience: get the cached selected model name (or null).
|
|
233
|
+
*/
|
|
234
|
+
getSelectedModelName(): string | null;
|
|
235
|
+
/**
|
|
236
|
+
* Convenience: get the cached discovery result (or null).
|
|
237
|
+
*/
|
|
238
|
+
getDiscovery(): DiscoveredModels | null;
|
|
247
239
|
}
|
|
248
240
|
|
|
249
241
|
/**
|
|
@@ -256,148 +248,132 @@ declare class GitLabModelCache {
|
|
|
256
248
|
* Message format is JSON-serialized protobuf with camelCase field names.
|
|
257
249
|
*/
|
|
258
250
|
interface GenerateTokenResponse {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
251
|
+
gitlab_rails: {
|
|
252
|
+
base_url: string;
|
|
253
|
+
token: string;
|
|
254
|
+
token_expires_at: string;
|
|
255
|
+
};
|
|
256
|
+
duo_workflow_service: {
|
|
257
|
+
base_url: string;
|
|
258
|
+
token: string;
|
|
259
|
+
secure: boolean;
|
|
260
|
+
token_expires_at: number;
|
|
261
|
+
headers: Record<string, string>;
|
|
262
|
+
};
|
|
263
|
+
duo_workflow_executor: {
|
|
264
|
+
executor_binary_url: string;
|
|
265
|
+
version: string;
|
|
266
|
+
};
|
|
275
267
|
}
|
|
276
268
|
interface McpToolDefinition {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
269
|
+
name: string;
|
|
270
|
+
description: string;
|
|
271
|
+
inputSchema: string;
|
|
280
272
|
}
|
|
281
273
|
interface AdditionalContext {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
274
|
+
category: string;
|
|
275
|
+
id?: string;
|
|
276
|
+
content?: string;
|
|
277
|
+
metadata?: string;
|
|
286
278
|
}
|
|
287
279
|
interface StartRequest {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
280
|
+
workflowID: string;
|
|
281
|
+
clientVersion: string;
|
|
282
|
+
workflowDefinition: string;
|
|
283
|
+
goal: string;
|
|
284
|
+
workflowMetadata?: string;
|
|
285
|
+
additional_context?: AdditionalContext[];
|
|
286
|
+
clientCapabilities?: string[];
|
|
287
|
+
mcpTools?: McpToolDefinition[];
|
|
288
|
+
preapproved_tools?: string[];
|
|
289
|
+
flowConfig?: unknown;
|
|
290
|
+
flowConfigSchemaVersion?: string;
|
|
299
291
|
}
|
|
300
292
|
interface ActionResponsePayload {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
293
|
+
requestID: string;
|
|
294
|
+
plainTextResponse: {
|
|
295
|
+
response: string;
|
|
296
|
+
error: string | null;
|
|
297
|
+
};
|
|
306
298
|
}
|
|
307
299
|
interface StopWorkflow {
|
|
308
|
-
|
|
300
|
+
reason: string;
|
|
309
301
|
}
|
|
310
302
|
interface Heartbeat {
|
|
311
|
-
|
|
303
|
+
timestamp: number;
|
|
312
304
|
}
|
|
313
305
|
/**
|
|
314
306
|
* Client → Server event union.
|
|
315
307
|
* Exactly one of the fields should be set per message.
|
|
316
308
|
*/
|
|
317
|
-
type ClientEvent =
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
| {
|
|
328
|
-
heartbeat: Heartbeat;
|
|
329
|
-
};
|
|
330
|
-
type WorkflowStatus =
|
|
331
|
-
| 'CREATED'
|
|
332
|
-
| 'RUNNING'
|
|
333
|
-
| 'FINISHED'
|
|
334
|
-
| 'COMPLETED'
|
|
335
|
-
| 'FAILED'
|
|
336
|
-
| 'STOPPED'
|
|
337
|
-
| 'CANCELLED'
|
|
338
|
-
| 'PAUSED'
|
|
339
|
-
| 'INPUT_REQUIRED'
|
|
340
|
-
| 'PLAN_APPROVAL_REQUIRED'
|
|
341
|
-
| 'TOOL_CALL_APPROVAL_REQUIRED'
|
|
342
|
-
| 'UNKNOWN';
|
|
309
|
+
type ClientEvent = {
|
|
310
|
+
startRequest: StartRequest;
|
|
311
|
+
} | {
|
|
312
|
+
actionResponse: ActionResponsePayload;
|
|
313
|
+
} | {
|
|
314
|
+
stopWorkflow: StopWorkflow;
|
|
315
|
+
} | {
|
|
316
|
+
heartbeat: Heartbeat;
|
|
317
|
+
};
|
|
318
|
+
type WorkflowStatus = 'CREATED' | 'RUNNING' | 'FINISHED' | 'COMPLETED' | 'FAILED' | 'STOPPED' | 'CANCELLED' | 'PAUSED' | 'INPUT_REQUIRED' | 'PLAN_APPROVAL_REQUIRED' | 'TOOL_CALL_APPROVAL_REQUIRED' | 'UNKNOWN';
|
|
343
319
|
interface NewCheckpoint {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
320
|
+
status: WorkflowStatus;
|
|
321
|
+
goal?: string;
|
|
322
|
+
/** Raw checkpoint JSON string from DWS (contains channel_values.ui_chat_log) */
|
|
323
|
+
checkpoint?: string;
|
|
324
|
+
/** Legacy content field (may be empty — text is in checkpoint.ui_chat_log) */
|
|
325
|
+
content?: string;
|
|
350
326
|
}
|
|
351
327
|
interface RunMcpTool {
|
|
352
|
-
|
|
353
|
-
|
|
328
|
+
name: string;
|
|
329
|
+
args: string;
|
|
354
330
|
}
|
|
355
331
|
interface ReadFileAction {
|
|
356
|
-
|
|
332
|
+
filepath: string;
|
|
357
333
|
}
|
|
358
334
|
interface ReadFilesAction {
|
|
359
|
-
|
|
335
|
+
filepaths: string[];
|
|
360
336
|
}
|
|
361
337
|
interface WriteFileAction {
|
|
362
|
-
|
|
363
|
-
|
|
338
|
+
filepath: string;
|
|
339
|
+
contents: string;
|
|
364
340
|
}
|
|
365
341
|
interface ShellCommandAction {
|
|
366
|
-
|
|
342
|
+
command: string;
|
|
367
343
|
}
|
|
368
344
|
interface EditFileAction {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
345
|
+
filepath: string;
|
|
346
|
+
oldString: string;
|
|
347
|
+
newString: string;
|
|
372
348
|
}
|
|
373
349
|
interface ListDirectoryAction {
|
|
374
|
-
|
|
350
|
+
directory: string;
|
|
375
351
|
}
|
|
376
352
|
interface FindFilesAction {
|
|
377
|
-
|
|
353
|
+
name_pattern: string;
|
|
378
354
|
}
|
|
379
355
|
interface GrepAction {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
356
|
+
pattern: string;
|
|
357
|
+
search_directory?: string;
|
|
358
|
+
case_insensitive?: boolean;
|
|
383
359
|
}
|
|
384
360
|
interface MkdirAction {
|
|
385
|
-
|
|
361
|
+
directory_path: string;
|
|
386
362
|
}
|
|
387
363
|
interface RunCommandAction {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
364
|
+
program: string;
|
|
365
|
+
flags?: string[];
|
|
366
|
+
arguments?: string[];
|
|
391
367
|
}
|
|
392
368
|
interface RunGitCommandAction {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
369
|
+
command: string;
|
|
370
|
+
arguments?: string[];
|
|
371
|
+
repository_url?: string;
|
|
396
372
|
}
|
|
397
373
|
interface GitLabApiRequestAction {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
374
|
+
method: string;
|
|
375
|
+
path: string;
|
|
376
|
+
body?: string;
|
|
401
377
|
}
|
|
402
378
|
/**
|
|
403
379
|
* Server → Client action union.
|
|
@@ -406,154 +382,148 @@ interface GitLabApiRequestAction {
|
|
|
406
382
|
* that need an `actionResponse` back).
|
|
407
383
|
*/
|
|
408
384
|
interface WorkflowAction {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
385
|
+
requestID?: string;
|
|
386
|
+
newCheckpoint?: NewCheckpoint;
|
|
387
|
+
runMCPTool?: RunMcpTool;
|
|
388
|
+
runReadFile?: ReadFileAction;
|
|
389
|
+
runReadFiles?: ReadFilesAction;
|
|
390
|
+
runWriteFile?: WriteFileAction;
|
|
391
|
+
runShellCommand?: ShellCommandAction;
|
|
392
|
+
runEditFile?: EditFileAction;
|
|
393
|
+
listDirectory?: ListDirectoryAction;
|
|
394
|
+
findFiles?: FindFilesAction;
|
|
395
|
+
grep?: GrepAction;
|
|
396
|
+
mkdir?: MkdirAction;
|
|
397
|
+
runCommand?: RunCommandAction;
|
|
398
|
+
runGitCommand?: RunGitCommandAction;
|
|
399
|
+
runHTTPRequest?: GitLabApiRequestAction;
|
|
424
400
|
}
|
|
425
401
|
/**
|
|
426
402
|
* Options for creating a workflow chat model via `provider.workflowChat()`.
|
|
427
403
|
*/
|
|
428
404
|
interface GitLabWorkflowOptions {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
405
|
+
/**
|
|
406
|
+
* Workflow definition type.
|
|
407
|
+
* @default 'chat'
|
|
408
|
+
*/
|
|
409
|
+
workflowDefinition?: string;
|
|
410
|
+
/**
|
|
411
|
+
* Root namespace ID for the GitLab group/project.
|
|
412
|
+
* Used for token scoping and model discovery.
|
|
413
|
+
*/
|
|
414
|
+
rootNamespaceId?: string;
|
|
415
|
+
/**
|
|
416
|
+
* GitLab project ID (numeric or path).
|
|
417
|
+
* Sent as `x-gitlab-project-id` header on WebSocket.
|
|
418
|
+
*/
|
|
419
|
+
projectId?: string;
|
|
420
|
+
/**
|
|
421
|
+
* GitLab namespace ID.
|
|
422
|
+
* Sent as `x-gitlab-namespace-id` header on WebSocket.
|
|
423
|
+
*/
|
|
424
|
+
namespaceId?: string;
|
|
425
|
+
/**
|
|
426
|
+
* MCP tool definitions to expose to the workflow.
|
|
427
|
+
* These are sent in `startRequest.mcpTools`.
|
|
428
|
+
*/
|
|
429
|
+
mcpTools?: McpToolDefinition[];
|
|
430
|
+
/**
|
|
431
|
+
* Client capabilities to advertise.
|
|
432
|
+
* @default ['shell_command']
|
|
433
|
+
*/
|
|
434
|
+
clientCapabilities?: string[];
|
|
435
|
+
/**
|
|
436
|
+
* Tool names that are pre-approved for execution without user confirmation.
|
|
437
|
+
* Sent in `startRequest.preapproved_tools`.
|
|
438
|
+
*/
|
|
439
|
+
preapprovedTools?: string[];
|
|
440
|
+
/**
|
|
441
|
+
* Additional context items to send with the first request.
|
|
442
|
+
* Used for conversation history continuity.
|
|
443
|
+
*/
|
|
444
|
+
additionalContext?: AdditionalContext[];
|
|
445
|
+
/**
|
|
446
|
+
* Feature flags to pass to the GitLab API.
|
|
447
|
+
*/
|
|
448
|
+
featureFlags?: Record<string, boolean>;
|
|
449
|
+
/**
|
|
450
|
+
* Working directory for auto-detecting GitLab project from git remote.
|
|
451
|
+
* Used to resolve `projectId` when not explicitly set.
|
|
452
|
+
* Defaults to `process.cwd()`.
|
|
453
|
+
*/
|
|
454
|
+
workingDirectory?: string;
|
|
455
|
+
/**
|
|
456
|
+
* Flow configuration (parsed YAML object) to send to DWS.
|
|
457
|
+
* Controls agent behavior, intermediate text generation, etc.
|
|
458
|
+
* Sent as `startRequest.flowConfig`.
|
|
459
|
+
*/
|
|
460
|
+
flowConfig?: unknown;
|
|
461
|
+
/**
|
|
462
|
+
* Schema version for the flow configuration.
|
|
463
|
+
* Sent as `startRequest.flowConfigSchemaVersion`.
|
|
464
|
+
*/
|
|
465
|
+
flowConfigSchemaVersion?: string;
|
|
466
|
+
/**
|
|
467
|
+
* Callback invoked when multiple workflow models are available for the
|
|
468
|
+
* workspace and model switching is enabled by the instance admin.
|
|
469
|
+
*
|
|
470
|
+
* The provider calls this before starting the workflow so the host can
|
|
471
|
+
* present a model picker to the user. Return the `ref` of the chosen
|
|
472
|
+
* model, or `null`/`undefined` to fall back to the workspace default.
|
|
473
|
+
*
|
|
474
|
+
* If the returned ref is not in the list of selectable models it is
|
|
475
|
+
* ignored and the workspace default is used instead.
|
|
476
|
+
*
|
|
477
|
+
* Not called when the admin has pinned a model — in that case the
|
|
478
|
+
* pinned model is always used regardless of user preference.
|
|
479
|
+
*
|
|
480
|
+
* @param models - List of models the user can select from
|
|
481
|
+
* @returns The selected model ref, or null/undefined for default
|
|
482
|
+
*/
|
|
483
|
+
onSelectModel?: (models: AiModel[]) => Promise<string | null | undefined>;
|
|
508
484
|
}
|
|
509
485
|
interface GitLabWorkflowClientConfig {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
486
|
+
/** GitLab instance URL (e.g., 'https://gitlab.com') */
|
|
487
|
+
instanceUrl: string;
|
|
488
|
+
/** Function to get current auth headers */
|
|
489
|
+
getHeaders: () => Record<string, string>;
|
|
490
|
+
/**
|
|
491
|
+
* Optional callback to refresh the API key when a 401 error occurs.
|
|
492
|
+
*/
|
|
493
|
+
refreshApiKey?: () => Promise<void>;
|
|
494
|
+
/** Custom fetch implementation */
|
|
495
|
+
fetch?: typeof fetch;
|
|
496
|
+
/** Feature flags for the token request */
|
|
497
|
+
featureFlags?: Record<string, boolean>;
|
|
498
|
+
/**
|
|
499
|
+
* AI Gateway URL.
|
|
500
|
+
* Can also be set via GITLAB_AI_GATEWAY_URL environment variable.
|
|
501
|
+
* @default 'https://cloud.gitlab.com'
|
|
502
|
+
*/
|
|
503
|
+
aiGatewayUrl?: string;
|
|
528
504
|
}
|
|
529
|
-
type WorkflowClientEvent =
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
| {
|
|
553
|
-
type: 'closed';
|
|
554
|
-
code: number;
|
|
555
|
-
reason: string;
|
|
556
|
-
};
|
|
505
|
+
type WorkflowClientEvent = {
|
|
506
|
+
type: 'checkpoint';
|
|
507
|
+
data: NewCheckpoint;
|
|
508
|
+
} | {
|
|
509
|
+
type: 'tool-request';
|
|
510
|
+
requestID: string;
|
|
511
|
+
data: RunMcpTool;
|
|
512
|
+
} | {
|
|
513
|
+
type: 'builtin-tool-request';
|
|
514
|
+
requestID: string;
|
|
515
|
+
toolName: string;
|
|
516
|
+
data: Record<string, unknown>;
|
|
517
|
+
} | {
|
|
518
|
+
type: 'completed';
|
|
519
|
+
} | {
|
|
520
|
+
type: 'failed';
|
|
521
|
+
error: Error;
|
|
522
|
+
} | {
|
|
523
|
+
type: 'closed';
|
|
524
|
+
code: number;
|
|
525
|
+
reason: string;
|
|
526
|
+
};
|
|
557
527
|
/**
|
|
558
528
|
* Workflow type enum — matches gitlab-lsp WorkflowType.
|
|
559
529
|
*
|
|
@@ -561,8 +531,8 @@ type WorkflowClientEvent =
|
|
|
561
531
|
* - SOFTWARE_DEVELOPMENT: Per-workflow token, tokens revoked on completion
|
|
562
532
|
*/
|
|
563
533
|
declare enum WorkflowType {
|
|
564
|
-
|
|
565
|
-
|
|
534
|
+
CHAT = "chat",
|
|
535
|
+
SOFTWARE_DEVELOPMENT = "software_development"
|
|
566
536
|
}
|
|
567
537
|
/** WebSocket ping interval (TCP keepalive) — 45s matching gitlab-lsp */
|
|
568
538
|
declare const WS_KEEPALIVE_PING_INTERVAL_MS = 45000;
|
|
@@ -573,27 +543,27 @@ declare const DEFAULT_WORKFLOW_DEFINITION = WorkflowType.CHAT;
|
|
|
573
543
|
/** Default client capabilities */
|
|
574
544
|
declare const DEFAULT_CLIENT_CAPABILITIES: string[];
|
|
575
545
|
/** Client version sent in startRequest */
|
|
576
|
-
declare const CLIENT_VERSION =
|
|
546
|
+
declare const CLIENT_VERSION = "1.0";
|
|
577
547
|
/**
|
|
578
548
|
* Agent privileges for workflow creation.
|
|
579
549
|
* Matches gitlab-lsp AGENT_PRIVILEGES enum.
|
|
580
550
|
*/
|
|
581
551
|
declare const AGENT_PRIVILEGES: {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
552
|
+
readonly READ_WRITE_FILES: 1;
|
|
553
|
+
readonly READ_ONLY_GITLAB: 2;
|
|
554
|
+
readonly READ_WRITE_GITLAB: 3;
|
|
555
|
+
readonly RUN_COMMANDS: 4;
|
|
556
|
+
readonly USE_GIT: 5;
|
|
557
|
+
readonly RUN_MCP_TOOLS: 6;
|
|
588
558
|
};
|
|
589
559
|
/** Default agent privileges — matches gitlab-lsp defaults */
|
|
590
560
|
declare const DEFAULT_AGENT_PRIVILEGES: (1 | 2 | 4 | 3 | 5 | 6)[];
|
|
591
561
|
/** Workflow execution environment */
|
|
592
|
-
declare const WORKFLOW_ENVIRONMENT:
|
|
562
|
+
declare const WORKFLOW_ENVIRONMENT: "ide";
|
|
593
563
|
|
|
594
564
|
interface GitLabWorkflowLanguageModelConfig extends GitLabWorkflowClientConfig {
|
|
595
|
-
|
|
596
|
-
|
|
565
|
+
/** Provider name (e.g., 'gitlab.workflow') */
|
|
566
|
+
provider: string;
|
|
597
567
|
}
|
|
598
568
|
/**
|
|
599
569
|
* Callback for executing a tool requested by DWS.
|
|
@@ -604,13 +574,11 @@ interface GitLabWorkflowLanguageModelConfig extends GitLabWorkflowClientConfig {
|
|
|
604
574
|
* @param args - JSON-encoded arguments
|
|
605
575
|
* @returns Tool execution result as a string, or throws on error
|
|
606
576
|
*/
|
|
607
|
-
type WorkflowToolExecutor = (
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
result: string;
|
|
613
|
-
error?: string | null;
|
|
577
|
+
type WorkflowToolExecutor = (toolName: string, args: string, requestID: string) => Promise<{
|
|
578
|
+
result: string;
|
|
579
|
+
error?: string | null;
|
|
580
|
+
metadata?: Record<string, unknown>;
|
|
581
|
+
title?: string;
|
|
614
582
|
}>;
|
|
615
583
|
/**
|
|
616
584
|
* GitLab Duo Agent Platform Language Model.
|
|
@@ -619,314 +587,313 @@ type WorkflowToolExecutor = (
|
|
|
619
587
|
* to the Vercel AI SDK stream part format.
|
|
620
588
|
*/
|
|
621
589
|
declare class GitLabWorkflowLanguageModel implements LanguageModelV2 {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
workflowOptions?: GitLabWorkflowOptions
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
private buildAdditionalContext;
|
|
590
|
+
readonly specificationVersion: "v2";
|
|
591
|
+
readonly modelId: string;
|
|
592
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
593
|
+
private readonly config;
|
|
594
|
+
private readonly workflowOptions;
|
|
595
|
+
private readonly tokenClient;
|
|
596
|
+
private readonly projectDetector;
|
|
597
|
+
private readonly modelDiscovery;
|
|
598
|
+
private readonly modelCache;
|
|
599
|
+
private detectedProjectPath;
|
|
600
|
+
private currentWorkflowId;
|
|
601
|
+
private persistedAgentEmitted;
|
|
602
|
+
private readonly activeClients;
|
|
603
|
+
private _selectedModelRef?;
|
|
604
|
+
private _selectedModelName?;
|
|
605
|
+
private _rootNamespaceId?;
|
|
606
|
+
private _discoveryPromise?;
|
|
607
|
+
/**
|
|
608
|
+
* Get the cached selected model ref.
|
|
609
|
+
*/
|
|
610
|
+
get selectedModelRef(): string | null;
|
|
611
|
+
/**
|
|
612
|
+
* Set the selected model ref (e.g., from an eager discover call).
|
|
613
|
+
* This will be used by resolveModelRef() to skip the picker.
|
|
614
|
+
* Also persists to the file-based workspace cache.
|
|
615
|
+
*/
|
|
616
|
+
set selectedModelRef(ref: string | null);
|
|
617
|
+
/**
|
|
618
|
+
* Get the cached selected model display name.
|
|
619
|
+
*/
|
|
620
|
+
get selectedModelName(): string | null;
|
|
621
|
+
/**
|
|
622
|
+
* Set the selected model display name.
|
|
623
|
+
* Also persists to the file-based workspace cache.
|
|
624
|
+
*/
|
|
625
|
+
set selectedModelName(name: string | null);
|
|
626
|
+
/**
|
|
627
|
+
* Optional external tool executor. When set, this is called for tool
|
|
628
|
+
* requests instead of looking up tools from `options.tools`.
|
|
629
|
+
* This allows the consumer (OpenCode) to wire in its permission system.
|
|
630
|
+
*
|
|
631
|
+
* The executor is automatically bound to the async context at the time
|
|
632
|
+
* it is set, so that AsyncLocalStorage-based contexts (like Instance)
|
|
633
|
+
* remain available when the executor is invoked from WebSocket callbacks.
|
|
634
|
+
*/
|
|
635
|
+
private _toolExecutor;
|
|
636
|
+
/**
|
|
637
|
+
* Optional callback invoked with intermediate token usage estimates
|
|
638
|
+
* after each tool execution completes. This allows the consumer to
|
|
639
|
+
* display live token counts during long-running DWS workflows, since
|
|
640
|
+
* the AI SDK only surfaces usage via finish-step at stream end.
|
|
641
|
+
*/
|
|
642
|
+
onUsageUpdate: ((usage: {
|
|
643
|
+
inputTokens: number;
|
|
644
|
+
outputTokens: number;
|
|
645
|
+
}) => void) | null;
|
|
646
|
+
/**
|
|
647
|
+
* Optional callback invoked when multiple workflow models are available
|
|
648
|
+
* and the user should pick one. Set per-stream by the host (e.g., OpenCode)
|
|
649
|
+
* alongside `toolExecutor`. Takes precedence over `workflowOptions.onSelectModel`.
|
|
650
|
+
*/
|
|
651
|
+
onSelectModel: ((models: AiModel[]) => Promise<string | null | undefined>) | null;
|
|
652
|
+
get toolExecutor(): WorkflowToolExecutor | null;
|
|
653
|
+
set toolExecutor(executor: WorkflowToolExecutor | null);
|
|
654
|
+
constructor(modelId: string, config: GitLabWorkflowLanguageModelConfig, workflowOptions?: GitLabWorkflowOptions);
|
|
655
|
+
get provider(): string;
|
|
656
|
+
/**
|
|
657
|
+
* Resolve the project ID (path) to use for workflow creation.
|
|
658
|
+
* Priority: explicit option > auto-detected from git remote > undefined.
|
|
659
|
+
*/
|
|
660
|
+
private resolveProjectId;
|
|
661
|
+
/**
|
|
662
|
+
* Resolve the root namespace GID to use for model discovery.
|
|
663
|
+
*
|
|
664
|
+
* Priority:
|
|
665
|
+
* 1. Explicit `rootNamespaceId` in workflowOptions (caller-provided GID)
|
|
666
|
+
* 2. Auto-detected from git remote via project detector (namespace.id → GID)
|
|
667
|
+
* 3. Cached from previous call
|
|
668
|
+
*/
|
|
669
|
+
private resolveRootNamespaceId;
|
|
670
|
+
/**
|
|
671
|
+
* Resolve the effective DWS model ref to use for this stream.
|
|
672
|
+
* Deduplicates concurrent calls via a shared promise.
|
|
673
|
+
*
|
|
674
|
+
* Priority for the canonical `duo-workflow` model ID:
|
|
675
|
+
* 1. Admin-pinned model (from GitLabModelDiscovery) — always wins
|
|
676
|
+
* 2. User selection via onSelectModel callback (if model switching enabled)
|
|
677
|
+
* 3. Workspace default model
|
|
678
|
+
* 4. File-cached discovery/selection — used when live discovery fails
|
|
679
|
+
* 5. Hard-coded 'default' (DWS decides) — fallback when discovery fails
|
|
680
|
+
*
|
|
681
|
+
* For all other `duo-workflow-*` model IDs the static mapping is used as-is.
|
|
682
|
+
*/
|
|
683
|
+
private resolveModelRef;
|
|
684
|
+
private doResolveModelRef;
|
|
685
|
+
/**
|
|
686
|
+
* Pre-fetch available models for the workspace.
|
|
687
|
+
* Call this early (e.g., on IDE startup) to avoid blocking the first stream.
|
|
688
|
+
* Results are persisted to the workspace model cache.
|
|
689
|
+
*
|
|
690
|
+
* @param rootNamespaceId - GitLab group ID (e.g., 'gid://gitlab/Group/12345')
|
|
691
|
+
* @returns Discovered models with default, selectable, and pinned models
|
|
692
|
+
*/
|
|
693
|
+
discoverModels(rootNamespaceId: string): Promise<DiscoveredModels>;
|
|
694
|
+
/**
|
|
695
|
+
* Get the file-based model cache instance for this workspace.
|
|
696
|
+
* Useful for consumers that need direct cache access (e.g., the discover route).
|
|
697
|
+
*/
|
|
698
|
+
getModelCache(): GitLabModelCache;
|
|
699
|
+
/**
|
|
700
|
+
* Stop the active workflow.
|
|
701
|
+
*/
|
|
702
|
+
stopWorkflow(): void;
|
|
703
|
+
/**
|
|
704
|
+
* Reset the workflow state, forcing a new workflow to be created on the
|
|
705
|
+
* next doStream() call. Call this when starting a new conversation.
|
|
706
|
+
*/
|
|
707
|
+
resetWorkflow(): void;
|
|
708
|
+
/**
|
|
709
|
+
* Get the current workflow ID (if any).
|
|
710
|
+
* Useful for consumers that need to track workflow state.
|
|
711
|
+
*/
|
|
712
|
+
get workflowId(): string | null;
|
|
713
|
+
doGenerate(options: LanguageModelV2CallOptions): Promise<{
|
|
714
|
+
content: LanguageModelV2Content[];
|
|
715
|
+
finishReason: LanguageModelV2FinishReason;
|
|
716
|
+
usage: LanguageModelV2Usage;
|
|
717
|
+
warnings: LanguageModelV2CallWarning[];
|
|
718
|
+
}>;
|
|
719
|
+
doStream(options: LanguageModelV2CallOptions): Promise<{
|
|
720
|
+
stream: ReadableStream<LanguageModelV2StreamPart>;
|
|
721
|
+
request?: {
|
|
722
|
+
body?: unknown;
|
|
723
|
+
};
|
|
724
|
+
}>;
|
|
725
|
+
private handleWorkflowEvent;
|
|
726
|
+
private processCheckpoint;
|
|
727
|
+
private executeToolAndRespond;
|
|
728
|
+
private cleanupClient;
|
|
729
|
+
private buildWorkflowMetadata;
|
|
730
|
+
private getGitInfo;
|
|
731
|
+
/**
|
|
732
|
+
* Extract the user's goal (last user message) from the AI SDK prompt.
|
|
733
|
+
*/
|
|
734
|
+
private extractGoalFromPrompt;
|
|
735
|
+
/**
|
|
736
|
+
* Convert AI SDK tools to DWS McpToolDefinition format.
|
|
737
|
+
*/
|
|
738
|
+
private extractMcpTools;
|
|
739
|
+
private static readonly MAX_START_REQUEST_BYTES;
|
|
740
|
+
/**
|
|
741
|
+
* Trim mcpTools and additionalContext to fit within the DWS 4MB gRPC
|
|
742
|
+
* message size limit (`MAX_MESSAGE_SIZE` in duo_workflow_service/server.py).
|
|
743
|
+
*
|
|
744
|
+
* DWS has no per-field limits on tool descriptions, schemas, or context items.
|
|
745
|
+
* The only hard constraint is the total serialized message size.
|
|
746
|
+
*
|
|
747
|
+
* Strategy (progressive, only if over budget):
|
|
748
|
+
* 1. Send everything as-is
|
|
749
|
+
* 2. Simplify tool input schemas (strip descriptions from properties)
|
|
750
|
+
* 3. Strip schemas to minimal form (type + property names only)
|
|
751
|
+
* 4. Drop tools from the end until it fits
|
|
752
|
+
*/
|
|
753
|
+
private trimPayload;
|
|
754
|
+
private buildAdditionalContext;
|
|
788
755
|
}
|
|
789
756
|
|
|
790
757
|
interface GitLabProvider {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
758
|
+
(modelId: string): LanguageModelV2;
|
|
759
|
+
readonly specificationVersion: 'v2';
|
|
760
|
+
languageModel(modelId: string): LanguageModelV2;
|
|
761
|
+
chat(modelId: string): LanguageModelV2;
|
|
762
|
+
/**
|
|
763
|
+
* Create an agentic chat model with tool calling support
|
|
764
|
+
*
|
|
765
|
+
* @param modelId - GitLab model identifier. Some IDs automatically map to specific Anthropic models.
|
|
766
|
+
* @param options - Configuration options for the agentic model
|
|
767
|
+
* @returns A language model with native tool calling support via Anthropic
|
|
768
|
+
*
|
|
769
|
+
* @example
|
|
770
|
+
* // Automatic model mapping
|
|
771
|
+
* const model = gitlab.agenticChat('duo-chat-opus-4-5');
|
|
772
|
+
* // Uses claude-opus-4-5-20251101
|
|
773
|
+
*
|
|
774
|
+
* @example
|
|
775
|
+
* // Explicit model override
|
|
776
|
+
* const model = gitlab.agenticChat('duo-chat', {
|
|
777
|
+
* anthropicModel: 'claude-sonnet-4-5-20250929'
|
|
778
|
+
* });
|
|
779
|
+
*/
|
|
780
|
+
agenticChat(modelId: string, options?: GitLabAgenticOptions): GitLabAnthropicLanguageModel;
|
|
781
|
+
/**
|
|
782
|
+
* Create a workflow chat model using GitLab Duo Agent Platform.
|
|
783
|
+
*
|
|
784
|
+
* Workflow models use a server-side agentic loop where GitLab's DWS drives
|
|
785
|
+
* the LLM, requests tool executions from the client via WebSocket, and
|
|
786
|
+
* streams text/status back.
|
|
787
|
+
*
|
|
788
|
+
* Requires GitLab Ultimate with Duo Enterprise add-on.
|
|
789
|
+
*
|
|
790
|
+
* @param modelId - Workflow model identifier (e.g., 'duo-workflow-sonnet-4-6')
|
|
791
|
+
* @param options - Workflow-specific configuration
|
|
792
|
+
* @returns A language model backed by the DWS WebSocket protocol
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* const model = gitlab.workflowChat('duo-workflow-sonnet-4-6', {
|
|
796
|
+
* mcpTools: [...],
|
|
797
|
+
* preapprovedTools: ['read_file', 'write_file'],
|
|
798
|
+
* });
|
|
799
|
+
*/
|
|
800
|
+
workflowChat(modelId: string, options?: GitLabWorkflowOptions): GitLabWorkflowLanguageModel;
|
|
801
|
+
textEmbeddingModel(modelId: string): never;
|
|
802
|
+
imageModel(modelId: string): never;
|
|
836
803
|
}
|
|
837
804
|
interface GitLabAgenticOptions {
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
805
|
+
/**
|
|
806
|
+
* Override the provider-specific model (optional).
|
|
807
|
+
* Must be a valid model for the detected provider.
|
|
808
|
+
*
|
|
809
|
+
* For Anthropic models:
|
|
810
|
+
* - 'claude-opus-4-6'
|
|
811
|
+
* - 'claude-sonnet-4-6'
|
|
812
|
+
* - 'claude-opus-4-5-20251101'
|
|
813
|
+
* - 'claude-sonnet-4-5-20250929'
|
|
814
|
+
* - 'claude-haiku-4-5-20251001'
|
|
815
|
+
*
|
|
816
|
+
* For OpenAI models:
|
|
817
|
+
* - 'gpt-5.1-2025-11-13'
|
|
818
|
+
* - 'gpt-5-mini-2025-08-07'
|
|
819
|
+
* - 'gpt-5-codex'
|
|
820
|
+
* - 'gpt-5.2-codex'
|
|
821
|
+
*
|
|
822
|
+
* @example
|
|
823
|
+
* // Override with explicit model
|
|
824
|
+
* const model = gitlab.agenticChat('duo-chat-opus-4-5', {
|
|
825
|
+
* providerModel: 'claude-sonnet-4-5-20250929'
|
|
826
|
+
* });
|
|
827
|
+
*/
|
|
828
|
+
providerModel?: string;
|
|
829
|
+
/**
|
|
830
|
+
* Maximum tokens to generate
|
|
831
|
+
* @default 8192
|
|
832
|
+
*/
|
|
833
|
+
maxTokens?: number;
|
|
834
|
+
/**
|
|
835
|
+
* Feature flags to pass to the GitLab API
|
|
836
|
+
*/
|
|
837
|
+
featureFlags?: Record<string, boolean>;
|
|
838
|
+
/**
|
|
839
|
+
* Custom headers for AI Gateway requests (per-model override).
|
|
840
|
+
* These headers are sent to the Anthropic/OpenAI proxy endpoints.
|
|
841
|
+
* Merged with provider-level aiGatewayHeaders (model-level takes precedence).
|
|
842
|
+
*/
|
|
843
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
877
844
|
}
|
|
878
845
|
interface GitLabProviderSettings {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
846
|
+
/**
|
|
847
|
+
* GitLab instance URL (e.g., 'https://gitlab.com')
|
|
848
|
+
* Can also be set via GITLAB_INSTANCE_URL environment variable.
|
|
849
|
+
* @default 'https://gitlab.com'
|
|
850
|
+
*/
|
|
851
|
+
instanceUrl?: string;
|
|
852
|
+
/**
|
|
853
|
+
* API token (Personal Access Token or OAuth access token)
|
|
854
|
+
* Can also be set via GITLAB_TOKEN environment variable
|
|
855
|
+
*/
|
|
856
|
+
apiKey?: string;
|
|
857
|
+
/**
|
|
858
|
+
* OAuth refresh token (optional, for OAuth flow)
|
|
859
|
+
*/
|
|
860
|
+
refreshToken?: string;
|
|
861
|
+
/**
|
|
862
|
+
* OAuth client ID (required for OAuth flow)
|
|
863
|
+
*/
|
|
864
|
+
clientId?: string;
|
|
865
|
+
/**
|
|
866
|
+
* OAuth redirect URI (required for OAuth flow)
|
|
867
|
+
*/
|
|
868
|
+
redirectUri?: string;
|
|
869
|
+
/**
|
|
870
|
+
* Custom headers to include in requests
|
|
871
|
+
*/
|
|
872
|
+
headers?: Record<string, string>;
|
|
873
|
+
/**
|
|
874
|
+
* Custom fetch implementation
|
|
875
|
+
*/
|
|
876
|
+
fetch?: typeof fetch;
|
|
877
|
+
/**
|
|
878
|
+
* Provider name override
|
|
879
|
+
*/
|
|
880
|
+
name?: string;
|
|
881
|
+
/**
|
|
882
|
+
* Default feature flags to pass to the GitLab API for all agentic chat models
|
|
883
|
+
*/
|
|
884
|
+
featureFlags?: Record<string, boolean>;
|
|
885
|
+
/**
|
|
886
|
+
* AI Gateway URL for the Anthropic proxy.
|
|
887
|
+
* Can also be set via GITLAB_AI_GATEWAY_URL environment variable.
|
|
888
|
+
* @default 'https://cloud.gitlab.com'
|
|
889
|
+
*/
|
|
890
|
+
aiGatewayUrl?: string;
|
|
891
|
+
/**
|
|
892
|
+
* Custom headers to include in AI Gateway requests (Anthropic/OpenAI proxy).
|
|
893
|
+
* These headers are merged with the default headers from direct_access response.
|
|
894
|
+
* Default User-Agent: gitlab-ai-provider/{version}
|
|
895
|
+
*/
|
|
896
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
930
897
|
}
|
|
931
898
|
declare function createGitLab(options?: GitLabProviderSettings): GitLabProvider;
|
|
932
899
|
/**
|
|
@@ -944,92 +911,92 @@ declare const gitlab: GitLabProvider;
|
|
|
944
911
|
declare const VERSION: string;
|
|
945
912
|
|
|
946
913
|
interface GitLabOpenAIConfig {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
914
|
+
provider: string;
|
|
915
|
+
instanceUrl: string;
|
|
916
|
+
getHeaders: () => Record<string, string>;
|
|
917
|
+
fetch?: typeof fetch;
|
|
918
|
+
refreshApiKey?: () => Promise<void>;
|
|
919
|
+
openaiModel?: string;
|
|
920
|
+
maxTokens?: number;
|
|
921
|
+
featureFlags?: {
|
|
922
|
+
DuoAgentPlatformNext: true;
|
|
923
|
+
} & Record<string, boolean>;
|
|
924
|
+
aiGatewayUrl?: string;
|
|
925
|
+
/** Whether to use the Responses API instead of Chat Completions API */
|
|
926
|
+
useResponsesApi?: boolean;
|
|
927
|
+
/**
|
|
928
|
+
* Custom headers for AI Gateway OpenAI proxy requests.
|
|
929
|
+
* Merged with headers from direct_access token response.
|
|
930
|
+
*/
|
|
931
|
+
aiGatewayHeaders?: Record<string, string>;
|
|
965
932
|
}
|
|
966
933
|
declare class GitLabOpenAILanguageModel implements LanguageModelV2 {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
934
|
+
readonly specificationVersion: "v2";
|
|
935
|
+
readonly modelId: string;
|
|
936
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
937
|
+
private readonly config;
|
|
938
|
+
private readonly directAccessClient;
|
|
939
|
+
private readonly useResponsesApi;
|
|
940
|
+
private openaiClient;
|
|
941
|
+
constructor(modelId: string, config: GitLabOpenAIConfig);
|
|
942
|
+
get provider(): string;
|
|
943
|
+
private getOpenAIClient;
|
|
944
|
+
private isTokenError;
|
|
945
|
+
/**
|
|
946
|
+
* Check if an error is a context overflow error (prompt too long)
|
|
947
|
+
* These should NOT trigger token refresh and should be reported to the user.
|
|
948
|
+
*/
|
|
949
|
+
private isContextOverflowError;
|
|
950
|
+
private convertTools;
|
|
951
|
+
private convertToolChoice;
|
|
952
|
+
private convertPrompt;
|
|
953
|
+
private convertFinishReason;
|
|
954
|
+
/**
|
|
955
|
+
* Convert tools to Responses API format
|
|
956
|
+
*/
|
|
957
|
+
private convertToolsForResponses;
|
|
958
|
+
/**
|
|
959
|
+
* Convert prompt to Responses API input format
|
|
960
|
+
*/
|
|
961
|
+
private convertPromptForResponses;
|
|
962
|
+
/**
|
|
963
|
+
* Extract system instructions from prompt
|
|
964
|
+
*/
|
|
965
|
+
private extractSystemInstructions;
|
|
966
|
+
/**
|
|
967
|
+
* Convert Responses API status to finish reason
|
|
968
|
+
* Note: Responses API returns 'completed' even when making tool calls,
|
|
969
|
+
* so we need to check the content for tool calls separately.
|
|
970
|
+
*/
|
|
971
|
+
private convertResponsesStatus;
|
|
972
|
+
doGenerate(options: LanguageModelV2CallOptions): Promise<{
|
|
973
|
+
content: LanguageModelV2Content[];
|
|
974
|
+
finishReason: LanguageModelV2FinishReason;
|
|
975
|
+
usage: LanguageModelV2Usage;
|
|
976
|
+
warnings: LanguageModelV2CallWarning[];
|
|
977
|
+
}>;
|
|
978
|
+
private doGenerateWithChatApi;
|
|
979
|
+
private doGenerateWithResponsesApi;
|
|
980
|
+
doStream(options: LanguageModelV2CallOptions): Promise<{
|
|
981
|
+
stream: ReadableStream<LanguageModelV2StreamPart>;
|
|
982
|
+
request?: {
|
|
983
|
+
body?: unknown;
|
|
984
|
+
};
|
|
985
|
+
response?: {
|
|
986
|
+
headers?: Record<string, string>;
|
|
987
|
+
};
|
|
988
|
+
}>;
|
|
989
|
+
private doStreamWithChatApi;
|
|
990
|
+
private doStreamWithResponsesApi;
|
|
1024
991
|
}
|
|
1025
992
|
|
|
1026
993
|
type ModelProvider = 'anthropic' | 'openai' | 'workflow';
|
|
1027
994
|
type OpenAIApiType = 'chat' | 'responses';
|
|
1028
995
|
interface ModelMapping {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
996
|
+
provider: ModelProvider;
|
|
997
|
+
model: string;
|
|
998
|
+
/** For OpenAI models, which API to use: 'chat' for /v1/chat/completions, 'responses' for /v1/responses */
|
|
999
|
+
openaiApiType?: OpenAIApiType;
|
|
1033
1000
|
}
|
|
1034
1001
|
declare const MODEL_MAPPINGS: Record<string, ModelMapping>;
|
|
1035
1002
|
declare function getModelMapping(modelId: string): ModelMapping | undefined;
|
|
@@ -1044,50 +1011,44 @@ declare function getWorkflowModelRef(modelId: string): string | undefined;
|
|
|
1044
1011
|
declare const MODEL_ID_TO_ANTHROPIC_MODEL: Record<string, string>;
|
|
1045
1012
|
|
|
1046
1013
|
interface GitLabErrorOptions {
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1014
|
+
message: string;
|
|
1015
|
+
statusCode?: number;
|
|
1016
|
+
responseBody?: string;
|
|
1017
|
+
cause?: unknown;
|
|
1051
1018
|
}
|
|
1052
1019
|
declare class GitLabError extends Error {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1020
|
+
readonly statusCode?: number;
|
|
1021
|
+
readonly responseBody?: string;
|
|
1022
|
+
readonly cause?: unknown;
|
|
1023
|
+
constructor(options: GitLabErrorOptions);
|
|
1024
|
+
static fromResponse(response: Response, body: string): GitLabError;
|
|
1025
|
+
isAuthError(): boolean;
|
|
1026
|
+
isRateLimitError(): boolean;
|
|
1027
|
+
isForbiddenError(): boolean;
|
|
1028
|
+
isServerError(): boolean;
|
|
1029
|
+
/**
|
|
1030
|
+
* Check if this error is a context overflow error (prompt too long).
|
|
1031
|
+
* These errors occur when the conversation exceeds the model's token limit.
|
|
1032
|
+
*/
|
|
1033
|
+
isContextOverflowError(): boolean;
|
|
1067
1034
|
}
|
|
1068
1035
|
|
|
1069
|
-
declare const gitlabOAuthTokenResponseSchema: z.ZodObject<
|
|
1070
|
-
{
|
|
1036
|
+
declare const gitlabOAuthTokenResponseSchema: z.ZodObject<{
|
|
1071
1037
|
access_token: z.ZodString;
|
|
1072
1038
|
refresh_token: z.ZodOptional<z.ZodString>;
|
|
1073
1039
|
expires_in: z.ZodNumber;
|
|
1074
1040
|
created_at: z.ZodNumber;
|
|
1075
|
-
|
|
1076
|
-
'strip',
|
|
1077
|
-
z.ZodTypeAny,
|
|
1078
|
-
{
|
|
1041
|
+
}, "strip", z.ZodTypeAny, {
|
|
1079
1042
|
created_at?: number;
|
|
1080
1043
|
access_token?: string;
|
|
1081
1044
|
refresh_token?: string;
|
|
1082
1045
|
expires_in?: number;
|
|
1083
|
-
|
|
1084
|
-
{
|
|
1046
|
+
}, {
|
|
1085
1047
|
created_at?: number;
|
|
1086
1048
|
access_token?: string;
|
|
1087
1049
|
refresh_token?: string;
|
|
1088
1050
|
expires_in?: number;
|
|
1089
|
-
|
|
1090
|
-
>;
|
|
1051
|
+
}>;
|
|
1091
1052
|
type GitLabOAuthTokenResponse = z.infer<typeof gitlabOAuthTokenResponseSchema>;
|
|
1092
1053
|
|
|
1093
1054
|
/**
|
|
@@ -1095,24 +1056,24 @@ type GitLabOAuthTokenResponse = z.infer<typeof gitlabOAuthTokenResponseSchema>;
|
|
|
1095
1056
|
* Based on gitlab-vscode-extension and gitlab-lsp patterns
|
|
1096
1057
|
*/
|
|
1097
1058
|
interface GitLabOAuthTokens {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1059
|
+
accessToken: string;
|
|
1060
|
+
refreshToken: string;
|
|
1061
|
+
expiresAt: number;
|
|
1062
|
+
instanceUrl: string;
|
|
1102
1063
|
}
|
|
1103
1064
|
interface OpenCodeAuthOAuth {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1065
|
+
type: 'oauth';
|
|
1066
|
+
refresh: string;
|
|
1067
|
+
access: string;
|
|
1068
|
+
expires: number;
|
|
1069
|
+
/** @deprecated Use enterpriseUrl instead. Kept for backwards compatibility with older auth.json files. */
|
|
1070
|
+
instanceUrl?: string;
|
|
1071
|
+
/** Instance URL as written by opencode-gitlab-auth plugin (e.g. 'https://gitlab.com') */
|
|
1072
|
+
enterpriseUrl?: string;
|
|
1112
1073
|
}
|
|
1113
1074
|
interface OpenCodeAuthApi {
|
|
1114
|
-
|
|
1115
|
-
|
|
1075
|
+
type: 'api';
|
|
1076
|
+
key: string;
|
|
1116
1077
|
}
|
|
1117
1078
|
type OpenCodeAuth = OpenCodeAuthOAuth | OpenCodeAuthApi;
|
|
1118
1079
|
/**
|
|
@@ -1122,18 +1083,16 @@ type OpenCodeAuth = OpenCodeAuthOAuth | OpenCodeAuthApi;
|
|
|
1122
1083
|
* Note: VS Code extension uses a different client ID ('36f2a70c...') but we use the opencode plugin's ID
|
|
1123
1084
|
* to ensure token refresh works correctly with tokens created by the auth plugin.
|
|
1124
1085
|
*/
|
|
1125
|
-
declare const OPENCODE_GITLAB_AUTH_CLIENT_ID =
|
|
1126
|
-
'1d89f9fdb23ee96d4e603201f6861dab6e143c5c3c00469a018a2d94bdc03d4e';
|
|
1086
|
+
declare const OPENCODE_GITLAB_AUTH_CLIENT_ID = "1d89f9fdb23ee96d4e603201f6861dab6e143c5c3c00469a018a2d94bdc03d4e";
|
|
1127
1087
|
/**
|
|
1128
1088
|
* @deprecated Use OPENCODE_GITLAB_AUTH_CLIENT_ID instead. This is the VS Code extension's client ID
|
|
1129
1089
|
* and will cause refresh failures if used with tokens created by opencode-gitlab-auth.
|
|
1130
1090
|
*/
|
|
1131
|
-
declare const BUNDLED_CLIENT_ID =
|
|
1132
|
-
'36f2a70cddeb5a0889d4fd8295c241b7e9848e89cf9e599d0eed2d8e5350fbf5';
|
|
1091
|
+
declare const BUNDLED_CLIENT_ID = "36f2a70cddeb5a0889d4fd8295c241b7e9848e89cf9e599d0eed2d8e5350fbf5";
|
|
1133
1092
|
/**
|
|
1134
1093
|
* GitLab.com URL constant
|
|
1135
1094
|
*/
|
|
1136
|
-
declare const GITLAB_COM_URL =
|
|
1095
|
+
declare const GITLAB_COM_URL = "https://gitlab.com";
|
|
1137
1096
|
/**
|
|
1138
1097
|
* Token expiry skew in milliseconds (5 minutes)
|
|
1139
1098
|
* Refresh tokens this many milliseconds before they expire
|
|
@@ -1151,64 +1110,64 @@ declare const OAUTH_SCOPES: string[];
|
|
|
1151
1110
|
*/
|
|
1152
1111
|
|
|
1153
1112
|
interface TokenExchangeParams {
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1113
|
+
instanceUrl: string;
|
|
1114
|
+
clientId?: string;
|
|
1115
|
+
redirectUri?: string;
|
|
1157
1116
|
}
|
|
1158
1117
|
interface AuthorizationCodeParams extends TokenExchangeParams {
|
|
1159
|
-
|
|
1160
|
-
|
|
1118
|
+
code: string;
|
|
1119
|
+
codeVerifier: string;
|
|
1161
1120
|
}
|
|
1162
1121
|
interface RefreshTokenParams extends TokenExchangeParams {
|
|
1163
|
-
|
|
1122
|
+
refreshToken: string;
|
|
1164
1123
|
}
|
|
1165
1124
|
declare class GitLabOAuthManager {
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1125
|
+
private fetch;
|
|
1126
|
+
constructor(fetchImpl?: typeof fetch);
|
|
1127
|
+
/**
|
|
1128
|
+
* Check if a token is expired
|
|
1129
|
+
*/
|
|
1130
|
+
isTokenExpired(expiresAt: number): boolean;
|
|
1131
|
+
/**
|
|
1132
|
+
* Check if a token needs refresh (within skew window)
|
|
1133
|
+
*/
|
|
1134
|
+
needsRefresh(expiresAt: number): boolean;
|
|
1135
|
+
/**
|
|
1136
|
+
* Refresh tokens if needed
|
|
1137
|
+
* Returns the same tokens if refresh is not needed, or new tokens if refreshed
|
|
1138
|
+
*/
|
|
1139
|
+
refreshIfNeeded(tokens: GitLabOAuthTokens, clientId?: string): Promise<GitLabOAuthTokens>;
|
|
1140
|
+
/**
|
|
1141
|
+
* Exchange authorization code for tokens
|
|
1142
|
+
* Based on gitlab-vscode-extension createOAuthAccountFromCode
|
|
1143
|
+
*/
|
|
1144
|
+
exchangeAuthorizationCode(params: AuthorizationCodeParams): Promise<GitLabOAuthTokens>;
|
|
1145
|
+
/**
|
|
1146
|
+
* Exchange refresh token for new tokens
|
|
1147
|
+
* Based on gitlab-vscode-extension TokenExchangeService
|
|
1148
|
+
*/
|
|
1149
|
+
exchangeRefreshToken(params: RefreshTokenParams): Promise<GitLabOAuthTokens>;
|
|
1150
|
+
/**
|
|
1151
|
+
* Get the OAuth client ID for an instance.
|
|
1152
|
+
* Priority: env var > opencode-gitlab-auth default (for GitLab.com).
|
|
1153
|
+
* Note: callers (e.g. exchangeRefreshToken) may pass an explicit clientId
|
|
1154
|
+
* that bypasses this method entirely.
|
|
1155
|
+
*/
|
|
1156
|
+
private getClientId;
|
|
1157
|
+
/**
|
|
1158
|
+
* Exchange token with GitLab OAuth endpoint
|
|
1159
|
+
* Based on gitlab-vscode-extension GitLabService.exchangeToken
|
|
1160
|
+
*/
|
|
1161
|
+
private exchangeToken;
|
|
1162
|
+
/**
|
|
1163
|
+
* Create GitLabOAuthTokens from token response
|
|
1164
|
+
*/
|
|
1165
|
+
private createTokensFromResponse;
|
|
1166
|
+
/**
|
|
1167
|
+
* Create expiry timestamp from token response
|
|
1168
|
+
* Based on gitlab-vscode-extension createExpiresTimestamp
|
|
1169
|
+
*/
|
|
1170
|
+
private createExpiresTimestamp;
|
|
1212
1171
|
}
|
|
1213
1172
|
|
|
1214
1173
|
/**
|
|
@@ -1216,68 +1175,68 @@ declare class GitLabOAuthManager {
|
|
|
1216
1175
|
* Used to avoid repeated API calls when detecting projects from git remotes
|
|
1217
1176
|
*/
|
|
1218
1177
|
interface GitLabProject {
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1178
|
+
id: number;
|
|
1179
|
+
path: string;
|
|
1180
|
+
pathWithNamespace: string;
|
|
1181
|
+
name: string;
|
|
1182
|
+
namespaceId?: number;
|
|
1224
1183
|
}
|
|
1225
1184
|
/**
|
|
1226
1185
|
* In-memory cache for GitLab project information with TTL support
|
|
1227
1186
|
*/
|
|
1228
1187
|
declare class GitLabProjectCache {
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1188
|
+
private cache;
|
|
1189
|
+
private defaultTTL;
|
|
1190
|
+
/**
|
|
1191
|
+
* Create a new project cache
|
|
1192
|
+
* @param defaultTTL - Default time-to-live in milliseconds (default: 5 minutes)
|
|
1193
|
+
*/
|
|
1194
|
+
constructor(defaultTTL?: number);
|
|
1195
|
+
/**
|
|
1196
|
+
* Get a cached project by key
|
|
1197
|
+
* @param key - Cache key (typically the working directory path)
|
|
1198
|
+
* @returns The cached project or null if not found or expired
|
|
1199
|
+
*/
|
|
1200
|
+
get(key: string): GitLabProject | null;
|
|
1201
|
+
/**
|
|
1202
|
+
* Store a project in the cache
|
|
1203
|
+
* @param key - Cache key (typically the working directory path)
|
|
1204
|
+
* @param project - The project to cache
|
|
1205
|
+
* @param ttl - Optional custom TTL in milliseconds
|
|
1206
|
+
*/
|
|
1207
|
+
set(key: string, project: GitLabProject, ttl?: number): void;
|
|
1208
|
+
/**
|
|
1209
|
+
* Check if a key exists in the cache (and is not expired)
|
|
1210
|
+
* @param key - Cache key to check
|
|
1211
|
+
* @returns true if the key exists and is not expired
|
|
1212
|
+
*/
|
|
1213
|
+
has(key: string): boolean;
|
|
1214
|
+
/**
|
|
1215
|
+
* Remove a specific entry from the cache
|
|
1216
|
+
* @param key - Cache key to remove
|
|
1217
|
+
*/
|
|
1218
|
+
delete(key: string): void;
|
|
1219
|
+
/**
|
|
1220
|
+
* Clear all entries from the cache
|
|
1221
|
+
*/
|
|
1222
|
+
clear(): void;
|
|
1223
|
+
/**
|
|
1224
|
+
* Get the number of entries in the cache (including expired ones)
|
|
1225
|
+
*/
|
|
1226
|
+
get size(): number;
|
|
1227
|
+
/**
|
|
1228
|
+
* Clean up expired entries from the cache
|
|
1229
|
+
* This is useful for long-running processes to prevent memory leaks
|
|
1230
|
+
*/
|
|
1231
|
+
cleanup(): void;
|
|
1273
1232
|
}
|
|
1274
1233
|
|
|
1275
1234
|
interface GitLabProjectDetectorConfig {
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1235
|
+
instanceUrl: string;
|
|
1236
|
+
getHeaders: () => Record<string, string>;
|
|
1237
|
+
fetch?: typeof fetch;
|
|
1238
|
+
cache?: GitLabProjectCache;
|
|
1239
|
+
gitTimeout?: number;
|
|
1281
1240
|
}
|
|
1282
1241
|
/**
|
|
1283
1242
|
* Detects GitLab project information from git remote URLs
|
|
@@ -1289,131 +1248,125 @@ interface GitLabProjectDetectorConfig {
|
|
|
1289
1248
|
* - Cache project information to avoid repeated API calls
|
|
1290
1249
|
*/
|
|
1291
1250
|
declare class GitLabProjectDetector {
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1251
|
+
private readonly config;
|
|
1252
|
+
private readonly fetchFn;
|
|
1253
|
+
private readonly cache;
|
|
1254
|
+
constructor(config: GitLabProjectDetectorConfig);
|
|
1255
|
+
/**
|
|
1256
|
+
* Auto-detect GitLab project from git remote in the working directory
|
|
1257
|
+
*
|
|
1258
|
+
* @param workingDirectory - The directory to check for git remote
|
|
1259
|
+
* @param remoteName - The git remote name to use (default: 'origin')
|
|
1260
|
+
* @returns The detected project or null if not a git repo / no matching remote
|
|
1261
|
+
* @throws GitLabError if the API call or an unexpected error occurs
|
|
1262
|
+
*/
|
|
1263
|
+
detectProject(workingDirectory: string, remoteName?: string): Promise<GitLabProject | null>;
|
|
1264
|
+
/**
|
|
1265
|
+
* Parse a git remote URL to extract the project path
|
|
1266
|
+
*
|
|
1267
|
+
* Supports:
|
|
1268
|
+
* - SSH: git@gitlab.com:namespace/project.git
|
|
1269
|
+
* - HTTPS: https://gitlab.com/namespace/project.git
|
|
1270
|
+
* - HTTP: http://gitlab.local/namespace/project.git
|
|
1271
|
+
* - Custom domains and ports
|
|
1272
|
+
*
|
|
1273
|
+
* @param remoteUrl - The git remote URL
|
|
1274
|
+
* @param instanceUrl - The GitLab instance URL to match against
|
|
1275
|
+
* @returns The project path (e.g., "namespace/project") or null if parsing fails
|
|
1276
|
+
*/
|
|
1277
|
+
parseGitRemoteUrl(remoteUrl: string, instanceUrl: string): string | null;
|
|
1278
|
+
/**
|
|
1279
|
+
* Get the git remote URL from a working directory
|
|
1280
|
+
*
|
|
1281
|
+
* @param workingDirectory - The directory to check
|
|
1282
|
+
* @param remoteName - The git remote name (default: 'origin')
|
|
1283
|
+
* @returns The remote URL or null if not found
|
|
1284
|
+
*/
|
|
1285
|
+
getGitRemoteUrl(workingDirectory: string, remoteName?: string): Promise<string | null>;
|
|
1286
|
+
/**
|
|
1287
|
+
* Fetch project details from GitLab API by project path
|
|
1288
|
+
*
|
|
1289
|
+
* @param projectPath - The project path (e.g., "namespace/project")
|
|
1290
|
+
* @returns The project details
|
|
1291
|
+
* @throws GitLabError if the API call fails
|
|
1292
|
+
*/
|
|
1293
|
+
getProjectByPath(projectPath: string): Promise<GitLabProject>;
|
|
1294
|
+
/**
|
|
1295
|
+
* Clear the project cache
|
|
1296
|
+
*/
|
|
1297
|
+
clearCache(): void;
|
|
1298
|
+
/**
|
|
1299
|
+
* Get the cache instance (useful for testing)
|
|
1300
|
+
*/
|
|
1301
|
+
getCache(): GitLabProjectCache;
|
|
1343
1302
|
}
|
|
1344
1303
|
|
|
1345
1304
|
/**
|
|
1346
1305
|
* Response from /api/v4/ai/third_party_agents/direct_access
|
|
1347
1306
|
*/
|
|
1348
|
-
declare const directAccessTokenSchema: z.ZodObject<
|
|
1349
|
-
{
|
|
1307
|
+
declare const directAccessTokenSchema: z.ZodObject<{
|
|
1350
1308
|
headers: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1351
1309
|
token: z.ZodString;
|
|
1352
|
-
|
|
1353
|
-
'strip',
|
|
1354
|
-
z.ZodTypeAny,
|
|
1355
|
-
{
|
|
1310
|
+
}, "strip", z.ZodTypeAny, {
|
|
1356
1311
|
headers?: Record<string, string>;
|
|
1357
1312
|
token?: string;
|
|
1358
|
-
|
|
1359
|
-
{
|
|
1313
|
+
}, {
|
|
1360
1314
|
headers?: Record<string, string>;
|
|
1361
1315
|
token?: string;
|
|
1362
|
-
|
|
1363
|
-
>;
|
|
1316
|
+
}>;
|
|
1364
1317
|
type DirectAccessToken = z.infer<typeof directAccessTokenSchema>;
|
|
1365
|
-
declare const DEFAULT_AI_GATEWAY_URL =
|
|
1318
|
+
declare const DEFAULT_AI_GATEWAY_URL = "https://cloud.gitlab.com";
|
|
1366
1319
|
interface GitLabDirectAccessConfig {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1320
|
+
instanceUrl: string;
|
|
1321
|
+
getHeaders: () => Record<string, string>;
|
|
1322
|
+
fetch?: typeof fetch;
|
|
1323
|
+
/**
|
|
1324
|
+
* Optional callback to refresh the API key when a 401 error occurs.
|
|
1325
|
+
* Should clear cached credentials and re-fetch from auth provider.
|
|
1326
|
+
*/
|
|
1327
|
+
refreshApiKey?: () => Promise<void>;
|
|
1328
|
+
/**
|
|
1329
|
+
* Feature flags to pass to the GitLab API
|
|
1330
|
+
*/
|
|
1331
|
+
featureFlags?: Record<string, boolean>;
|
|
1332
|
+
/**
|
|
1333
|
+
* AI Gateway URL for the Anthropic proxy.
|
|
1334
|
+
* Can also be set via GITLAB_AI_GATEWAY_URL environment variable.
|
|
1335
|
+
* @default 'https://cloud.gitlab.com'
|
|
1336
|
+
*/
|
|
1337
|
+
aiGatewayUrl?: string;
|
|
1385
1338
|
}
|
|
1386
1339
|
/**
|
|
1387
1340
|
* Client for GitLab's third-party agents direct access API.
|
|
1388
1341
|
* This allows routing requests through GitLab's proxy to Anthropic.
|
|
1389
1342
|
*/
|
|
1390
1343
|
declare class GitLabDirectAccessClient {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1344
|
+
private readonly config;
|
|
1345
|
+
private readonly fetchFn;
|
|
1346
|
+
private readonly aiGatewayUrl;
|
|
1347
|
+
private cachedToken;
|
|
1348
|
+
private tokenExpiresAt;
|
|
1349
|
+
constructor(config: GitLabDirectAccessConfig);
|
|
1350
|
+
/**
|
|
1351
|
+
* Get a direct access token for the Anthropic proxy.
|
|
1352
|
+
* Tokens are cached for 25 minutes (they expire after 30 minutes).
|
|
1353
|
+
* @param forceRefresh - If true, ignores the cache and fetches a new token
|
|
1354
|
+
*/
|
|
1355
|
+
getDirectAccessToken(forceRefresh?: boolean): Promise<DirectAccessToken>;
|
|
1356
|
+
/**
|
|
1357
|
+
* Get the Anthropic proxy base URL
|
|
1358
|
+
*/
|
|
1359
|
+
getAnthropicProxyUrl(): string;
|
|
1360
|
+
/**
|
|
1361
|
+
* Get the OpenAI proxy base URL
|
|
1362
|
+
* Note: The OpenAI SDK expects a base URL like https://api.openai.com/v1
|
|
1363
|
+
* and appends paths like /chat/completions. So we need /v1 at the end.
|
|
1364
|
+
*/
|
|
1365
|
+
getOpenAIProxyUrl(): string;
|
|
1366
|
+
/**
|
|
1367
|
+
* Invalidate the cached token
|
|
1368
|
+
*/
|
|
1369
|
+
invalidateToken(): void;
|
|
1417
1370
|
}
|
|
1418
1371
|
|
|
1419
1372
|
/**
|
|
@@ -1428,77 +1381,77 @@ declare class GitLabDirectAccessClient {
|
|
|
1428
1381
|
*/
|
|
1429
1382
|
|
|
1430
1383
|
interface WorkflowWebSocketOptions {
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1384
|
+
/** GitLab instance URL */
|
|
1385
|
+
instanceUrl: string;
|
|
1386
|
+
/** Model reference for DWS (e.g. 'anthropic/claude-sonnet-4-5-20250929' or 'default') */
|
|
1387
|
+
modelRef: string;
|
|
1388
|
+
/** Auth headers — must include Authorization */
|
|
1389
|
+
headers: Record<string, string>;
|
|
1390
|
+
/** Optional correlation ID */
|
|
1391
|
+
requestId?: string;
|
|
1392
|
+
/** Optional project context */
|
|
1393
|
+
projectId?: string;
|
|
1394
|
+
namespaceId?: string;
|
|
1395
|
+
rootNamespaceId?: string;
|
|
1443
1396
|
}
|
|
1444
1397
|
type EventCallback = (event: WorkflowClientEvent) => void;
|
|
1445
1398
|
declare class GitLabWorkflowClient {
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1399
|
+
private socket;
|
|
1400
|
+
private keepaliveInterval;
|
|
1401
|
+
private heartbeatInterval;
|
|
1402
|
+
private eventCallback;
|
|
1403
|
+
private closed;
|
|
1404
|
+
private lastSendTime;
|
|
1405
|
+
/**
|
|
1406
|
+
* Connect to the DWS WebSocket and start listening for events.
|
|
1407
|
+
*
|
|
1408
|
+
* @param options - Connection parameters
|
|
1409
|
+
* @param onEvent - Callback invoked for each WorkflowClientEvent
|
|
1410
|
+
* @returns Promise that resolves when the connection is open
|
|
1411
|
+
*/
|
|
1412
|
+
connect(options: WorkflowWebSocketOptions, onEvent: EventCallback): Promise<void>;
|
|
1413
|
+
/**
|
|
1414
|
+
* Send a startRequest to begin the workflow.
|
|
1415
|
+
*/
|
|
1416
|
+
sendStartRequest(request: StartRequest): void;
|
|
1417
|
+
/**
|
|
1418
|
+
* Send an actionResponse (tool result) back to DWS.
|
|
1419
|
+
*/
|
|
1420
|
+
sendActionResponse(requestID: string, response: string, error?: string | null): void;
|
|
1421
|
+
/**
|
|
1422
|
+
* Stop the workflow gracefully.
|
|
1423
|
+
*/
|
|
1424
|
+
stop(): void;
|
|
1425
|
+
/**
|
|
1426
|
+
* Close the WebSocket connection.
|
|
1427
|
+
*/
|
|
1428
|
+
close(): void;
|
|
1429
|
+
/**
|
|
1430
|
+
* Check if the WebSocket is currently connected.
|
|
1431
|
+
*/
|
|
1432
|
+
get isConnected(): boolean;
|
|
1433
|
+
private validateOptions;
|
|
1434
|
+
private buildWebSocketUrl;
|
|
1435
|
+
private buildWebSocketHeaders;
|
|
1436
|
+
private handleAction;
|
|
1437
|
+
private send;
|
|
1438
|
+
private sendHeartbeatIfNeeded;
|
|
1439
|
+
private emit;
|
|
1440
|
+
/**
|
|
1441
|
+
* Start ws.ping() keepalive (45s interval).
|
|
1442
|
+
* Keeps TCP connection alive through proxies/load balancers.
|
|
1443
|
+
*/
|
|
1444
|
+
private startKeepalive;
|
|
1445
|
+
/**
|
|
1446
|
+
* Start application-level heartbeat (60s interval).
|
|
1447
|
+
* Prevents DWS from timing out the workflow.
|
|
1448
|
+
*/
|
|
1449
|
+
private startHeartbeat;
|
|
1450
|
+
private cleanedUp;
|
|
1451
|
+
/**
|
|
1452
|
+
* Clean up intervals. Idempotent — safe to call multiple times.
|
|
1453
|
+
*/
|
|
1454
|
+
private cleanup;
|
|
1502
1455
|
}
|
|
1503
1456
|
|
|
1504
1457
|
/**
|
|
@@ -1514,145 +1467,110 @@ declare class GitLabWorkflowClient {
|
|
|
1514
1467
|
*/
|
|
1515
1468
|
|
|
1516
1469
|
declare class GitLabWorkflowTokenClient {
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
/**
|
|
1569
|
-
* Invalidate cached tokens.
|
|
1570
|
-
*
|
|
1571
|
-
* @param workflowDefinition - If provided, only invalidate for this type.
|
|
1572
|
-
* If omitted, clears ALL cached tokens.
|
|
1573
|
-
*/
|
|
1574
|
-
invalidateToken(workflowDefinition?: string, rootNamespaceId?: string): void;
|
|
1470
|
+
private readonly config;
|
|
1471
|
+
private readonly fetchFn;
|
|
1472
|
+
/**
|
|
1473
|
+
* Token cache keyed by workflow definition type.
|
|
1474
|
+
*
|
|
1475
|
+
* - CHAT workflows use a shared key (CHAT_SHARED_TOKEN_KEY) so tokens
|
|
1476
|
+
* are reused across ALL chat sessions (matching gitlab-lsp behavior).
|
|
1477
|
+
* - SOFTWARE_DEVELOPMENT workflows would use per-workflow-id keys,
|
|
1478
|
+
* but since we fetch tokens before creating workflows, we key by type.
|
|
1479
|
+
*/
|
|
1480
|
+
private tokenCache;
|
|
1481
|
+
constructor(config: GitLabWorkflowClientConfig);
|
|
1482
|
+
/**
|
|
1483
|
+
* Resolve the cache key for a given workflow definition.
|
|
1484
|
+
* CHAT workflows share a single token per namespace; other types get per-type keys.
|
|
1485
|
+
*/
|
|
1486
|
+
private getCacheKey;
|
|
1487
|
+
/**
|
|
1488
|
+
* Get a DWS token, using cached value if still valid.
|
|
1489
|
+
*
|
|
1490
|
+
* Token caching strategy (matches gitlab-lsp):
|
|
1491
|
+
* - CHAT workflows: shared token across all sessions
|
|
1492
|
+
* - Other workflows: per-type token
|
|
1493
|
+
*
|
|
1494
|
+
* @param workflowDefinition - Workflow type (default: 'chat')
|
|
1495
|
+
* @param rootNamespaceId - Optional root namespace for scoping
|
|
1496
|
+
* @param forceRefresh - Bypass cache
|
|
1497
|
+
*/
|
|
1498
|
+
getToken(workflowDefinition?: string, rootNamespaceId?: string, forceRefresh?: boolean): Promise<GenerateTokenResponse>;
|
|
1499
|
+
/**
|
|
1500
|
+
* Create a new workflow on the GitLab instance.
|
|
1501
|
+
*
|
|
1502
|
+
* @param goal - The user's message / goal for this workflow
|
|
1503
|
+
* @param options - Additional workflow creation options
|
|
1504
|
+
* @returns The created workflow's ID
|
|
1505
|
+
*/
|
|
1506
|
+
createWorkflow(goal: string, options?: {
|
|
1507
|
+
projectId?: string;
|
|
1508
|
+
namespaceId?: string;
|
|
1509
|
+
workflowDefinition?: string;
|
|
1510
|
+
agentPrivileges?: number[];
|
|
1511
|
+
environment?: string;
|
|
1512
|
+
allowAgentToRequestUser?: boolean;
|
|
1513
|
+
}): Promise<string>;
|
|
1514
|
+
/**
|
|
1515
|
+
* Invalidate cached tokens.
|
|
1516
|
+
*
|
|
1517
|
+
* @param workflowDefinition - If provided, only invalidate for this type.
|
|
1518
|
+
* If omitted, clears ALL cached tokens.
|
|
1519
|
+
*/
|
|
1520
|
+
invalidateToken(workflowDefinition?: string, rootNamespaceId?: string): void;
|
|
1575
1521
|
}
|
|
1576
1522
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
type OpenCodeAuth,
|
|
1632
|
-
type OpenCodeAuthApi,
|
|
1633
|
-
type OpenCodeAuthOAuth,
|
|
1634
|
-
type RunMcpTool,
|
|
1635
|
-
type StartRequest,
|
|
1636
|
-
TOKEN_EXPIRY_SKEW_MS,
|
|
1637
|
-
VERSION,
|
|
1638
|
-
WORKFLOW_ENVIRONMENT,
|
|
1639
|
-
WS_HEARTBEAT_INTERVAL_MS,
|
|
1640
|
-
WS_KEEPALIVE_PING_INTERVAL_MS,
|
|
1641
|
-
type WorkflowAction,
|
|
1642
|
-
type WorkflowClientEvent,
|
|
1643
|
-
type WorkflowStatus,
|
|
1644
|
-
type WorkflowToolExecutor,
|
|
1645
|
-
WorkflowType,
|
|
1646
|
-
type WorkflowWebSocketOptions,
|
|
1647
|
-
createGitLab,
|
|
1648
|
-
getAnthropicModelForModelId,
|
|
1649
|
-
getModelMapping,
|
|
1650
|
-
getOpenAIApiType,
|
|
1651
|
-
getOpenAIModelForModelId,
|
|
1652
|
-
getProviderForModelId,
|
|
1653
|
-
getValidModelsForProvider,
|
|
1654
|
-
getWorkflowModelRef,
|
|
1655
|
-
gitlab,
|
|
1656
|
-
isResponsesApiModel,
|
|
1657
|
-
isWorkflowModel,
|
|
1658
|
-
};
|
|
1523
|
+
/**
|
|
1524
|
+
* Fetches and caches model configuration from the GitLab AI Gateway's
|
|
1525
|
+
* models.yml definition file. Provides per-model context window and
|
|
1526
|
+
* output token limits keyed by `gitlab_identifier`.
|
|
1527
|
+
*
|
|
1528
|
+
* Results are cached both in memory and on disk at
|
|
1529
|
+
* `~/.cache/opencode/gitlab-model-configs.json`
|
|
1530
|
+
* (or `$XDG_CACHE_HOME/opencode/...` when set).
|
|
1531
|
+
*
|
|
1532
|
+
* @see https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/main/ai_gateway/model_selection/models.yml
|
|
1533
|
+
*/
|
|
1534
|
+
interface ModelConfig {
|
|
1535
|
+
/** Maximum input context tokens */
|
|
1536
|
+
context: number;
|
|
1537
|
+
/** Maximum output tokens (from params.max_tokens) */
|
|
1538
|
+
output: number;
|
|
1539
|
+
}
|
|
1540
|
+
interface ModelConfigRegistryOptions {
|
|
1541
|
+
/** Override the URL to fetch models.yml from */
|
|
1542
|
+
url?: string;
|
|
1543
|
+
/** Cache TTL in milliseconds (default: 24 hours) */
|
|
1544
|
+
ttlMs?: number;
|
|
1545
|
+
/** Custom fetch implementation */
|
|
1546
|
+
fetch?: typeof fetch;
|
|
1547
|
+
}
|
|
1548
|
+
declare class GitLabModelConfigRegistry {
|
|
1549
|
+
private readonly url;
|
|
1550
|
+
private readonly ttlMs;
|
|
1551
|
+
private readonly fetchFn;
|
|
1552
|
+
private memCache;
|
|
1553
|
+
private memExpiresAt;
|
|
1554
|
+
private pending;
|
|
1555
|
+
constructor(options?: ModelConfigRegistryOptions);
|
|
1556
|
+
/**
|
|
1557
|
+
* Get model configs, fetching and caching as needed.
|
|
1558
|
+
* Returns a Map keyed by `gitlab_identifier` (the discovery `ref`).
|
|
1559
|
+
*/
|
|
1560
|
+
getConfigs(): Promise<Map<string, ModelConfig>>;
|
|
1561
|
+
/**
|
|
1562
|
+
* Look up config for a single model ref.
|
|
1563
|
+
* Returns defaults if the ref is not found or fetch fails.
|
|
1564
|
+
*/
|
|
1565
|
+
getConfig(ref: string): Promise<ModelConfig>;
|
|
1566
|
+
/** Invalidate both in-memory and file caches. */
|
|
1567
|
+
invalidateCache(): void;
|
|
1568
|
+
private fetchConfigs;
|
|
1569
|
+
}
|
|
1570
|
+
/**
|
|
1571
|
+
* Parse models.yml to extract gitlab_identifier → { context, output } mapping.
|
|
1572
|
+
* Uses simple line-by-line parsing to avoid a YAML dependency.
|
|
1573
|
+
*/
|
|
1574
|
+
declare function parseModelsYml(text: string): Map<string, ModelConfig>;
|
|
1575
|
+
|
|
1576
|
+
export { AGENT_PRIVILEGES, type ActionResponsePayload, type AdditionalContext, type AiChatAvailableModels, type AiModel, BUNDLED_CLIENT_ID, CLIENT_VERSION, type ClientEvent, DEFAULT_AGENT_PRIVILEGES, DEFAULT_AI_GATEWAY_URL, DEFAULT_CLIENT_CAPABILITIES, DEFAULT_WORKFLOW_DEFINITION, type DirectAccessToken, type DiscoveredModels, GITLAB_COM_URL, type GenerateTokenResponse, type GitLabAgenticOptions, type GitLabAnthropicConfig, GitLabAnthropicLanguageModel, GitLabDirectAccessClient, type GitLabDirectAccessConfig, GitLabError, type GitLabErrorOptions, GitLabModelCache, GitLabModelConfigRegistry, GitLabModelDiscovery, GitLabOAuthManager, type GitLabOAuthTokenResponse, type GitLabOAuthTokens, type GitLabOpenAIConfig, GitLabOpenAILanguageModel, type GitLabProject, GitLabProjectCache, GitLabProjectDetector, type GitLabProjectDetectorConfig, type GitLabProvider, type GitLabProviderSettings, GitLabWorkflowClient, type GitLabWorkflowClientConfig, GitLabWorkflowLanguageModel, type GitLabWorkflowLanguageModelConfig, type GitLabWorkflowOptions, GitLabWorkflowTokenClient, MODEL_ID_TO_ANTHROPIC_MODEL, MODEL_MAPPINGS, type McpToolDefinition, type ModelCacheEntry, type ModelConfig, type ModelConfigRegistryOptions, type ModelDiscoveryConfig, type ModelMapping, type ModelProvider, type NewCheckpoint, OAUTH_SCOPES, OPENCODE_GITLAB_AUTH_CLIENT_ID, type OpenAIApiType, type OpenCodeAuth, type OpenCodeAuthApi, type OpenCodeAuthOAuth, type RunMcpTool, type StartRequest, TOKEN_EXPIRY_SKEW_MS, VERSION, WORKFLOW_ENVIRONMENT, WS_HEARTBEAT_INTERVAL_MS, WS_KEEPALIVE_PING_INTERVAL_MS, type WorkflowAction, type WorkflowClientEvent, type WorkflowStatus, type WorkflowToolExecutor, WorkflowType, type WorkflowWebSocketOptions, createGitLab, getAnthropicModelForModelId, getModelMapping, getOpenAIApiType, getOpenAIModelForModelId, getProviderForModelId, getValidModelsForProvider, getWorkflowModelRef, gitlab, isResponsesApiModel, isWorkflowModel, parseModelsYml };
|