Skip to content

Commit 05867f9

Browse files
feat: Add GitLab Duo Agentic Chat Provider Support (#7333)
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
1 parent 5947fe7 commit 05867f9

File tree

7 files changed

+470
-2
lines changed

7 files changed

+470
-2
lines changed

bun.lock

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/opencode/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"@ai-sdk/vercel": "1.0.31",
7171
"@ai-sdk/xai": "2.0.51",
7272
"@clack/prompts": "1.0.0-alpha.1",
73+
"@gitlab/gitlab-ai-provider": "3.1.0",
7374
"@hono/standard-validator": "0.1.5",
7475
"@hono/zod-validator": "catalog:",
7576
"@modelcontextprotocol/sdk": "1.25.2",

packages/opencode/src/plugin/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import { NamedError } from "@opencode-ai/util/error"
1414
export namespace Plugin {
1515
const log = Log.create({ service: "plugin" })
1616

17-
const BUILTIN = ["opencode-copilot-auth@0.0.12", "opencode-anthropic-auth@0.0.8"]
17+
const BUILTIN = [
18+
"opencode-copilot-auth@0.0.12",
19+
"opencode-anthropic-auth@0.0.8",
20+
"@gitlab/opencode-gitlab-auth@1.3.0",
21+
]
1822

1923
// Built-in plugins that are directly imported (not installed from npm)
2024
const INTERNAL_PLUGINS: PluginInstance[] = [CodexAuthPlugin]
@@ -46,6 +50,7 @@ export namespace Plugin {
4650
if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) {
4751
plugins.push(...BUILTIN)
4852
}
53+
4954
for (let plugin of plugins) {
5055
// ignore old codex plugin since it is supported first party now
5156
if (plugin.includes("opencode-openai-codex-auth")) continue

packages/opencode/src/provider/provider.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import z from "zod"
2+
import path from "path"
3+
import os from "os"
24
import fuzzysort from "fuzzysort"
35
import { Config } from "../config/config"
46
import { mapValues, mergeDeep, omit, pickBy, sortBy } from "remeda"
@@ -35,6 +37,7 @@ import { createGateway } from "@ai-sdk/gateway"
3537
import { createTogetherAI } from "@ai-sdk/togetherai"
3638
import { createPerplexity } from "@ai-sdk/perplexity"
3739
import { createVercel } from "@ai-sdk/vercel"
40+
import { createGitLab } from "@gitlab/gitlab-ai-provider"
3841
import { ProviderTransform } from "./transform"
3942

4043
export namespace Provider {
@@ -60,6 +63,7 @@ export namespace Provider {
6063
"@ai-sdk/togetherai": createTogetherAI,
6164
"@ai-sdk/perplexity": createPerplexity,
6265
"@ai-sdk/vercel": createVercel,
66+
"@gitlab/gitlab-ai-provider": createGitLab,
6367
// @ts-ignore (TODO: kill this code so we dont have to maintain it)
6468
"@ai-sdk/github-copilot": createGitHubCopilotOpenAICompatible,
6569
}
@@ -390,6 +394,43 @@ export namespace Provider {
390394
},
391395
}
392396
},
397+
async gitlab(input) {
398+
const instanceUrl = Env.get("GITLAB_INSTANCE_URL") || "https://gitlab.com"
399+
400+
const auth = await Auth.get(input.id)
401+
const apiKey = await (async () => {
402+
if (auth?.type === "oauth") return auth.access
403+
if (auth?.type === "api") return auth.key
404+
return Env.get("GITLAB_TOKEN")
405+
})()
406+
407+
const config = await Config.get()
408+
const providerConfig = config.provider?.["gitlab"]
409+
410+
return {
411+
autoload: !!apiKey,
412+
options: {
413+
instanceUrl,
414+
apiKey,
415+
featureFlags: {
416+
duo_agent_platform_agentic_chat: true,
417+
duo_agent_platform: true,
418+
...(providerConfig?.options?.featureFlags || {}),
419+
},
420+
},
421+
async getModel(sdk: ReturnType<typeof createGitLab>, modelID: string, options?: { anthropicModel?: string }) {
422+
const anthropicModel = options?.anthropicModel
423+
return sdk.agenticChat(modelID, {
424+
anthropicModel,
425+
featureFlags: {
426+
duo_agent_platform_agentic_chat: true,
427+
duo_agent_platform: true,
428+
...(providerConfig?.options?.featureFlags || {}),
429+
},
430+
})
431+
},
432+
}
433+
},
393434
"cloudflare-ai-gateway": async (input) => {
394435
const accountId = Env.get("CLOUDFLARE_ACCOUNT_ID")
395436
const gateway = Env.get("CLOUDFLARE_GATEWAY_ID")

packages/opencode/test/provider/amazon-bedrock.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import path from "path"
99

1010
mock.module("../../src/bun/index", () => ({
1111
BunProc: {
12-
install: async (pkg: string) => pkg,
12+
install: async (pkg: string, _version?: string) => {
13+
// Return package name without version for mocking
14+
const lastAtIndex = pkg.lastIndexOf("@")
15+
return lastAtIndex > 0 ? pkg.substring(0, lastAtIndex) : pkg
16+
},
1317
run: async () => {
1418
throw new Error("BunProc.run should not be called in tests")
1519
},
@@ -28,6 +32,7 @@ mock.module("@aws-sdk/credential-providers", () => ({
2832
const mockPlugin = () => ({})
2933
mock.module("opencode-copilot-auth", () => ({ default: mockPlugin }))
3034
mock.module("opencode-anthropic-auth", () => ({ default: mockPlugin }))
35+
mock.module("@gitlab/opencode-gitlab-auth", () => ({ default: mockPlugin }))
3136

3237
// Import after mocks are set up
3338
const { tmpdir } = await import("../fixture/fixture")

0 commit comments

Comments
 (0)