spend

package
v0.5.8 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package spend reads what coding agents on this machine spent, from the transcripts their hosts already keep: Claude Code's under ~/.claude/projects and Codex's under ~/.codex/sessions. It is the one figure on `logos stats --usage` that is not Logos's own ledger, and it is labelled so: tokens the host recorded, priced from a built-in table.

It reads and never writes. The transcripts are the host's files, and the totals are recomputed on every run, so there is no cache to fall out of step with them and nothing for an index rebuild to lose.

Index

Constants

View Source
const PriceSource = "Anthropic list prices as of 6 Oct 2026, standard tier, before any discount"

PriceSource is shown beside every dollar figure. The table is built in and never fetched: nothing leaves the machine, and a price looked up on each run would be a network call for a number that changes a few times a year. The date says how old it is, so a reader can tell a stale table from a cheap month.

Variables

This section is empty.

Functions

func Cost

func Cost(model string, u Usage) (usd float64, ok bool)

Cost prices one request. ok is false for a model with no list price.

func Top

func Top(m map[string]*Bucket, n int) []string

Top is the n largest rows of a breakdown, by dollars and then by tokens, largest first.

Types

type Bucket

type Bucket struct {
	Usage
	USD      float64
	Unpriced int64
}

Bucket is one row of a breakdown. Unpriced counts the tokens of models with no list price, so a total in dollars can say how much it leaves out.

type Price

type Price struct {
	Input, Output, CacheRead float64
	// Long is the rate card for a request whose prompt passes LongAfter
	// tokens, for a model with two (Haiku 5.5). Zero when there is one card.
	Long      *Price
	LongAfter int64
}

Price is a model's list price in dollars per million tokens. Cache writes are priced from Input by the published multipliers — 1.25× for the 5-minute cache, 2× for the 1-hour one — so only the read rate, which differs by model, is listed.

type Report

type Report struct {
	From             time.Time
	Total            Bucket
	Models, Projects map[string]*Bucket
	// Days is keyed "2006-01-02" in local time.
	Days     map[string]*Bucket
	Sessions []Session
	// Files is how many transcripts were read and Unreadable how many lines
	// in them could not be parsed, so a total missing lines says so. Skipped
	// is the files that could not be read to the end — removed while the walk
	// ran, or holding a line past the scanner's limit — whose lines up to the
	// failure are counted and the rest are not.
	Files, Unreadable, Skipped int
	// Hosts names the hosts whose transcripts were found.
	Hosts []string
}

Report is the window read.

func Read

func Read(from time.Time, project string) (*Report, error)

Read totals what Claude Code and Codex recorded from from onward, for one project or, when project is "", all of them. A host whose directory is missing is skipped. A file that cannot be read to the end is counted in Skipped rather than failing the report: one host file deleted mid-walk should not blank a month of figures, and the count says what is missing.

type Session

type Session struct {
	Host, Model string
	Start       int64
	Peak        int64
}

Session is one agent session's largest context, for the session-size panel.

type Usage

type Usage struct {
	Input, CacheWrite5m, CacheWrite1h, CacheRead, Output int64
}

Usage is token counts as a request was billed: uncached input, the two cache-write durations, cache reads, and output.

func (Usage) Prompt

func (u Usage) Prompt() int64

Prompt is everything the model read on a request — its context size.

func (Usage) Total

func (u Usage) Total() int64

Total is every token, read and written.

Jump to

Keyboard shortcuts

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