@agentskit/adapters
Profile: major-package

Connect to any LLM provider — and swap between them — without touching your app code.

Tags: ai · agents · llm · agentskit · openai · anthropic · claude · gemini · chatgpt · ollama · embeddings · providers
Verified proof
How this fits the ecosystem
@agentskit/adapters is the provider layer: swap OpenAI, Anthropic, Gemini, Ollama, local models, and embedding providers without rewriting your agent.
- AgentsKit: compose it with the other packages in this repo to build agents from small, swappable parts.
- Registry: look for ready agents and templates that already use this layer at registry.agentskit.io.
- Playbook: learn the production patterns behind this layer at playbook.agentskit.io.
- AKOS: run the same concepts with enterprise deployment, governance, and observability at akos.agentskit.io.
Docs: package guide · agent handoff
Why adapters
- Vendor independence — switch from OpenAI to Anthropic to a local Ollama model by changing one line; your hooks, runtime, and tools stay untouched
- 25 native adapters in the catalog — Anthropic, OpenAI, Gemini, Ollama, DeepSeek, Grok, Kimi, Mistral, Cohere, Together, Groq, Fireworks, OpenRouter, Hugging Face, LM Studio, vLLM, llama.cpp, LangChain, Vercel AI SDK, and additional compatible providers
- Embedder functions built in — the same adapter pattern covers text embeddings, so you can reuse provider config for both chat and RAG
- One-line local AI —
ollama({ model: 'llama3.1' }) for fully offline agents with no API key required
- CLI-backed agents —
@agentskit/adapters/cli normalizes text, JSON, and ACP-based local LLM CLIs
Install
npm install @agentskit/adapters
The runtime example below also needs @agentskit/runtime. The RAG example
also needs @agentskit/rag, @agentskit/memory, and the optional vectra
peer (npm install @agentskit/rag @agentskit/memory vectra).
Quick example
import { anthropic } from '@agentskit/adapters'
import { createRuntime } from '@agentskit/runtime'
const adapter = anthropic({ apiKey: process.env.ANTHROPIC_API_KEY, model: 'claude-sonnet-4-6' })
const runtime = createRuntime({ adapter })
const result = await runtime.run('Summarize the latest AI news')
console.log(result.content)
Embeddings (for RAG)
Use the same package for vector embeddings — wire openaiEmbedder, geminiEmbedder, or ollamaEmbedder into @agentskit/rag:
import { openaiEmbedder } from '@agentskit/adapters'
import { createRAG } from '@agentskit/rag'
import { fileVectorMemory } from '@agentskit/memory'
const rag = createRAG({
embed: openaiEmbedder({ apiKey: process.env.OPENAI_API_KEY! }),
store: fileVectorMemory({ path: './vectors' }),
})
Features
- Providers: Anthropic, OpenAI, Gemini, Ollama, DeepSeek, Grok, Kimi, Mistral, Cohere, Together, Groq, Fireworks, OpenRouter, Hugging Face, LM Studio, vLLM, llama.cpp, LangChain, LangGraph, Vercel AI SDK, generic
ReadableStream
- Embedders:
openaiEmbedder, geminiEmbedder, ollamaEmbedder, deepseekEmbedder, grokEmbedder, kimiEmbedder, createOpenAICompatibleEmbedder
- Fetch-backed adapters run against the shared
Adapter contract v1 suite (ADR 0001); SDK-backed adapters have provider-specific contract and resilience coverage
- Custom adapter authoring via
createAdapter()
- Higher-order adapters:
createRouter (cost/latency/classifier), createEnsembleAdapter (fan-out + merge), createFallbackAdapter (ordered try-next)
CLI-backed adapters
The Node-only @agentskit/adapters/cli subpath runs an explicitly selected
local LLM executable without a shell:
import { createCliAdapter, getCliProviderManifest, resolveCliManifest } from '@agentskit/adapters/cli'
const manifest = getCliProviderManifest('codex')
if (!manifest) throw new Error('provider manifest is unavailable')
const adapter = createCliAdapter(resolveCliManifest(manifest, { mode: 'review-safe' }))
The generic factories are createCliAdapter (exec-text),
createJsonCliAdapter (exec-json), and createAcpCliAdapter (ACP v1 over
JSON lines). The built-in manifests cover Codex, Claude Code, Grok CLI, and
OpenCode. resolveCliManifest keeps command, argv, protocol, provider id, and
mode explicit; diagnoseCliProviderManifest verifies availability and an
optional version pattern. review-safe is the default: no shell, automatic
installation, native login, MCP, plugins, or terminal tools. Use
trusted-local explicitly when a developer intentionally wants the CLI's local
authentication and environment. requiredCapabilities is checked before
spawning, and onDiagnostic receives redacted exit, timeout, abort, and
output-limit data. Structured output fails closed; timeouts, aborts, output
limits, and non-zero exits produce terminal adapter errors. Process termination
is awaited before the adapter finishes, including when input or output fails.
restricted-environment is an explicit environment allowlist mode; it is not
an OS, filesystem, process, or network sandbox. Use @agentskit/sandbox when a
real isolation boundary is required.
Use buildArgs(request) only for CLIs that require the prompt in argv; it is
request-aware and still uses direct, shell-free spawning. Set
serializeRequest: () => '' when the provider does not consume stdin. For
JSONL or event-wrapped output, parseOutput(stdout) can decode raw stdout
before the normal parse(value) callback runs.
For CLIs that write the final response to a file, outputFile reads that file
after process completion with the same byte limit and abort handling.
Stream guarantees
- A stream terminates exactly once with
done or error; terminal errors carry an Error in metadata.error.
- Provider streams that close before their native completion marker are treated as truncated, not successful.
abort(reason) propagates to active fetch readers and SDK requests and terminates with the same error semantics.
- Native tool histories preserve call/result correlation. Parallel tool results are encoded in a single provider turn where required.
- Credentials stay in provider headers when the protocol supports them; Gemini API keys are never placed in request URLs.
vercelAI consumes the Vercel AI SDK UI message stream v1 protocol, including its required response header and [DONE] marker.
Higher-order adapters
import { createRouter, anthropic, openai } from '@agentskit/adapters'
const router = createRouter({
candidates: [
{ id: 'haiku', adapter: anthropic({ model: 'claude-haiku-4-5' }), cost: 0.25 },
{ id: 'sonnet', adapter: anthropic({ model: 'claude-sonnet-4-6' }), cost: 3 },
{ id: 'gpt-mini', adapter: openai({ model: 'gpt-4o-mini' }), cost: 0.15 },
],
})
See Adapter router, Ensemble, and Fallback chain.
Ecosystem
Testing Adapters
Three built-in utilities let you test agents without hitting a real LLM.
mockAdapter — deterministic responses
import { mockAdapter } from '@agentskit/adapters'
const adapter = mockAdapter({
response: [
{ type: 'text', content: 'Hello!' },
{ type: 'done' },
],
})
Pass a function to make responses request-aware, or pass an array of arrays to return different chunks on each call (sequenced mode). Use the optional history array to capture every request for assertions.
recordingAdapter + inMemorySink — capture real calls
import { recordingAdapter, inMemorySink, anthropic } from '@agentskit/adapters'
const sink = inMemorySink()
const adapter = recordingAdapter(
anthropic({ apiKey: process.env.ANTHROPIC_API_KEY!, model: 'claude-sonnet-4-6' }),
sink,
)
replayAdapter — replay captured fixtures
import { replayAdapter } from '@agentskit/adapters'
import fixture from './fixture.json'
const adapter = replayAdapter(fixture)
Typical workflow: record once in dev → commit JSON fixture → replay in CI.
Contributors
License
MIT — see LICENSE.
Docs
Full documentation · GitHub
Maturity and compatibility
- Stability: beta — see docs/STABILITY.md
- The implementation is hardened for a future freeze, but promotion still requires the 90-day beta window, two released minor lines, accepted package RFC, and repository evidence required by ADR 0024.
- Node.js 20+ and TypeScript strict mode
- Published as
@agentskit/adapters
Contributing
See CONTRIBUTING.md and the monorepo LICENSE.