Measure how full your agent's context is getting from weighted signals, pick a load mode, and budget tokens — so long sessions degrade gracefully instead of blowing up.
Context Budget keeps a long-running LLM agent from capsizing under its own context. Register the signals that predict pressure — memory-file size, log line-counts, session age, task count, anything — each with comfortable/stressed/critical thresholds and a weight. Context Budget blends them into a single 0–1 pressure score and picks a load mode: FULL, COMPRESSED, or EMERGENCY. Pair it with a token budget (a cheap chars-based estimate or your own tokenizer) to decide how much history to keep, when to summarize, and when to hard-trim. Pure Node, zero dependencies, never throws — a small keel for agents that run for hours.
Register any signal — a memory file's size, a log's line-count, minutes since session start, tasks completed — with comfortable/stressed/critical thresholds and a weight. Context Budget normalizes each to 0–1 and blends them into one pressure score. Values can be numbers or lazy functions; missing files read as zero, never a throw.
Pressure maps to a mode: FULL (load everything), COMPRESSED (essentials only), EMERGENCY (bare minimum + flag for compaction). Cutoffs are yours to set. Ask Context Budget for the mode at the top of a turn and load memory accordingly — a smooth ramp-down instead of a hard overflow.
Estimate any text's token cost with a fast chars-based heuristic, or plug in your model's real tokenizer. Track spend against a ceiling, ask what's remaining, and decide what to keep or summarize before you run out — the budget is a hard number, not a guess.
Every value comes from .env. Nothing here is tied to any account — bring your own.
# 1. no install needed — pure Node builtins node examples/demo.cjs # build a meter, print pressure + mode + budget # 2. in your code # const { Meter, Budget, estimateTokens } = require('./lib/context-budget.cjs'); # const m = new Meter(); # m.add({ name: 'memory', weight: 0.5, value: () => require('fs').statSync('mem.json').size, # comfortable: 50e3, stressed: 200e3, critical: 500e3 }); # m.add({ name: 'session-min', weight: 0.2, value: minutesSinceStart, comfortable: 30, stressed: 90, critical: 180 }); # const mode = m.mode(); // 'FULL' | 'COMPRESSED' | 'EMERGENCY' # const b = new Budget(120000); b.spend(estimateTokens(history)); b.remaining();