Documentation
¶
Overview ¶
Package geminishape parses the Gemini CLI telemetry file shape shared by the gemini and agy adapters, so a parser bug is fixed exactly once. Records for a single turn are CUMULATIVE: each new record for a given id re-emits the turn's growing running totals, so the last record for an id (equivalently, the one with the largest total) holds the final figures. ReadFile therefore groups records by id within a file, keeps the max snapshot per id, and emits one AggregateSnapshot per (file, id).
Token mapping (per plan section 1):
Input = (tokens.input + tokens.tool) - cached overlap (clamped >= 0) Output = tokens.output CacheRead = tokens.cached CacheCreation = 0 Reasoning = tokens.thoughts Total = max(tokens.total, input+tool+output+thoughts)
The total accounts for every component this shape folds into the event's own token fields, so a row can never report a total below the counts stored beside it (issue #49). tokens.tool is part of it because it is folded into InputTokens; tokens.thoughts is part of it because reasoning is ADDITIVE for this shape (model.ReasoningModeFor). Cached is NOT added on top: it is the slice of tokens.input that was served from cache, already inside that count, and it is reported separately in CacheReadTokens.
tokens.total is the provider's own figure and stays authoritative wherever it covers those components; it is only raised when the provider itemised more than it totalled (real records do: a turn reporting input+output+thoughts as its total leaves its tool tokens out of it).
The adapters keep their own roots/Discover policy and their size+mtime checkpoint gates; only the file parsing lives here.
CRITICAL: strictly read-only. Files are opened O_RDONLY and never written, locked, or modified.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HasUsageExt ¶
HasUsageExt reports whether a path ends in .json or .jsonl — the extensions the Discover walks of both adapters accept.
Types ¶
type FileResult ¶
type FileResult struct {
Snapshots []model.AggregateSnapshot
// Skipped counts genuinely unparseable lines/entries (permanently bad, a
// re-read cannot fix them).
Skipped int
// ScanErr is non-nil when the JSONL scanner aborted mid-file (e.g. an
// over-long line): the snapshots above are best-effort and the caller MUST
// NOT advance its checkpoint — the unread remainder would be skipped until
// the next size/mtime change.
ScanErr error
}
FileResult is the outcome of parsing one telemetry file.
type Shape ¶
type Shape struct {
Tool string // tool id stamped on every snapshot (model.ToolGemini, ...)
Provider string // billing identity stamped on every snapshot (model.ProviderGoogle)
Project string // project label (the telemetry records no cwd)
}
Shape parameterises the shared parser for one adapter.