Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
292 changes: 292 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions packages/ai/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Added

- Added GitLab Duo provider support using `@gitlab/gitlab-ai-provider` for native tool calling via GitLab's Anthropic proxy. Supports Claude Opus 4.5, Sonnet 4.5, and Haiku 4.5 models with automatic OAuth token management.

### Fixed

- Fixed OpenCode provider's `/v1` endpoint to use `system` role instead of `developer` role, fixing `400 Incorrect role information` error for models using `openai-completions` API ([#755](https://github.com/badlogic/pi-mono/pull/755) by [@melihmucuk](https://github.com/melihmucuk))
Expand Down
10 changes: 10 additions & 0 deletions packages/ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Unified LLM API with automatic model discovery, provider configuration, token an
- **Anthropic**
- **Google**
- **Vertex AI** (Gemini via Vertex AI)
- **GitLab Duo**
- **Mistral**
- **Groq**
- **Cerebras**
Expand Down Expand Up @@ -478,6 +479,13 @@ await complete(googleModel, context, {
budgetTokens: 8192 // -1 for dynamic, 0 to disable
}
});

// GitLab Duo (uses Claude via GitLab's Anthropic proxy)
const gitlabDuoModel = getModel('gitlab-duo', 'duo-chat');
await complete(gitlabDuoModel, context, {
thinking: true,
instanceUrl: 'https://gitlab.example.com', // Optional: self-hosted GitLab URL
});
```

### Streaming Thinking Content
Expand Down Expand Up @@ -858,6 +866,7 @@ In Node.js environments, you can set environment variables to avoid passing API
| OpenAI | `OPENAI_API_KEY` |
| Anthropic | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |
| Google | `GEMINI_API_KEY` |
| GitLab Duo | `GITLAB_DUO_TOKEN` or `GITLAB_TOKEN` |
| Vertex AI | `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) + `GOOGLE_CLOUD_LOCATION` + ADC |
| Mistral | `MISTRAL_API_KEY` |
| Groq | `GROQ_API_KEY` |
Expand Down Expand Up @@ -898,6 +907,7 @@ Several providers require OAuth authentication instead of static API keys:
- **Anthropic** (Claude Pro/Max subscription)
- **OpenAI Codex** (ChatGPT Plus/Pro subscription, access to GPT-5.x Codex models)
- **GitHub Copilot** (Copilot subscription)
- **GitLab Duo** (GitLab subscription with Duo access)
- **Google Gemini CLI** (Gemini 2.0/2.5 via Google Cloud Code Assist; free tier or paid subscription)
- **Antigravity** (Free Gemini 3, Claude, GPT-OSS via Google Cloud)

Expand Down
1 change: 1 addition & 0 deletions packages/ai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"dependencies": {
"@anthropic-ai/sdk": "0.71.2",
"@aws-sdk/client-bedrock-runtime": "^3.966.0",
"@gitlab/gitlab-ai-provider": "^3.1.1",
"@google/genai": "1.34.0",
"@mistralai/mistralai": "1.10.0",
"@sinclair/typebox": "^0.34.41",
Expand Down
6 changes: 5 additions & 1 deletion packages/ai/scripts/generate-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { writeFileSync } from "fs";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
import { Api, KnownProvider, Model } from "../src/types.js";
import { getGitLabDuoModels } from "../src/providers/gitlab-duo-models.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Expand Down Expand Up @@ -618,7 +619,10 @@ async function generateModels() {
const aiGatewayModels = await fetchAiGatewayModels();

// Combine models (models.dev has priority)
const allModels = [...modelsDevModels, ...openRouterModels, ...aiGatewayModels];
// Get GitLab Duo models
const gitLabDuoModels = getGitLabDuoModels();

const allModels = [...modelsDevModels, ...openRouterModels, ...aiGatewayModels, ...gitLabDuoModels];

// Fix incorrect cache pricing for Claude Opus 4.5 from models.dev
// models.dev has 3x the correct pricing (1.5/18.75 instead of 0.5/6.25)
Expand Down
14 changes: 14 additions & 0 deletions packages/ai/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { existsSync, readFileSync, writeFileSync } from "fs";
import { createInterface } from "readline";
import { loginAnthropic } from "./utils/oauth/anthropic.js";
import { loginGitHubCopilot } from "./utils/oauth/github-copilot.js";
import { loginGitLabDuo } from "./utils/oauth/gitlab-duo.js";
import { loginAntigravity } from "./utils/oauth/google-antigravity.js";
import { loginGeminiCli } from "./utils/oauth/google-gemini-cli.js";
import { getOAuthProviders } from "./utils/oauth/index.js";
Expand Down Expand Up @@ -64,6 +65,19 @@ async function login(provider: OAuthProvider): Promise<void> {
});
break;

case "gitlab-duo":
credentials = await loginGitLabDuo(
(info) => {
console.log(`\nOpen this URL in your browser:\n${info.url}`);
if (info.instructions) console.log(info.instructions);
console.log();
},
async (p) => {
return await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : ""}:`);
},
);
break;

case "google-gemini-cli":
credentials = await loginGeminiCli(
(info) => {
Expand Down
Loading