News / release

21 adapters for the agent you already built

Eight TypeScript adapters, thirteen Python adapters, and recoverable tool-result compression inside the agent you already run.

Author
Julius Brussee
Published
19 September 2026
Length
5 min read
Caveman: 21 adapters. Keep your framework. Graphite sheets close into a compact stack. Eight TypeScript adapters and thirteen Python adapters. Middleware alpha.

21 adapters. Two languages. Keep the agent you already built.

Caveman 2.7 brings tool-result compression into existing TypeScript and Python applications through new middleware packages, available now in alpha. Your framework still runs the model, tools, retries, and streaming. Caveman prepares a smaller version of supported tool results for the next model call.

The original stays in your application history. When a transform removes detail, a registered recovery tool lets the model read that detail back.

Your agent keeps paying to read yesterday's tool output

A coding agent runs a test suite. A research agent reads a long document. A support agent searches a pile of records. The useful result lands in the conversation, and the next model call carries that text again.

Caveman's middleware works at that boundary. It selects supported tool-result text from the outgoing request and asks the local compression runtime to shorten it. Your existing SDK still sends the model request to its provider.

That gives an application you already have a place to reduce repeated context without replacing its agent loop.

Eight TypeScript adapters. Thirteen Python adapters.

The release includes adapters for agent frameworks, provider SDKs, and protocol integrations. The count is 8 TypeScript adapters plus 13 Python adapters. Some names appear in both languages; this is not a claim of 21 distinct frameworks.

LanguageIncluded adapters
TypeScriptVercel AI SDK, OpenAI, Anthropic, Google GenAI, LangChain, Strands, Mastra, MCP
PythonLangChain, LiteLLM, OpenAI, Anthropic, Google GenAI, Strands, Agno, CrewAI, AutoGen, Pydantic AI, LlamaIndex, ASGI, MCP

Install the adapter for your existing stack. Each has a supported version range, listed in the TypeScript and Python package guides. Outside that range, compression is skipped by default and the adapter reports unsupported_version.

Shorten the request. Keep the original.

The middleware changes a copy of the outgoing request. It does not replace the messages you save to your database or conversation checkpoint.

For supported tool loops, Caveman can register caveman_retrieve. The model uses it to read the exact original behind a compressed result. A transform that needs recovery only runs when the adapter can confirm that recovery is registered. Otherwise, it uses only transforms that do not need it.

The boundary is deliberately narrow: supported successful tool-result text and explicit document bodies. User messages, system instructions, assistant reasoning, errored results, images, and protected content stay outside it.

Recovery has a lifetime. Originals are scoped to the application, session, branch, and cache epoch, and scopes expire after 24 hours without use. Keep your original history; do not persist the compressed copy as its replacement.

Add it around your existing model call

Start the local runtime with the released CLI:

terminal
npm install -g @caveman-ai/[email protected]
caveman setup --install
caveman start

Then install the TypeScript packages in your app:

terminal
npm install @caveman-ai/[email protected] @caveman-ai/[email protected]

For Vercel AI SDK, the released adapter accepts ai >=7.0.94 <8 and @ai-sdk/provider >=4.0.11 <5. Wrap your existing options:

typescript
import { streamText } from "ai";
import { createMiddlewareRuntime } from "@caveman-ai/sdk/middleware";
import { withCaveman } from "@caveman-ai/middleware/ai-sdk";

const runtime = createMiddlewareRuntime({
endpoint: "http://127.0.0.1:8787",
mode: "compress",
onReport: (report) => console.log(report.status, report.reason),
});
await runtime.ready();

const scope = {
namespace: "my-app",
session_id: conversationId,
branch_id: "main",
cache_epoch: "0",
};

const result = streamText(
withCaveman(existingOptions, { runtime, scope }),
);

Here, existingOptions is the model, messages, tools, and stop conditions already used by your application; conversationId is its stable conversation ID. Keep the returned tool and callback bundle intact so recovery can work. Consume the stream normally, and call runtime.close() when your app shuts down.

Python packages are also available. For a LangChain application on Python 3.13 or newer:

terminal
pip install "caveman-sdk==1.1.0" "caveman-middleware[langchain]==0.1.0a1"

The Python guide shows the native integration and version constraints. Some extras have conflicting upstream dependencies, so check the guide before combining them.

Earlier wrap benchmark: 33.2% fewer input tokens

Our published CaveBench Wrap report recorded 33.2% fewer provider-reported input tokens across 18 paired runs, with 18/18 exact answers for both direct Claude Code and Caveman wrap plus skill.

Earlier benchmark armInput tokensExact answers
Direct Claude Code885,79318/18
Caveman wrap plus skill591,67318/18

That August 6 report used six deterministic tool-output workloads, Claude Code 2.1.223, and Sonnet 5. Its 95% interval was 14.6% to 48.5%; the HTML case used 9.9% more input tokens. Recovery and skill overhead stayed counted.

This measured the older wrap-plus-skill setup, not the new middleware. It is context for why tool-output compression matters, not a middleware result or a claim about your bill. The public report includes provenance hashes; its raw harness and run artifacts are not published, so it cannot be independently reproduced from that repository alone.

Measure the finished task

This is an alpha feature release. It does not come with a new savings percentage.

Use record mode to inspect candidates without changing request text, then compare compress on the same tasks. Check answer quality, provider usage, latency, and recovery calls together. A shorter tool result is useful only if the agent still finishes the work.

Middleware token estimates describe the segments the runtime saw. They do not establish a lower bill. Recovery calls, cache behavior, and retries can change the total.

During model calls, the default behavior on an unavailable runtime or missed deadline is to use the original input and report the skip. Startup runtime.ready() can still fail; handle that in your app's startup policy. Choose strict mode only when you want optimization failures to stop inference.

Get the v2.7.0 release and pick the adapter for the framework you already use.

Also fixed

This release also fixes Codex approval-rule breakage caused by shell-command rewriting, improves native-install cleanup, and preserves mixed CJK text in shrink output. Details are in the release notes.