opencode-gitlab-duo-agentic 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -2
- package/dist/index.js +137 -41
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProviderV2 } from '@ai-sdk/provider';
|
|
2
|
+
import { Plugin, PluginInput, Hooks } from '@opencode-ai/plugin';
|
|
2
3
|
|
|
4
|
+
type EntryInput = PluginInput | Record<string, unknown>;
|
|
5
|
+
type EntryOutput = Promise<Hooks> | ProviderV2;
|
|
6
|
+
declare const createGitLabDuoAgentic: (input: EntryInput) => EntryOutput;
|
|
3
7
|
declare const GitLabDuoAgenticPlugin: Plugin;
|
|
4
8
|
|
|
5
|
-
export { GitLabDuoAgenticPlugin, GitLabDuoAgenticPlugin as default };
|
|
9
|
+
export { GitLabDuoAgenticPlugin, createGitLabDuoAgentic, GitLabDuoAgenticPlugin as default };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var PROVIDER_ID = "gitlab";
|
|
2
|
+
var PROVIDER_ID = "gitlab-duo-agentic";
|
|
3
|
+
var MODEL_ID = "duo-agentic";
|
|
3
4
|
var DEFAULT_INSTANCE_URL = "https://gitlab.com";
|
|
5
|
+
var AUTH_KEY_PREFIX = "gitlab-duo-v1:";
|
|
6
|
+
var NOT_IMPLEMENTED_MESSAGE = "gitlab-duo-agentic is configured, but the Duo Workflow runtime is not implemented yet.";
|
|
4
7
|
|
|
5
|
-
// src/
|
|
8
|
+
// src/utils/url.ts
|
|
6
9
|
function text(value) {
|
|
7
10
|
if (typeof value !== "string") return void 0;
|
|
8
11
|
const trimmed = value.trim();
|
|
9
12
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
10
13
|
}
|
|
11
|
-
function
|
|
14
|
+
function envInstanceUrl() {
|
|
12
15
|
return process.env.GITLAB_INSTANCE_URL ?? process.env.GITLAB_URL ?? process.env.GITLAB_BASE_URL;
|
|
13
16
|
}
|
|
14
17
|
function normalizeInstanceUrl(value) {
|
|
@@ -21,6 +24,27 @@ function normalizeInstanceUrl(value) {
|
|
|
21
24
|
return DEFAULT_INSTANCE_URL;
|
|
22
25
|
}
|
|
23
26
|
}
|
|
27
|
+
|
|
28
|
+
// src/plugin/auth.ts
|
|
29
|
+
function encodeAuthKey(value) {
|
|
30
|
+
const payload = Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
31
|
+
return `${AUTH_KEY_PREFIX}${payload}`;
|
|
32
|
+
}
|
|
33
|
+
function decodeAuthKey(key) {
|
|
34
|
+
if (!key.startsWith(AUTH_KEY_PREFIX)) {
|
|
35
|
+
return { token: key };
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const payload = key.slice(AUTH_KEY_PREFIX.length);
|
|
39
|
+
const parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
40
|
+
return {
|
|
41
|
+
token: text(parsed.token),
|
|
42
|
+
instanceUrl: text(parsed.instanceUrl)
|
|
43
|
+
};
|
|
44
|
+
} catch {
|
|
45
|
+
return { token: key };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
24
48
|
async function validateToken(instanceUrl, token) {
|
|
25
49
|
const response = await fetch(`${instanceUrl}/api/v4/user`, {
|
|
26
50
|
headers: {
|
|
@@ -29,38 +53,24 @@ async function validateToken(instanceUrl, token) {
|
|
|
29
53
|
}).catch(() => void 0);
|
|
30
54
|
return !!response?.ok;
|
|
31
55
|
}
|
|
32
|
-
|
|
33
|
-
await input.client.config.update({
|
|
34
|
-
query: {
|
|
35
|
-
directory: input.directory
|
|
36
|
-
},
|
|
37
|
-
body: {
|
|
38
|
-
provider: {
|
|
39
|
-
[PROVIDER_ID]: {
|
|
40
|
-
options: {
|
|
41
|
-
instanceUrl
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}).catch(() => void 0);
|
|
47
|
-
}
|
|
48
|
-
function applyGitLabConfig(config) {
|
|
49
|
-
config.provider ??= {};
|
|
50
|
-
const current = config.provider[PROVIDER_ID] ?? {};
|
|
51
|
-
const options = current.options ?? {};
|
|
52
|
-
const instanceUrl = normalizeInstanceUrl(options.instanceUrl ?? instanceFromEnv());
|
|
53
|
-
config.provider[PROVIDER_ID] = {
|
|
54
|
-
...current,
|
|
55
|
-
options: {
|
|
56
|
-
...options,
|
|
57
|
-
instanceUrl
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function createGitLabAuthHook(input) {
|
|
56
|
+
function createAuthHook() {
|
|
62
57
|
return {
|
|
63
58
|
provider: PROVIDER_ID,
|
|
59
|
+
loader: async (getAuth, provider) => {
|
|
60
|
+
const auth = await getAuth();
|
|
61
|
+
const decoded = auth?.type === "api" ? decodeAuthKey(auth.key) : {};
|
|
62
|
+
const options = provider.options ?? {};
|
|
63
|
+
const instanceUrl = normalizeInstanceUrl(decoded.instanceUrl ?? options.instanceUrl ?? envInstanceUrl());
|
|
64
|
+
if (!decoded.token) {
|
|
65
|
+
return {
|
|
66
|
+
instanceUrl
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
apiKey: decoded.token,
|
|
71
|
+
instanceUrl
|
|
72
|
+
};
|
|
73
|
+
},
|
|
64
74
|
methods: [
|
|
65
75
|
{
|
|
66
76
|
type: "api",
|
|
@@ -84,14 +94,12 @@ function createGitLabAuthHook(input) {
|
|
|
84
94
|
authorize: async (inputs = {}) => {
|
|
85
95
|
const token = text(inputs.token);
|
|
86
96
|
if (!token) return { type: "failed" };
|
|
87
|
-
const instanceUrl = normalizeInstanceUrl(inputs.instanceUrl ??
|
|
97
|
+
const instanceUrl = normalizeInstanceUrl(inputs.instanceUrl ?? envInstanceUrl());
|
|
88
98
|
const valid = await validateToken(instanceUrl, token);
|
|
89
99
|
if (!valid) return { type: "failed" };
|
|
90
|
-
process.env.GITLAB_INSTANCE_URL = instanceUrl;
|
|
91
|
-
await persistInstanceUrl(input, instanceUrl);
|
|
92
100
|
return {
|
|
93
101
|
type: "success",
|
|
94
|
-
key: token
|
|
102
|
+
key: encodeAuthKey({ token, instanceUrl })
|
|
95
103
|
};
|
|
96
104
|
}
|
|
97
105
|
}
|
|
@@ -99,13 +107,101 @@ function createGitLabAuthHook(input) {
|
|
|
99
107
|
};
|
|
100
108
|
}
|
|
101
109
|
|
|
110
|
+
// src/plugin/config.ts
|
|
111
|
+
function applyRuntimeConfig(config, moduleUrl) {
|
|
112
|
+
config.provider ??= {};
|
|
113
|
+
const current = config.provider[PROVIDER_ID] ?? {};
|
|
114
|
+
const options = current.options ?? {};
|
|
115
|
+
const models = current.models ?? {};
|
|
116
|
+
const instanceUrl = normalizeInstanceUrl(options.instanceUrl ?? envInstanceUrl());
|
|
117
|
+
config.provider[PROVIDER_ID] = {
|
|
118
|
+
...current,
|
|
119
|
+
name: current.name ?? "GitLab Duo Agentic",
|
|
120
|
+
npm: current.npm ?? moduleUrl,
|
|
121
|
+
env: current.env ?? ["GITLAB_TOKEN", "GITLAB_INSTANCE_URL"],
|
|
122
|
+
options: {
|
|
123
|
+
...options,
|
|
124
|
+
instanceUrl
|
|
125
|
+
},
|
|
126
|
+
models: Object.keys(models).length > 0 ? models : {
|
|
127
|
+
[MODEL_ID]: {
|
|
128
|
+
id: MODEL_ID,
|
|
129
|
+
name: "GitLab Duo Agentic (fallback)"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
if (Array.isArray(config.disabled_providers)) {
|
|
134
|
+
config.disabled_providers = config.disabled_providers.filter((id) => id !== PROVIDER_ID);
|
|
135
|
+
}
|
|
136
|
+
if (Array.isArray(config.enabled_providers) && !config.enabled_providers.includes(PROVIDER_ID)) {
|
|
137
|
+
config.enabled_providers = [...config.enabled_providers, PROVIDER_ID];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/plugin/hooks.ts
|
|
142
|
+
async function createPluginHooks(_input, moduleUrl) {
|
|
143
|
+
return {
|
|
144
|
+
config: async (config) => applyRuntimeConfig(config, moduleUrl),
|
|
145
|
+
auth: createAuthHook()
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/provider/index.ts
|
|
150
|
+
import { NoSuchModelError, UnsupportedFunctionalityError } from "@ai-sdk/provider";
|
|
151
|
+
function notImplemented() {
|
|
152
|
+
return new UnsupportedFunctionalityError({
|
|
153
|
+
functionality: "gitlab-duo-workflow-runtime",
|
|
154
|
+
message: NOT_IMPLEMENTED_MESSAGE
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function fallbackModel(modelId) {
|
|
158
|
+
return {
|
|
159
|
+
specificationVersion: "v2",
|
|
160
|
+
provider: PROVIDER_ID,
|
|
161
|
+
modelId,
|
|
162
|
+
supportedUrls: {},
|
|
163
|
+
async doGenerate(_options) {
|
|
164
|
+
throw notImplemented();
|
|
165
|
+
},
|
|
166
|
+
async doStream(_options) {
|
|
167
|
+
throw notImplemented();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function createFallbackProvider() {
|
|
172
|
+
return {
|
|
173
|
+
languageModel(modelId) {
|
|
174
|
+
if (modelId !== MODEL_ID) {
|
|
175
|
+
throw new NoSuchModelError({ modelId, modelType: "languageModel" });
|
|
176
|
+
}
|
|
177
|
+
return fallbackModel(modelId);
|
|
178
|
+
},
|
|
179
|
+
textEmbeddingModel(modelId) {
|
|
180
|
+
throw new NoSuchModelError({ modelId, modelType: "textEmbeddingModel" });
|
|
181
|
+
},
|
|
182
|
+
imageModel(modelId) {
|
|
183
|
+
throw new NoSuchModelError({ modelId, modelType: "imageModel" });
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
102
188
|
// src/index.ts
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
189
|
+
function isPluginInput(value) {
|
|
190
|
+
if (!value || typeof value !== "object") return false;
|
|
191
|
+
const input = value;
|
|
192
|
+
return "client" in input && "project" in input && "directory" in input && "worktree" in input && "serverUrl" in input;
|
|
193
|
+
}
|
|
194
|
+
var entry = (input) => {
|
|
195
|
+
if (isPluginInput(input)) {
|
|
196
|
+
return createPluginHooks(input, import.meta.url);
|
|
197
|
+
}
|
|
198
|
+
return createFallbackProvider();
|
|
199
|
+
};
|
|
200
|
+
var createGitLabDuoAgentic = entry;
|
|
201
|
+
var GitLabDuoAgenticPlugin = entry;
|
|
107
202
|
var src_default = GitLabDuoAgenticPlugin;
|
|
108
203
|
export {
|
|
109
204
|
GitLabDuoAgenticPlugin,
|
|
205
|
+
createGitLabDuoAgentic,
|
|
110
206
|
src_default as default
|
|
111
207
|
};
|