For your AI agent

Give your agent the right cost semantics.

You already code with an AI agent. Pick your stack, copy the prompt, and paste it into Claude Code, Cursor, or any agent. It starts by finding your server-side model calls, then uses provider-aware adapters where available and explicit mappings otherwise. Cache, reasoning, modality, and multi-step usage stay separate; guardrails remain optional and enforced by your code.

# Task: Integrate BurnCap into this project — Next.js + Vercel AI SDK

BurnCap is an out-of-band AI cost monitor and budget guardrail. After each LLM call we
send usage metadata (never prompts) to BurnCap; optionally we ask it for an advisory
budget decision before expensive calls. **Enforcement always stays in our code — BurnCap
only advises.**

## 0. Discover before changing anything
- Find every **server-side** LLM call site in this project and list them back to me.
- Identify the framework, where env vars live, and a home for a shared server util.
- Never expose the API key to client/browser code.

## 1. Install & configure
Install: `pnpm add @burncap/sdk`

Add **server-only** env vars (never client-exposed):
```bash
BURNCAP_API_KEY=bc_your_key_here
BURNCAP_URL=https://www.burncap.app
```

Create one shared client:
If `@burncap/sdk` isn't installable from your registry, replace the client with thin `fetch()` calls to the endpoints in section 4 — same JSON, same headers.
```ts
// lib/burncap.ts
import { BurnCap } from "@burncap/sdk";

export const burncap = new BurnCap({
  apiKey: process.env.BURNCAP_API_KEY!,
  baseUrl: process.env.BURNCAP_URL, // optional; defaults to https://www.burncap.app
  // failMode defaults to "open": a BurnCap outage must never block your traffic.
});
```

## 2. Track usage after every server-side model call
Invariants (BurnCap miscounts otherwise):
- Every separately reported cache, reasoning, modality, and tool meter stays separate; do not fold it into base input/output.
- Always pass a stable `request_id` (the provider's response id) so retries never double-count.
- Never block the user's request path on tracking — it is best-effort.

Map the provider's usage object (adapt to the SDK version in this repo):
```ts
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { usageFromAISDK } from "@burncap/sdk";
import { burncap } from "@/lib/burncap";

const result = await generateText({ model: openai("gpt-5.5"), prompt });

burncap.trackUsageInBackground(() =>
  usageFromAISDK(result, {
    provider: "openai", // anthropic/google when that is the provider behind the AI SDK model
    feature: "chatbot",
    customerId: user?.id,
  }),
);
```

The TypeScript SDK adapters validate totals and throw rather than emit contradictory usage.
Pass them as a factory to `trackUsageInBackground(() => adapter(...))` so mapping and network
failures stay contained on the best-effort path.

Use stable, low-cardinality `feature` labels per call site (e.g. "chatbot", "summarizer",
"agent-runs"). Other usage dimensions: `image_count`, `audio_seconds`, `tool_call_count`,
`session_id` (powers runaway-loop detection). Pass `actual_cost_usd` if you know it, else
BurnCap estimates from your workspace pricing table.

## 3. (Optional — confirm with me first) Budget guardrails
Gate expensive calls on the advisory `action`. We do the enforcing:
```ts
import { burncap } from "@/lib/burncap";

const gate = await burncap.checkBudget({ feature: "agent-runs", customerId: user.id });
if (gate.action === "block") return Response.json({ error: "budget_exceeded" }, { status: 402 });
if (gate.action === "use_cheaper_model") model = "gpt-5-mini";
if (gate.action === "warn") console.warn("AI budget nearly spent", gate.budgets);
// "continue" -> under budget, proceed as normal
```
`checkBudget` **fails open** on network errors by default — keep it that way on user-facing
paths. Use a closed/blocking fallback only for internal, spend-critical jobs.
For concurrent expensive calls, use `checkBudget({ reserveUsd })`, continue only according to
the returned action, and pass `gate.reservation?.id` to the adapter as `budgetReservationId`.
Do not retry reservation POSTs automatically; abandoned holds expire after their short TTL.

## 4. API contract (source of truth)
Both endpoints use `Authorization: Bearer bc_your_key_here` against `https://www.burncap.app`.

- **POST `/api/v1/events`** — body `{ "events": [event, ...] }`, a bare array, or a single
  event object. 1–500 events per call; idempotent by `request_id`.
  - `200 → { inserted, duplicates, invalid, errors[], unpriced_models[], partial_models[] }`
  - `429` rate limited (honor `Retry-After`) · `402 quota_exceeded` · `401` invalid key
- **GET `/api/v1/budget/check?feature=…&customer_id=…&environment=…`**
  - `200 → { allowed, state, action, reason, budgets[] }`
  - `action` ∈ `continue | warn | use_cheaper_model | block`; `allowed` is `false` only when
    a hard-cap budget is exhausted. **Fail open** on any network error.
- **POST `/api/v1/budget/check`** — same scopes plus `reserve_usd` and optional `ttl_seconds`
  (5–300). Returns a short-lived `reservation`; pass its id as `budget_reservation_id` on usage.

## Hard rules (do not violate)
1. Server-side only. The `bc_…` key must never reach the browser/client bundle.
2. Tracking is best-effort — never block or fail a user request because of it.
3. Always send a stable `request_id`. Preserve every separately reported usage meter.
4. Keep `checkBudget` fail-open on anything user-facing.
5. Minimal, surgical changes — a thin shared client plus one tracking call per LLM call site.
   No broad refactors.

## Verify before you're done
- Build / type-checks pass.
- Add focused tests for each provider usage shape and a duplicate `request_id` retry.
- Do not spend money or call production services unless I explicitly authorize it. If I do,
  verify one development call returns `inserted: 1`, then the same event returns `duplicates: 1`.
- Summarize the call sites instrumented, feature labels chosen, checks run, and any usage fields
  the installed provider SDK does not expose.
Tailored for your stack

Next.js + Vercel AI SDK

Current totalUsage details, including cache reads, writes, and multi-step calls.

Node / Next.js + OpenAI SDK

OpenAI Responses or Chat Completions, with cache and reasoning separated.

Node + Anthropic SDK

@anthropic-ai/sdk — cache reads, 5m/1h writes, region, and web search.

Node + Google Gemini SDK

@google/genai — resolved model, modalities, cache, tier, and thinking tokens.

Python (FastAPI + OpenAI / Anthropic)

No SDK needed — thin httpx calls, fail-open guardrail.

Create a free workspace to get your API key — the in-app prompt bakes it in for you, so the agent has everything it needs.

Start free

BurnCap never proxies your model traffic and never stores prompts — these prompts only add out-of-band usage tracking and advisory budget checks. Enforcement always stays in your code.