wire

package
v0.37.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

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

View Source
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

func IsKnownEventType(eventType string) bool

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

func IsPartDelta(eventType string) bool

IsPartDelta reports whether eventType is a message-part delta event, tolerating the store surface's version suffix ("message.part.delta.1").

func IsPartUpdated

func IsPartUpdated(eventType string) bool

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

func IsSessionUpdated(eventType string) bool

IsSessionUpdated reports whether eventType is a session.updated event, tolerating the store surface's version suffix ("session.updated.1").

func IsStepEnded

func IsStepEnded(eventType string) bool

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

type StepUsage struct {
	SessionID string
	Tokens    Tokens
}

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

func ParseStepUsage(eventType string, raw string) (StepUsage, bool, error)

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

func ParseStepUsageProps(eventType string, props json.RawMessage) (StepUsage, bool, error)

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

func (t Tokens) PromptTokens() int64

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.

Jump to

Keyboard shortcuts

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