Skip to content
Cavemandocs
MIT

Supported frameworks

Every TypeScript and Python adapter, the entrypoint for each, and the versions it accepts.

Every Caveman middleware adapter, the module it is imported from, and the framework versions it accepts. Outside the accepted range an adapter reports unsupported_version and leaves the call unchanged. Every range below is the literal pair of bounds in the published package's own version gate.

TypeScript#

@caveman-ai/middleware 0.1.0-alpha.2.

AdapterImportAccepted versionsExample
Vercel AI SDK@caveman-ai/middleware/ai-sdkai >=7.0.94 <8, @ai-sdk/provider >=4.0.11 <5ai-sdk.mjs
OpenAI@caveman-ai/middleware/openaiopenai >=7.12 <8openai.mjs
Anthropic@caveman-ai/middleware/anthropic@anthropic-ai/sdk >=0.124 <1anthropic.mjs
Google Gen AI@caveman-ai/middleware/google@google/genai >=2.21 <3google.mjs
LangChain@caveman-ai/middleware/langchainlangchain >=1.5 <2, @langchain/core >=1.2 <2, @langchain/langgraph >=1.4 <2langchain.mjs
Strands@caveman-ai/middleware/strands@strands-agents/sdk >=1.17 <2strands.mjs
Mastra@caveman-ai/middleware/mastra@mastra/core >=1.65 <2mastra.mjs
MCP@caveman-ai/middleware/mcp@modelcontextprotocol/sdk >=1.30 <2mcp.mjs

@caveman-ai/middleware declares no dependency on any of them, so npm install @caveman-ai/middleware brings in the adapters and nothing else. Install the framework the adapter wraps yourself. One import picks the adapter:

typescript
import { withCaveman } from "@caveman-ai/middleware/ai-sdk";
import { withCavemanOpenAI } from "@caveman-ai/middleware/openai";
import { withCavemanAnthropic } from "@caveman-ai/middleware/anthropic";
import { CavemanGoogleGenAI } from "@caveman-ai/middleware/google";
import { withCavemanAgent } from "@caveman-ai/middleware/langchain";
import { withCavemanStrands } from "@caveman-ai/middleware/strands";
import { withCavemanMastra } from "@caveman-ai/middleware/mastra";
import { CavemanMCPHost } from "@caveman-ai/middleware/mcp";

Each line needs its own framework resolvable. Import one adapter, not the eight together.

Python#

caveman-middleware 0.1.0a1, on Python 3.13 or newer. The extra in brackets installs that family's frameworks.

AdapterImportAccepted versionsExample
OpenAI [openai]caveman_middleware.openaiopenai >=3.10 <4openai.py
Anthropic [anthropic]caveman_middleware.anthropicanthropic >=1.4 <2anthropic.py
Google Gen AI [google]caveman_middleware.googlegoogle-genai >=2.22 <3google.py
LangChain [langchain]caveman_middleware.langchainlangchain >=1.4 <2, langchain-core >=1.6 <2, langgraph >=1.2 <2langchain.py
LiteLLM [litellm]caveman_middleware.litellmlitellm >=1.100 <2litellm.py
Strands [strands]caveman_middleware.strandsstrands-agents >=1.55 <2strands.py
Agno [agno]caveman_middleware.agnoagno >=3.0 <4agno.py
CrewAI [crewai]caveman_middleware.crewaicrewai >=1.15 <2crewai.py
Pydantic AI [pydantic-ai]caveman_middleware.pydantic_aipydantic-ai-slim >=2.42 <3pydantic_ai.py
AutoGen [autogen]caveman_middleware.autogenautogen-core, autogen-agentchat and autogen-ext, each >=0.7 <0.8autogen.py
LlamaIndex [llama-index]caveman_middleware.llama_indexllama-index-core >=0.14 <0.15llama_index.py
MCP [mcp]caveman_middleware.mcpmcp >=2.2 <3mcp.py
ASGI [asgi]caveman_middleware.asgifastapi >=0.141 <1, starlette >=1.6 <2asgi.py

The LlamaIndex adapter gates the LLM integration it finds as well: llama-index-llms-openai >=0.8 <1 with openai >=2.54 <4, or llama-index-llms-anthropic >=0.12 <1 with anthropic >=0.125 <2.

Both gates read the leading numeric release segments and drop anything after them, so a prerelease or build suffix is compared as its release: 1.5.0rc1 and 1.5.0-beta.2 both count as 1.5.0.

What a version outside the range looks like#

An adapter checks its gate before it touches history, tools or the transport. Outside the range it declines locally, sends nothing to the runtime, and passes the call through untouched. This is the onReport line from a run with @caveman-ai/middleware 0.1.0-alpha.2 against ai reporting 6.9.0, with the per-run ids shortened:

json
{"schema_version":1,"status":"skipped","reason":"unsupported_version","transform_ids":[],"replacement_count":0,"reused_count":0,"adapter":"ai-sdk","logical_call_id":"a209549d…","attempt_id":"8af13b65…"}

adapter names which one declined, which is the field to read when an application wraps more than one call.