budget

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package budget meters model usage against workload budget ceilings.

Spike-2 probe for the "where does cost accounting come from" question (docs/orchestration-design.md budget composition): ADK v2 carries genai UsageMetadata on every model event (session.Event embeds model.LLMResponse), so a meter over the runner's event stream sees token counts per call with no ADK patching. What ADK does NOT provide is pricing or enforcement — both are mast-side. This package is the minimal mast-side shape: per-session cumulative token/cost meter, checked as events stream; the caller aborts the run when Observe reports the ceiling is crossed.

Known limitation (finding, not TODO): metering at the event stream is enforcement-after-the-call — a single runaway call is only caught once its usage event lands. Pre-call gating needs a model-layer interceptor (wrap model.LLM) or the v2.1.0 TaskRunner seam for tool fan-out; both compose with this meter rather than replacing it.

Index

Constants

This section is empty.

Variables

View Source
var ErrExceeded = errors.New("budget exceeded")

ErrExceeded is returned by Observe once the session's cumulative usage crosses a ceiling. Callers should abort the run.

Functions

This section is empty.

Types

type Limits

type Limits struct {
	MaxCostUSD float64
	MaxTokens  int64

	// MaxTurns caps the number of model calls in the session.
	//
	// Vocabulary: mast counts one "turn" per model call — the same
	// unit as the meter's calls counter (one streamed event carrying
	// UsageMetadata). This matches docs/orchestration-design.md's
	// "budget.max_turns remains mast-side turn counting (ADK has no
	// turn cap)": a Task specialist that loops through five model
	// calls before finish_task has spent five turns, not one.
	MaxTurns int

	RatePer1K float64 // flat USD per 1K total tokens (spike pricing model)
}

Limits are the ceilings for one session. Zero values mean unlimited.

type Meter

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

Meter accumulates usage for one session.

func NewMeter

func NewMeter(limits Limits) *Meter

NewMeter constructs a Meter with the given limits.

func (*Meter) Observe

func (m *Meter) Observe(ev *session.Event) error

Observe folds one event's usage into the meter and reports whether a ceiling has been crossed. Events without UsageMetadata (function responses, control events) are free.

func (*Meter) Snapshot

func (m *Meter) Snapshot() (tokens int64, costUSD float64, calls int)

Snapshot returns the cumulative usage so far.

Jump to

Keyboard shortcuts

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