cost

package
v0.167.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package cost tracks Anthropic token usage and running dollar cost per PromptZero session, and implements the simple "consecutive errors → offline" heuristic that flips the observability offline banner.

Pricer is a read-only rate table: model name → USD per million tokens (input/output split). PromptZero ships with built-in rates for the current Claude lineup; operators can override or extend the table via config.

Tracker accumulates tokens and stream errors. When three consecutive streams fail within a 60s window, Tracker flips to offline and invokes the Offline hook; a successful stream clears the error run and flips back online. The three-strikes rule keeps transient network hiccups from flipping the banner on every stutter.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultRates

func DefaultRates() map[string]Rate

DefaultRates returns a copy of the built-in rate table. Current Claude lineup as of late-2025: Opus 4.7 $15/$75, Sonnet 4.6 $3/$15, Haiku 4.5 $0.80/$4. Values should track Anthropic's public pricing page; adjust via config override when it drifts.

Types

type Pricer

type Pricer struct {
	// contains filtered or unexported fields
}

Pricer owns the rate table. Lookup is case-insensitive and falls through on unknown models to (0, 0) so the Tracker still records token counts even when the rate isn't known.

func NewPricer

func NewPricer(overrides map[string]Rate) *Pricer

NewPricer seeds a Pricer with DefaultRates plus any overrides. Keys are normalized (trimmed, lower-cased) so "Claude-Opus-4-7" and "claude-opus-4-7" resolve to the same row.

func (*Pricer) Cost

func (p *Pricer) Cost(model string, inTokens, outTokens int64) float64

Cost computes USD for (input, output) token counts against the model's rates. Zero rates produce zero cost.

func (*Pricer) CostWithCache added in v0.3.0

func (p *Pricer) CostWithCache(model string, inTokens, outTokens, cacheReadTokens, cacheCreationTokens int64) float64

CostWithCache is Cost plus prompt-cache read and creation tokens. Cache reads are billed at 0.1x the normal input rate; cache creations at 1.25x. The multipliers match Anthropic's published pricing as of late 2025; if they drift, this is the only place to update.

func (*Pricer) Rate

func (p *Pricer) Rate(model string) (Rate, bool)

Rate returns the per-million-token rates for the given model. Unknown models return zero rates (and ok=false); callers typically still record the token counts with zero cost.

type Rate

type Rate struct {
	InputPerMTok  float64
	OutputPerMTok float64
}

Rate is one model's price schedule. Values are USD per million tokens.

type Snapshot

type Snapshot struct {
	Model               string
	InputTokens         int64
	OutputTokens        int64
	CacheReadTokens     int64
	CacheCreationTokens int64
	TotalUSD            float64
	Offline             bool
	// BudgetUSD is the configured session cap; 0 means no budget.
	// /cost and /status render the spent/cap pair when non-zero.
	BudgetUSD float64
}

Snapshot is a point-in-time copy of the Tracker's accumulated state.

func (Snapshot) CacheHitRate added in v0.3.0

func (s Snapshot) CacheHitRate() float64

CacheHitRate returns the fraction of prompt-cacheable input tokens that landed on an existing cache (vs. paid full-price for cache creation). Returns 0 when neither counter has moved yet so fresh sessions don't render a divide-by-zero. Intended for /stats and dashboard display.

func (Snapshot) Format

func (s Snapshot) Format() string

Format returns the single-line human summary used by /cost and /status.

type Tracker

type Tracker struct {
	// contains filtered or unexported fields
}

Tracker accumulates token counts, dollar cost, and stream error streaks. It is safe for concurrent use. A zero-value Tracker is NOT usable — call NewTracker.

func NewTracker

func NewTracker(p *Pricer, model string, onOffline func(bool)) *Tracker

NewTracker builds a Tracker bound to a specific model. The offline hook is invoked (with the new state) on every transition — pass nil to disable. Model can be changed later via SetModel when the user picks a new default mid-session.

func (*Tracker) AddUsage

func (t *Tracker) AddUsage(inTokens, outTokens int64)

AddUsage records one response's input/output token counts and bumps the running USD total. Any successful usage record also clears the consecutive-error run and flips the tracker back online if it was offline. Prefer AddUsageFull for callers that have cache token counters — this wrapper ignores them.

func (*Tracker) AddUsageFull added in v0.3.0

func (t *Tracker) AddUsageFull(inTokens, outTokens, cacheReadTokens, cacheCreationTokens int64)

AddUsageFull is the complete version of AddUsage that also records prompt-cache read / creation tokens. Cache-read tokens are billed at ~10 % of the normal input rate (Anthropic's current published number); cache-creation tokens are billed at ~125 % to amortise the cache write. Model rates default to uncached input pricing if no cache rate is configured, so the dollar line is always conservative.

func (*Tracker) BudgetExceeded added in v0.21.0

func (t *Tracker) BudgetExceeded() bool

BudgetExceeded reports whether the session has crossed the configured 100% cap. Returns false when no budget is set. Used by the agent's pre-dispatch check to refuse new turns once the cap is exhausted.

func (*Tracker) RecordStreamError

func (t *Tracker) RecordStreamError()

RecordStreamError notifies the tracker that one Messages.NewStreaming call failed. Three failures inside errRunWindow flip offline.

func (*Tracker) SetBudget added in v0.21.0

func (t *Tracker) SetBudget(usdCap float64, onWarn, onHit func(spent, cap float64))

SetBudget configures a session USD cap and the callbacks that fire at the 80%-warn and 100%-cap thresholds. usdCap == 0 disables the budget entirely (default). Either callback may be nil.

The 80% threshold fires once per session; the 100% threshold fires once. Re-entering thresholds after a budget bump (e.g. operator raises the cap with /budget set) requires resetting the flags via SetBudget — passing usdCap >= current spend resets warned/hit automatically.

func (*Tracker) SetModel

func (t *Tracker) SetModel(model string)

SetModel updates the tracker's active model. Past usage stays attributed to the prior model's cost — only future AddUsage calls pick up the new rate.

func (*Tracker) Snapshot

func (t *Tracker) Snapshot() Snapshot

Snapshot returns the current state for the /cost REPL command and the /debug view.

func (*Tracker) UpdateBudgetCap added in v0.23.0

func (t *Tracker) UpdateBudgetCap(usdCap float64)

UpdateBudgetCap changes the configured USD cap without touching the warn/hit callbacks (which were wired once at setup time). When the new cap clears the current spend the warned/hit flags reset so a future re-cross fires a fresh notification — matching SetBudget's "operator bumps the cap" behaviour. Setting cap to 0 disables the budget gate entirely. Used by the /budget REPL command.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL