Docs
Prompt Caching
An agent loop re-sends its whole history on every step, so a long session pays for the same tokens again and again. NanoCodana marks the stable parts of the prompt as cacheable automatically — on Anthropic models, re-read input is billed at a fraction of the full price, cutting input cost by up to ~90% on long sessions.
It's on by default and needs zero configuration. When the model is an Anthropic provider instance (or a Claude model routed through OpenRouter), the agent places cacheControl breakpoints on the system prompt + tool definitions and on the tail of the conversation, so each loop step re-reads the growing history from cache instead of re-paying full price. You can watch it work: result.totalUsage reports cached input tokens separately.
const agent = NodeAgent({
model: anthropic('claude-sonnet-5'),
workingDirectory: process.cwd(),
// promptCaching: true is the default — nothing to do.
})
// Opt out to manage cacheControl yourself:
const manual = NodeAgent({ model, promptCaching: false })What gets detected#
- Auto: Anthropic provider instances (
anthropic('claude-…')) and Claude models via OpenRouter. - Not auto: gateway model strings (
model: 'anthropic/claude-…') and Claude via Bedrock or Vertex — wrap those with the exportedpromptCachingMiddlewareyourself if the route forwards Anthropic provider options. - Other providers: no-op. OpenAI, Google, and DeepSeek cache automatically server-side; there's nothing to mark.
import { wrapLanguageModel } from 'ai'
import { promptCachingMiddleware } from '@nanocodana/core'
const model = wrapLanguageModel({ model: bedrockClaude, middleware: promptCachingMiddleware })anthropic or openrouter namespace) are left untouched, with or without auto-caching — your explicit placement always wins.