Documentation
¶
Overview ¶
Package events implements odek's structured runtime event stream (schema odek.event/v1, see docs/EXTENSIONS.md): a small Event type, a non-blocking panic-isolated Emitter that fans events out to a handler, and an append-only JSONL sink (jsonl.go).
Events are observability data for orchestrators. They never carry raw tool arguments (only a SHA-256 digest and sizes), never carry environment variables or credentials, and human-readable string fields pass through internal/redact before dispatch.
Index ¶
Constants ¶
const ( TypeRunStarted = "run_started" TypeIterationCompleted = "iteration_completed" TypeToolCallStarted = "tool_call_started" TypeToolCallCompleted = "tool_call_completed" TypeToolCallFailed = "tool_call_failed" TypeSessionSaved = "session_saved" TypeContextTrimmed = "context_trimmed" TypeBudgetExceeded = "budget_exceeded" TypeRunCompleted = "run_completed" TypeRunFailed = "run_failed" TypePlanCreated = "plan_created" TypePlanUpdated = "plan_updated" TypeSubagentSpawned = "subagent_spawned" TypeSubagentCompleted = "subagent_completed" )
Event types emitted by odek. Consumers must ignore unknown types.
const ( LimitRuntime = "runtime" LimitToolCalls = "tool_calls" LimitInputTokens = "input_tokens" LimitOutputTokens = "output_tokens" LimitCostUSD = "cost_usd" )
Budget limit names carried in budget_exceeded events (data.limit_name). The constants are defined now so producers and consumers share one vocabulary; the enforcement that triggers these events lands with the execution-budget work (WP6).
const DefaultBufferSize = 1024
DefaultBufferSize is the default capacity of an Emitter's dispatch queue. When the queue is full, new events are dropped (and counted) rather than blocking the agent loop.
const Schema = "odek.event/v1"
Schema is the event envelope schema identifier. All schemas are additive: consumers must ignore unknown fields and unknown event types.
Variables ¶
This section is empty.
Functions ¶
func ArgsDigest ¶
ArgsDigest returns the SHA-256 hex digest of raw tool-call arguments. Events carry this digest plus the argument byte size — never the raw arguments — so a start/complete pair can be correlated without leaking potentially secret argument content into the event stream.
func ErrorClass ¶
ErrorClass maps an error to a stable, low-cardinality class string for tool_call_failed / run_failed events. Raw error text is never emitted: it may contain attacker-controlled or secret-bearing content.
Types ¶
type Emitter ¶
type Emitter struct {
// contains filtered or unexported fields
}
Emitter fans events out to a handler from a dedicated goroutine. Emit is non-blocking (drop-on-full) and the handler is panic-isolated: a slow or panicking handler can never stall or crash the agent loop.
The Emitter stamps Schema, Timestamp, RunID, and SessionID centrally, and redacts secret-looking content from human-readable fields (Tool and string values in Data) before dispatch.
func NewEmitter ¶
NewEmitter creates an Emitter that dispatches to handler. runID is stamped on every event; pass NewRunID() for a fresh run. A nil handler discards events (still useful for tests that only count drops).
func (*Emitter) Close ¶
func (e *Emitter) Close()
Close stops accepting events, drains the queue, and waits for the dispatch goroutine to finish. Safe to call more than once, and safe to call from inside a handler: a reentrant call tears down state and returns without waiting for itself.
func (*Emitter) Dropped ¶
Dropped returns how many events were discarded because the dispatch queue was full.
func (*Emitter) Emit ¶
Emit stamps and queues an event for dispatch. It never blocks: when the queue is full the event is dropped and counted (see Dropped). Emit after Close is a no-op.
func (*Emitter) SetSessionID ¶
SetSessionID sets the session identifier stamped on subsequent events. Call it as soon as the session is known; earlier events simply carry no session_id.
type Event ¶
type Event struct {
Schema string `json:"schema"`
Type string `json:"type"`
RunID string `json:"run_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
Iteration int `json:"iteration,omitempty"`
Tool string `json:"tool,omitempty"`
Timestamp time.Time `json:"timestamp"`
Data map[string]any `json:"data,omitempty"`
}
Event is a single structured runtime event (schema odek.event/v1).
Not every field is set for every Type; the zero value means "not applicable" and is omitted from the JSON form. Data carries the per-type fields documented in docs/EXTENSIONS.md.
type JSONLSink ¶
type JSONLSink struct {
// contains filtered or unexported fields
}
JSONLSink is an append-only sink that writes one JSON object per line.
Safety properties:
- the parent directory must already exist (the sink never creates it)
- an existing symlink at the target path is refused
- the file is created (and hardened) with 0600 permissions
- every event is flushed to stable storage before Write returns
func OpenJSONLSink ¶
OpenJSONLSink opens path for append-only event writes, creating it with 0600 permissions if necessary. The parent directory must already exist.