package agent import ( "encoding/json" "os" "path/filepath" "time" "ollie/paths" ) // usageEntry is one line in the append-only usage JSONL log. type usageEntry struct { Timestamp string `json:"ts"` SessionID string `json:"session"` Backend string `json:"backend"` Model string `json:"model"` InputTokens int `json:"input"` OutputTokens int `json:"output"` CachedTokens int `json:"cached"` CreationTokens int `json:"creation"` CostUSD float64 `json:"cost_usd"` } // usageLogPath returns the path for the usage log file. // Respects OLLIE_USAGE_LOG env var; defaults to ~/.local/share/ollie/usage.jsonl. func usageLogPath() string { if p := os.Getenv("OLLIE_USAGE_LOG"); p != "" { return p } return filepath.Join(paths.DataDir(), "usage.jsonl") } // appendUsageLog writes a single usage entry to the append-only JSONL log. func appendUsageLog(sessionID, backendName, model string, sess *Session) { path := usageLogPath() if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { return } f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) if err != nil { return } defer f.Close() entry := usageEntry{ Timestamp: time.Now().UTC().Format(time.RFC3339), SessionID: sessionID, Backend: backendName, Model: model, InputTokens: sess.turnInputTokens, OutputTokens: sess.turnOutputTokens, CachedTokens: sess.turnCachedTokens, CreationTokens: sess.turnCreationTokens, CostUSD: sess.LastTurnCostUSD, } data, _ := json.Marshal(entry) data = append(data, '\n') f.Write(data) //nolint:errcheck }