Help us shape the future of Go! Take the 2026 Go Developer Survey

usage

package
v0.57.0 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package usage keeps the ledger of model spend and prices it.

Every agent step and every utility call (title, risk check, compaction, turn-memory summary, deep-search ranking and synthesis) is written to one table in the global config DB, tagged with the project, session, provider and model it ran on. That is what lets a single view total spend across every project and model: each project keeps its sessions in its own DB, so the sessions alone could never answer "what have I spent this month".

Prices are never stored. A row is priced when it is read, from the provider's own listing or the model catalogue, so a price correction reaches history too.

Index

Constants

View Source
const (
	// KindStep is one agent step, keyed by its assistant message id.
	KindStep = "step"
	// KindUtility is one utility call made on a session's behalf.
	KindUtility = "utility"
)

Kinds of ledger row.

View Source
const (
	// BillingMetered is billed per token at a known price.
	BillingMetered = "metered"
	// BillingIncluded is a flat plan (Ollama Cloud) or a local model: nothing
	// is billed per token. OGX meters at the rates its gateway publishes.
	BillingIncluded = "included"
	// BillingUnpriced is billed per token at a price nothing publishes.
	BillingUnpriced = "unpriced"
	// BillingUnknown is work whose provider was never recorded (sessions from
	// before ogcode stored one) on a model nothing configured serves today, so
	// whether it was billed at all cannot be told. It is never counted as a
	// charge.
	BillingUnknown = "unknown"
)

How a model's tokens are paid for.

Variables

This section is empty.

Functions

This section is empty.

Types

type Day

type Day struct {
	Day             string  `json:"day"` // YYYY-MM-DD
	Input           int     `json:"input"`
	Output          int     `json:"output"`
	Effective       int     `json:"effective"`
	CostUSD         float64 `json:"costUsd"`
	IncludedListUSD float64 `json:"includedListUsd"`
}

Day is one calendar day of spend, in the server's local time.

type Ledger

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

Ledger writes model spend to the global config DB for one project. A nil *Ledger records nothing, so a caller without a global DB (tests, one-off tools) needs no guard. Recording never fails a turn: errors are logged.

func NewLedger

func NewLedger(global *db.DB, project string) *Ledger

NewLedger returns a ledger that records into global under project, the workspace directory the spend happened in. It returns nil when there is no global DB.

func (*Ledger) Backfill

func (l *Ledger) Backfill(store *session.Store) (steps, utility int, err error)

Backfill copies the project's usage from before the ledger existed, once per project: every assistant step that reported usage, at the model its message names or else its session's, and each session's utility total as one row at the session's model (the calls behind it were never itemised). Rows already in the ledger are left alone, so running it twice, or from two servers on the same project at once, adds nothing. Usage from sessions deleted before the ledger existed is gone and stays uncounted.

func (*Ledger) DB

func (l *Ledger) DB() *db.DB

DB is the global database the ledger writes to.

func (*Ledger) RecordStep

func (l *Ledger) RecordStep(sessionID, messageID, providerID, modelID string, tc session.TokenCounts, at int64)

RecordStep writes one agent step's usage under its assistant message id. A step recorded again replaces its row rather than adding a second one, so a step's final counts are what stays.

func (*Ledger) RecordUtility

func (l *Ledger) RecordUtility(sessionID, providerID, modelID string, tc session.TokenCounts, at int64)

RecordUtility appends one utility call's usage.

func (*Ledger) SetHosts

func (l *Ledger) SetHosts(hosts func(providerID string) string)

SetHosts installs the lookup that names the host a provider calls, so each row records where the work actually ran. Set it before the first turn.

type ModelUsage

type ModelUsage struct {
	Provider string `json:"provider"`
	Model    string `json:"model"`
	// Name is the catalogue's display name, empty for a model it does not know.
	Name    string `json:"name,omitempty"`
	Billing string `json:"billing"`
	// InferredProvider is set when Provider is empty — the work predates
	// recorded providers — and a configured provider serves the model today:
	// the row is billed as that provider, and says the provider was inferred.
	InferredProvider string `json:"inferredProvider,omitempty"`
	// Host is the endpoint the calls went to when the provider slot points
	// somewhere other than its own default (the OpenAI slot at Z.ai), so the
	// row can be named by it; empty on default endpoints. Rows from before
	// hosts were recorded take where the provider points today.
	Host string `json:"host,omitempty"`
	// Calls counts ledger rows: agent steps plus utility calls.
	Calls    int `json:"calls"`
	Sessions int `json:"sessions"`
	Tokens
	// CostUSD is what was billed per token: 0 for included usage, null when the
	// model is billed per token at an unknown price.
	CostUSD *float64 `json:"costUsd"`
	// ListUSD is included usage priced at the model's list price — what the
	// same tokens would cost on the vendor's own API. Null for metered usage,
	// which has a real cost, and when the catalogue does not price the model.
	ListUSD *float64 `json:"listUsd"`
}

ModelUsage is one provider/model pair's usage and what it cost.

type ProjectUsage

type ProjectUsage struct {
	Project string `json:"project"`
	Name    string `json:"name"`
	Tokens
	CostUSD         float64 `json:"costUsd"`
	IncludedListUSD float64 `json:"includedListUsd"`
}

ProjectUsage is one project's share of the spend.

type SessionCost

type SessionCost struct {
	Models []ModelUsage `json:"models"`
	Totals Totals       `json:"totals"`
}

SessionCost is one session's spend by model.

func ForSession

func ForSession(store *session.Store, reg *provider.Registry, id session.SessionID) (*SessionCost, error)

ForSession prices one session from its own messages: each step at the model its message names — or the session's model, for steps from before messages recorded one — and its utility calls at the session's model. Sub-agent work is inside the utility total, folded in when the sub-agent finished.

It reads the session's messages rather than the ledger so it prices exactly the tokens the session's token view counts.

type Summary

type Summary struct {
	From int64 `json:"from"`
	To   int64 `json:"to"`
	// Project is the workspace the summary is narrowed to, empty for all.
	Project string `json:"project,omitempty"`
	// First is when the ledger's oldest row was spent, 0 when it is empty.
	First    int64          `json:"first"`
	Models   []ModelUsage   `json:"models"`
	Projects []ProjectUsage `json:"projects"`
	Days     []Day          `json:"days"`
	Totals   Totals         `json:"totals"`
}

Summary is the ledger totalled over a period.

func Summarize

func Summarize(global *db.DB, reg *provider.Registry, from, to int64, project string) (*Summary, error)

Summarize totals the ledger's spend between from and to (unix ms; to <= 0 means now), by model, by project and by day, pricing each model with reg. project narrows it to one workspace — its own rows and those of the task worktrees inside it; empty means every project.

type Tokens

type Tokens struct {
	Input      int `json:"input"`
	Output     int `json:"output"`
	Reasoning  int `json:"reasoning"`
	CacheRead  int `json:"cacheRead"`
	CacheWrite int `json:"cacheWrite"`
	Effective  int `json:"effective"`
	Total      int `json:"total"`
}

Tokens are the counts in one bucket. Effective is everything but cache reads and Total is everything, as session.TokenCounts defines them.

type Totals

type Totals struct {
	Tokens
	Calls    int `json:"calls"`
	Sessions int `json:"sessions"`
	// CostUSD is everything billed per token at a known price.
	CostUSD float64 `json:"costUsd"`
	// IncludedListUSD is plan and local usage at list price, the part of the
	// work the flat plans covered.
	IncludedListUSD float64 `json:"includedListUsd"`
	// IncludedEffective is the effective tokens that were not billed per token.
	IncludedEffective int `json:"includedEffective"`
	// UnpricedEffective is the effective tokens billed per token at a price
	// nothing publishes, so CostUSD leaves them out.
	UnpricedEffective int `json:"unpricedEffective"`
	// UnknownEffective is the effective tokens whose provider was never
	// recorded and cannot be inferred, so CostUSD leaves them out too.
	UnknownEffective int `json:"unknownEffective"`
}

Totals add up every model in a view.

Jump to

Keyboard shortcuts

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