---
title: "vercel/ai"
description: "The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents"
source: https://github.com/vercel/ai
ref: main
license: null
licenseName: "Other"
canonical: https://skillsdocs.com/vercel/ai
base: https://github.com/vercel/ai/blob/main/
provenance: authored
chapters: 12
inlined: 12
withheld: 0
words: 8455
updated: 2026-09-24T12:02:05Z
generator: "Skills Docs"
---

> **vercel/ai** — every Agent Skill in this repository, inlined verbatim.
>
> Canonical HTML: https://skillsdocs.com/vercel/ai
> Per-skill Markdown: https://skillsdocs.com/vercel/ai/<skill>.md
> Machine manifest: https://skillsdocs.com/vercel/ai/.well-known/agent-skills/index.json
> JSON: https://skillsdocs.com/api/v1/books/vercel/ai
> Install: `npx skills add vercel/ai`
> Upstream: https://github.com/vercel/ai @ `main`
> Licence: Other
>
> Content is mirrored from GitHub and © its authors, served unmodified. Takedown: https://github.com/DreambaseAI/skillsdocs/issues/new?labels=takedown&title=Takedown+request

# vercel/ai

The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents

- **Skills:** 12
- **Inlined:** 12 (licence detected)
- **Words:** 8,455
- **Reading time:** 41 min
- **Stars:** 26,924

## Table of contents

1. [add-function-examples](https://skillsdocs.com/vercel/ai/add-function-examples.md) — Guide for adding new AI function examples, for testing specific features against the actual provider APIs.
2. [add-harness-package](https://skillsdocs.com/vercel/ai/add-harness-package.md) — Guide for adding new AI SDK harness packages. Use when creating a new @ai-sdk/harness-<name> package that adapts a coding-agent runtime to HarnessV1.
3. [add-provider-package](https://skillsdocs.com/vercel/ai/add-provider-package.md) — Guide for adding first-party AI provider packages to the AI SDK. Use when creating a provider package under packages/ to integrate an external AI service.
4. [adr-skill](https://skillsdocs.com/vercel/ai/adr-skill.md) — Create and maintain Architecture Decision Records (ADRs) optimized for agentic coding workflows. Use when you need to propose, write, update, accept/reject, de…
5. [capture-api-response-test-fixture](https://skillsdocs.com/vercel/ai/capture-api-response-test-fixture.md) — Capture API response test fixture.
6. [develop-ai-functions-example](https://skillsdocs.com/vercel/ai/develop-ai-functions-example.md) — Develop examples for AI SDK functions. Use when creating, running, or modifying examples under examples/ai-functions/src to validate provider support, demonstr…
7. [list-npm-package-content](https://skillsdocs.com/vercel/ai/list-npm-package-content.md) — List the contents of an npm package tarball before publishing. Use when the user wants to see what files are included in an npm bundle, verify package contents…
8. [major-version-mode](https://skillsdocs.com/vercel/ai/major-version-mode.md) — Context for working on the next AI SDK major release. Only use when explicitly invoked by the user (e.g. via '/major-version-mode'). Do NOT trigger autonomousl…
9. [migrate-ai-sdk-v6-to-v7](https://skillsdocs.com/vercel/ai/migrate-ai-sdk-v6-to-v7.md) — Migrate applications from AI SDK 6.x to AI SDK 7.0. Use when upgrading Vercel AI SDK packages, fixing v7 migration errors, or when the user mentions AI SDK v6,…
10. [update-harness-dependencies](https://skillsdocs.com/vercel/ai/update-harness-dependencies.md) — Update the primary SDK dependencies of harness packages. Use when asked to update the harness SDKs or harness adapter dependencies.
11. [update-provider-models](https://skillsdocs.com/vercel/ai/update-provider-models.md) — Add new or remove obsolete model IDs for existing AI SDK providers. Use when adding a model to a provider, removing an obsolete model, or processing a list of…
12. [ai-sdk](https://skillsdocs.com/vercel/ai/use-ai-sdk.md) — Answer questions about the AI SDK and help build AI-powered features. Use when developers: (1) Ask about AI SDK functions like generateText, streamText, ToolLo…


## Front matter

_The repository README, verbatim except that relative links are resolved against https://github.com/vercel/ai/blob/main/._

packages/ai/README.md

---

<!-- chapter:begin slug=add-function-examples position=1 -->

## 1. add-function-examples

- **Source:** https://github.com/vercel/ai/blob/main/skills/add-function-examples/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/add-function-examples/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/add-function-examples.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: add-function-examples
description: Guide for adding new AI function examples, for testing specific features against the actual provider APIs.
metadata:
  internal: true
---

## Adding Function Examples

Review the changes in the current branch, and identify new or modified features or bug fixes that would benefit from having an example in the `examples/ai-functions` directory. These examples are used for testing specific features against the actual provider APIs, and can also serve as documentation for users.

Determine for which kind of model and top-level function the example should be added. For a language model, the example should be added in two variants, one for `generateText` and one for `streamText`. For any other models kinds, add the example for the relevant top-level function (e.g. `generateImage`, `generateSpeech`).

After creating the example, run `pnpm type-check:full`; fix any errors encountered.

<!-- chapter:end slug=add-function-examples -->

---

<!-- chapter:begin slug=add-harness-package position=2 -->

## 2. add-harness-package

- **Source:** https://github.com/vercel/ai/blob/main/skills/add-harness-package/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/add-harness-package/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/add-harness-package.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: add-harness-package
description: Guide for adding new AI SDK harness packages. Use when creating a new @ai-sdk/harness-<name> package that adapts a coding-agent runtime to HarnessV1.
metadata:
  internal: true
---

## Adding a New Harness Package

This guide covers creating a new `@ai-sdk/harness-<name>` package for an agent harness.

A harness can be **host-driven**, where the runtime runs in the host process and uses the sandbox remotely, or **bridge-backed**, where a small bridge runs inside the sandbox because the runtime needs local access to the sandbox filesystem or process environment.
Prefer host-driven when the runtime supports it.

## First-Party vs Third-Party Harnesses

- **Third-party packages**: Any runtime can publish an external harness package.
- **First-party `@ai-sdk/harness-<name>` packages**: Create an issue first to discuss whether the runtime belongs in this repo.

## Reference Example

See https://github.com/vercel/ai/pull/16255/changes for a complete example of adding a new harness.

## Harness Architecture

The AI SDK uses a layered harness architecture following the adapter pattern:

1. **Harness specification** (`@ai-sdk/harness`): Defines interfaces like `HarnessV1` and `HarnessV1Session`
2. **Utilities** (`@ai-sdk/harness/utils`): Shared code for implementing harnesses
3. **Harness implementations** (`@ai-sdk/harness-<name>`): Concrete adapters for harnesses
4. **Harness agent** (`@ai-sdk/harness/agent`): The high-level user-facing `HarnessAgent` API

## Step-by-Step Guide

### 1. Create Package Structure

Create `packages/harness-<name>` with this baseline structure:

```
packages/harness-<name>/
├── src/
│   ├── index.ts
│   ├── <name>-harness.ts
│   ├── <name>-harness.test.ts
│   └── <name>-auth.ts              # if the runtime needs auth resolution
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
└── README.md
```

If the runtime must execute inside the sandbox, add bridge files as well:

```
src/
├── <name>-bridge-protocol.ts
├── <name>-bridge-protocol.test.ts
└── bridge/
    ├── index.ts
    ├── package.json
    └── pnpm-lock.yaml
```

Add a `CHANGELOG.md` containing just the package heading (`# @ai-sdk/harness-<name>`). Every package is required to have one.

### 2. Configure package.json

Use existing harness packages as the source of truth for scripts, exports, repository metadata, and publish settings.

Required package basics:

- `"name": "@ai-sdk/harness-<name>"`
- `"type": "module"`
- `"version": "0.0.0"` (starting point for new packages)
- `"license": "Apache-2.0"`
- `"sideEffects": false`
- dependency on `@ai-sdk/harness` via `workspace:*`
- dependency on `@ai-sdk/provider-utils` via `workspace:*` when using sandbox/auth/schema utilities
- runtime SDK/CLI dependencies required by the harness
- dev dependencies matching existing harness packages
- `"engines": { "node": ">=22" }`

For bridge packages, add any bridge asset copy step required for files under `src/bridge/`.

Bridge dependency rules (bridge-backed harnesses):

- The bridge's runtime deps live in `src/bridge/package.json` (installed in-sandbox at bootstrap), not the main package.json. After changing them, regenerate `src/bridge/pnpm-lock.yaml` with `pnpm --dir packages/harness-<name>/src/bridge install --lockfile-only --ignore-workspace` (runnable from the repo root).
- For every third-party import in `src/bridge/`, keep three things in sync: the import, the `external` array in `tsup.config.ts`, and the dep in `src/bridge/package.json`. A missing entry shows up only at sandbox runtime as a module-resolution error.
- Include packages the runtime _lazily_ imports — e.g. provider SDKs (`@anthropic-ai/sdk`, `openai`) resolved from the model id at runtime — even though nothing imports them directly. These fail only when a model of that provider is actually used.
- Match shared dependency versions (transport, schema, tooling, runtime SDKs) to what the other harness packages currently use — copy from a sibling package rather than choosing your own pins. Stale pins drift from security patches and can desync from the shared bridge runtime; check the current versions at creation time.

### 3. Create TypeScript, Build, and Test Configs

Copy the nearest existing harness package config files and adjust paths/package names:

- `tsconfig.json`
- `tsconfig.build.json`
- `tsup.config.ts`
- `turbo.json`
- `vitest.node.config.js`

Harness packages currently use Node tests only unless the implementation has a specific reason to add another runtime.

### 4. Implement the Harness Adapter

Export a factory from `<name>-harness.ts` and re-export it from `src/index.ts`.

Use the architecture doc for contract details. At implementation time, verify:

- return a `HarnessV1` with `specificationVersion: 'harness-v1'`;
- use a stable kebab-case `harnessId`;
- expose adapter-native built-in tools through `builtinTools`;
- keep construction synchronous and side-effect free;
- use `startOpts.sandboxSession` and `startOpts.sessionWorkDir`; never create a separate sandbox;
- throw `HarnessCapabilityUnsupportedError` from the method that needs an unsupported runtime capability;
- don't hardcode a default model unless the runtime technically requires one — some underlying SDKs have no default of their own. Otherwise pass the model only when the consumer configured one and leave the original SDK's default untouched; keep the session's `modelId` consistent with what's actually sent (don't report a model the bridge silently overrode);
- handle the `tools` and `instructions` that `doPromptTurn`/`doContinueTurn` may receive: if the runtime can't take custom `tools`, throw `HarnessCapabilityUnsupportedError` so it's obvious rather than silently dropped; if it has no native `instructions` input, prepend them to the first user message (the Codex/Claude Code workaround);
- quote interpolated paths (`workDir`, bridge-state dir, …) when building shell commands for `sandbox.run`/`sandbox.spawn` — they can contain spaces.

If the runtime needs in-sandbox setup, expose `getBootstrap()`.

### 5. Implement Runtime-Specific Concerns

Add only the concerns the runtime needs:

- auth resolution — for AI Gateway support, use the central `getAiGatewayAuthFromEnv()` helper rather than reading env directly. This ensures both `VERCEL_OIDC_TOKEN` and `AI_GATEWAY_API_KEY` are accepted as Gateway credential. When the runtime resolves provider per model, resolve the provider from the model id and set that provider's env; if routing through the gateway, note that base-URL conventions differ per provider (e.g. an Anthropic client appends `/v1/messages` to a root base, an OpenAI client appends to a `/v1` base);
- AI Gateway client attribution — follow the convention in existing harness packages: define a versioned client app value such as `ai-sdk/harness-<name>/${VERSION}` and use it for Gateway requests. Configure both `User-Agent` and `x-client-app` headers when the underlying runtime/SDK supports both; at least one of those two headers is required. If the runtime cannot set arbitrary headers directly, use the runtime-supported equivalent that produces one of those headers (e.g. an SDK client-app environment variable);
- custom-tool schema translation — if you convert host tools' JSON Schema into the runtime's tool format, convert _recursively_ (nested objects, array `items`, enums, descriptions); a flat top-level-only conversion silently drops the model's structured guidance. Passing the JSON Schema through directly, if the runtime accepts it, avoids the problem;
- skill or discovery-file materialization;
- native protocol to harness stream/control translation;
- lifecycle state schema;
- bridge protocol and diagnostics.

Certain structural conventions for harness adapters are being enforced via the `konsistent` CLI.
Run `pnpm konsistent` once you're done to check for those. Fix any violations flagged before proceeding.

### 6. Write Tests

Add focused Node tests for:

- factory metadata and settings;
- auth resolution;
- sandbox usage and path placement;
- host-driven remote operations or bridge protocol behavior;
- prompt/control event translation;
- resume session vs continue turn behavior;
- unsupported capability errors;
- skill materialization, if supported.

Use mocked sandbox sessions and bridge/runtime boundaries where possible. Do not require live provider credentials in unit tests.

`getBootstrap()` reads the _compiled_ bridge assets (e.g. `dist/bridge/index.mjs`), which don't exist when tests run against `src`, so a test that calls it will hit `ENOENT`. Mock `node:fs/promises` `readFile` for the bridge asset paths (see the Codex/OpenCode harness tests for the pattern).

### 7. Add README

Keep README short:

- package purpose;
- setup command;
- minimal `HarnessAgent` usage;
- required sandbox capabilities, such as ports for bridge-backed runtimes;
- notable auth configuration.

Link to the main harness docs for broader concepts.

### 8. Add Examples

Add relevant examples for the new harness.

- Add API/function examples under `examples/ai-functions` when the harness package needs a scriptable provider-behavior example.
- Add interactive examples mirroring the existing harness examples in `examples/harness-e2e-next` (Next.js) and `examples/harness-e2e-tui` (TUI).

### 9. Add Documentation

Create documentation in `content/providers/02-ai-sdk-harnesses/<next number>-<name>.mdx`.

Include:

- Setup instructions
- Required sandbox capabilities
- Authentication configuration
- Harness-specific options
- Usage examples
- Known limitations

Update `content/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx` to list the new harness when it is ready to be public.

### 10. Update References and Validate

Run from the workspace root:

```bash
pnpm konsistent
pnpm update-references
pnpm --filter @ai-sdk/harness-<name> build
pnpm --filter @ai-sdk/harness-<name> test
pnpm type-check:full
```

Add a changeset with `pnpm changeset`. For a brand-new harness package's first release, use `major` (not the usual `patch`), matching the other harness packages.

Run relevant harness examples against a live sandbox **early** — don't rely on unit tests and `type-check` alone. Runtime API constraints (e.g. unexpected config-option rejections, the exact streaming event names the runtime emits, gateway base-URL format) surface only when the bridge actually drives the runtime, and they're far cheaper to find before the docs/examples are built on top.

## Checklist

- [ ] Package structure created in `packages/harness-<name>`
- [ ] `package.json` configured with correct dependencies
- [ ] TypeScript configs set up (`tsconfig.json`, `tsconfig.build.json`)
- [ ] Build configuration (`tsup.config.ts`)
- [ ] Test configuration (`vitest.node.config.js`)
- [ ] Harness adapter implementation complete
- [ ] Runtime placement handled without creating a hidden sandbox
- [ ] Bridge assets copied during build, if bridge-backed
- [ ] Auth resolution implemented, if needed
- [ ] AI Gateway requests include `User-Agent` and/or `x-client-app` client attribution
- [ ] Harness infra, skills, bridge code, and secrets kept out of `sessionWorkDir`
- [ ] Session resume and turn continuation tested
- [ ] Unit tests written and passing
- [ ] README.md written
- [ ] `CHANGELOG.md` added (package heading; required by `konsistent`)
- [ ] Changeset added (`major` for a first release)
- [ ] Examples added
- [ ] Documentation added in `content/providers/02-ai-sdk-harnesses/`
- [ ] Harness adapter list updated, if public
- [ ] Validated against a live sandbox (not just unit tests / type-check)
- [ ] `pnpm update-references` run
- [ ] Package build passing
- [ ] Package tests passing
- [ ] Type checking passing (`pnpm type-check:full` from root)
- [ ] Relevant examples run successfully

## Related Documentation

- [Harness Abstraction Architecture](../../architecture/harness-abstraction.md)
- [`@ai-sdk/harness` README](../../packages/harness/README.md)
- Existing harness packages with similar runtime placement

<!-- chapter:end slug=add-harness-package -->

---

<!-- chapter:begin slug=add-provider-package position=3 -->

## 3. add-provider-package

- **Source:** https://github.com/vercel/ai/blob/main/skills/add-provider-package/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/add-provider-package/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/add-provider-package.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: add-provider-package
description: Guide for adding first-party AI provider packages to the AI SDK. Use when creating a provider package under packages/ to integrate an external AI service.
metadata:
  internal: true
---

# Add a Provider Package

Add a complete first-party `@ai-sdk/<provider>` package that follows the current provider interfaces, repository conventions, security requirements, and release process.

## Read the Current Sources of Truth

Before implementing anything, read:

- [Add new provider](../../contributing/add-new-provider.md) for current package and release requirements
- [Provider development notes](../../contributing/providers.md) for naming, schemas, and workflow serialization
- [Provider architecture](../../contributing/provider-architecture.md) for the provider abstraction
- [Secure URL handling](../../contributing/secure-url-handling.md) when the provider fetches polling, image, audio, video, or other URLs

Use [PR #18595](https://github.com/vercel/ai/pull/18595/changes) as a recent end-to-end example, but choose the current provider package whose API shape and model types most closely resemble the new provider as the implementation reference.

Third parties can publish provider packages outside this repository. A new first-party `@ai-sdk/<provider>` package requires prior discussion in an issue. Confirm that agreement exists before implementing the package.

## Discover the API Contract

Before designing model classes, look for an official, versioned OpenAPI or Swagger specification in the provider's documentation or repositories. Prefer first-party specifications and record the source URL plus its version, publication date, or commit in the implementation notes or pull request.

Use the specification and official documentation to identify:

- base URLs and authentication schemes
- supported endpoints, model types, and capabilities
- request parameters and response shapes
- streaming transports and event formats
- error response envelopes
- asynchronous polling and download URL flows

Treat an OpenAPI specification as implementation evidence, not unquestioned truth. Specifications are often incomplete for server-sent events, streaming deltas, polymorphic content, tool calls, nullable fields, and errors. Do not add a generated client or generated production types by default. Implement minimal hand-written types and Zod schemas, then verify them against official documentation and captured API responses.

If no official specification exists, derive the contract from official documentation and real response fixtures, and note that limitation in the pull request.

## Plan the Provider Shape

Determine which AI SDK model interfaces the provider supports, such as `LanguageModelV4`, `EmbeddingModelV4`, `ImageModelV4`, `SpeechModelV4`, `TranscriptionModelV4`, `RerankingModelV4`, or `Experimental_VideoModelV4`.

Before introducing a dependency, public API pattern, or new abstraction, read `contributing/decisions/README.md` and relevant accepted ADRs. Prefer existing provider utilities and implementation patterns.

## Scaffold the Package

Create `packages/<provider>/` by adapting a current, comparable provider package. A typical package contains:

```text
packages/<provider>/
├── src/
│   ├── index.ts
│   ├── version.ts
│   ├── <provider>-provider.ts
│   ├── <provider>-provider.test.ts
│   ├── <provider>-<model-type>-model.ts
│   ├── <provider>-<model-type>-model.test.ts
│   └── <provider>-<model-type>-options.ts
├── CHANGELOG.md
├── README.md
├── package.json
├── tsconfig.json
├── tsconfig.build.json
├── tsup.config.ts
├── turbo.json
├── vitest.node.config.js
└── vitest.edge.config.js
```

Preserve current package conventions rather than recreating configuration from memory:

- Set the repository package version to exactly `2.0.0`, with no prerelease suffix.
- Create `CHANGELOG.md` with an initial `# @ai-sdk/<provider>` heading.
- Use ESM output and the current `tsup` package-version injection pattern.
- Extend `./node_modules/@vercel/ai-tsconfig/ts-library.json`, enable a composite project, and add package references for workspace dependencies.
- Include the standard build, clean, type-check, Node test, and Edge test scripts.
- Include the standard `files`, documentation prepack, repository, bugs, engines, and public provenance publishing metadata.
- Use `workspace:*` for AI SDK workspace dependencies. Add `@ai-sdk/test-server` only when tests use it.
- Support the repository's Zod 3 and Zod 4 peer dependency range and use `zod/v4` for new implementation schemas.

Run `pnpm update-references` after adding or changing workspace dependencies.

## Implement the Provider Factory

Follow the current provider factory pattern:

- Define a provider interface that extends `ProviderV4`.
- Export `create<Provider>(settings)` and a default provider instance.
- Make the provider callable when it has a meaningful default model type and comparable providers follow that pattern; otherwise return a provider object.
- Set `provider.specificationVersion = 'v4'`.
- Implement the fully specified factory methods required by `ProviderV4`, such as `languageModel`, `embeddingModel`, and `imageModel`.
- Add short aliases such as `chat`, `embedding`, or `image` only when they improve the provider's API.
- Throw `NoSuchModelError` from unsupported required model factories.
- Support provider-appropriate settings such as `apiKey`, `baseURL`, `headers`, and a custom `fetch` implementation.
- Load credentials with `loadApiKey` or the appropriate shared utility, normalize configurable base URLs, and include the package version in the user-agent suffix.
- Export the provider factory, default instance, public option types, model ID types, and `VERSION` from `src/index.ts`.

## Implement Model Classes

Implement each supported model using the appropriate interface from `@ai-sdk/provider` and shared utilities from `@ai-sdk/provider-utils`.

Provider option types and schemas must follow [the repository naming and export rules](../../contributing/providers.md#provider-specific-model-options-types). User-facing option fields should use `.optional()` unless `null` is meaningful. Response schemas should be minimal, tolerate unused provider fields, and use `.nullish()` where the API may omit or return `null`.

All model classes must implement the workflow serialization contract described in [Provider development notes](../../contributing/providers.md#workflow-serialization):

- make model configuration headers optional
- add `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE` static methods
- use `serializeModel`, `serializeModelOptions`, or the matching existing pattern
- ensure authentication and other non-serializable functions can be restored from request options or the workflow environment

## Handle Responses, Errors, and URLs Safely

- Never use `JSON.parse` in production code. Use `parseJSON` or `safeParseJSON` from `@ai-sdk/provider-utils`.
- Validate successful and failed responses with minimal schemas and shared response handlers such as `createJsonResponseHandler` and `createJsonErrorResponseHandler`.
- Introduce a custom `AISDKError` subclass only when the package needs a new public SDK error type; ordinary provider HTTP failures should use the shared API error handling.
- Set `validateUrl` explicitly on every `getFromApi` call.
- Use `validateUrl: true` when the URL host or scheme comes from a provider response, and `false` when it is derived from a developer-configured base URL.
- Use `trustedOrigin` for legitimate response URLs that may point to a configured private or self-hosted endpoint.
- Use `credentialedOrigin` when credentials may be sent on the first hop, so they are withheld from off-origin URLs and redirects.

Read [Secure URL handling](../../contributing/secure-url-handling.md) before implementing any polling or provider-supplied download URL flow.

## Test Against the Real Contract

Add focused tests for:

- provider defaults, custom settings, factory aliases, and unsupported model types
- request serialization and response parsing
- streaming events, usage, finish reasons, warnings, tool calls, and provider metadata where supported
- error response parsing and malformed responses
- workflow serialization and deserialization
- URL trust decisions for polling or downloads
- both Node.js and Edge runtimes

Use real provider responses as fixtures when practical. Read the [capture API response fixture skill](../capture-api-response-test-fixture/SKILL.md) before capturing them. Trim oversized fixtures only when doing so does not change their semantics.

## Add Examples and Repository Integration

Read the [AI Functions example skill](../develop-ai-functions-example/SKILL.md) before adding examples.

For each supported model type, put the entry example at:

```text
examples/ai-functions/src/<function>/<provider>/basic.ts
```

Put additional examples in the same provider directory with descriptive `kebab-case.ts` names. Do not create flat provider files such as `src/generate-text/<provider>.ts`.

Also update the relevant repository integration points:

- add `@ai-sdk/<provider>` to `examples/ai-functions/package.json`
- add its project reference to `examples/ai-functions/tsconfig.json`
- add required credentials to `examples/ai-functions/.env.example`
- add credential names to the root `turbo.json` environment configuration when needed
- run `pnpm update-references` to update root and package TypeScript references

Run representative examples against the real API and confirm both non-streaming and streaming behavior when supported.

## Add Package and Provider Documentation

- Write the package `README.md` with installation, authentication, configuration, supported models, and basic usage.
- Add `content/providers/01-ai-sdk-providers/<last number + 10>-<provider>.mdx` with setup, model capabilities, provider options, and examples.
- Configure the package's documentation prepack script to include that provider page.

## Prepare the Release

Create a major changeset for the new provider package. The repository package remains at plain `2.0.0`; do not add `-beta`, `-canary`, or another prerelease suffix.

Before the first automated release, coordinate with the Vercel IT team to bootstrap an empty `@ai-sdk/<provider>` package on npm at `0.0.0` and configure its Trusted Publisher. Follow [Bootstrapping a new `@ai-sdk/*` package](../../contributing/releases.md#bootstrapping-a-new-ai-sdk-package). The temporary npm bootstrap version is separate from the repository package version.

When `main` is in prerelease mode, do not backport the new package to a stable `vX.Y` branch.

## Verify the Complete Change

Run, at minimum:

```bash
pnpm --filter @ai-sdk/<provider> build
pnpm --filter @ai-sdk/<provider> test
pnpm --filter @ai-sdk/<provider> type-check
pnpm type-check:full
pnpm check
```

Also run the new examples with the required provider credentials. Run the root build when changes to shared packages or build configuration make it relevant.

## Completion Checklist

- [ ] First-party package approved in an issue
- [ ] Official OpenAPI specification reviewed, or its absence documented
- [ ] API specification checked against documentation and real responses
- [ ] Comparable current provider implementation selected
- [ ] Repository package created at version `2.0.0`
- [ ] Package, TypeScript, build, test, provenance, and documentation configuration added
- [ ] Provider factory implements `ProviderV4`
- [ ] Supported model classes and public option types implemented
- [ ] Workflow serialization implemented for every model class
- [ ] Response parsing, error handling, and URL fetching follow repository security rules
- [ ] Node and Edge tests pass with representative response fixtures
- [ ] Nested AI Functions examples added and run successfully
- [ ] Example dependencies, TypeScript references, environment variables, and Turbo configuration updated
- [ ] README and provider documentation added
- [ ] Major changeset added
- [ ] npm package and Trusted Publisher bootstrap coordinated
- [ ] Package build, tests, full type check, and repository checks pass

<!-- chapter:end slug=add-provider-package -->

---

<!-- chapter:begin slug=adr-skill position=4 -->

## 4. adr-skill

- **Source:** https://github.com/vercel/ai/blob/main/skills/adr-skill/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/adr-skill.md
- **Licence:** Other — https://github.com/vercel/ai

Bundled files (10), referenced from this skill's directory:
  - `assets/templates/adr-madr.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/assets/templates/adr-madr.md
  - `assets/templates/adr-readme.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/assets/templates/adr-readme.md
  - `assets/templates/adr-simple.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/assets/templates/adr-simple.md
  - `references/adr-conventions.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/references/adr-conventions.md
  - `references/examples.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/references/examples.md
  - `references/review-checklist.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/references/review-checklist.md
  - `references/template-variants.md` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/references/template-variants.md
  - `scripts/bootstrap_adr.js` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/scripts/bootstrap_adr.js
  - `scripts/new_adr.js` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/scripts/new_adr.js
  - `scripts/set_adr_status.js` — https://raw.githubusercontent.com/vercel/ai/main/skills/adr-skill/scripts/set_adr_status.js

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: adr-skill
description: Create and maintain Architecture Decision Records (ADRs) optimized for agentic coding workflows. Use when you need to propose, write, update, accept/reject, deprecate, or supersede an ADR; bootstrap an adr folder and index; consult existing ADRs before implementing changes; or enforce ADR conventions. This skill uses Socratic questioning to capture intent before drafting, and validates output against an agent-readiness checklist.
metadata:
  internal: true
---

# ADR Skill

## Philosophy

ADRs created with this skill are **executable specifications for coding agents**. A human approves the decision; an agent implements it. The ADR must contain everything the agent needs to write correct code without asking follow-up questions.

This means:

- Constraints must be explicit and measurable, not vibes
- Decisions must be specific enough to act on ("use PostgreSQL 16 with pgvector" not "use a database")
- Consequences must map to concrete follow-up tasks
- Non-goals must be stated to prevent scope creep
- The ADR must be self-contained — no tribal knowledge assumptions
- **The ADR must include an implementation plan** — which files to touch, which patterns to follow, which tests to write, and how to verify the decision was implemented correctly

## When to Write an ADR

Write an ADR when a decision:

- **Changes how the system is built or operated** (new dependency, architecture pattern, infrastructure choice, API design)
- **Is hard to reverse** once code is written against it
- **Affects other people or agents** who will work in this codebase later
- **Has real alternatives** that were considered and rejected

Do NOT write an ADR for:

- Routine implementation choices within an established pattern
- Bug fixes or typo corrections
- Decisions already captured in an existing ADR (update it instead)
- Style preferences already covered by linters or formatters

When in doubt: if a future agent working in this codebase would benefit from knowing _why_ this choice was made, write the ADR.

### Proactive ADR Triggers (For Agents)

If you are an agent coding in a repo and you encounter any of these situations, **stop and propose an ADR** before continuing:

- You are about to introduce a new dependency that doesn't already exist in the project
- You are about to create a new architectural pattern (new way of handling errors, new data access layer, new API convention) that other code will need to follow
- You are about to make a choice between two or more real alternatives and the tradeoffs are non-obvious
- You are about to change something that contradicts an existing accepted ADR
- You realize you're writing a long code comment explaining "why" — that reasoning belongs in an ADR

**How to propose**: Tell the human what decision you've hit, why it matters, and ask if they want to capture it as an ADR. If yes, run the full four-phase workflow. If no, note the decision in a code comment and move on.

## Creating an ADR: Four-Phase Workflow

Every ADR goes through four phases. Do not skip phases.

### Phase 0: Scan the Codebase

Before asking any questions, gather context from the repo:

1. **Find existing ADRs.** Check `contributing/decisions/`, `docs/decisions/`, `adr/`, `docs/adr/`, `decisions/` for existing records. Read them. Note:
   - Existing conventions (directory, naming, template style)
   - Decisions that relate to or constrain the current one
   - Any ADRs this new decision might supersede

2. **Check the tech stack.** Read `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, or equivalent. Note relevant dependencies and versions.

3. **Find related code patterns.** If the decision involves a specific area (e.g., "how we handle auth"), scan for existing implementations. Identify the specific files, directories, and patterns that will be affected by the decision.

4. **Check for ADR references in code.** Look for ADR references in comments and docs (see "Code ↔ ADR Linking" below). This reveals which existing decisions govern which parts of the codebase.

5. **Note what you found.** Carry this context into Phase 1 — it will sharpen your questions and prevent the ADR from contradicting existing decisions.

### Phase 1: Capture Intent (Socratic)

Interview the human to understand the decision space. Ask questions **one at a time**, building on previous answers. Do not dump a list of questions.

**Core questions** (ask in roughly this order, skip what's already clear from context or Phase 0):

1. **What are you deciding?** — Get a short, specific title. Push for a verb phrase ("Choose X", "Adopt Y", "Replace Z with W").
2. **Why now?** — What broke, what's changing, or what will break if you do nothing? This is the trigger.
3. **What constraints exist?** — Tech stack, timeline, budget, team size, existing code, compliance. Be concrete. Reference what you found in Phase 0 ("I see you're already using X — does that constrain this?").
4. **What does success look like?** — Measurable outcomes. Push past "it works" to specifics (latency, throughput, DX, maintenance burden).
5. **What options have you considered?** — At least two. For each: what's the core tradeoff? If they only have one option, help them articulate why alternatives were rejected.
6. **What's your current lean?** — Capture gut intuition early. Often reveals unstated priorities.
7. **Who needs to know or approve?** — Decision-makers, consulted experts, informed stakeholders.
8. **What would an agent need to implement this?** — Which files/directories are affected? What existing patterns should it follow? What should it avoid? What tests would prove it's working? This directly feeds the Implementation Plan.

**Adaptive follow-ups**: Based on answers, probe deeper where the decision is fuzzy. Common follow-ups:

- "What's the worst-case outcome if this decision is wrong?"
- "What would make you revisit this in 6 months?"
- "Is there anything you're explicitly choosing NOT to do?"
- "What prior art or existing patterns in the codebase does this relate to?"
- "I found [existing ADR/pattern] — does this new decision interact with it?"

**When to stop**: You have enough when you can fill every section of the ADR — including the Implementation Plan — without making things up. If you're guessing at any section, ask another question.

**Intent Summary Gate**: Before moving to Phase 2, present a structured summary of what you captured and ask the human to confirm or correct it:

> **Here's what I'm capturing for the ADR:**
>
> - **Title**: {title}
> - **Trigger**: {why now}
> - **Constraints**: {list}
> - **Options**: {option 1} vs {option 2} [vs ...]
> - **Lean**: {which option and why}
> - **Non-goals**: {what's explicitly out of scope}
> - **Related ADRs/code**: {what exists that this interacts with}
> - **Affected files/areas**: {where in the codebase this lands}
> - **Verification**: {how we'll know it's implemented correctly}
>
> **Does this capture your intent? Anything to add or correct?**

Do NOT proceed to Phase 2 until the human confirms the summary.

### Phase 2: Draft the ADR

1. **Choose the ADR directory.**
   - If one exists (found in Phase 0), use it.
   - If none exists, create `contributing/decisions/` (if `contributing/` exists), `docs/decisions/` (MADR default), or `adr/` (simpler repos).

2. **Choose a filename strategy.**
   - If existing ADRs use date prefixes (`YYYY-MM-DD-...`), continue that.
   - Otherwise use slug-only filenames (`choose-database.md`).

3. **Choose a template.**
   - Use `assets/templates/adr-simple.md` for straightforward decisions (one clear winner, minimal tradeoffs).
   - Use `assets/templates/adr-madr.md` when you need to document multiple options with structured pros/cons/drivers.
   - See `references/template-variants.md` for guidance.

4. **Fill every section from the confirmed intent summary.** Do not leave placeholder text. Every section should contain real content or be removed (optional sections only).

5. **Write the Implementation Plan.** This is the most important section for agent-first ADRs. It tells the next agent exactly what to do. See the template for structure.

6. **Write Verification criteria as checkboxes.** These must be specific enough that an agent can programmatically or manually check each one.

7. **Generate the file.**
   - Preferred: run `scripts/new_adr.js` (handles directory, naming, and optional index updates).
   - If you can't run scripts, copy a template from `assets/templates/` and fill it manually.

### Phase 3: Review Against Checklist

After drafting, review the ADR against the agent-readiness checklist in `references/review-checklist.md`.

**Present the review as a summary**, not a raw checklist dump. Format:

> **ADR Review**
>
> ✅ **Passes**: {list what's solid — e.g., "context is self-contained, implementation plan covers affected files, verification criteria are checkable"}
>
> ⚠️ **Gaps found**:
>
> - {specific gap 1 — e.g., "Implementation Plan doesn't mention test files — which test suite should cover this?"}
> - {specific gap 2}
>
> **Recommendation**: {Ship it / Fix the gaps first / Needs more Phase 1 work}

Only surface failures and notable strengths — do not recite every passing checkbox.

If there are gaps, propose specific fixes. Do not just flag problems — offer solutions and ask the human to approve.

Do not finalize until the ADR passes the checklist or the human explicitly accepts the gaps.

## Consulting ADRs (Read Workflow)

Agents should read existing ADRs **before implementing changes** in a codebase that has them. This is not part of the create-an-ADR workflow — it's a standalone operation any agent should do.

### When to Consult ADRs

- Before starting work on a feature that touches architecture (auth, data layer, API design, infrastructure)
- When you encounter a pattern in the code and wonder "why is it done this way?"
- Before proposing a change that might contradict an existing decision
- When a human says "check the ADRs" or "there's a decision about this"
- When you find an ADR reference in a code comment

### How to Consult ADRs

1. **Find the ADR directory.** Check `contributing/decisions/`, `docs/decisions/`, `adr/`, `docs/adr/`, `decisions/`. Also check for an index file (`README.md` or `index.md`).

2. **Scan titles and statuses.** Read the index or list filenames. Focus on `accepted` ADRs — these are active decisions.

3. **Read relevant ADRs fully.** Don't just read the title — read context, decision, consequences, non-goals, AND the Implementation Plan. The Implementation Plan tells you what patterns to follow and what files are governed by this decision.

4. **Respect the decisions.** If an accepted ADR says "use PostgreSQL," don't propose switching to MongoDB without creating a new ADR that supersedes it. If you find a conflict between what the code does and what the ADR says, flag it to the human.

5. **Follow the Implementation Plan.** When implementing code in an area governed by an ADR, follow the patterns specified in its Implementation Plan. If the plan says "all new queries go through the data-access layer in `src/db/`," do that.

6. **Reference ADRs in your work.** Add ADR references in code comments and PR descriptions (see "Code ↔ ADR Linking" below).

## Code ↔ ADR Linking

ADRs should be bidirectionally linked to the code they govern.

### ADR → Code (in the Implementation Plan)

The Implementation Plan section names specific files, directories, and patterns:

```markdown
## Implementation Plan

- **Affected paths**: `src/db/`, `src/config/database.ts`, `tests/integration/`
- **Pattern**: all database queries go through `src/db/client.ts`
```

### Code → ADR (in comments)

When implementing code guided by an ADR, add a comment referencing it:

```typescript
// ADR: Using better-sqlite3 for test database
// See: docs/decisions/2025-06-15-use-sqlite-for-test-database.md
import Database from 'better-sqlite3';
```

Keep these lightweight — one comment at the entry point, not on every line. The goal is discoverability: when a future agent reads this code, they can find the reasoning.

### Why This Matters

- An agent working in `src/db/` can find which ADRs govern that area
- An agent reading an ADR can find the code that implements it
- When an ADR is superseded, the code references make it easy to find all code that needs updating

## Other Operations

### Update an Existing ADR

1. Identify the intent:
   - **Accept / reject**: change status, add any final context.
   - **Deprecate**: status → `deprecated`, explain replacement path.
   - **Supersede**: create a new ADR, link both ways (old → new, new → old).
   - **Add learnings**: append to `## More Information` with a date stamp. Do not rewrite history.

2. Use `scripts/set_adr_status.js` for status changes (supports YAML front matter, bullet status, and section status).

### Post-Acceptance Lifecycle

After an ADR is accepted:

1. **Create implementation tasks.** Each item in the Implementation Plan and each follow-up in Consequences should become a trackable task (issue, ticket, or TODO).
2. **Reference the ADR in PRs.** Link to the ADR in PR descriptions, e.g. "Implements `contributing/decisions/2025-06-15-use-sqlite-for-test-database.md`."
3. **Add code references.** Add ADR path comments at key implementation points.
4. **Check verification criteria.** Once implementation is complete, walk through the Verification checkboxes. Update the ADR with results in `## More Information`.
5. **Revisit when triggers fire.** If the ADR specified revisit conditions ("if X happens, reconsider"), monitor for those conditions.

### Index

If the repo has an ADR index/log file (often `README.md` or `index.md` in the ADR dir), keep it updated.

Preferred: let `scripts/new_adr.js --update-index` do it. Otherwise:

- Add a bullet entry for the new ADR.
- Keep ordering consistent (numeric if numbered; date or alpha if slugs).

### Bootstrap

When introducing ADRs to a repo that has none:

```bash
node /path/to/adr-skill/scripts/bootstrap_adr.js
```

This creates the directory, an index file, and a filled-out first ADR ("Adopt architecture decision records") with real content explaining why the team is using ADRs. Use `--json` for machine-readable output. Use `--dir` to override the directory name.

### Categories (Large Projects)

For repos with many ADRs, organize by subdirectory:

```
docs/decisions/
  backend/
    2025-06-15-use-postgres.md
  frontend/
    2025-06-20-use-react.md
  infrastructure/
    2025-07-01-use-terraform.md
```

Date prefixes are local to each category. Choose a categorization scheme early (by layer, by domain, by team) and document it in the index.

## Resources

### scripts/

- `scripts/new_adr.js` — create a new ADR file from a template, using repo conventions.
- `scripts/set_adr_status.js` — update an ADR status in-place (YAML front matter or inline). Use `--json` for machine output.
- `scripts/bootstrap_adr.js` — create ADR dir, `README.md`, and initial "Adopt ADRs" decision.

### references/

- `references/review-checklist.md` — agent-readiness checklist for Phase 3 review.
- `references/adr-conventions.md` — directory, filename, status, and lifecycle conventions.
- `references/template-variants.md` — when to use simple vs MADR-style templates.
- `references/examples.md` — filled-out short and long ADR examples with implementation plans.

### assets/

- `assets/templates/adr-simple.md` — lean template for straightforward decisions.
- `assets/templates/adr-madr.md` — MADR 4.0 template for decisions with multiple options and structured tradeoffs.
- `assets/templates/adr-readme.md` — default ADR index scaffold used by `scripts/bootstrap_adr.js`.

### Script Usage

From the target repo root:

```bash
# Simple ADR
node /path/to/adr-skill/scripts/new_adr.js --title "Choose database" --status proposed

# MADR-style with options
node /path/to/adr-skill/scripts/new_adr.js --title "Choose database" --template madr --status proposed

# With index update
node /path/to/adr-skill/scripts/new_adr.js --title "Choose database" --status proposed --update-index

# Bootstrap a new repo
node /path/to/adr-skill/scripts/bootstrap_adr.js --dir docs/decisions
```

Notes:

- Scripts auto-detect ADR directory and filename strategy.
- Use `--dir` and `--strategy` to override.
- Use `--json` to emit machine-readable output.

<!-- chapter:end slug=adr-skill -->

---

<!-- chapter:begin slug=capture-api-response-test-fixture position=5 -->

## 5. capture-api-response-test-fixture

- **Source:** https://github.com/vercel/ai/blob/main/skills/capture-api-response-test-fixture/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/capture-api-response-test-fixture/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/capture-api-response-test-fixture.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: capture-api-response-test-fixture
description: Capture API response test fixture.
metadata:
  internal: true
---

### API Response Test Fixtures

For provider response parsing tests, we aim at storing test fixtures with the true responses from the providers (unless they are too large in which case some cutting that does not change semantics is advised).

The fixtures are stored in a `__fixtures__` subfolder, e.g. `packages/openai/src/responses/__fixtures__`. See the file names in `packages/openai/src/responses/__fixtures__` for naming conventions and `packages/openai/src/responses/openai-responses-language-model.test.ts` for how to set up test helpers.

You can use our examples under `/examples/ai-functions` to generate test fixtures.

#### generateText (doGenerate testing)

For `generateText`, put the script under `src/generate-text/<provider>/`, log the raw response output to the console, and copy it into a new test fixture.

```ts
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
import { run } from '../../lib/run';

run(async () => {
  const result = await generateText({
    model: openai('gpt-5-nano'),
    prompt: 'Invent a new holiday and describe its traditions.',
  });

  console.log(JSON.stringify(result.response.body, null, 2));
});
```

#### streamText (doStream testing)

For `streamText`, you need to set `includeRawChunks` to `true` and use the special `saveRawChunks` helper. Put the script under the provider directory and run it from the `/examples/ai-functions` folder via `pnpm tsx src/stream-text/<provider>/<script-name>.ts`. The result is then stored in the `/examples/ai-functions/output` folder. You can copy it to your fixtures folder and rename it.

```ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
import { run } from '../../lib/run';
import { saveRawChunks } from '../../lib/save-raw-chunks';

run(async () => {
  const result = streamText({
    model: openai('gpt-5-nano'),
    prompt: 'Invent a new holiday and describe its traditions.',
    includeRawChunks: true,
  });

  await saveRawChunks({ result, filename: 'openai-gpt-5-nano' });
});
```

<!-- chapter:end slug=capture-api-response-test-fixture -->

---

<!-- chapter:begin slug=develop-ai-functions-example position=6 -->

## 6. develop-ai-functions-example

- **Source:** https://github.com/vercel/ai/blob/main/skills/develop-ai-functions-example/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/develop-ai-functions-example/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/develop-ai-functions-example.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: develop-ai-functions-example
description: Develop examples for AI SDK functions. Use when creating, running, or modifying examples under examples/ai-functions/src to validate provider support, demonstrate features, or create test fixtures.
metadata:
  internal: true
---

## AI Functions Examples

The `examples/ai-functions/` directory contains scripts for validating, testing, and iterating on AI SDK functions across providers.

## Example Categories

Examples are organized by AI SDK function in `examples/ai-functions/src/`:

| Directory          | Purpose                                              |
| ------------------ | ---------------------------------------------------- |
| `generate-text/`   | Non-streaming text generation with `generateText()`  |
| `stream-text/`     | Streaming text generation with `streamText()`        |
| `generate-object/` | Structured output generation with `generateObject()` |
| `stream-object/`   | Streaming structured output with `streamObject()`    |
| `agent/`           | `ToolLoopAgent` examples for agentic workflows       |
| `embed/`           | Single embedding generation with `embed()`           |
| `embed-many/`      | Batch embedding generation with `embedMany()`        |
| `generate-image/`  | Image generation with `generateImage()`              |
| `generate-speech/` | Text-to-speech with `generateSpeech()`               |
| `transcribe/`      | Audio transcription with `transcribe()`              |
| `rerank/`          | Document reranking with `rerank()`                   |
| `middleware/`      | Custom middleware implementations                    |
| `registry/`        | Provider registry setup and usage                    |
| `telemetry/`       | OpenTelemetry integration                            |
| `complex/`         | Multi-component examples (agents, routers)           |
| `lib/`             | Shared utilities (not examples)                      |
| `tools/`           | Reusable tool definitions                            |

## File Naming Convention

Group examples by function and provider. Name the entry example `basic.ts` and use descriptive `kebab-case.ts` names for additional examples:

| Pattern                                             | Example                                                | Description                |
| --------------------------------------------------- | ------------------------------------------------------ | -------------------------- |
| `<function>/<provider>/basic.ts`                    | `generate-text/openai/basic.ts`                        | Basic provider usage       |
| `<function>/<provider>/<feature>.ts`                | `stream-text/openai/tool-call.ts`                      | Specific feature           |
| `<function>/<provider>/<sub-provider>.ts`           | `stream-text/amazon-bedrock/anthropic.ts`              | Provider with sub-provider |
| `<function>/<provider>/<sub-provider>-<feature>.ts` | `stream-text/google/vertex-anthropic-cache-control.ts` | Sub-provider with feature  |

Do not create flat provider files such as `generate-text/openai.ts`.

## Example Structure

All examples use the `run()` wrapper from `lib/run.ts` which:

- Loads environment variables from `.env`
- Provides error handling with detailed API error logging

### Basic Template

```typescript
import { providerName } from '@ai-sdk/provider-name';
import { generateText } from 'ai';
import { run } from '../../lib/run';

run(async () => {
  const result = await generateText({
    model: providerName('model-id'),
    prompt: 'Your prompt here.',
  });

  console.log(result.text);
  console.log('Token usage:', result.usage);
  console.log('Finish reason:', result.finishReason);
});
```

### Streaming Template

```typescript
import { providerName } from '@ai-sdk/provider-name';
import { streamText } from 'ai';
import { printFullStream } from '../../lib/print-full-stream';
import { run } from '../../lib/run';

run(async () => {
  const result = streamText({
    model: providerName('model-id'),
    prompt: 'Your prompt here.',
  });

  await printFullStream({ result });
});
```

### Tool Calling Template

```typescript
import { providerName } from '@ai-sdk/provider-name';
import { generateText, tool } from 'ai';
import { z } from 'zod';
import { run } from '../../lib/run';

run(async () => {
  const result = await generateText({
    model: providerName('model-id'),
    tools: {
      myTool: tool({
        description: 'Tool description',
        inputSchema: z.object({
          param: z.string().describe('Parameter description'),
        }),
        execute: async ({ param }) => {
          return { result: `Processed: ${param}` };
        },
      }),
    },
    prompt: 'Use the tool to...',
  });

  console.log(JSON.stringify(result, null, 2));
});
```

### Structured Output Template

```typescript
import { providerName } from '@ai-sdk/provider-name';
import { generateObject } from 'ai';
import { z } from 'zod';
import { run } from '../../lib/run';

run(async () => {
  const result = await generateObject({
    model: providerName('model-id'),
    schema: z.object({
      name: z.string(),
      items: z.array(z.string()),
    }),
    prompt: 'Generate a...',
  });

  console.log(JSON.stringify(result.object, null, 2));
  console.log('Token usage:', result.usage);
});
```

## Running Examples

From the `examples/ai-functions` directory:

```bash
pnpm tsx src/generate-text/openai/basic.ts
pnpm tsx src/stream-text/openai/tool-call.ts
pnpm tsx src/agent/openai/generate.ts
```

## When to Write Examples

Write examples when:

1. **Adding a new provider**: Create basic examples for each supported API (`generateText`, `streamText`, `generateObject`, etc.)

2. **Implementing a new feature**: Demonstrate the feature with at least one provider example

3. **Reproducing a bug**: Create an example that shows the issue for debugging

4. **Adding provider-specific options**: Show how to use `providerOptions` for provider-specific settings

5. **Creating test fixtures**: Use examples to generate API response fixtures (see `capture-api-response-test-fixture` skill)

## Utility Helpers

The `lib/` directory contains shared utilities:

| File                   | Purpose                                                  |
| ---------------------- | -------------------------------------------------------- |
| `run.ts`               | Error-handling wrapper with `.env` loading               |
| `print.ts`             | Clean object printing (removes undefined values)         |
| `print-full-stream.ts` | Colored streaming output for tool calls, reasoning, text |
| `save-raw-chunks.ts`   | Save streaming chunks for test fixtures                  |
| `present-image.ts`     | Display images in terminal                               |
| `save-audio.ts`        | Save audio files to disk                                 |

### Using print utilities

```typescript
import { print } from '../lib/print';

// Pretty print objects without undefined values
print('Result:', result);
print('Usage:', result.usage, { depth: 2 });
```

### Using printFullStream

```typescript
import { printFullStream } from '../lib/print-full-stream';

const result = streamText({ ... });
await printFullStream({ result }); // Colored output for text, tool calls, reasoning
```

## Reusable Tools

The `tools/` directory contains reusable tool definitions:

```typescript
import { weatherTool } from '../tools/weather-tool';

const result = await generateText({
  model: openai('gpt-4o'),
  tools: { weather: weatherTool },
  prompt: 'What is the weather in San Francisco?',
});
```

## Best Practices

1. **Keep examples focused**: Each example should demonstrate one feature or use case

2. **Use descriptive prompts**: Make it clear what the example is testing

3. **Handle errors gracefully**: The `run()` wrapper handles this automatically

4. **Use realistic model IDs**: Use actual model IDs that work with the provider

5. **Add comments for complex logic**: Explain non-obvious code patterns

6. **Reuse tools when appropriate**: Use `weatherTool` or create new reusable tools in `tools/`

<!-- chapter:end slug=develop-ai-functions-example -->

---

<!-- chapter:begin slug=list-npm-package-content position=7 -->

## 7. list-npm-package-content

- **Source:** https://github.com/vercel/ai/blob/main/skills/list-npm-package-content/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/list-npm-package-content/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/list-npm-package-content.md
- **Licence:** Other — https://github.com/vercel/ai

Bundled files (1), referenced from this skill's directory:
  - `scripts/list-package-files.sh` — https://raw.githubusercontent.com/vercel/ai/main/skills/list-npm-package-content/scripts/list-package-files.sh

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: list-npm-package-content
description: List the contents of an npm package tarball before publishing. Use when the user wants to see what files are included in an npm bundle, verify package contents, or debug npm publish issues.
metadata:
  internal: true
---

# List npm Package Content

This skill lists the exact contents of an npm package tarball - the same files that would be uploaded to npm and downloaded by users.

## Usage

Run the script from the package directory (e.g., `packages/ai`):

```bash
bash scripts/list-package-files.sh
```

The script will build the package, create a tarball, list its contents, and clean up automatically.

## Understanding Package Contents

The files included are determined by:

1. **`files` field in `package.json`** - explicit allowlist of files/directories
2. **`.npmignore`** - files to exclude (if present)
3. **`.gitignore`** - used if no `.npmignore` exists
4. **Always included**: `package.json`, `README`, `LICENSE`, `CHANGELOG`
5. **Always excluded**: `.git`, `node_modules`, `.npmrc`, etc.

<!-- chapter:end slug=list-npm-package-content -->

---

<!-- chapter:begin slug=major-version-mode position=8 -->

## 8. major-version-mode

- **Source:** https://github.com/vercel/ai/blob/main/skills/major-version-mode/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/major-version-mode/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/major-version-mode.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: major-version-mode
description: "Context for working on the next AI SDK major release. Only use when explicitly invoked by the user (e.g. via '/major-version-mode'). Do NOT trigger autonomously based on task content."
metadata:
  internal: true
---

## Context

This task is part of the next AI SDK major release. Breaking changes are acceptable.

## Breaking Change Guidelines

While breaking changes are acceptable, it is still encouraged to minimize unnecessary disruption for 3P consumers of the AI SDK. Providing deprecated aliases and automated migration logic can help ease the transition.

### Renamed/changed exports

If renaming or modifying an exported function or type, provide a deprecated alias as a package-level export where feasible:

```typescript
/** @deprecated Use `newFunctionName` instead. */
export { newFunctionName as oldFunctionName } from './new-module';
```

Only do this if it doesn't introduce meaningful technical debt. If it does, skip the alias — but **check with the user first** before making a clean break.

### Modified message types (e.g. in `@ai-sdk/provider-utils`)

If modifying model message shapes (e.g. content part types in `packages/provider-utils/src/types/content-part.ts`):

1. **Deprecate in `@ai-sdk/provider-utils`** rather than removing immediately, if feasible. Mark deprecated types/members with a `@deprecated` JSDoc comment and a `TODO` note to remove in the following major version.
2. **Keep deprecated equivalents in `packages/ai/src/prompt/content-part.ts`** — this file is the consumer-facing layer and should retain the old shapes in the Zod schemas so existing consumer code continues to compile with a deprecation warning. Include a similar note about deprecation and removal in the following major version.
3. If clean deprecation isn't feasible without meaningful technical debt, a hard removal may be preferred — but **check with the user first**.

### Provider spec changes (`@ai-sdk/provider`)

The `provider` package defines the spec that provider implementers code against. It should generally not be modified outside of major versions, so keeping the spec clean and consistent is critical.

Breaking changes _without_ maintaining temporary backward compatibility measures are more acceptable here than elsewhere, because the audience is smaller — far fewer developers implement their own providers than build features on top of the AI SDK.

Rules:

- **Only modify the latest spec version.** Older versioned spec interfaces must remain completely untouched.
- Deprecated aliases are not required — a clean break is preferred to preserve spec clarity.
- The current spec version is **not** the same as the current AI SDK major version number. If it's unclear which spec version to operate on, **ask the user before proceeding**.

## Documentation

After implementing changes, update relevant documentation in `content/docs/`.

If the change requires consumers to update their code or migrate stored data, add a section to the latest migration guide:

- Find the migration guide with the highest version number in `content/docs/08-migration-guides/`
- Add a concise section explaining what changed and how to migrate

<!-- chapter:end slug=major-version-mode -->

---

<!-- chapter:begin slug=migrate-ai-sdk-v6-to-v7 position=9 -->

## 9. migrate-ai-sdk-v6-to-v7

- **Source:** https://github.com/vercel/ai/blob/main/skills/migrate-ai-sdk-v6-to-v7/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/migrate-ai-sdk-v6-to-v7/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/migrate-ai-sdk-v6-to-v7.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: migrate-ai-sdk-v6-to-v7
description: Migrate applications from AI SDK 6.x to AI SDK 7.0. Use when upgrading Vercel AI SDK packages, fixing v7 migration errors, or when the user mentions AI SDK v6, v7, upgrade, migration, breaking changes, system to instructions, fullStream, telemetry, tool context, or finalStep.
---

## AI SDK 6 to 7 Migration

Use `content/docs/08-migration-guides/23-migration-guide-7-0.mdx` from the AI SDK repo as the source of truth. This skill is the working checklist; read the guide for exact examples or when behavior is unclear.

## Migration Workflow

1. Ensure the user has a clean backup or committed baseline before editing.
2. Inspect `package.json` and lockfiles to identify installed `ai`, `@ai-sdk/*`, provider, UI, MCP, and telemetry packages.
3. Upgrade AI SDK packages to latest versions, and add `@ai-sdk/otel` only if the project uses OpenTelemetry spans.
4. Update runtime and module assumptions: Node.js must be `>=22`, and AI SDK packages are ESM-only. Replace `require()` imports with ESM imports and add `"type": "module"` or use `.mjs` where needed.
5. Search for the v6 patterns below, migrate only the code that exists, then run typecheck and targeted tests.

Prefer behavior-preserving changes. When v7 changes semantics, decide whether the app wants the new all-steps behavior or the previous final-step-only behavior.

## Core API Changes

- `experimental_customProvider` -> `customProvider`.
- `experimental_generateImage` -> `generateImage`; `Experimental_GenerateImageResult` -> `GenerateImageResult`.
- `experimental_transcribe` -> `transcribe`; `Experimental_TranscriptionResult` -> `TranscriptionResult`.
- `experimental_generateSpeech` -> `generateSpeech`; `Experimental_SpeechResult` -> `SpeechResult`.
- `experimental_output` option/result -> `output` option/result.
- `CallSettings` -> `LanguageModelCallOptions & Omit<RequestOptions, 'timeout'>`; `prepareCallSettings` -> `prepareLanguageModelCallOptions`.
- `stepCountIs` -> `isStepCount`.

## Prompts and Steps

- Rename top-level `system` to `instructions` for `generateText`, `streamText`, `generateObject`, `streamObject`, and `streamUI`.
- Move `{ role: 'system' }` messages from `prompt` or `messages` into top-level `instructions`. Only use `allowSystemInMessages: true` for trusted persisted messages.
- Rename `experimental_prepareStep` to `prepareStep`.
- In `prepareStep`, rename returned `system` to `instructions`.
- In `experimental_repairToolCall`, use `{ instructions }` instead of `{ system }`.
- Audit `prepareStep` behavior: returned `instructions` and `messages` now carry forward into later steps. If code depended on one-step-only overrides, rebuild from `initialInstructions`, `initialMessages`, and `responseMessages` explicitly.

## Lifecycle Callbacks

- `experimental_onStart` -> `onStart`.
- `experimental_onStepStart` -> `onStepStart`.
- `onFinish` -> `onEnd`.
- `onStepFinish` -> `onStepEnd`.
- For `embed`, `embedMany`, and `rerank`, `experimental_onFinish` -> `onEnd`.
- Callback event fields use `instructions` instead of `system`.

## Usage, Telemetry, and Include Options

- `usage.cachedInputTokens` -> `usage.inputTokenDetails.cacheReadTokens`.
- `usage.reasoningTokens` -> `usage.outputTokenDetails.reasoningTokens`.
- OpenTelemetry moved out of `ai`; install `@ai-sdk/otel` and call `registerTelemetry(new OpenTelemetry(...))` at app startup.
- Telemetry is enabled by default once an integration is registered. Remove redundant `isEnabled: true`; use `isEnabled: false` to opt out per call.
- Move `experimental_telemetry.tracer` into the `OpenTelemetry` constructor.
- `experimental_telemetry` -> `telemetry`.
- Telemetry integration callbacks: `onRerankFinish` -> `onRerankEnd`, `onEmbedFinish` -> `onEmbedEnd`. Update tracing-channel subscribers for the same event type names.
- `experimental_include` -> `include`.
- `includeRawChunks` -> `include.rawChunks`.
- Request and response bodies are excluded by default. If code reads `request.body` or `response.body`, opt in with `include.requestBody` and, for `generateText`, `include.responseBody`.

## Streaming, Messages, and Tools

- `StreamTextResult.fullStream` -> `stream`.
- `streamText` `onChunk` now receives all stream parts, including lifecycle, boundary, finish, abort, and error parts. Guard by `chunk.type` before assuming text/tool/raw content.
- `step.response.messages` is no longer accumulated across previous steps. Use `result.responseMessages` for the full response message history, or flatten `result.steps`.
- Tool execution callbacks: `experimental_onToolCallStart` -> `onToolExecutionStart`, `experimental_onToolCallFinish` -> `onToolExecutionEnd`.
- Tool callback `experimental_context` -> `context`.
- Split shared runtime data from tool-specific data: use top-level `runtimeContext` for orchestration state, declare per-tool `contextSchema`, and pass per-tool values through `toolsContext`.
- Move `needsApproval` from `tool()` / `dynamicTool()` into per-call or agent `toolApproval`.
- `experimental_activeTools` -> `activeTools`.
- `ToolCallOptions` -> `ToolExecutionOptions`.
- `isToolOrDynamicToolUIPart` -> `isToolUIPart`.

## Content Parts and Reasoning

- Tool result `{ type: 'media' }` is removed; use `{ type: 'file-data' }`.
- Migrate `toModelOutput` `image-*`, `file-*`, `file-id`, and `image-file-id` variants to canonical `{ type: 'file', mediaType, data: { type: 'data' | 'url' | 'reference', ... } }`.
- User message `{ type: 'image', image, mediaType? }` is deprecated; use `{ type: 'file', mediaType: 'image' | 'image/*', data }`.
- Add support for the new `reasoning-file` content type in exhaustive switches, renderers, serializers, and validators.
- When adopting top-level `reasoning`, remove overlapping provider-specific reasoning settings from `providerOptions` unless provider-specific settings intentionally take precedence.

## Multi-Step Result Shape

- `result.usage` now includes all steps; `result.totalUsage` is deprecated. Use `result.finalStep.usage` for final-step-only usage.
- Top-level `content`, `toolCalls`, `staticToolCalls`, `dynamicToolCalls`, `toolResults`, `staticToolResults`, `dynamicToolResults`, `files`, `sources`, and `warnings` now include all steps. Use `finalStep` for previous final-step-only behavior.
- Top-level `reasoning`, `reasoningText`, `request`, `response`, and `providerMetadata` are deprecated for final-step data. Use `result.finalStep.*`; for `streamText`, await `result.finalStep`.
- Apply the same result-shape rules to `onEnd` events.

## Stream Response Helpers

The `streamText` result helper methods are deprecated. Replace result methods with top-level stateless helpers:

- `result.toUIMessageStream(...)` -> `toUIMessageStream({ stream: result.stream, ... })`.
- `result.toUIMessageStreamResponse(...)` -> `toUIMessageStream(...)` plus `createUIMessageStreamResponse({ stream })`.
- `result.pipeUIMessageStreamToResponse(response, ...)` -> `toUIMessageStream(...)` plus `pipeUIMessageStreamToResponse({ response, stream })`.
- `result.toTextStreamResponse()` -> `toTextStream({ stream: result.stream })` plus `createTextStreamResponse({ stream })`.
- `result.pipeTextStreamToResponse(response)` -> `toTextStream({ stream: result.stream })` plus `pipeTextStreamToResponse({ response, stream })`.

## Package-Specific Checks

- MCP: `MCPTransportConfig.redirect` now defaults to `'error'`. Only set `redirect: 'follow'` for trusted MCP servers that rely on redirects.
- Vue: `@ai-sdk/vue` `Chat` class is deprecated. Prefer `useChat`, including getter/ref init for reactive chat inputs.
- Anthropic and `@ai-sdk/google-vertex/anthropic`: `providerMetadata.anthropic.cacheCreationInputTokens` was removed. Use `usage.inputTokenDetails.cacheWriteTokens`; raw Anthropic usage remains at `finalStep.providerMetadata?.anthropic?.usage`.
- Google: rename `GoogleGenerativeAI*` types, classes, and functions to `Google*`, e.g. `createGoogleGenerativeAI` -> `createGoogle`. The `google` entry point is unchanged.

## Validation

Run the project typecheck after edits, then the smallest relevant test suite. Also smoke-test streaming, chat UI, tool execution, telemetry, and multi-step flows if the migration touched them. If type errors remain, search the migration guide for the exact removed or renamed symbol before inventing a workaround.

<!-- chapter:end slug=migrate-ai-sdk-v6-to-v7 -->

---

<!-- chapter:begin slug=update-harness-dependencies position=10 -->

## 10. update-harness-dependencies

- **Source:** https://github.com/vercel/ai/blob/main/skills/update-harness-dependencies/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/update-harness-dependencies/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/update-harness-dependencies.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: update-harness-dependencies
description: Update the primary SDK dependencies of harness packages. Use when asked to update the harness SDKs or harness adapter dependencies.
metadata:
  internal: true
---

## Update the harness packages

The harness adapters are all the `packages/harness-*` packages. They each rely on one or more third-party packages for the respective harness's primary SDK. It is crucial to keep those dependencies up to date.

Below you find the instructions on how to update those packages to their latest versions, while adhering to the minimum release age defined in `pnpm-workspace.yaml`.

### Update the harness dependency packages

Run the following commands to update each harness's primary SDK packages.

- For bridge harnesses (e.g. Claude Code), this will update the packages in `devDependencies`, while the actual package versions used as `dependencies` are only relevant to the harness's bridge itself.
- For non-bridge harnesses (e.g. Pi), this will update the packages in `dependencies`.

Run these commands exactly as below:

```bash
# ACP
pnpm --filter harness-acp update @agentclientprotocol/sdk @modelcontextprotocol/sdk --latest --lockfile-only
# Claude Code
pnpm --filter harness-claude-code update @anthropic-ai/claude-agent-sdk @modelcontextprotocol/sdk --latest --lockfile-only
# Cline
pnpm --filter harness-cline update @cline/agents --latest --lockfile-only
# Codex
pnpm --filter harness-codex update @openai/codex-sdk --latest --lockfile-only
# Deep Agents
pnpm --filter harness-deepagents update @langchain/core @langchain/langgraph deepagents langchain langsmith --latest --lockfile-only
# GitHub Copilot
pnpm --filter harness-github-copilot update @github/copilot --latest --lockfile-only
# Grok Build
pnpm --filter harness-grok-build update @xai-official/grok --latest --lockfile-only
# OpenCode
pnpm --filter harness-opencode update @opencode-ai/sdk --latest --lockfile-only
# Pi
pnpm --filter harness-pi update @earendil-works/pi-coding-agent --latest --lockfile-only
```

For the bridge dependencies of bridge harnesses, you must additionally run the following commands. It is important to specify the `config.minimumReleaseAge` flag in accordance with what `pnpm-workspace.yaml` defines, because for these commands the `--ignore-workspace` flag is needed.

Run these commands exactly as below:

```bash
# ACP
pnpm --dir packages/harness-acp/src/v1/bridge update @agentclientprotocol/sdk @modelcontextprotocol/sdk --latest --ignore-workspace --config.minimumReleaseAge=4320
# Claude Code
pnpm --dir packages/harness-claude-code/src/bridge update @anthropic-ai/claude-agent-sdk @anthropic-ai/claude-code @modelcontextprotocol/sdk --latest --ignore-workspace --config.minimumReleaseAge=4320
# Codex
pnpm --dir packages/harness-codex/src/bridge update @openai/codex-sdk --latest --ignore-workspace --config.minimumReleaseAge=4320
# Deep Agents
pnpm --dir packages/harness-deepagents/src/bridge update @langchain/anthropic @langchain/core @langchain/langgraph deepagents langchain langsmith --latest --ignore-workspace --config.minimumReleaseAge=4320
# GitHub Copilot
pnpm --dir packages/harness-github-copilot/src/bridge update @github/copilot --latest --ignore-workspace --config.minimumReleaseAge=4320
# Grok Build
pnpm --dir packages/harness-grok-build/src/bridge update @agentclientprotocol/sdk @modelcontextprotocol/sdk @xai-official/grok --latest --ignore-workspace --config.minimumReleaseAge=4320
# OpenCode
pnpm --dir packages/harness-opencode/src/bridge update @opencode-ai/sdk opencode-ai --latest --ignore-workspace --config.minimumReleaseAge=4320
```

For bridge CLI packages that require install scripts, also update the exact
version in the bridge's `pnpm-workspace.yaml` `allowBuilds` entry to match the
new version in its `package.json`:

- `packages/harness-claude-code/src/bridge/pnpm-workspace.yaml`
- `packages/harness-github-copilot/src/bridge/pnpm-workspace.yaml`
- `packages/harness-grok-build/src/bridge/pnpm-workspace.yaml`
- `packages/harness-opencode/src/bridge/pnpm-workspace.yaml`

The following harness adapters use an unversioned installer script instead of an NPM package for their SDK / CLI and therefore can be ignored:

- `packages/harness-cursor`
- `packages/harness-fx`

#### Example dependencies

Check the `package.json` files in `examples/harness-e2e-next` and `examples/harness-e2e-tui` for any of the above SDKs they depend on. Those dependencies need to be updated to match the exact version used in the packages as well.

### Verification

Run the verification script to ensure all relevant dependency versions are aligned:

```bash
./tools/verify-harness-adapter-deps.mjs
```

If this script shows errors, you must address them, then rerun the verification script until it passes.

<!-- chapter:end slug=update-harness-dependencies -->

---

<!-- chapter:begin slug=update-provider-models position=11 -->

## 11. update-provider-models

- **Source:** https://github.com/vercel/ai/blob/main/skills/update-provider-models/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/update-provider-models/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/update-provider-models.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: update-provider-models
description: Add new or remove obsolete model IDs for existing AI SDK providers. Use when adding a model to a provider, removing an obsolete model, or processing a list of model changes from an issue. Triggers on "add model", "remove model", "new model ID", "obsolete model", "update model IDs".
metadata:
  internal: true
---

## Update Provider Model IDs

This skill covers adding new model IDs and removing obsolete ones across the AI SDK codebase. Each workflow uses search to discover all locations that need changes.

You may be asked to add or remove a single model ID, or to process a list of multiple model ID changes from an issue. For each model ID, follow the appropriate workflow:

- If a new model ID is being added, follow the `<adding-new-model>` workflow.
- If an obsolete model ID is being removed, follow the `<removing-obsolete-model>` workflow.

## Critical Rules

- **Exact matching**: Model IDs are often substrings of others (e.g. `grok-3` vs `grok-3-mini`). Always verify each search result is the exact model, not a substring match.
- **Respect sort order**: When inserting into any list (type unions, table rows, arrays), observe the existing order and place the new entry accordingly.
- **File naming for examples**: Use kebab-case with hyphens replacing dots (e.g. `gpt-5.4-codex` → `gpt-5-4-codex.ts`).
- **Sequential processing**: When handling multiple models, complete the full workflow for one model before starting the next.
- **Affected providers**: New model IDs always need to be added to the primary provider package and the AI Gateway. There may be additional affected packages (e.g. Bedrock, Vertex, OpenAI-compatible) if the model is available there or referenced in tests/docs.
- **Never make unrelated changes**: Only update model IDs and related references. Don't modify any other code, text, or formatting in the files you edit.
- **Never modify `CHANGELOG.md` files of `packages/codemod`**: Changelog files are historical records, codemods are migration scripts. Do not edit either when updating model IDs.

<adding-new-model>

## Workflow for Adding a New Model ID

### Step 1: Identify Scope

Determine:

- Provider name (e.g. `anthropic`, `openai`, `google`, `xai`)
- Exact model ID string (e.g. `claude-haiku-4-5-20260218`, `gemini-3.1-pro`, `gpt-5.4-codex`)
- Model type: chat, embedding, image, etc.
- Whether this is a new version of an existing older model, or even the stable version of an existing preview or experimental model
- Whether any provider packages other than the primary one and the AI Gateway need to be updated (e.g. Bedrock, Vertex, OpenAI-compatible)
  - If a similar model ID is listed in one of those other provider packages, the new model ID should likely be added there as well. Check the provider's documentation for clues on availability.

### Step 2: Find Where Similar Models Are Referenced

Search for a similar existing model from the same provider (e.g. a lower version, or the preview version being replaced) across `packages/`, `content/`, and `examples/`. This reveals all locations that need updates.

```bash
# Search quoted occurrences to find all reference locations
grep -r "'<similar-model-id>'" packages/ content/ examples/ --include='*.ts' --include='*.mdx' --include='*.md'
grep -r '"<similar-model-id>"' packages/ content/ examples/ --include='*.ts' --include='*.mdx' --include='*.md'
```

### Step 3: Update Type Definitions

For each relevant `packages` file found, add the new model ID to the type union (and const arrays if present), respecting existing sort order.

Examples of common locations for model ID type definitions:

- `packages/<provider>/src/*-options.ts` — the primary provider package
- `packages/gateway/src/gateway-language-model-settings.ts` — the AI Gateway package
- `packages/amazon-bedrock/src/**/*-options.ts` — if the model is available on Amazon Bedrock
- `packages/google-vertex/src/*-options.ts` — if the model is available on Google Vertex

This is NOT an exhaustive list — the search in Step 2 may reveal other files with model ID references that need updating as well.

**Never** replace a model ID here. Only add the new model ID. Replacing references to an older or preview model ID is only relevant in documentation and examples.

Example type union addition:

```typescript
export type SomeModelId =
  | 'existing-model-a'
  | 'new-model-id' // ← add in sorted position
  | 'existing-model-b'
  | (string & {});
```

Example const array addition:

```typescript
export const reasoningModelIds = [
  'existing-model-a',
  'new-model-id', // ← add in sorted position
  'existing-model-b',
] as const;
```

### Step 4: Update Documentation

For each `.mdx` file found in `content/`, add or update entries:

- **Capability tables**: Add a row for the new model in the correct position with the appropriate capability checks (`<Check />` or `<Cross />`).
- **Inline code examples**: If replacing a preview/older model as the recommended one, update code snippets like `const model = provider('old-model')` to use the new model.
- **"Latest" descriptions**: Update text like "Latest model with enhanced reasoning" to reference the new model.

If you found the similar model ID referenced in a specific package's `README.md` file, update the model ID in those code examples as well.

### Step 5: Create or Update Examples

**If the new model replaces an older one**: Find existing examples using the old model and update them to use the new model ID.

**If purely new with no predecessor**: Create new example files, one file per top-level function that is relevant for the new model (e.g. `generateText`, `streamText`, `generateImage`). For example, if it's a new language model, you would create files like:

- `examples/ai-functions/src/generate-text/<provider>/<model-kebab>.ts`
- `examples/ai-functions/src/stream-text/<provider>/<model-kebab>.ts`

Or if it's a new image model, you might create:

- `examples/ai-functions/src/generate-image/<provider>/<model-kebab>.ts`

Look for existing example files for the provider in the same folder, to use as a reference for your new example files.

In your search for the similar model ID, you may have found examples in which the model ID is part of a list of models (e.g. in an array of options for a test or example). In that case, add the new model ID to the same list in the example file, respecting sort order.

### Step 6: Update Tests

Where reasonable, replace references to the older or preview model with the new model in test files, especially if the new model is now the recommended one.

**Exception:** Do not replace model IDs in fixtures or snapshots, or tests that use those fixtures or snapshots, as those are meant to be stable and reflect actual API responses captured.

### Step 7: Run Tests

```bash
pnpm --filter @ai-sdk/<provider> test
pnpm --filter @ai-sdk/gateway test
```

Also run tests for any other affected packages:

```bash
pnpm --filter @ai-sdk/openai-compatible test  # if snapshots/tests were updated
pnpm --filter @ai-sdk/amazon-bedrock test     # if Bedrock options were updated
pnpm --filter @ai-sdk/google-vertex test      # if Vertex options were updated
```

</adding-new-model>

<removing-obsolete-model>

## Workflow for Removing an Obsolete Model ID

### Step 1: Identify Successor

Determine which model replaces the removed one in examples, tests, and docs. This is relevant for updating references.

If there is no obvious successor, you should leave old references in place in examples, docs, and tests.

### Step 2: Find All Exact Occurrences

Search for the model ID with quotes to avoid substring false positives:

```bash
# Single-quoted (TypeScript source, type unions)
grep -r "'<model-id>'" packages/ content/ examples/ --include='*.ts' --include='*.mdx' --include='*.md' --include='*.snap'

# Double-quoted (JSON in snapshots, test fixtures with embedded JSON, docs)
grep -r '"<model-id>"' packages/ content/ examples/ --include='*.ts' --include='*.mdx' --include='*.md' --include='*.snap'
```

Manually verify each result is the exact model and not a substring match (e.g. searching `'grok-3'` must not match `'grok-3-mini'`).

### Step 3: Remove from Type Definitions

Remove the `| 'model-id'` line from union types and entries from const arrays in `*-options.ts` files.

### Step 4: Update Documentation

- Remove rows from capability tables in `.mdx` files.
- Replace inline code examples and descriptions referencing the removed model with the successor.
- Update community provider docs in `content/providers/05-community-providers/`.

### Step 5: Update Examples

- Replace the removed model with the successor in example files that use it directly.
- Remove from model lists in examples.
- Delete dedicated example files only if no unique feature is demonstrated beyond the model itself (e.g. if the file is named after the model).

### Step 6: Update Tests and Snapshots

- Replace the model ID with the successor in `*.test.ts` files.
- Replace the model ID in `__snapshots__/*.snap` files — model IDs appear in serialized JSON strings.
- Replace in embedded JSON strings within test fixtures (e.g. `"model":"old-model"` → `"model":"new-model"`).
- Update `examples/ai-functions/src/e2e/*.test.ts` — remove from model arrays or replace.
- Update `packages/<provider>/README.md` if it contains code examples.

### Step 7: Run Tests

```bash
pnpm --filter @ai-sdk/<provider> test
```

Also run tests for any other affected packages (same as Workflow A Step 7).

</removing-obsolete-model>

<!-- chapter:end slug=update-provider-models -->

---

<!-- chapter:begin slug=use-ai-sdk position=12 -->

## 12. ai-sdk

- **Source:** https://github.com/vercel/ai/blob/main/skills/use-ai-sdk/SKILL.md
- **Raw:** https://raw.githubusercontent.com/vercel/ai/main/skills/use-ai-sdk/SKILL.md
- **Markdown:** https://skillsdocs.com/vercel/ai/use-ai-sdk.md
- **Licence:** Other — https://github.com/vercel/ai

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: ai-sdk
description: 'Answer questions about the AI SDK and help build AI-powered features. Use when developers: (1) Ask about AI SDK functions like generateText, streamText, ToolLoopAgent, embed, or tools, (2) Want to build AI agents, chatbots, RAG systems, or text generation features, (3) Have questions about AI providers (OpenAI, Anthropic, Google, etc.), streaming, tool calling, structured output, or embeddings, (4) Use React hooks like useChat or useCompletion. Triggers on: "AI SDK", "Vercel AI SDK", "generateText", "streamText", "add AI to my app", "build an agent", "tool calling", "structured output", "useChat".'
---

## What the AI SDK Is

The AI SDK by Vercel (the `ai` package on npm) is a TypeScript toolkit for building AI applications. It provides a unified API across model providers for text generation, structured output, tool calling, agents, embeddings, and framework UI integrations.

- Repository: https://github.com/vercel/ai
- Documentation: https://ai-sdk.dev/docs

## Critical: Do Not Trust Your Own Memory

Whatever you remember about the AI SDK is likely outdated. The SDK changes frequently across versions - APIs are renamed, removed, and added. Your training data almost certainly contains obsolete APIs, deprecated patterns, and model IDs that no longer exist. UI hooks like `useChat` are among the most frequently changed APIs, so be especially careful with client code.

**Never write AI SDK code from memory.** Always verify every API, option, and pattern against the documentation and source code for the version that is actually installed in the project.

## Use the Bundled, Version-Matched Docs

The `ai` package ships its full documentation and source code inside `node_modules`. These always match the installed version, so trust them over anything you remember.

1. Ensure `ai` is installed. Check `node_modules/ai/` or locate the workspace package in a monorepo that depends on `ai` (e.g. `apps/<name>/node_modules/ai/`). If `ai` is not installed anywhere in the project, install **only** the `ai` package into the target package using the project's package manager (e.g. `pnpm add ai --filter <pkg>` or `npm install ai`). Install provider packages (e.g. `@ai-sdk/openai`) and framework packages (e.g. `@ai-sdk/react`) later, when the task requires them.
2. Read and grep the bundled docs at `node_modules/ai/docs/` (or `<package>/node_modules/ai/docs/`) and the source at `node_modules/ai/src/`.
3. Provider and framework packages bundle their own docs at `node_modules/@ai-sdk/<name>/docs/` (or `<package>/node_modules/@ai-sdk/<name>/docs/`).
4. If something isn't in the bundled docs, search https://ai-sdk.dev/docs. You can append `.md` to any docs page URL to get its markdown, and search via `https://ai-sdk.dev/api/search-docs?q=your_query`.
5. If you cannot find support for an answer in the docs or source, say so explicitly — do not guess.

## AI Gateway: The Fastest Way to Start

The Vercel AI Gateway is the fastest way to get started with the AI SDK. It provides access to models from OpenAI, Anthropic, Google, and other providers through a single API, without installing provider packages or managing multiple API keys.

To set it up:

1. Authenticate with OIDC (for Vercel deployments) or get an AI Gateway API key.
2. Provide it to your app via the `AI_GATEWAY_API_KEY` environment variable.
3. Reference models with `provider/model` strings.

For exact setup, authentication, and usage, read the bundled guide and the AI Gateway docs.

### Choosing a Model

Never use model IDs from memory — models are released and retired frequently. Fetch the current list before writing code that references a model. Do not truncate the list (e.g. with `head`) so you can find the newest models:

```bash
# All available models
curl -s https://ai-gateway.vercel.sh/v1/models | jq -r '.data[].id'

# Filter by provider (e.g. anthropic, openai, google)
curl -s https://ai-gateway.vercel.sh/v1/models | jq -r '[.data[] | select(.id | startswith("anthropic/")) | .id] | reverse | .[]'
```

When multiple versions of a model exist, prefer the one with the highest version number.

## Building and Consuming Agents

Use the SDK's built-in agent abstraction (such as `ToolLoopAgent`) rather than hand-rolling tool-calling loops. For end-to-end type safety, infer the UI message type from your agent definition when consuming it on the client (e.g. with `useChat`). Consuming an agent is framework-specific: check `package.json` to detect the stack, then follow the matching quickstart.

Look up the current agent, tool, and type-safety APIs in the bundled docs (`node_modules/ai/docs/`, especially the agents section) or at https://ai-sdk.dev/docs.

## DevTools

AI SDK DevTools captures your AI SDK calls - requests, responses, tool calls, token usage, and multi-step runs - so you can inspect exactly what your agents do. Use it while developing to debug generations. It is a separate package and is intended for local development only.

For setup instructions, read the bundled DevTools documentation.

## Keep the SDK Current

Outdated installs are the most common source of errors. Compare the installed version against the latest:

- **Installed:** the `version` field in `node_modules/ai/package.json`.
- **Latest:** run `npm view ai version`.

If the installed version is a major version (or more) behind the latest, tell the user they are on an old release, and recommend upgrading before continuing. Migration guides are at https://ai-sdk.dev/docs/migration-guides.

## After Making Changes

Run the project's type checker. Be minimal — only set options that differ from the defaults, checking docs or source for the defaults rather than over-specifying. Most type errors come from remembered, now-changed APIs; re-check the current docs and source when they occur.

<!-- chapter:end slug=use-ai-sdk -->
