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

@thenoo/finops

v0.1.0

Published

FinOps cost tracking and budget management for @thenoo/agentkit with multi-session support

Readme

@thenoo/finops

FinOps cost tracking and budget management for AI agents

Multi-session support, real-time alerts, and adapter integration.

npm version CI Status Coverage Downloads License: MIT TypeScript

Quick StartAPI DocsExamplesChangelog


🎉 What's New in v0.2.0

@thenoo/finops is now a standalone package extracted from @thenoo/agentkit for better modularity and reusability.

✨ New Features

  • FinOpsContext - Multi-session cost tracking with isolated budgets
  • Adapter Integration - Seamless integration with @thenoo/adapter-openai via withFinOps()
  • Event System - Subscribe to cost:update, cost:alert, and budget:reset events
  • OpenTelemetry Ready - Export metrics to OpenTelemetry collectors

📦 Migration from v0.1.0

If you were using budget utilities from @thenoo/[email protected]:

- import { budget, BudgetManager } from '@thenoo/agentkit';
+ import { createBudgetManager, BudgetManager } from '@thenoo/finops';

The API remains the same - only the import path changed.

🔗 Related


Features

  • 💰 Budget Management - Session and per-request budget limits
  • 📊 Cost Tracking - Token usage and cost calculation
  • 🎯 Multi-Session Support - Track costs independently per session
  • 🚨 Event-Driven Alerts - Real-time cost alerts and updates
  • 🔌 Adapter Integration - FinOpsContext interface for seamless adapter integration
  • 🛡️ Type-Safe - Full TypeScript support with Zod validation
  • 🌍 Edge Compatible - Works in edge runtimes

Installation

npm install @thenoo/finops

Quick Start

Basic Budget Manager

import { createBudgetManager } from '@thenoo/finops';

const manager = createBudgetManager({
  usd: 10,                    // Max $10 per session
  perRequestCents: 50,        // Max 50 cents per request
  onExceed: 'halt',           // Action when limit exceeded
});

// Track token usage
const state = manager.recordUsage(1000, 0.002); // 1k tokens at $0.002/1M
console.log(`Total spend: $${state.totalUsd.toFixed(4)}`);
console.log(`Remaining: $${state.remainingUsd.toFixed(4)}`);

FinOps Context with Multi-Session

import { createFinOpsContext } from '@thenoo/finops';

const context = createFinOpsContext({
  budgetConfig: {
    usd: 10,
    perRequestCents: 50,
    onExceed: 'halt',
  },
  debug: true,
});

// Track cost for different sessions
await context.trackCost({
  sessionId: 'user-123',
  tokens: 1000,
  costPerMTokenUsd: 0.002,
  model: 'gpt-4o-mini',
});

await context.trackCost({
  sessionId: 'user-456',
  tokens: 2000,
  costPerMTokenUsd: 0.002,
  model: 'gpt-4o-mini',
});

// Get state per session
const state = await context.getState('user-123');
console.log(`User 123 spent: $${state.totalUsd.toFixed(4)}`);

Core Concepts

Budget Manager

The BudgetManager tracks token usage and enforces spending limits for a single session:

import { createBudgetManager } from '@thenoo/finops';

const manager = createBudgetManager({
  usd: 5,                     // Session budget
  perRequestCents: 20,        // Per-request budget
  onExceed: 'halt',           // Policy: halt | truncate | degrade_model | alert
});

// Record usage
manager.recordUsage(1000, 0.002); // tokens, cost per 1M tokens

// Check if request would exceed budget
if (manager.wouldExceed(5000, 0.002)) {
  console.warn('Request would exceed budget');
}

// Get current state
const state = manager.getState();
console.log(state.totalUsd, state.remainingUsd, state.exceeded);

// Reset budget
manager.reset();

FinOps Context

The FinOpsContext provides multi-session support and adapter integration:

import { createFinOpsContext } from '@thenoo/finops';

const context = createFinOpsContext({
  budgetConfig: { usd: 10 },
});

// Track costs per session
await context.trackCost({
  sessionId: 'session-123',
  tokens: 1000,
  costPerMTokenUsd: 0.002,
  model: 'gpt-4o-mini',
});

// Check budget before request
const wouldExceed = await context.wouldExceed({
  sessionId: 'session-123',
  estimatedTokens: 5000,
  costPerMTokenUsd: 0.002,
});

// Get all active sessions
const sessions = await context.getSessions();
console.log(`Active sessions: ${sessions.length}`);

Budget Policies

Control what happens when budget limits are exceeded:

| Policy | Description | |--------|-------------| | halt | Stop execution immediately (default) | | truncate | Reduce token limits for next request | | degrade_model | Switch to a cheaper model | | alert | Emit warning but continue |

const manager = createBudgetManager({
  usd: 10,
  onExceed: 'degrade_model',
});

Event Handling

Listen for cost alerts and updates:

import { createBudgetManager, createFinOpsContext } from '@thenoo/finops';

// Budget Manager events
const manager = createBudgetManager({ usd: 5 });
manager.onEvent((event) => {
  if (event.type === 'cost:alert') {
    console.error('Budget exceeded!', event.payload);
  } else if (event.type === 'cost:update') {
    console.log('Cost update:', event.payload);
  }
});

// FinOps Context events
const context = createFinOpsContext({ budgetConfig: { usd: 10 } });

context.onCostAlert((payload) => {
  console.error('Cost alert:', payload);
  // payload: { sessionId, totalUsd, limitUsd, requestCents, policy, model, timestamp }
});

context.onCostUpdate((payload) => {
  console.log('Cost update:', payload);
  // payload: { sessionId, totalUsd, requestCents, requestCount, exceeded, model, timestamp }
});

Integration with Adapters

OpenAI Adapter Example

import { createOpenAIAdapter } from '@thenoo/adapter-openai';
import { createFinOpsContext } from '@thenoo/finops';

const finops = createFinOpsContext({
  budgetConfig: { usd: 10, perRequestCents: 50 },
});

const adapter = createOpenAIAdapter({
  apiKey: process.env.OPENAI_API_KEY!,
});

// Make a request
const response = await adapter.createChatCompletion({
  messages: [{ role: 'user', content: 'Hello!' }],
});

// Track cost
await finops.trackCost({
  sessionId: 'user-123',
  tokens: response.usage.total_tokens,
  costPerMTokenUsd: 2, // Model-specific rate
  model: response.model,
});

// Check budget state
const state = await finops.getState('user-123');
if (state.exceeded) {
  console.warn('Budget exceeded for user-123');
}

Custom Adapter Integration

Implement FinOpsContext in your adapter:

import type { FinOpsContext } from '@thenoo/finops';

class MyAdapter {
  constructor(private finops?: FinOpsContext) {}

  async generateText(prompt: string, sessionId?: string) {
    // Check budget before request
    if (this.finops) {
      const wouldExceed = await this.finops.wouldExceed({
        sessionId,
        estimatedTokens: estimateTokens(prompt),
        costPerMTokenUsd: 0.002,
      });

      if (wouldExceed) {
        throw new Error('Request would exceed budget');
      }
    }

    // Make API call
    const response = await this.makeRequest(prompt);

    // Track actual cost
    if (this.finops) {
      await this.finops.trackCost({
        sessionId,
        tokens: response.usage.total_tokens,
        costPerMTokenUsd: 0.002,
        model: response.model,
      });
    }

    return response;
  }
}

Utility Functions

Estimate Tokens

import { estimateTokens } from '@thenoo/finops';

const tokens = estimateTokens('Hello, world!');
console.log(`Estimated: ${tokens} tokens`); // ~4 tokens (4 chars/token heuristic)

Calculate Token Usage

import { calculateTokens } from '@thenoo/finops';

const usage = calculateTokens(100, 50); // input, output
console.log(usage.total); // 150
console.log(usage.input); // 100
console.log(usage.output); // 50

Configuration

BudgetConfig

interface BudgetConfig {
  /** Maximum spend per session in USD */
  usd?: number;
  
  /** Maximum spend per request in cents */
  perRequestCents?: number;
  
  /** Action when budget exceeded */
  onExceed?: 'halt' | 'truncate' | 'degrade_model' | 'alert';
}

FinOpsContextConfig

interface FinOpsContextConfig {
  /** Budget manager instance */
  budgetManager?: BudgetManager;
  
  /** Default budget config (used if budgetManager not provided) */
  budgetConfig?: BudgetConfig;
  
  /** Enable debug logging */
  debug?: boolean;
}

TypeScript Support

Full TypeScript support with exported types:

import type {
  BudgetConfig,
  BudgetState,
  BudgetPolicy,
  TokenUsage,
  CostCalculation,
  CostAlertPayload,
  CostUpdatePayload,
  FinOpsContext,
  FinOpsContextConfig,
  FinOpsEvent,
} from '@thenoo/finops';

Backward Compatibility

For @thenoo/agentkit v0.1.0 users, the budget functionality is still available but deprecated:

// Old way (still works, but deprecated)
import { budget } from '@thenoo/agentkit';

// New way (recommended)
import { createBudgetManager } from '@thenoo/finops';

Related Packages

Examples

Basic Budget Enforcement

import { createBudgetManager } from '@thenoo/finops';

const manager = createBudgetManager({
  usd: 1,
  onExceed: 'halt',
});

// Track usage
try {
  manager.recordUsage(1_000_000, 2); // $2 (exceeds $1 limit)
} catch (error) {
  console.error('Budget exceeded!');
}

Multi-User Application

import { createFinOpsContext } from '@thenoo/finops';

const finops = createFinOpsContext({
  budgetConfig: { usd: 5 }, // $5 per user
});

async function handleUserRequest(userId: string, prompt: string) {
  // Check budget
  const wouldExceed = await finops.wouldExceed({
    sessionId: userId,
    estimatedTokens: estimateTokens(prompt),
    costPerMTokenUsd: 0.002,
  });

  if (wouldExceed) {
    throw new Error('User budget exceeded');
  }

  // Process request...
  const tokens = 1000;
  await finops.trackCost({
    sessionId: userId,
    tokens,
    costPerMTokenUsd: 0.002,
  });
}

Real-Time Monitoring

import { createFinOpsContext } from '@thenoo/finops';

const finops = createFinOpsContext({ budgetConfig: { usd: 10 } });

// Real-time cost monitoring
finops.onCostUpdate(async (payload) => {
  console.log(`Session: ${payload.sessionId}`);
  console.log(`Total: $${payload.totalUsd.toFixed(4)}`);
  console.log(`Requests: ${payload.requestCount}`);

  // Send to monitoring service
  await sendMetric('llm.cost', payload.totalUsd, {
    session: payload.sessionId,
    model: payload.model,
  });
});

// Alert on budget breach
finops.onCostAlert(async (payload) => {
  await sendAlert({
    severity: 'high',
    message: `Budget exceeded for ${payload.sessionId}`,
    totalUsd: payload.totalUsd,
    limitUsd: payload.limitUsd,
  });
});

Adapter Integration

The @thenoo/finops package is designed to integrate with LLM adapters like @thenoo/adapter-openai and @thenoo/adapter-azure to provide automatic cost tracking and budget enforcement.

Using with @thenoo/adapter-openai

Wrap your OpenAI adapter with withFinOps() from @thenoo/adapter-openai:

import { createOpenAIAdapter, withFinOps } from '@thenoo/adapter-openai';

const adapter = createOpenAIAdapter({
  apiKey: process.env.OPENAI_API_KEY!,
});

const wrapped = withFinOps(adapter, {
  sessionId: 'user-123',
  budget: {
    usd: 10,
    perRequestCents: 50,
    policy: 'degrade_model',
  },
  onAlert: (event) => {
    console.warn('Budget alert:', event);
  },
});

// Automatic cost tracking
const response = await wrapped.createChatCompletion({
  messages: [{ role: 'user', content: 'Hello!' }],
});

Events Payload Shapes

cost:update

{
  type: 'cost:update',
  payload: {
    sessionId: string;
    totalUsd: number;
    requestCount: number;
    tokens: number;
    model?: string;
    timestamp: number;
  }
}

cost:alert

{
  type: 'cost:alert',
  payload: {
    sessionId: string;
    totalUsd: number;
    limitUsd: number;
    policy: BudgetPolicy;
    exceeded: boolean;
    timestamp: number;
  }
}

budget:reset

{
  type: 'budget:reset',
  payload: {
    sessionId?: string; // undefined for global reset
    timestamp: number;
  }
}

OpenTelemetry Integration (Optional)

Export FinOps metrics to OpenTelemetry:

import { createFinOpsContext } from '@thenoo/finops';
import { metrics } from '@opentelemetry/api';

const finops = createFinOpsContext({ budgetConfig: { usd: 10 } });
const meter = metrics.getMeter('@thenoo/finops');
const costCounter = meter.createCounter('llm.cost.usd', {
  description: 'LLM API costs in USD',
});

finops.onCostUpdate((payload) => {
  costCounter.add(payload.totalUsd, {
    session: payload.sessionId,
    model: payload.model || 'unknown',
  });
});

License

MIT © Zachery Kuykendall

Links