Skip to content

Latest commit

 

History

History
307 lines (216 loc) · 12.4 KB

File metadata and controls

307 lines (216 loc) · 12.4 KB

AGENTS.md

This file provides context for AI coding assistants (Cursor, GitHub Copilot, Claude Code, etc.) working with the Vercel AI SDK repository.

Project Overview

The AI SDK by Vercel is a TypeScript/JavaScript SDK for building AI-powered applications with Large Language Models (LLMs). It provides a unified interface for multiple AI providers and framework integrations.

Repository Structure

This is a monorepo using pnpm workspaces and Turborepo.

Key Directories

Directory Description
packages/ai Main SDK package (ai on npm)
packages/provider Provider interface specifications (@ai-sdk/provider)
packages/provider-utils Shared utilities for providers and core (@ai-sdk/provider-utils)
packages/<provider> AI provider implementations (openai, anthropic, google, azure, amazon-bedrock, etc.)
packages/<framework> UI framework integrations (react, vue, svelte, angular, rsc)
packages/codemod Automated migrations for major releases
examples/ Example applications (ai-functions, next-openai, etc.)
content/ Documentation source files (MDX)
contributing/ Contributor guides and documentation
tools/ Internal tooling (tsconfig)

Core Package Dependencies

ai ─────────────────┬──▶ @ai-sdk/provider-utils ──▶ @ai-sdk/provider
                    │
@ai-sdk/<provider> ─┴──▶ @ai-sdk/provider-utils ──▶ @ai-sdk/provider

Development Setup

Requirements

  • Node.js: v18, v20, or v22 (v22 recommended for development)
  • pnpm: v10+ (npm install -g pnpm@10)

Initial Setup

pnpm install        # Install all dependencies
pnpm build          # Build all packages

Development Commands

Root-Level Commands

Command Description
pnpm install Install dependencies
pnpm build Build all packages
pnpm test Run all tests (excludes examples)
pnpm check Run linting (oxlint) and formatting (oxfmt) checks
pnpm fix Fix linting and formatting issues
pnpm type-check:full TypeScript type checking (includes examples)
pnpm changeset Add a changeset for your PR
pnpm update-references Update tsconfig.json references after adding package dependencies

Package-Level Commands

Run these from within a package directory (e.g., packages/ai):

Command Description
pnpm build Build the package
pnpm build:watch Build with watch mode
pnpm test Run all tests (node + edge)
pnpm test:node Run Node.js tests only
pnpm test:edge Run Edge runtime tests only
pnpm test:watch Run tests in watch mode

Running Examples

cd examples/ai-functions
pnpm tsx src/stream-text/openai/basic.ts    # Run a specific example

AI Functions Example Layout

  • Place examples under examples/ai-functions/src/<function>/<provider>/
  • Use basic.ts for the provider entry example file
  • Place all other examples in the same provider folder using descriptive kebab-case file names
  • Do not create flat top-level provider files like src/stream-text/openai.ts

Core APIs

Function Purpose Package
generateText Generate text completion ai
streamText Stream text completion ai
generateObject Generate structured output ai
streamObject Stream structured output ai
embed / embedMany Generate embeddings ai
generateImage Generate images ai
tool Define a tool ai
jsonSchema / zodSchema Define schemas ai

Import Patterns

What Import From
Core functions (generateText, streamText) ai
Tool/schema utilities (tool, jsonSchema) ai
Provider implementations @ai-sdk/<provider> (e.g., @ai-sdk/openai)
Error classes ai (re-exports from @ai-sdk/provider)
Provider type interfaces (LanguageModelV4) @ai-sdk/provider
Provider implementation utilities @ai-sdk/provider-utils

Coding Standards

Formatting

  • Formatter: oxfmt (via pnpm fix or ultracite fix)
  • Linter: oxlint (via pnpm check or ultracite check)
  • Config: .oxfmtrc.jsonc (formatter) and .oxlintrc.json (linter)
  • Pre-commit hook: Runs pnpm install if package.json changes are staged

Testing

  • Framework: Vitest
  • Test files: *.test.ts alongside source files
  • Type tests: *.test-d.ts for type-level tests
  • Fixtures: Store in __fixtures__ subfolders
  • Snapshots: Store in __snapshots__ subfolders

Zod Usage

The SDK supports both Zod 3 and Zod 4. Use correct imports:

// For Zod 3 (compatibility code only)
import * as z3 from 'zod/v3';

// For Zod 4
import * as z4 from 'zod/v4';
// Use z4.core.$ZodType for type references

JSON parsing

Never use JSON.parse directly in production code to prevent security risks. Instead use parseJSON or safeParseJSON from @ai-sdk/provider-utils.

Type Checking

Always run type checking after making code changes:

pnpm type-check:full    # Run from workspace root

This ensures your changes don't introduce type errors across the codebase, including examples.

File Naming Conventions

  • Source files: kebab-case.ts
  • Test files: kebab-case.test.ts
  • Type test files: kebab-case.test-d.ts
  • React/UI components: kebab-case.tsx

Error Pattern

Errors extend AISDKError from @ai-sdk/provider and use a marker pattern for instanceof checks:

import { AISDKError } from '@ai-sdk/provider';

const name = 'AI_MyError';
const marker = `vercel.ai.error.${name}`;
const symbol = Symbol.for(marker);

export class MyError extends AISDKError {
  private readonly [symbol] = true; // used in isInstance

  constructor({ message, cause }: { message: string; cause?: unknown }) {
    super({ name, message, cause });
  }

  static isInstance(error: unknown): error is MyError {
    return AISDKError.hasMarker(error, marker);
  }
}

Architecture Decision Records (ADRs)

This repo uses ADRs in contributing/decisions/ to capture important architecture decisions. Before making changes that touch architecture (new dependencies, new patterns, API design, infrastructure), check existing ADRs:

  1. Read contributing/decisions/README.md for the index of decisions.
  2. Read any accepted ADRs relevant to your area of work. Follow the decisions and implementation patterns they specify.
  3. If you encounter a pattern in the code and wonder "why is it done this way?", check whether an ADR explains it.
  4. If your work would contradict an existing accepted ADR, stop and discuss with the human before proceeding.

To propose or create a new ADR, use the ADR skill.

Project Philosophies

For an overview of the project's key philosophies that guide decision making, see contributing/project-philosophies.md.

Architecture

Provider Pattern

The SDK uses a layered provider architecture following the adapter pattern:

  1. Specifications (@ai-sdk/provider): Defines interfaces like LanguageModelV4
  2. Utilities (@ai-sdk/provider-utils): Shared code for implementing providers
  3. Providers (@ai-sdk/<provider>): Concrete implementations for each AI service
  4. Core (ai): High-level functions like generateText, streamText, generateObject

For a focused conceptual walkthrough of AI functions, model specifications, and provider implementations, see architecture/provider-abstraction.md.

Provider Development

Provider Options Schemas (user-facing):

  • Use .optional() unless null is meaningful
  • Be as restrictive as possible for future flexibility

Response Schemas (API responses):

  • Use .nullish() instead of .optional()
  • Keep minimal - only include properties you need
  • Allow flexibility for provider API changes

Adding New Packages

  1. Create folder under packages/<name>
  2. Add to root tsconfig.json references
  3. Run pnpm update-references if adding dependencies between packages

Contributing Guides

Task Guide
Add new provider contributing/add-new-provider.md
Add new model contributing/add-new-model.md
Testing & fixtures contributing/testing.md
Provider architecture contributing/provider-architecture.md
Building new features contributing/building-new-features.md
Codemods contributing/codemods.md

Changesets

  • Required: Every PR modifying production code needs a changeset
  • Default: Use patch (non-breaking changes)
  • Command: pnpm changeset in workspace root
  • Note: Don't select example packages - they're not published

Task Completion Guidelines

These guidelines outline typical artifacts for different task types. Use judgment to adapt based on scope and context.

Bug Fixes

A complete bug fix typically includes:

  1. Reproduction example: Create/update an example in examples/ that demonstrates the bug before fixing
  2. Unit tests: Add tests that would fail without the fix (regression tests)
  3. Implementation: Fix the bug
  4. Manual verification: Run the reproduction example to confirm the fix
  5. Changeset: Describe what was broken and how it's fixed

New Features

A complete feature typically includes:

  1. Implementation: Build the feature
  2. Examples: Add usage examples in examples/ demonstrating the feature
  3. Unit tests: Comprehensive test coverage for new functionality
  4. Documentation: Update relevant docs in content/ for public APIs
  5. Changeset: Describe the feature for release notes

Refactoring / Internal Changes

  • Unit tests for any changed behavior
  • No documentation needed for internal-only changes
  • Changeset only if it affects published packages

When to Deviate

These are guidelines, not rigid rules. Adjust based on:

  • Scope: Trivial fixes (typos, comments) may not need examples
  • Visibility: Internal changes may not need documentation
  • Context: Some changes span multiple categories

When uncertain about expected artifacts, ask for clarification.

Do Not

  • Add minor/major changesets
  • Change public APIs without updating documentation
  • Use require() for imports
  • Add new dependencies without running pnpm update-references
  • Modify content/docs/08-migration-guides or packages/codemod as part of broader codebase changes