@polyweave/costs (1.0.6)
Installation
@polyweave:registry=https://hub.kl1.tenere.ai/api/packages/Polyweave/npm/npm install @polyweave/costs@1.0.6"@polyweave/costs": "1.0.6"About this package
@polyweave/costs
Cost tracking, prediction, and budget enforcement for Polyweave adapters. Provides a frame-protocol cost tracker with anytime-valid statistical guarantees, a Gaussian conjugate ratio e-process for output/input token ratio estimation, a rolling-hash cache-hit estimator, per-provider pricing tables, and token estimation utilities.
Synopsis
import { createCostTracker, createRatioEProcess, createRollingHash, setCustomPricing, getModelCost } from '@polyweave/costs';
import { createOpenAIAdapter } from '@polyweave/openai';
const adapter = createOpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY });
const tracker = createCostTracker(adapter, {
budget: 10.00,
provider: 'openai',
priorRatio: 1.5,
alpha: 0.10,
mode: 'conservative'
});
tracker.source.pipe(mySink);
// Query budget state
tracker.sink.write({ type: 'DESCRIBE' });
// → DESCRIPTION { budget: 10.00, totalCost: 0, ... }
// Predict cost before executing
tracker.sink.write({ type: 'COST_CHECK', content: { maxBudget: 2.00 } });
// → COST { estimatedCost, pExceeded, wouldBlock: false }
Install
npm install @polyweave/costs
Why
Cost enforcement in LLM pipelines needs more than a simple budget counter. The cost tracker uses:
- Anytime-valid e-processes — the Gaussian conjugate e-process provides statistical guarantees on false-block probability. Unlike p-values, e-values remain valid under optional stopping and continuous monitoring.
- Rolling-hash cache estimation — estimates KV-cache reuse across conversation turns by tracking which text windows have been seen before.
- Provider pricing tables — built-in pricing for 50+ models across all major providers. Overridable via
setCustomPricing.
These were extracted from @polyweave/core into a standalone package so consumers can use cost tracking without pulling in the full core dependency tree.
API
createCostTracker(innerDuplex, options)
Returns a wrapped duplex. Intercepts frames flowing through the adapter and tracks cumulative costs from RECEIPT frames. Blocks TEXT frames when budget is exceeded.
| Parameter | Type | Default | Description |
|---|---|---|---|
innerDuplex |
IFrameDuplex |
Yes | The adapter to wrap |
budget |
number |
0 |
Global spend limit in USD. 0 disables enforcement |
provider |
string |
null |
Provider name for pricing lookups |
priorRatio |
number |
1.5 |
Prior mean for the output/input token ratio e-process |
priorWeight |
number |
4 |
Prior precision (pseudo-observations) for the e-process |
alpha |
number |
0.10 |
Confidence interval width for cost estimates |
mode |
string |
'conservative' |
Estimation mode: 'conservative' or 'mean' |
cacheDiscount |
number |
0.5 |
Cost reduction factor for cache-hit tokens (0–1) |
sigma2 |
number |
0.01 |
Observation noise variance for the e-process |
onBudgetExceeded() |
function |
null |
Callback when budget is exceeded |
Frame protocol:
| Inbound (sink) | Effect |
|---|---|
TEXT / IMAGE / AUDIO |
Accumulates text for hashing; forwards to inner duplex |
COST_CHECK { maxBudget } |
Returns COST frame with estimate without executing |
DESCRIBE |
Returns DESCRIPTION with full budget state snapshot |
PARAM { budget, prior_gpt-4o, ... } |
Runtime parameter overrides |
RESET |
Resets all accumulators |
Output frames added on source:
| Frame | Content |
|---|---|
COST { estimatedCost, pExceeded, wouldBlock } |
Cost estimate based on e-process prediction |
DESCRIPTION { budget, totalCost, inputTokens, outputTokens, providerBreakdown, eprocess, cache } |
Full budget snapshot |
ERROR { code: 'BUDGET_EXCEEDED' } |
Budget has been exceeded and TEXT frames are blocked |
Snapshot:
The DESCRIPTION response includes a detailed snapshot:
budget/budgetRemaining— USD limitsinputTokens/outputTokens— cumulative token countsinputCost/outputCost/totalCost— cumulative USD costsrequestCount— number of requests processedproviderBreakdown— per-provider token and cost breakdowneprocess— e-process posterior state (mean, precision, sd)cache— rolling hash state for cache-hit estimation
createRatioEProcess(options)
Returns { update, estimate, tailProbability, testBudgetExceeded, getState }. A Gaussian conjugate e-process for tracking the output/input token ratio.
| Parameter | Type | Default | Description |
|---|---|---|---|
priorRatio |
number |
1.5 |
Prior mean (typical output tokens per input token) |
priorWeight |
number |
4 |
Prior precision in pseudo-observations |
sigma2 |
number |
0.01 |
Observation noise variance |
alpha |
number |
0.10 |
CI width for estimation and gating |
Methods:
| Method | Description |
|---|---|
update(inputTokens, outputTokens) |
Add an observation pair from a RECEIPT frame |
estimate(inputTokens, mode?) |
Predict output tokens and cost for given input. mode: 'conservative' uses upper CI bound |
tailProbability(theta) |
Posterior probability that ratio ≤ theta |
testBudgetExceeded(thetaDanger) |
Returns true if e-value exceeds 1/alpha (budget likely exceeded) |
getState() |
Returns { n, posteriorMean, posteriorSD, priorRatio, priorWeight } |
Statistical properties:
- The e-process is anytime-valid — you can peek at results and make decisions at any point without inflating false-positive rates
- The posterior converges as RECEIPT frames arrive
testBudgetExceededgates TEXT frame emission: if the e-process signals budget danger, the tracker blocks
createRollingHash(options)
Returns { match, commit, getState, reset }. Sliding window polynomial hash for cache-hit estimation.
| Parameter | Type | Default | Description |
|---|---|---|---|
windowSize |
number |
32 |
Sliding window size in characters |
base |
number |
31 |
Polynomial hash base |
Methods:
| Method | Description |
|---|---|
match(text) |
Returns { total, matched, ratio } — how many windows in text have been seen before |
commit(text) |
Adds all windows from text to the history. Returns count of new hashes |
getState() |
Returns { totalHashes, windowSize } — total unique hashes stored |
reset() |
Clears all hash history |
Use case: Before sending a request, match() the prompt text against the hash history. If the ratio is high, most of the prompt's KV-cache can reuse prior computation. The cacheDiscount in createCostTracker applies a cost reduction for cached tokens.
getModelCost(provider, model)
Returns the pricing entry for a provider-model pair from the built-in pricing tables.
const pricing = getModelCost('openai', 'gpt-4o');
// → { mtoksInput: 2.50, mtoksOutput: 10.00 }
Returns null if the provider or model is unknown.
calculateTokenCost(model, inputTokens, outputTokens, config?)
Calculates total cost in USD given token counts and a cost configuration.
const cost = calculateTokenCost('gpt-4o', 1000, 500, { mtoksInput: 2.50, mtoksOutput: 10.00 });
// → 0.0075
If no config is provided, looks up the model in the built-in pricing tables.
setCustomPricing(overrides)
Overrides default pricing tables.
setCustomPricing({
openai: {
'gpt-5': { mtoksInput: 2.00, mtoksOutput: 15.00 }
},
anthropic: {
'claude-4-5-sonnet': { mtoksInput: 3.50, mtoksOutput: 17.50 }
}
});
Call before creating adapters. Pricing is global — all adapters share the same pricing tables.
createCostEstimator(provider)
Creates a provider-specific cost estimator. Used internally by adapters.
const estimator = createCostEstimator('openai');
const cost = estimator.estimate({ model: 'gpt-4o', inputTokens: 500 });
// → { inputCost, outputCost, totalCost, model }
Errors
Error('Provider not found: <name>')—getModelCostcalled with unknown providerError('Model not found: <name>')—getModelCostcalled with unknown model
Tests
npm test
104 tests covering cost tracker frame interception, budget enforcement, e-process update/estimate/validation, rolling hash match/commit, pricing table lookups, custom pricing overrides, and token estimation.
Benchmarks
npm run bench
bench/cost-tracking.bench.js — cost tracker overhead, e-process update throughput, and rolling hash throughput.
Requirements
Node.js 22 or later. ESM only.
Peer dependency: @polyweave/core.
Dependencies
Development Dependencies
| ID | Version |
|---|---|
| @rigor/core | * |
| fast-check | ^3.23.2 |
Peer Dependencies
| ID | Version |
|---|---|
| @polyweave/core | * |