Documentation
¶
Overview ¶
Package hooks defines the usage-event contract — the gateway's only metering output. There is no database: consumers observe usage through a Hook (in-process), the JSONL sink, or the webhook sink.
Index ¶
Constants ¶
const ( StatusOK = "ok" StatusUpstreamError = "upstream_error" StatusClientAbort = "client_abort" StatusBadRequest = "bad_request" )
Status values for UsageEvent.Status.
const ( TransportHTTP = "http" TransportWebSocket = "websocket" )
Transport values for UsageEvent.Transport.
const ( MediaUnitImage = "image" MediaUnitVideoSecond = "video_second" MediaUnitAudioCharacter = "audio_character" MediaUnitAudioMinute = "audio_minute" MediaUnitSessionMinute = "session_minute" )
MediaUnitKind values for MediaUsage.UnitKind (billing hooks; not prices).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Func ¶
type Func func(ctx context.Context, ev UsageEvent)
Func adapts a function to the Hook interface.
type Hook ¶
type Hook interface {
OnUsage(ctx context.Context, ev UsageEvent)
}
Hook receives usage events. Implementations must not block: the proxy calls OnUsage synchronously after the response completes.
type MediaUsage ¶
type MediaUsage struct {
Units int `json:"units,omitempty"`
UnitKind string `json:"unit_kind,omitempty"`
DurationMS int64 `json:"duration_ms,omitempty"`
Size string `json:"size,omitempty"`
Format string `json:"format,omitempty"`
}
MediaUsage carries non-token billable dimensions for media/realtime requests. Omitted from JSON when empty (all zero / blank).
type UsageEvent ¶
type UsageEvent struct {
RequestID string `json:"request_id"`
Time time.Time `json:"time"`
DialectIn string `json:"dialect_in"`
Provider string `json:"provider"`
Model string `json:"model"` // public id as the client sent it
UpstreamModel string `json:"upstream_model"` // id sent upstream
// Modality is text|embedding|image_gen|video_gen|audio_speech|audio_transcribe|realtime.
// Empty means legacy text chat (treat as text).
Modality string `json:"modality,omitempty"`
// Transport is http|websocket. Empty means http.
Transport string `json:"transport,omitempty"`
TokensIn int `json:"tokens_in"`
TokensOut int `json:"tokens_out"`
// CachedTokens is prompt tokens served from cache when known
// (OpenAI cached_tokens / Anthropic cache_read_input_tokens).
CachedTokens int `json:"cached_tokens,omitempty"`
// CacheWriteTokens is Anthropic cache_creation_input_tokens when known.
CacheWriteTokens int `json:"cache_write_tokens,omitempty"`
// ReasoningTokens is completion reasoning/thinking tokens when known.
// tokens_out already includes them when the upstream folds them into
// completion totals — do not add again for billing without checking provider.
ReasoningTokens int `json:"reasoning_tokens,omitempty"`
Estimated bool `json:"estimated"` // true when upstream reported no usage
// Media is set for image/video/audio/realtime metering when known.
Media *MediaUsage `json:"media,omitempty"`
Stream bool `json:"stream"`
Status string `json:"status"`
HTTPStatus int `json:"http_status"`
LatencyMS int64 `json:"latency_ms"`
TTFTMS int64 `json:"ttft_ms,omitempty"`
// KeyHash is a short sha256 prefix of the forwarded credential — enough to
// correlate usage per key without ever storing the key itself.
KeyHash string `json:"key_hash,omitempty"`
// DroppedFields lists translation field names when observe_dropped_fields is
// enabled (names only; never request/response payloads). Omitted when empty.
DroppedFields []string `json:"dropped_fields,omitempty"`
}
UsageEvent is emitted exactly once per proxied request (or realtime session end).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package jsonl writes one JSON line per usage event to stdout, stderr, or a file.
|
Package jsonl writes one JSON line per usage event to stdout, stderr, or a file. |
|
Package webhook posts usage events as JSON to an HTTP endpoint.
|
Package webhook posts usage events as JSON to an HTTP endpoint. |