Selected work
A wrapper that adds prompt caching to an existing Anthropic, OpenAI or Gemini client, so the caching rules of each provider stop leaking into application code.
- Role
- Author and maintainer
- Type
- Open source library
- Status
- v0.2.0 on npm and PyPI
- Licence
- MIT
Signal path
- Input
- Hidden 01
- Hidden 02
- Output
The problem
Prompt caching makes a repeated prompt prefix far cheaper, but every provider does it differently. Anthropic wants explicit cache breakpoints in the request. OpenAI caches a prefix automatically, as long as the stable part comes first. Gemini wants a cached content object created ahead of time and referenced later.
Doing this by hand means provider specific code at every call site, plus a guess about which parts of a prompt are stable enough to be worth caching.
What I built
For Anthropic and OpenAI you pass in the client you already have and get the same client back. For Gemini you pass the client and its cache manager and get back a model wrapper. Calls go through unchanged, except that the prompt is prepared for caching on the way out. There is a TypeScript package on npm and a Python port on PyPI.
Where it stands
The library has no runtime dependencies and runs on Node 18 or Python 3.9 and later. Token counts come from a characters per token heuristic by default, which is the main approximation in the design; you can pass your own counter for prompt text when you need exact numbers.
The token counts behind the savings it reports are not estimates: they come from the usage figures each provider returns. The dollar figure applies a built in price table to those counts.
Request path
- Input
Your client
The Anthropic, OpenAI or Gemini client you already have.
Leads to: Wrap.
- Process
Wrap
Wrapped once. Each call is prepared for caching on the way out.
Leads to: Split and score (Anthropic), Reorder (OpenAI), Cached content (Gemini).
- AnthropicProcess
Split and score
System, tools and messages, each scored for stability.
Leads to: Rank.
- Decision
Rank
Under 1,024 estimated tokens: skipped. The rest ranked by stability times size.
Leads to: Breakpoints.
- Process
Breakpoints
Up to four cache breakpoints placed in the request.
Leads to: Provider API.
- OpenAIProcess
Reorder
System messages moved to the front, longest first.
Leads to: Provider API.
- GeminiStore
Cached content
Created once the static part is large enough, then reused.
Leads to: Provider API.
- Output
Provider API
The prepared request goes out through the provider's own SDK.
Leads to: Stats.
- Store
Stats
Usage figures the provider returns feed the savings report.
How it works
A proxy, not a new SDK
The Anthropic and OpenAI clients are wrapped in a JavaScript Proxy, so their methods and types stay as the provider shipped them, with three stats methods added. There is nothing new to learn and nothing to migrate.
Stability scoring
For Anthropic requests, the prompt is split into system, tools and message segments, and each one gets a score for how likely it is to repeat. System prompts and tool definitions start high. Message content earns a higher score once the same text has been seen across calls, and the most recent messages score lowest.
Breakpoint placement
Segments under 1,024 estimated tokens are skipped. The rest are ranked by stability times size, and up to four breakpoints are placed. Three modes (auto, aggressive and conservative) set how stable a segment must be to qualify.
One strategy per provider
For OpenAI the adapter moves system messages to the front, longest first, so the shared prefix is as long as possible, because caching there is automatic. For Gemini it creates a cached content object once the static part is large enough (32,768 estimated tokens by default) and reuses it until shortly before its time to live runs out.
Stack
- TypeScript
- Python
- Anthropic SDK
- OpenAI SDK
- Gemini SDK
- Vitest

