Documentation
¶
Overview ¶
Package wire is the ONLY code in the platform that decodes opencode wire bytes (HTTP bodies and /event SSE envelopes). The API-side adapter, the SSE tracker's metering path, and the in-pod agentd's usage parser all consume it; nothing else may import it. Shapes are pinned by golden fixtures in ../testdata — see the opencode upgrade runbook.
Parsing is dual-shape tolerant by design. Two reasons with live-capture evidence (see testdata/REFRESH.md): (1) the same logical event type is named differently on different surfaces — the /event SSE stream emits unsuffixed types ("message.part.updated") while the persisted event store emits version-suffixed types ("message.part.updated.1"); (2) the fleet runs mixed opencode versions during image rollouts. Decoders accept every supported shape rather than branching on versions at runtime.
Index ¶
- Constants
- func IsKnownEventType(eventType string) bool
- func IsPartDelta(eventType string) bool
- func IsPartUpdated(eventType string) bool
- func IsSessionUpdated(eventType string) bool
- func IsStepEnded(eventType string) bool
- func SessionIDFromProps(props json.RawMessage) string
- type Envelope
- type SessionUsage
- type StepUsage
- type Tokens
Constants ¶
const ( EventTypeSessionStatus = "session.status" EventTypeSessionCreated = "session.created" EventTypeSessionUpdated = "session.updated" EventTypeSessionIdle = "session.idle" EventTypeMessagePartUpdated = "message.part.updated" EventTypeMessagePartDelta = "message.part.delta" )
knownEventTypes is the pinned event taxonomy: every type observed in the golden fixtures (live /event capture + persisted store; see ../testdata/REFRESH.md) plus legacy event-system names retained for mixed-fleet rollout tolerance. The fixture-coverage test forces every fixture type to be listed here, so a fixture refresh that introduces a type extends this set in the same change. Event-type literals (the dialect seam — Rule 12): consumers outside pkg/agent/opencode reference these constants, never raw strings (repolint: agent-event-literals gate).
Variables ¶
This section is empty.
Functions ¶
func IsKnownEventType ¶ added in v0.16.1
IsKnownEventType reports whether eventType belongs to the pinned opencode taxonomy (version suffixes tolerated: the persisted store emits suffixed variants of the same logical types). Unknown types are not errors — they are the drift signal consumers count and warn on (#739 Gap 2: a taxonomy rename must be observable, not silent).
func IsPartDelta ¶ added in v0.16.1
IsPartDelta reports whether eventType is a message-part delta event, tolerating the store surface's version suffix ("message.part.delta.1").
func IsPartUpdated ¶
IsPartUpdated reports whether eventType is a message-part update. The live /event stream emits "message.part.updated"; the persisted event store emits "message.part.updated.N" — both must match (see REFRESH.md).
func IsSessionUpdated ¶
IsSessionUpdated reports whether eventType is a session.updated event, tolerating the store surface's version suffix ("session.updated.1").
func IsStepEnded ¶
IsStepEnded reports whether eventType is the legacy per-step usage event (pre-1.18.10). The legacy name is unversioned.
func SessionIDFromProps ¶ added in v0.30.1
func SessionIDFromProps(props json.RawMessage) string
SessionIDFromProps extracts the owning session from one event's properties payload (#1342: the SSE progress signal — any event carrying a sessionID is evidence that session's turn is alive). Empty when the payload carries none (sessionless events).
Types ¶
type Envelope ¶
type Envelope struct {
ID string `json:"id"`
Type string `json:"type"`
Properties json.RawMessage `json:"properties"`
}
Envelope is the /event SSE wire envelope shared by all event types.
type SessionUsage ¶
type SessionUsage struct {
SessionID string
ModelID string
ProviderID string
InputTokens int64
OutputTokens int64
CostUSD float64
// CostMalformed reports a cost field that is neither a number nor
// an object with a numeric "cost" — decoded as CostUSD=0 so billing
// proceeds, but callers should warn: it is a wire-drift signal.
CostMalformed bool
}
SessionUsage is the decoded session-level CUMULATIVE usage and model attribution from session.updated events — the metering/billing signal. Unlike StepUsage (per-step occupancy), these counters only grow; delta computation is the caller's policy, not the decoder's.
func ParseSessionUpdated ¶
func ParseSessionUpdated(eventType string, raw string) (SessionUsage, bool, error)
ParseSessionUpdated decodes a session.updated event's cumulative usage and model attribution. ok=false (no error) when the event carries no info block — session.updated legitimately fires without one (early lifecycle). err is non-nil only for usage-bearing payloads that fail to decode (wire drift). Envelope-based, like ParseStepUsage.
func ParseSessionUpdatedProps ¶
func ParseSessionUpdatedProps(props json.RawMessage) (SessionUsage, bool, error)
ParseSessionUpdatedProps is ParseSessionUpdated for callers holding already-stripped properties (the SSE tracker's dispatch path).
type StepUsage ¶
StepUsage is the decoded per-step usage signal from any supported wire shape: the session it belongs to and that step's token accounting.
func ParseStepUsage ¶
ParseStepUsage decodes a raw /event payload carrying per-step usage: the legacy standalone step-ended event (≤1.15.x era) or a part-update event whose part is a step-finish (1.18.x). ok=false when the event carries no usage (any other part type, or an event type that never carries usage). err is non-nil when the event TYPE claims usage but the payload fails to decode — that is wire drift and must surface, not silently drop.
The eventType check runs before any byte conversion or JSON decode, so the non-usage majority of stream traffic (deltas are the hottest and largest events) costs only string compares through this function. Matched part-update events pay one envelope decode — inherent, since only the payload says whether the part is a step-finish.
func ParseStepUsageProps ¶
ParseStepUsageProps is ParseStepUsage for callers that already stripped the envelope (agentd's legacy nested-payload path). Same semantics.
type Tokens ¶
type Tokens struct {
Total int64 `json:"total,omitempty"`
Input int64 `json:"input"`
Output int64 `json:"output"`
Reasoning int64 `json:"reasoning"`
Cache struct {
Read int64 `json:"read"`
Write int64 `json:"write"`
} `json:"cache"`
}
Tokens mirrors opencode's token-usage shape, stable across 1.15.x–1.18.x.
func (Tokens) PromptTokens ¶
PromptTokens returns the raw prompt occupancy in opencode's accounting convention: input + cache.read + cache.write. Providers with no cache convention report it all in input; the sum stays correct.