llmstats

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package llmstats provides a durable sink for per-call LLM metrics. It implements llm.StatsSink by appending one JSON record per call to a local JSONL file (.sdd/stats/llm.jsonl), so prompt-cache effectiveness and token usage become measurable over time without an external service (d-tac-zis).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FileSink

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

FileSink appends one JSON record per LLM call to a JSONL file. Safe for concurrent use — batch operations record from multiple goroutines.

func NewFileSink

func NewFileSink(dir string) (*FileSink, error)

NewFileSink returns a sink that appends to <dir>/llm.jsonl, creating dir if it does not exist.

func (*FileSink) RecordCall

func (s *FileSink) RecordCall(stat llm.CallStat)

RecordCall appends one JSON line for the call. Errors are swallowed: stats collection is best-effort and must never break a capture or summarize. The on-disk shape is Record, shared with the reader (reader.go).

type Reader added in v0.9.0

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

Reader reads the per-call stats sink written by FileSink.

func NewReader added in v0.9.0

func NewReader(dir string) *Reader

NewReader returns a reader over <dir>/llm.jsonl — the same path FileSink writes, so the dir argument matches what NewFileSink was given.

func (*Reader) Path added in v0.9.0

func (r *Reader) Path() string

Path returns the sink file path, for display in the stats header.

func (*Reader) Read added in v0.9.0

func (r *Reader) Read() ([]model.StatsRecord, error)

Read returns every parseable record in the sink, in file order. An absent sink yields an empty slice and no error — that is the "no stats recorded yet" case, not a failure. Malformed lines are skipped rather than aborting the read: stats collection is best-effort, so one bad line must not blank the whole report.

type Record added in v0.9.0

type Record struct {
	Timestamp         string `json:"ts"`
	Op                string `json:"op"`
	Provider          string `json:"provider,omitempty"`
	Model             string `json:"model,omitempty"`
	Items             int    `json:"items,omitempty"`
	InputTokens       int    `json:"input_tokens"`
	OutputTokens      int    `json:"output_tokens"`
	CacheReadTokens   int    `json:"cache_read_tokens"`
	CacheCreateTokens int    `json:"cache_create_tokens"`
	DurationMS        int64  `json:"duration_ms"`
}

Record is the on-disk JSONL shape, shared by the writer (FileSink) and the Reader so the wire format has a single definition. Cost is intentionally absent: the active provider path reports tokens and the cache breakdown but no dollar cost, and we keep no pricing table (d-tac-zis).

Jump to

Keyboard shortcuts

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