Budget Tracker
BudgetTracker tracks token usage and cost during agent execution, and enforces spend limits so a runaway agent can't drain your API budget.
Papayya does not ship per-provider rate cards. LLM pricing changes too often and varies per customer contract, so the tracker uses a neutral default unless you supply your own
TokenPricing. For accurate numbers, pass pricing that matches your provider contract.
import { BudgetTracker, DEFAULT_PRICING } from "papayya";
import type { TokenPricing } from "papayya";Constructor
new BudgetTracker(
limit_usd?: number,
options?: {
pricing?: TokenPricing;
soft_limit_fraction?: number;
},
)| Parameter | Type | Description |
|---|---|---|
limit_usd | number | undefined | Maximum spend in USD. If omitted, tracking is unlimited. |
options.pricing | TokenPricing | USD per million input/output tokens. Defaults to a neutral placeholder — override to match your contract. |
options.soft_limit_fraction | number | Fraction of limit_usd at which the soft limit warning fires (default: 0.8). |
TokenPricing
interface TokenPricing {
input_per_million: number;
output_per_million: number;
}Supply the numbers you pay — Papayya does not know your provider contract:
const tracker = new BudgetTracker(1.0, {
pricing: { input_per_million: 3.0, output_per_million: 15.0 },
});Methods
tracker.record(tokens)
Record token usage from a single LLM call.
tracker.record({ input: 1500, output: 350 });tracker.exceeded()
Returns true if the total cost has exceeded the budget limit.
if (tracker.exceeded()) {
console.log("Budget exceeded — stopping agent");
}tracker.remaining()
Returns the remaining budget in USD, or undefined if no limit was set.
tracker.summary()
tracker.summary();
// { consumed_usd: 0.15, limit_usd: 0.50 }How it works with agents
When you set budget_usd on an AgentConfig, the SDK creates a BudgetTracker internally using the default pricing. After each LLM call in AgentLoop, token usage from your ModelClient's response is recorded against the tracker. If the budget is exceeded, the run stops with a budget_exceeded status.
For accurate cost numbers, either:
- Construct your
BudgetTrackerwith a customTokenPricingand use the engine directly, or - Call
run.record_cost(usd)explicitly after each LLM call in a durable run, using a number you compute from your own pricing.
In cloud runs, budget enforcement happens server-side using integer math (cents) to avoid floating-point drift.
const agent = new Agent({
name: "my-agent",
model: myClient, // your ModelClient
instructions: "...",
max_steps: 50,
budget_usd: 1.00, // Hard cap: $1.00 per run
tools: [],
});