llmledger

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package llmledger is the single writer for the llm_usage ledger — the authoritative record of every LLM token/cost charge in Airlock. Both the runtime model proxy (api) and the in-process build codegen runner (builder) funnel through Record so cost computation lives in exactly one place. Runtime calls attribute to a run (RunID); build/upgrade codegen attributes to a build (BuildID); CallKind disambiguates.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Record

func Record(ctx context.Context, q *dbq.Queries, logger *zap.Logger, c Capture)

Record computes cost and writes one append-only llm_usage row. Best-effort: every failure is logged and swallowed — accounting must never break a model call (runtime or build) that already happened. Callers pass their own ctx; use a fresh bounded one if the request context may already be cancelled (e.g. client disconnected mid-stream).

Types

type Capture

type Capture struct {
	AgentID        pgtype.UUID
	RunID          pgtype.UUID
	BuildID        pgtype.UUID
	SystemRunID    pgtype.UUID
	UserID         pgtype.UUID
	ConversationID pgtype.UUID

	ProviderCatalogID string
	ProviderSlug      string
	Model             string
	Capability        string
	CallKind          string
	Slug              string

	TokensIn        int64
	TokensOut       int64
	TokensCached    int64
	TokensReasoning int64

	Units    float64
	UnitKind string // "" | "image" | "character" | "second"

	FinishReason string
	Errored      bool
	Latency      time.Duration
}

Capture is one fully-resolved model charge. Attribution (RunID/BuildID/ SystemRunID/UserID/ConversationID) is the caller's responsibility — the api side resolves it from the run row; the builder side sets BuildID plus UserID (the agent owner, so build spend is attributed to a real user, not an orphaned row); the sysagent side sets SystemRunID plus UserID (the operator). Exactly one of RunID/BuildID/SystemRunID is normally Valid (or none, for an unattributed call); they are not mutually enforced here.

func (*Capture) TokensFromStreamUsage

func (c *Capture) TokensFromStreamUsage(u stream.Usage)

TokensFromStreamUsage populates the token fields from an accumulated stream.Usage — totals plus the cache-read / reasoning breakdown when the provider reported it. Shared by every caller that has a stream.Usage in hand (the build codegen runner; the runtime proxy uses its own accumulator before handing tokens over).

Jump to

Keyboard shortcuts

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