npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@gitlab/gitlab-ai-provider

v3.0.8

Published

GitLab Duo provider for Vercel AI SDK

Readme

GitLab AI Provider

A comprehensive TypeScript provider for integrating GitLab Duo AI capabilities with the Vercel AI SDK. This package enables seamless access to GitLab's AI-powered features including chat, agentic workflows, and tool calling through a unified interface.

🌟 Features

  • 🤖 Agentic Chat: Native tool calling support via GitLab's Anthropic proxy
  • 🔐 Multiple Authentication: Support for OAuth, Personal Access Tokens, and OpenCode auth
  • 🌐 Self-Hosted Support: Works with both GitLab.com and self-hosted instances
  • 📦 Tool Executors: Built-in Anthropic and GitLab API tool executors
  • 🔍 Project Detection: Automatic GitLab project detection from git remotes
  • 💾 Smart Caching: Project and token caching for optimal performance
  • 🎯 Type-Safe: Complete TypeScript definitions with Zod validation

📦 Installation

npm install @gitlab/gitlab-ai-provider

Peer Dependencies

npm install @ai-sdk/provider @ai-sdk/provider-utils

🚀 Quick Start

Basic Chat

import { createGitLab } from '@gitlab/gitlab-ai-provider';
import { generateText } from 'ai';

const gitlab = createGitLab({
  apiKey: process.env.GITLAB_TOKEN,
  instanceUrl: 'https://gitlab.com', // optional, defaults to gitlab.com
});

// All equivalent ways to create a chat model:
const model = gitlab('duo-chat'); // callable provider
const model2 = gitlab.chat('duo-chat'); // .chat() alias (recommended)
const model3 = gitlab.languageModel('duo-chat'); // explicit method

const { text } = await generateText({
  model: gitlab.chat('duo-chat'),
  prompt: 'Explain how to create a merge request in GitLab',
});

console.log(text);

Agentic Chat with Tool Calling

import { createGitLab } from '@gitlab/gitlab-ai-provider';
import { generateText } from 'ai';

const gitlab = createGitLab({
  apiKey: process.env.GITLAB_TOKEN,
});

// Use agentic model for native tool calling support
const model = gitlab.agenticChat('duo-chat', {
  anthropicModel: 'claude-sonnet-4-20250514',
  maxTokens: 8192,
});

const { text } = await generateText({
  model,
  prompt: 'List all open merge requests in my project',
  tools: {
    // Your custom tools here
  },
});

Agentic Chat with Feature Flags

You can pass feature flags to enable experimental features in GitLab's Anthropic proxy:

import { createGitLab } from '@gitlab/gitlab-ai-provider';

// Option 1: Set feature flags globally for all agentic chat models
const gitlab = createGitLab({
  apiKey: process.env.GITLAB_TOKEN,
  featureFlags: {
    duo_agent_platform_agentic_chat: true,
    duo_agent_platform: true,
  },
});

const model = gitlab.agenticChat('duo-chat');

// Option 2: Set feature flags per model (overrides global flags)
const modelWithFlags = gitlab.agenticChat('duo-chat', {
  featureFlags: {
    duo_agent_platform_agentic_chat: true,
    duo_agent_platform: true,
    custom_feature_flag: false,
  },
});

// Option 3: Merge both (model-level flags take precedence)
const gitlab2 = createGitLab({
  featureFlags: {
    duo_agent_platform: true, // will be overridden
  },
});

const mergedModel = gitlab2.agenticChat('duo-chat', {
  featureFlags: {
    duo_agent_platform: false, // overrides provider-level
    duo_agent_platform_agentic_chat: true, // adds new flag
  },
});

🔑 Authentication

Personal Access Token

const gitlab = createGitLab({
  apiKey: 'glpat-xxxxxxxxxxxxxxxxxxxx',
});

Environment Variable

export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
const gitlab = createGitLab(); // Automatically uses GITLAB_TOKEN

OAuth (OpenCode Auth)

The provider automatically detects and uses OpenCode authentication if available:

const gitlab = createGitLab({
  instanceUrl: 'https://gitlab.com',
  // OAuth tokens are loaded from ~/.opencode/auth.json
});

Custom Headers

const gitlab = createGitLab({
  apiKey: 'your-token',
  headers: {
    'X-Custom-Header': 'value',
  },
});

🏗️ Architecture

Core Components

1. GitLabProvider

Main provider factory that creates language models with different capabilities.

interface GitLabProvider {
  (modelId: string): LanguageModelV2;
  languageModel(modelId: string): LanguageModelV2;
  agenticChat(modelId: string, options?: GitLabAgenticOptions): GitLabAgenticLanguageModel;
}

2. GitLabAgenticLanguageModel

Provides native tool calling through GitLab's Anthropic proxy.

  • Uses Claude models via https://cloud.gitlab.com/ai/v1/proxy/anthropic/
  • Automatic token refresh and retry logic
  • Direct access token management
  • Supports all Anthropic tool calling features

Tool Executors

AnthropicToolExecutor

Executes local file system and command tools:

  • list_dir - List directory contents
  • read_file - Read file contents
  • write_file - Write to files
  • edit_file - Edit file with find/replace
  • find_files - Find files by pattern
  • mkdir - Create directories
  • grep - Search file contents
  • run_command - Execute shell commands
  • run_git_command - Execute git commands

GitLabApiToolExecutor

Executes GitLab API operations:

  • Merge Requests: get, list, changes, discussions, notes
  • Issues: get, list, notes
  • Pipelines: list, get, jobs, logs
  • Repository: files, commits, branches
  • Search: global and project search
  • Projects: get, members

Supporting Utilities

GitLabProjectDetector

Automatically detects GitLab projects from git remotes.

const detector = new GitLabProjectDetector({
  instanceUrl: 'https://gitlab.com',
  getHeaders: () => ({ Authorization: `Bearer ${token}` }),
});

const project = await detector.detectProject(process.cwd());
// Returns: { id: 12345, path: 'group/project', namespaceId: 67890 }

GitLabProjectCache

Caches project information with TTL.

const cache = new GitLabProjectCache(5 * 60 * 1000); // 5 minutes
cache.set('key', project);
const cached = cache.get('key');

GitLabOAuthManager

Manages OAuth token lifecycle.

const oauthManager = new GitLabOAuthManager();

// Exchange authorization code
const tokens = await oauthManager.exchangeAuthorizationCode({
  instanceUrl: 'https://gitlab.com',
  code: 'auth-code',
  codeVerifier: 'verifier',
});

// Refresh tokens
const refreshed = await oauthManager.refreshIfNeeded(tokens);

GitLabDirectAccessClient

Manages direct access tokens for Anthropic proxy.

const client = new GitLabDirectAccessClient({
  instanceUrl: 'https://gitlab.com',
  getHeaders: () => ({ Authorization: `Bearer ${token}` }),
});

const directToken = await client.getDirectAccessToken();
// Returns: { token: 'xxx', headers: {...}, expiresAt: 123456 }

📚 API Reference

Provider Configuration

interface GitLabProviderSettings {
  instanceUrl?: string; // Default: 'https://gitlab.com'
  apiKey?: string; // PAT or OAuth access token
  refreshToken?: string; // OAuth refresh token
  name?: string; // Provider name prefix
  headers?: Record<string, string>; // Custom headers
  fetch?: typeof fetch; // Custom fetch implementation
}

Agentic Chat Options

interface GitLabAgenticOptions {
  anthropicModel?: string; // Default: 'claude-sonnet-4-20250514'
  maxTokens?: number; // Default: 8192
}

Error Handling

import { GitLabError } from '@gitlab/gitlab-ai-provider';

try {
  const result = await generateText({ model, prompt });
} catch (error) {
  if (error instanceof GitLabError) {
    if (error.isAuthError()) {
      console.error('Authentication failed');
    } else if (error.isRateLimitError()) {
      console.error('Rate limit exceeded');
    } else if (error.isServerError()) {
      console.error('Server error:', error.statusCode);
    }
  }
}

🔧 Development

Build

npm run build          # Build once
npm run build:watch    # Build in watch mode

Testing

npm test              # Run all tests
npm run test:watch    # Run tests in watch mode

Code Quality

npm run lint          # Lint code
npm run lint:fix      # Lint and auto-fix
npm run format        # Format code
npm run format:check  # Check formatting
npm run type-check    # TypeScript type checking

Project Structure

gitlab-ai-provider/
├── src/
│   ├── index.ts                          # Main exports
│   ├── gitlab-provider.ts                # Provider factory
│   ├── gitlab-agentic-language-model.ts  # Agentic chat model
│   ├── gitlab-direct-access.ts           # Direct access tokens
│   ├── gitlab-oauth-manager.ts           # OAuth management
│   ├── gitlab-oauth-types.ts             # OAuth types
│   ├── gitlab-project-detector.ts        # Project detection
│   ├── gitlab-project-cache.ts           # Project caching
│   ├── gitlab-anthropic-tools.ts         # Anthropic tool executor
│   ├── gitlab-api-tools.ts               # GitLab API tool executor
│   ├── gitlab-api-types.ts               # API types
│   ├── gitlab-error.ts                   # Error handling
│   └── gitlab-workflow-debug.ts          # Debug logging
├── tests/                                # Test files
├── dist/                                 # Build output
├── package.json
├── tsconfig.json
├── tsup.config.ts
└── vitest.config.ts

📝 Code Style

  • Imports: Named imports, organized by external → internal → types
  • Formatting: Single quotes, semicolons, 100 char line width, 2 space indent
  • Types: Interfaces for public APIs, Zod schemas for runtime validation
  • Naming: camelCase (variables/functions), PascalCase (classes/types), kebab-case (files)
  • Exports: Named exports only (no default exports)
  • Comments: JSDoc for public APIs with @param/@returns

Assistant

🤝 Contributing

Contributions are welcome! Please see our Contributing Guide for detailed guidelines on:

  • Code style and conventions
  • Development workflow
  • Testing requirements
  • Submitting merge requests
  • Developer Certificate of Origin and License

Quick Start for Contributors:

  1. Commit Messages: Use conventional commits format

    feat(scope): add new feature
    fix(scope): fix bug
    docs(scope): update documentation
  2. Code Quality: Ensure all checks pass

    npm run lint
    npm run type-check
    npm test
  3. Testing: Add tests for new features

🔗 Links

🙏 Acknowledgments

This project is built on top of:


Made with ❤️ for the OpenCode community