Caveman
@caveman/agent

Agents are expensive.
Compile them.

A TypeScript framework for agents that run all day: support bots, ops triage, document pipelines. Bring your own loop or use ours. Declare behavior, tools, context and evals; the build locks the cheapest plan that clears every gate.

See how it works

Drops into the loop you already run
Claude Agent SDKVercel AI SDKMastraEve
TypeScript · publishes to npm at launch
Declare

An agent is a declaration

Behavior, tools, context and evals sit next to each other in TypeScript. The build lowers them into a typed context IR and searches candidate plans against it.

agent.ts
import { agent, auto } from "@caveman/agent";
export default agent({
id: "support",
instructions: "Answer from policy. Never invent policy.",
model: auto(),
});
tools.ts
import { schema, tool } from "@caveman/agent";
const lookupPolicy = tool({
name: "lookup_policy",
description: "Read current refund policy.",
input: schema.object({ region: schema.string() }),
effect: "read",
result: "auto",
async execute({ region }) {
return { region, refundWindowDays: 14 };
},
});
context.ts
import { context, file, memory, output, schema } from "@caveman/agent";
const playbook = context({
id: "support.playbook",
kind: "skill",
source: file("./support.md"),
stability: "build",
safety: "S0",
priority: "required",
});
const supportMemory = memory({
namespace: "support",
ttl: "30d",
recallBudget: 1_200,
consent: "local_only",
});
const answer = output({
maxTokens: 500,
schema: schema.object({ answer: schema.string() }),
});
evals.ts
import { eval as defineEval } from "@caveman/agent";
export const refund = defineEval({
id: "refund",
approved: true,
input: "Can I get a refund?",
quality: [
{ type: "contains", fragments: ["14 days"] },
{ type: "tool_called", tools: ["lookup_policy"] },
],
});
no lock is written unless every gate passes
The bill

Every run ends with its bill

Per-segment token accounting from provider-reported usage: what was sent, what was compressed, what the model saw, cache reads against cache writes. Anything counted locally is labeled inferred.

a missing engine is a WARN · doctor makes no model request · verified savings: $0
Mechanism

Efficient by construction

A coding agent runs while you sit at the keyboard. A support bot runs fifty thousand times a month off the same frozen prefix, and cache reads compound with that repetition.

maxCostUsdcap
reserve → settle
cave_run_cost_budget_exceeded

Spend is a ledger. Every call reserves against maxCostUsd before it fires, subagents included. At the cap the run stops with cave_run_cost_budget_exceeded. Unpriced models fail closed.

frozen prefixlive zone

Breaking the cache is a build failure. The frozen prefix is hash-checked every turn. A plan that shrinks it fails the build, even when it cut raw token count.

recovery proof:
read_file:big.txt
round-trip OK
(sha256 match efac7be09c1a)

Compression you can take back. Originals are stored before replacement. cave_retrieve pulls them back mid-run; proveRecovery prints the sha256 match.

WARN engine — transforms off
WARN gateway — telemetry off
run mode: observe-only
nothing measured, nothing claimed

Observe-only, loudly. With no engine installed, runs keep your provider's URLs and transform nothing. doctor prints what's missing and how to install it.

Adapters

Keep your loop.

The adapters bring the bill, the cap and the gates to a loop you already run. Each needs a matching Cave Build before it hits a provider, and cost is recomputed from the public catalog.

Exact-pinned: Vercel AI SDK 7.0.43 Eve 0.29.2 Mastra 1.55.0

claude-lane.ts
import { runClaudeAgent } from "@caveman/agent/claude";
import { fileURLToPath } from "node:url";
import support from "./agent.js";
const result = await runClaudeAgent(support, "Can I get a refund?", {
entryPath: fileURLToPath(new URL("./agent.js", import.meta.url)),
maxTurns: 8,
maxBudgetUsd: 0.50,
});
the Claude lane is always unlocked · claimBasis "inferred" · verified savings $0
Taken all the way

The hard case, measured

Caveman Code is a terminal coding agent with four compression layers under an autonomous goal loop. Across 25 matched gpt-5.5 tasks it spent 1.93× fewer tokens than Codex CLI, passing 14 of them against Codex's 15.

Read the repo
████ ████ █  █ ████ █  █ ████ █  █
█    █  █ █  █ █    ████ █  █ ██ █
█    ████ █  █ ███  ████ ████ ████
█    █  █  ██  █    █  █ █  █ █ ██
████ █  █  ██  ████ █  █ █  █ █  █

████ ████ ███  ████
█    █  █ █  █ █   
█    █  █ █  █ ███ 
█    █  █ █  █ █   
████ ████ ███  ████

terminal coding agent · four compression layers · 20+ providers

MicroBench · 25 matched gpt-5.5 tasks

fresh tokenscaveman-code 524kcodex cli 1,010k1.93× fewer
tasks passedcaveman-code 14/25codex cli 15/25
inferred · token counts from the run, never an invoice

Build production
agents

Explore the stack