Caveman
@caveman-ai/agent

See what agents spend.
Guard every run.

Build support, operations and document agents with a best-effort local catalog-price guard and a token bill for every successful run. Declare tools, context and evals in TypeScript. Caveman keeps a cheaper context plan only after your tests pass.

See how it works

Use included loop or keep yours
Claude Agent SDKVercel AI SDKMastraEve
TypeScript · publishes to npm at launch
Declare

Put rules next to code

Instructions, tools, context, evals and spend guards live together in TypeScript. Caveman can test cheaper ways to assemble context and rejects every candidate that fails your declared checks.

agent.ts
import { agent, auto } from "@caveman-ai/agent";
export default agent({
id: "support",
instructions: "Answer from policy. Never invent policy.",
model: auto(),
});
tools.ts
import { schema, tool } from "@caveman-ai/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-ai/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-ai/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
Before first run

Know what will run

Doctor checks runtime, sandbox, Engine, gateway and config without making a model request. Missing Engine is a warning: agent can still run directly through provider in observe-only mode.

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

Spend less context safely

Production agents reuse instructions, tools and policy across many runs. Caveman protects stable prefix, applies a best-effort catalog-priced spend guard and adds recoverable local compression when Engine is available.

maxCostUsdcap
reserve → settle
cave_run_cost_budget_exceeded

Stop before next call. maxCostUsd reserves catalog worst-case price before each model call, then settles provider-reported catalog subtotal. Includes subagents. Unpriced models cannot silently count as free.

frozen prefixlive zone

Keep stable prompts stable. Frozen prefix is hash-checked every turn. Candidate that makes warm-cache cost worse fails build even when raw token count fell.

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

Recover exact original. Local Engine stores original bytes before lossy replacement. cave_retrieve restores them mid-run; proveRecovery checks SHA-256.

WARN engine — transforms off
WARN gateway — telemetry off
run mode: observe-only
provider usage + local context estimates remain

Works without Engine. SDK uses provider's URL directly in observe-only mode. No transform or Caveman gateway telemetry; provider usage and local context estimates remain. Doctor says what is missing.

Adapters

Keep your framework

Locked adapters bring spend controls and context plan to Vercel AI SDK, Eve and Mastra. Each checks matching Cave Build before provider call and recomputes cost from 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-ai/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

Build with a spend
guard

Explore the stack