Skip to content
Night Owls.dev
Jump to a page

@nightowlsdev/provider-anthropic

Adapter/Model

Anthropic Claude model provider for Night Owls swarms, backed by the native AI SDK.

What it does

Exposes `anthropicModels(opts?)`, a model factory you pass to `defineSwarm({ modelFactory })` in `@nightowlsdev/core`. It wraps `@ai-sdk/anthropic`'s `createAnthropic`, mapping a model id (e.g. `claude-sonnet-4-6`) to an AI SDK `LanguageModelV3`. By default it reads `ANTHROPIC_API_KEY` from the environment; pass `{ apiKey }` to override. Also ships a declarative `nightOwlsPlugin` manifest the CLI uses to scaffold env/config. Model providers compose: install one `provider-*` package per provider you use, then route per agent with `createModelFactory` from `@nightowlsdev/core`.

Install

pnpm add @nightowlsdev/provider-anthropic

Key exports

  • anthropicModels
  • nightOwlsPlugin

Usage

provider-anthropic.ts
import { defineSwarm } from "@nightowlsdev/core";
import { anthropicModels } from "@nightowlsdev/provider-anthropic";

// Reads ANTHROPIC_API_KEY from the env by default.
const swarm = defineSwarm({ agents, modelFactory: anthropicModels() });

What it provides

A one-line model provider for Night Owls: anthropicModels() returns a modelFactory you hand to defineSwarm, mapping a Claude model id (claude-sonnet-4-6, claude-haiku-4-5, …) to an AI SDK LanguageModelV3 backed by the native @ai-sdk/anthropic. It reads ANTHROPIC_API_KEY from the environment (pass { apiKey } to override), and also ships anthropicProvider() — the adapter-object form for the model registry, carrying a small hand-curated, priced catalog (Sonnet / Opus / Haiku 4.x with prompt-cache multipliers). It is one of six interchangeable provider-* packages: they compose, so you install one per vendor you use and route per agent with createModelFactory from core.

When to use it

  • You want Claude directly — native SDK, no gateway hop — for the orchestrator or any step that needs strong tool-calling and long-context reasoning.
  • You want prompt-caching accounted in your cost caps: the catalog carries the cache-read and cache-write multipliers, not just the base rates.
  • You have a direct billing relationship with Anthropic and want provider-qualified allow-list entries (anthropic:*) priced from the shipped snapshot.

When not to

  • You want one key to reach many vendors — use provider-vercel-gateway (one key, live pricing) or provider-openrouter (one key, hundreds of models).
  • You want the cheapest or fastest inference for high-volume simple tasks — pair provider-groq (hosted, fast) or provider-ollama (local, free) for those agents.
  • You need a runtime model listing in the picker — the Anthropic SDK exposes none, so this adapter is catalog-only (canList is honestly false).

Alternatives

  • provider-vercel-gatewayYou want Claude AND every other vendor behind a single key, with a live model listing and per-model pricing feeding the picker and cost caps.
  • provider-openrouterYou want Claude alongside hundreds of other models via provider/model ids and one key, and can live with an unpriced catalog.
  • provider-groq / provider-ollamaThe step is high-volume and cost- or latency-bound; route those agents to fast hosted (Groq) or free local (Ollama) open models and keep Claude for the hard step.

Strengths

  • Native @ai-sdk/anthropic — no extra routing hop, and full Claude features (vision, tool calling, prompt caching) come through.
  • An honest priced catalog including the cache read/write multipliers, so anthropic:* expansion, the picker, and cost.maxCostUsd all see real numbers.
  • Engine-wall clean: exactly one dependency, zero @mastra and zero @nightowlsdev/core — safe to tree-shake and compose.

Limits & trade-offs

  • No runtime model listing: the SDK has none, so the small hand-curated catalog is the entire picker input for this provider.
  • claude-sonnet-4-6 ships UNPRICED in the catalog (its rate post-dates the snapshot and the catalog refuses to guess), so anthropic:* drops it unless you supply a price or pass allowUnpriced.
  • Prices are a snapshot (transcribed 2026-07-27), not a live feed — override via cost.prices / cost.priceFeed if you bill on them.
  • A single vendor: for a real cost/latency spread across tasks you must compose other provider-* packages with createModelFactory.

How it works

anthropicModels(opts) calls createAnthropic and returns a (modelId) => provider(modelId) factory — the AI SDK LanguageModelV3 the engine drives. defineSwarm({ modelFactory }) uses that one factory for every agent; to send different agents to different vendors, wrap several factories in createModelFactory with a resolve() that maps an agent slug to a { provider, modelId } route. anthropicProvider() is the adapter-object form consumed by createModelProviderRegistry: the same .model factory plus a static catalog and, deliberately, no models() (the Anthropic SDK exposes no listing). The catalog's USD-per-million-token prices — including cache multipliers — feed the cost governor and the model picker.

Examples

Wire Claude into a swarm

One factory for every agent; the key comes from ANTHROPIC_API_KEY.

provider-anthropic-example-1.ts
import { defineSwarm } from "@nightowlsdev/core";
import { anthropicModels } from "@nightowlsdev/provider-anthropic";

export default defineSwarm({
  modelFactory: anthropicModels(),         // reads ANTHROPIC_API_KEY
  models: { allow: ["claude-sonnet-4-6"] },
  agents,
});

Claude for the orchestrator, a cheaper model for the rest

createModelFactory composes several provider factories and routes per agent slug; allow gates the routed models.

provider-anthropic-example-2.ts
import { createModelFactory } from "@nightowlsdev/core";
import { anthropicModels } from "@nightowlsdev/provider-anthropic";
import { groqModels } from "@nightowlsdev/provider-groq";

const modelFactory = createModelFactory({
  factories: { anthropic: anthropicModels(), groq: groqModels() },
  resolve: (agentSlug) =>
    agentSlug === "orchestrator"
      ? { provider: "anthropic", modelId: "claude-sonnet-4-6" }
      : { provider: "groq", modelId: "llama-3.3-70b-versatile" },
  allow: ["anthropic/claude-sonnet-4-6", "groq/llama-3.3-70b-versatile"],
});

Register the adapter for a model picker

anthropicProvider() contributes its priced catalog; providers compose in the registry.

provider-anthropic-example-3.ts
import { createModelProviderRegistry } from "@nightowlsdev/core";
import { anthropicProvider } from "@nightowlsdev/provider-anthropic";
import { openaiProvider } from "@nightowlsdev/provider-openai";

const registry = createModelProviderRegistry({
  providers: [anthropicProvider(), openaiProvider()],
});

Doing the parts it doesn't support

  • Listing available Claude models at runtimeThe Anthropic SDK has no listing endpoint, so this adapter is catalog-only. Either treat the shipped catalog as the source, or front Claude through provider-vercel-gateway, whose adapter has a genuine live models().
  • Pricing a new / unpriced Claude modelSupply the rate via cost.prices or resolveModelAllowList({ prices }); an unpriced model prices at $0 and silently disables cost.maxCostUsd, which is why anthropic:* drops unpriced rows unless allowUnpriced is set.
  • Mixing Claude with other vendors per agentWrap anthropicModels() and the other provider factories in createModelFactory with a resolve() that maps each agent slug to a { provider, modelId } route, and list the routed ids in allow.

Related

  • coredefineSwarm / modelFactory consume the factory, and createModelFactory composes it with other providers.
  • provider-vercel-gatewayReach Claude plus every other vendor through one key, with a live listing and per-model pricing.
  • provider-openrouterReach Claude among hundreds of models via provider/model ids and a single key.
  • model-providersThe guide to registering providers, provider-qualified allow-lists, and per-provider pricing.
  • cliowl install provider-anthropic scaffolds the env vars and the modelFactory config marker for you.