npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@painitehq/ai-budget

v0.5.1

Published

Track AI agent costs, tokens, runtime and spending. Prevent runaway OpenAI, Anthropic, LangGraph and OpenRouter agents from exceeding budget.

Readme

@painitehq/ai-budget

Stop runaway AI agents from burning through your API credits. Track cost, tokens, runtime, and steps. Enforce hard budget limits for OpenAI, Anthropic, LangGraph, LangChain, OpenRouter, CrewAI, Mastra, AutoGen, and any LLM workflow.

@painitehq/ai-budget helps developers track AI agent costs, enforce token limits, set spending caps, monitor LLM usage, and prevent runaway OpenAI, Anthropic, and OpenRouter agents from exceeding budget. Works with every provider. Zero vendor lock-in.

Install

npm install @painitehq/ai-budget

Quick start

import { AgentBudget, BudgetError } from '@painitehq/ai-budget';

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: {
    maxCostUSD:     0.10,
    maxSteps:       15,
    maxTotalTokens: 50_000,
    maxWallTimeMs:  30_000,
  },
});

const response = await agent.step({
  model: 'anthropic/claude-opus-4-8',
  messages: [{ role: 'user', content: 'Hello' }],
});

console.log(agent.getUsage());

Prevent runaway AI agents

Agent loops multiply LLM costs across every step. Without guardrails, a single loop can burn through your entire API budget in seconds. @painitehq/ai-budget blocks each call before and after it hits your provider -- so you never overspend.

const agent = new AgentBudget({
  apiKey: key,
  limits: { maxCostUSD: 0.05, maxSteps: 10 },
});

try {
  while (true) {
    const res = await agent.step({ model, messages });
    messages.push(res.choices[0].message);
    messages.push({ role: 'user', content: 'Continue.' });
  }
} catch (err) {
  if (err instanceof BudgetError) {
    console.log('Agent stopped:', err.exceeded.reason);
  }
}

Track LLM costs in production

Get real-time visibility into every API call. See cost per step, total spend, token breakdown, and wall time.

const usage = agent.getUsage();
// {
//   steps: 12,
//   totalCostUSD: 0.0847,
//   totalInputTokens: 24300,
//   totalOutputTokens: 8200,
//   elapsedMs: 45200,
//   stepHistory: [...]
// }

agent.summary(); // formatted table in console

Set hard budget caps

Every limit is optional. Set only what you need.

limits: {
  maxCostUSD:      0.05,   // total USD across all steps
  maxSteps:        10,     // total LLM calls
  maxInputTokens:  50000,  // input tokens only
  maxOutputTokens: 10000,  // output tokens only
  maxTotalTokens:  60000,  // input + output combined
  maxWallTimeMs:   60000,  // wall clock time in ms
}

Runtime limits for AI agents

Kill agents that run too long. Set wall time limits to prevent infinite loops from consuming compute and money.

const agent = new AgentBudget({
  apiKey: key,
  limits: {
    maxWallTimeMs: 30_000,  // 30 second hard stop
    maxCostUSD: 1.00,
  },
});

Token usage tracking

Track input tokens, output tokens, and total tokens across every step. Know exactly where your budget goes.

agent.on('step:end', (e) => {
  console.log(`Step ${e.stepIndex}: ${e.inputTokens} in / ${e.outputTokens} out / $${e.costUSD}`);
});

Agent guardrails

Pre-flight checks estimate output cost before the API call. Post-step checks record actual spend. If a limit is hit, the step rolls back and you can retry cleanly.

try {
  await agent.step({ model, messages });
} catch (err) {
  if (err instanceof BudgetError) {
    err.exceeded.reason;  // 'cost' | 'steps' | 'totalTokens' | 'wallTime'
    err.exceeded.usage;   // full snapshot at cutoff
  }
}

OpenAI cost tracking

Use @painitehq/ai-budget with the OpenAI SDK to track GPT-5.5 costs in real time.

import { AgentBudget } from '@painitehq/ai-budget';
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const agent = new AgentBudget({
  apiKey: process.env.OPENAI_API_KEY,
  limits: { maxCostUSD: 0.50 },
  executor: async (request) => {
    const completion = await openai.chat.completions.create({
      model: request.model,
      messages: request.messages,
    });
    return {
      model: completion.model,
      usage: {
        prompt_tokens: completion.usage?.prompt_tokens ?? 0,
        completion_tokens: completion.usage?.completion_tokens ?? 0,
        total_tokens: completion.usage?.total_tokens ?? 0,
      },
      choices: completion.choices.map(c => ({
        message: { role: c.message.role, content: c.message.content ?? '' },
        finish_reason: c.finish_reason ?? 'stop',
      })),
    };
  },
});

Anthropic budget limits

Set spending caps on Claude Opus, Sonnet, and Haiku. Track token usage and enforce cost limits for Anthropic models.

const agent = new AgentBudget({
  apiKey: process.env.ANTHROPIC_API_KEY,
  limits: { maxCostUSD: 0.25, maxSteps: 20 },
  executor: async (request) => {
    const response = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'x-api-key': process.env.ANTHROPIC_API_KEY!,
        'anthropic-version': '2026-01-01',
        'content-type': 'application/json',
      },
      body: JSON.stringify({
        model: request.model,
        messages: request.messages,
        max_tokens: 1024,
      }),
    });
    const data = await response.json();
    return {
      model: data.model,
      usage: {
        prompt_tokens: data.usage?.input_tokens ?? 0,
        completion_tokens: data.usage?.output_tokens ?? 0,
        total_tokens: (data.usage?.input_tokens ?? 0) + (data.usage?.output_tokens ?? 0),
      },
      choices: [{
        message: { role: 'assistant', content: data.content?.[0]?.text ?? '' },
        finish_reason: 'stop',
      }],
    };
  },
});

LangGraph budget control

Add budget limits to LangGraph agent graphs. Prevent infinite loops and control cost per execution.

import { AgentBudget, BudgetError } from '@painitehq/ai-budget';

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: { maxCostUSD: 0.20, maxSteps: 50 },
});

// Use inside a LangGraph node
async function agentNode(state) {
  const response = await agent.step({
    model: 'anthropic/claude-opus-4-8',
    messages: state.messages,
  });
  return { messages: [...state.messages, response.choices[0].message] };
}

LangChain cost monitoring

Track costs for LangChain chains and agents. Set token limits and spending caps.

import { AgentBudget } from '@painitehq/ai-budget';

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: { maxCostUSD: 0.15, maxTotalTokens: 100_000 },
});

// Wrap any LangChain call
const response = await agent.step({
  model: 'openai/gpt-5.5',
  messages: [{ role: 'user', content: prompt }],
});

OpenRouter spend caps

@painitehq/ai-budget fetches live pricing from OpenRouter. No hardcoded price tables. If OpenRouter adds a model, it works automatically.

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: { maxCostUSD: 0.10 },
});

// Pricing is fetched and cached automatically
const response = await agent.step({
  model: 'anthropic/claude-opus-4-8',
  messages: [{ role: 'user', content: 'Hello' }],
});

Ollama agent limits

Set budget limits for local Ollama models. Track token usage even for self-hosted inference.

const agent = new AgentBudget({
  apiKey: 'ollama',
  limits: { maxSteps: 100, maxWallTimeMs: 60_000 },
  baseUrl: 'http://localhost:11434/v1',
  executor: async (request) => {
    const res = await fetch('http://localhost:11434/api/chat', {
      method: 'POST',
      body: JSON.stringify({ model: request.model, messages: request.messages }),
    });
    const data = await res.json();
    return {
      model: data.model,
      usage: data.usage ?? { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
      choices: data.messages?.map((m) => ({
        message: { role: m.role, content: m.content },
        finish_reason: 'stop',
      })) ?? [],
    };
  },
});

CrewAI budget enforcement

Add cost limits to CrewAI agent crews. Prevent multi-agent systems from running up bills.

import { AgentBudget } from '@painitehq/ai-budget';

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: { maxCostUSD: 1.00, maxSteps: 100 },
});

// Use in CrewAI task execution
const response = await agent.step({
  model: 'anthropic/claude-opus-4-8',
  messages: [{ role: 'user', content: taskDescription }],
});

Mastra agent limits

Set budget limits for Mastra agents. Track cost and tokens across agent workflows.

import { AgentBudget } from '@painitehq/ai-budget';

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: { maxCostUSD: 0.50, maxSteps: 30 },
});

AutoGen cost control

Add budget limits to AutoGen multi-agent conversations. Prevent agent loops from exceeding budget.

import { AgentBudget } from '@painitehq/ai-budget';

const agent = new AgentBudget({
  apiKey: process.env.OPENROUTER_API_KEY,
  limits: { maxCostUSD: 0.25, maxSteps: 20 },
});

LLM observability

Subscribe to lifecycle events for full visibility into agent behavior.

agent.on('step:start', (e) => console.log('Step', e.stepIndex, 'started'));
agent.on('step:token', (e) => process.stdout.write(e.token));
agent.on('step:end', (e) => console.log(`Step cost: $${e.costUSD}`));
agent.on('budget:exceeded', (e) => console.log('Limit hit:', e.exceeded.reason));
agent.on('budget:warning', (e) => console.log(`Warning: ${e.pctConsumed * 100}% consumed`));
agent.on('model:downgraded', (e) => console.log(`Downgraded: ${e.from} → ${e.to}`));

Adaptive model routing

Downgrade to cheaper models as budget depletes. Automatic fallback chains.

const agent = new AgentBudget({
  apiKey: key,
  limits: { maxCostUSD: 5.00 },
  adaptiveRouting: {
    fallbackChain: [
      'anthropic/claude-opus-4-8',
      'openai/gpt-5.5',
      'openrouter/free',
    ],
    thresholds: [0.4, 0.75],
  },
});

Circuit breaker

Detect repetition or stagnation and halt the agent before it burns through credits.

const agent = new AgentBudget({
  apiKey: key,
  limits: { maxCostUSD: 1.00 },
  circuitBreaker: {
    repetitionWindow: 3,
    repetitionThreshold: 0.85,
    stagnationWindow: 4,
    stagnationMinLength: 50,
  },
});

Auto-compress messages

Truncate message history with an LLM summary when token count exceeds a threshold.

const agent = new AgentBudget({
  apiKey: key,
  limits: { maxTotalTokens: 100_000 },
  autoCompress: {
    thresholdTokens: 80_000,
    keepLastN: 4,
  },
});

Checkpoints

Save and resume agent state across restarts.

const agent = new AgentBudget({
  apiKey: key,
  limits: { maxCostUSD: 0.50 },
  checkpoint: { enabled: true, path: './agent-state.json' },
});

// Resume later
const resumed = await AgentBudget.resume(options);

Warning thresholds

Get notified before hitting limits.

const agent = new AgentBudget({
  limits: { maxCostUSD: 0.10 },
  warningThreshold: 0.5,
});

agent.on('budget:warning', (e) => {
  console.log(`${e.pctConsumed * 100}% of ${e.reason} budget consumed`);
});

@painitehq/ai-budget vs LangSmith

LangSmith is an observability platform. @painitehq/ai-budget is a runtime enforcement layer. LangSmith shows you what happened. @painitehq/ai-budget stops it from happening.

| | @painitehq/ai-budget | LangSmith | |---|---|---| | Runtime enforcement | Yes | No | | Pre-flight cost estimation | Yes | No | | Budget limits | Hard stops | Soft alerts | | Pricing | Free, self-hosted | Paid SaaS | | Provider lock-in | None | LangChain ecosystem |


@painitehq/ai-budget vs Helicone

Helicone is a proxy for LLM cost tracking. @painitehq/ai-budget is an SDK that enforces limits at runtime. Helicone tracks after the fact. @painitehq/ai-budget blocks before spend happens.

| | @painitehq/ai-budget | Helicone | |---|---|---| | Runtime enforcement | Yes | No | | Pre-flight checks | Yes | No | | Self-hosted | Yes | Cloud only | | Free tier | Yes | Limited |


@painitehq/ai-budget vs Langfuse

Langfuse is an LLM observability tool. @painitehq/ai-budget is a budget enforcement SDK. Langfuse gives you dashboards. @painitehq/ai-budget gives you hard limits.

| | @painitehq/ai-budget | Langfuse | |---|---|---| | Runtime enforcement | Yes | No | | Pre-flight cost estimation | Yes | No | | Budget limits | Hard stops | Observability only | | Self-hosted | Yes | Yes | | Free | Yes | Yes (self-hosted) |


@painitehq/ai-budget vs OpenAI Usage Dashboard

OpenAI's dashboard shows usage after the fact. @painitehq/ai-budget prevents overspend in real time.

| | @painitehq/ai-budget | OpenAI Dashboard | |---|---|---| | Real-time enforcement | Yes | No | | Pre-flight checks | Yes | No | | Multi-provider | Yes | OpenAI only | | Agent loop protection | Yes | No |


API

new AgentBudget(options)

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | required | Your provider API key | | limits | object | required | Budget limits (cost, tokens, steps, wall time) | | executor | function | -- | Custom API executor | | baseUrl | string | https://openrouter.ai/api/v1 | API base URL | | defaultHeaders | object | -- | Extra HTTP headers | | autoCompress | object | -- | Auto-compress messages at token threshold | | circuitBreaker | object | -- | Detect repetition/stagnation | | adaptiveRouting | object | -- | Downgrade models as budget depletes | | checkpoint | object | -- | Persist and resume agent state | | onExceeded | 'abort' \| function | 'abort' | Strategy when limit hit | | onEvent | function | -- | Global event listener | | warningThreshold | number | 0.75 | Warning at this fraction of any limit | | pricingCacheTTLMs | number | 300000 | Pricing cache TTL | | telemetry | object | -- | Enable OpenTelemetry spans |

agent.step(request)

One LLM call. Checks limits before and after. Throws BudgetError on exceed.

agent.getUsage()

Returns: steps, totalInputTokens, totalOutputTokens, totalCostUSD, elapsedMs, stepHistory.

agent.reset()

Reset all counters.

agent.refreshPricing()

Force re-fetch model prices.

agent.summary()

Formatted usage table in console.

agent.loadCheckpoint() / agent.clearCheckpoint()

Load or clear persisted state.

AgentBudget.resume(options, checkpointPath?)

Create a new agent pre-loaded with checkpoint state.

License

MIT