Skip to content

Repository files navigation

agent-budget-guard

Budget-aware degradation for autonomous AI agents. Map a spend balance to survival tiers, enforce per-call, hourly and daily LLM inference budgets, and automatically downgrade the model when funds run low.

CI License: MIT TypeScript Zero dependencies

A tiny, zero-runtime-dependency TypeScript library for LLM cost control in cost-bounded, autonomous AI agents. It gives an agent a survival instinct: as its budget shrinks it moves through tiers (high → normal → low_compute → critical → dead), switches to a cheaper model, and refuses inference calls that would blow the per-call, hourly, daily or session budget. Useful for FinOps / LLMOps, token-budget enforcement, rate-limiting inference spend, and model-selection for OpenAI, Anthropic and any other provider.

Why

An autonomous agent that pays for its own inference needs to not go broke. Three pieces of the original Automaton design actually pulled their weight, and this library extracts exactly those:

  • Map a balance to survival tiers. One function turns a cents balance into a tier with sensible, fully configurable thresholds.
  • Enforce per-call / hourly / daily / session inference budgets. A budget tracker denies calls before you spend, driven by whatever cost store you plug in.
  • Auto-downgrade the model when funds run low. Below the healthy tiers, the agent falls back to a cheaper model instead of stopping dead.

Everything else (Conway APIs, on-chain USDC, SQLite schema, sandbox plumbing) has been stripped out. What is left is small, testable, and dependency-free.

Install

npm i github:Princeu3/agent-budget-guard

npm-registry release coming soon. For now install straight from GitHub.

Requires Node.js >= 20.

Quick start

import {
  getSurvivalTier,
  getModelForTier,
  TierManager,
  InferenceBudgetTracker,
  DEFAULT_MODEL_STRATEGY_CONFIG,
} from "agent-budget-guard";

// 1. Map a balance (in cents) to a survival tier.
getSurvivalTier(650); // "high"
getSurvivalTier(30);  // "low_compute"
getSurvivalTier(0);   // "critical" (broke but alive)
getSurvivalTier(-5);  // "dead"

// 2. Pick the model for the current tier (cheap-model name is configurable).
getModelForTier("high", "gpt-5.2", "gpt-5-mini");        // "gpt-5.2"
getModelForTier("low_compute", "gpt-5.2", "gpt-5-mini"); // "gpt-5-mini"

// 3. Track tier changes + react via hooks (no database required).
const tiers = new TierManager({
  hooks: {
    setLowComputeMode: (on) => console.log("low-compute:", on),
    onTier: (tier) => console.log("now in tier:", tier),
  },
});
tiers.update(650); // enters "high"
tiers.update(5);   // "high" → "critical", transition recorded
tiers.canRunInference(); // true (false only when dead)

// 4. Enforce inference budgets before spending.
const budget = new InferenceBudgetTracker({
  ...DEFAULT_MODEL_STRATEGY_CONFIG,
  perCallCeilingCents: 50,
  hourlyBudgetCents: 500,
  dailyBudgetCents: 2000,
});

const decision = budget.checkBudget(40); // { allowed: true }
if (decision.allowed) {
  // ...make the call, then record what it cost:
  budget.recordCost({
    sessionId: "sess-1", turnId: null, model: "gpt-5.2", provider: "openai",
    inputTokens: 800, outputTokens: 200, costCents: 40, latencyMs: 900,
    tier: "high", taskType: "chat", cacheHit: false,
  });
}

API

Tier functions (tiers)

Function Description
getSurvivalTier(creditsCents, thresholds?) Map a cents balance to "high" | "normal" | "low_compute" | "critical" | "dead". Thresholds default to SURVIVAL_THRESHOLDS. Zero → critical, negative → dead.
getModelForTier(tier, defaultModel, cheapModel?) Returns defaultModel in high/normal, and cheapModel (default "gpt-5-mini") once low.
canRunInference(tier) false only when dead.
applyTierRestrictions(tier, hooks) Calls hooks.setLowComputeMode(on) and hooks.onTier(tier).
formatCredits(cents) 512 → "$5.12".
SURVIVAL_THRESHOLDS Default thresholds (cents): high 500, normal 50, low_compute 10, critical 0, dead -1. Fully overridable.

TierManager

new TierManager({ thresholds?, hooks?, maxHistory? }) — wraps the tier functions with change detection and a capped in-memory transition history (default 50).

  • update(creditsCents){ tier, previousTier, tierChanged, transition }; applies restrictions and records a transition on change.
  • getTier(creditsCents), getCurrentTier(), getHistory(), canRunInference(), recordTransition(from, to, creditsCents).

InferenceBudgetTracker

new InferenceBudgetTracker(config, store?)config is a ModelStrategyConfig; store defaults to InMemoryCostStore.

  • checkBudget(estimatedCostCents, model?, sessionId?){ allowed, reason? }; enforces per-call ceiling, then hourly, daily and (with a sessionId) session budgets. A budget of 0 means "no limit".
  • recordCost(row), getHourlyCost(), getDailyCost(date?), getSessionCost(sessionId), getModelCosts(model, days?).

CostStore

Inject your own persistence by implementing CostStore (insert, getSessionCosts, getDailyCost, getHourlyCost, getModelCosts). The bundled InMemoryCostStore is the zero-dependency default.

Attribution

Extracted, refactored and decoupled by Prince Upadhyay (@Princeu3) from the MIT-licensed Conway-Research/automaton. See NOTICE for details.

Keywords

llm, ai-agents, budget, cost-control, inference-cost, rate-limiting, model-selection, autonomous-agents, token-budget, degradation, openai, anthropic, typescript, finops, llmops

License

MIT

About

Budget-aware degradation for autonomous AI agents — map a spend balance to survival tiers, enforce per-call, hourly and daily LLM inference budgets, and automatically downgrade the model when funds run low.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages