Skip to main content

Cost Tracking

The CostTracker hook monitors LLM API costs in real time. It accumulates token usage per session and globally, computes costs using a configurable price table, and optionally enforces budget limits.

Quick Setup

import "github.com/spawn08/chronos/engine/hooks"

tracker := hooks.NewCostTracker(nil) // uses default price table

a, _ := agent.New("assistant", "Assistant").
WithModel(model.NewOpenAI(key)).
AddHook(tracker).
Build()

resp, _ := a.Chat(ctx, "Summarize this document...")

report := tracker.GetGlobalCost()
fmt.Printf("Tokens: %d prompt + %d completion\n",
report.PromptTokens, report.CompletionTokens)
fmt.Printf("Cost: $%.6f\n", report.TotalCost)

CostReport

type CostReport struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
TotalCost float64 `json:"total_cost"`
Currency string `json:"currency"`
}

Custom Price Table

Override the default prices by passing a custom price table:

prices := map[string]hooks.ModelPrice{
"gpt-5.5": {
PromptPricePerToken: 0.000005,
CompletionPricePerToken: 0.00003,
},
"claude-opus-4-8": {
PromptPricePerToken: 0.000005,
CompletionPricePerToken: 0.000025,
},
}

tracker := hooks.NewCostTracker(prices)

Default Price Table

The built-in table covers these models (prices as of mid-2026 — override with a custom table for current rates):

ModelPrompt (per token)Completion (per token)
gpt-5.5$0.000005$0.00003
gpt-5$0.00000125$0.00001
gpt-4o$0.0000025$0.00001
gpt-4o-mini$0.00000015$0.0000006
o3$0.00001$0.00004
claude-fable-5$0.00001$0.00005
claude-opus-4-8$0.000005$0.000025
claude-sonnet-5$0.000003$0.000015
claude-haiku-4-5$0.000001$0.000005
gemini-2.0-flash$0.00000015$0.0000006
mistral-large-latest$0.000002$0.000006

Budget Enforcement

Set a maximum spend. When the budget is exceeded, the hook returns an error on the next model call, preventing further API charges:

tracker := hooks.NewCostTracker(nil)
tracker.Budget = 5.00 // $5.00 maximum

a, _ := agent.New("budget-agent", "Budget Agent").
WithModel(model.NewOpenAI(key)).
AddHook(tracker).
Build()

// After spending $5.00, subsequent calls return:
// "cost budget exceeded: spent $5.0012 of $5.0000 budget"

Per-Session Tracking

Track costs for individual sessions:

// After running several sessions
sessionReport := tracker.GetSessionCost("sess_abc123")
globalReport := tracker.GetGlobalCost()

fmt.Printf("Session cost: $%.4f\n", sessionReport.TotalCost)
fmt.Printf("Global cost: $%.4f\n", globalReport.TotalCost)

To associate model calls with sessions, set session_id in event metadata. The ChatWithSession method does this automatically.

Combining with Other Hooks

Cost tracking works alongside other middleware. Order matters -- place the cost tracker after retry hooks so retried calls are counted:

a, _ := agent.New("production", "Production Agent").
WithModel(model.NewOpenAI(key)).
AddHook(hooks.NewRetryHook(3)). // retries first
AddHook(hooks.NewRateLimitHook(60, 0)). // then rate limit
AddHook(tracker). // then track costs
AddHook(hooks.NewMetricsHook()). // then record metrics
Build()