Skip to content

Stream Events Reference

orchcore normalizes the JSONL output of five agent CLI formats into one event model. This page lists the event types, the StreamEvent fields, and the related monitoring and result models.

StreamFormat

Identifies the JSONL output format of an agent CLI.

Value Agent CLI
claude Claude Code
codex Codex
opencode OpenCode
antigravity Antigravity CLI (agy)
copilot Copilot CLI
from orchcore.stream import StreamFormat

format = StreamFormat.CLAUDE  # "claude"

StreamEventType

The category of a StreamEvent, covering the agent lifecycle from launch to result.

Value Description
init Agent process started
state Agent state changed (see AgentState)
heartbeat Keep-alive signal from the agent
tool_start Agent began executing a tool
tool_exec Tool execution in progress (intermediate update)
tool_done Tool execution completed
text Agent emitted text output
subagent Agent spawned a sub-agent
result Agent completed with final result
error Agent encountered an error
cancelled Agent was cancelled (e.g., via SIGINT)
retry Agent is being retried after failure
rate_limit Agent hit a rate limit
stall Agent stalled (no activity for timeout period)

StreamEvent

The normalized event model. A JSONL line from any agent format yields zero, one, or several StreamEvent instances, depending on the line's content.

from orchcore.stream import StreamEvent, StreamEventType

Fields

Field Type Default Description
event_type StreamEventType (required) Event category
timestamp datetime now(UTC) When the event occurred (timezone-aware)
tool_id str \| None None Unique identifier for a tool invocation
tool_name str \| None None Tool name (e.g., "Read", "Bash", "Write")
tool_detail str \| None None Tool-specific detail (file path, command, etc.)
tool_status "running" \| "done" \| "error" \| None None Current tool execution status
tool_duration_ms int \| None None Tool execution duration in milliseconds
text_preview str \| None None Truncated text content for display
text_full str \| None None Complete text content
cost_usd Decimal \| None None Cumulative cost in USD
duration_ms int \| None None Total agent execution duration
exit_code int \| None None Process exit code (on result events)
num_turns int \| None None Number of conversation turns
session_id str \| None None Agent session identifier
token_usage dict[str, int] \| None None Token counts (e.g., {"input": 1000, "output": 500})
error str \| None None Error message (on error events)
retry_attempt int \| None None Current retry attempt number
retry_max int \| None None Maximum retry attempts
retry_delay_ms int \| None None Delay before next retry
error_category str \| None None Error classification
idle_seconds float \| None None Seconds since last activity (on stall events)
raw dict \| None None Original parsed JSON for debugging

StreamEvent is a frozen Pydantic model, so instances cannot be changed after creation.

AgentState

The state machine AgentMonitor uses to track an agent's lifecycle. It has nine states:

STARTING → THINKING → WRITING
                ↓         ↓
          TOOL_RUNNING ───┘
                ↓
           STALLED / RATE_LIMITED
                ↓
     COMPLETED / FAILED / CANCELLED
State Description
starting Agent subprocess has been launched
thinking Agent is processing (no tool active)
writing Agent is emitting text output
tool_running Agent is executing a tool
stalled No activity detected for timeout period
rate_limited Agent hit a rate limit
completed Agent finished successfully
failed Agent exited with an error
cancelled Agent was terminated by signal

ToolExecution

Tracks a single tool invocation through its lifecycle.

Field Type Description
tool_id str Unique invocation identifier
name str Raw tool name
friendly_name str Human-readable name (e.g., "Read" → "Read file")
detail str \| None Tool-specific detail (file path, command)
started_at datetime When the tool started
completed_at datetime \| None When the tool finished
status "running" \| "done" \| "error" Current status
duration timedelta \| None Execution time

ToolCounters

Aggregated tool execution statistics.

Field Type Description
total int Total tool invocations
succeeded int Successfully completed
failed int Failed with error
running int Currently in progress

AgentMonitorSnapshot

Point-in-time state of a monitored agent, returned by AgentMonitor.snapshot() for dashboards and status displays.

Field Type Description
agent_name str Agent identifier
state AgentState Current state
elapsed timedelta Time since agent started
counters ToolCounters Aggregated tool stats
active_tools list[ToolExecution] Currently running tools
recent_tools list[ToolExecution] Recently completed tools (max 20)
last_tool str \| None Name of most recent tool
last_tool_detail str \| None Detail of most recent tool
cost_usd Decimal \| None Cumulative cost
token_usage dict[str, int] \| None Token consumption
text_count int Number of text events
subagent_count int Number of sub-agent spawns
idle_seconds float Seconds since last activity

AgentResult

Return type of AgentRunner.run(). It holds the outputs and diagnostics of a single agent execution.

Field Type Default Description
agent_name str "" Agent identifier
output_path Path \| None None Path to extracted output file
stream_path Path \| None None Path to raw JSONL stream
log_path Path \| None None Path to log file
exit_code int 0 Process exit code
duration timedelta \| None None Execution duration
cost_usd Decimal \| None None Total cost
token_usage dict[str, int] \| None None Token counts
num_turns int \| None None Conversation turns
session_id str \| None None Session identifier
output_empty bool False Whether output file was empty
error str \| None None Human-readable error message if the run failed, kept in full
error_category AgentErrorCategory \| None None Typed failure classification (see below)
rate_limit_reset_seconds int \| None None Reset wait parsed from the rate-limit message, once, at the source
json_parse_error_count int 0 Malformed JSONL lines the stream parser skipped
wire_validation_error_count int 0 Well-formed JSONL lines that failed the selected wire-format schema
agent_version str \| None None CLI version detected by the advisory version check; None when detection is disabled or fails

AgentResult.error is set from the final stream state as well as the process exit code. A subprocess that exits 0 but emits a result with error, an error event, or an unrecovered rate_limit event returns a result with error set, and phase aggregation treats it as failed.

AgentErrorCategory

error_category lets consumers, and the engine's retry loop, branch on the kind of failure without matching error messages. The category is set where the failure is first observed:

Population site Category
Runner sees a typed rate_limit stream event rate_limit (reset parsed once into rate_limit_reset_seconds)
Runner sees error or result(error=...) with exit 0 stream_error
Runner: exit code != 0, no stream category nonzero_exit, upgraded to rate_limit when the fallback RateLimitDetector matches the stderr tail (for CLIs that never emit typed events)
Runner: empty output file on an otherwise clean run empty_output
Runner: max_runtime exceeded / kill_on_stall fired timeout / stall_timeout
Engine: agent binary missing (FileNotFoundError) binary_not_found
Engine: other OSError at launch os_error
Engine: shutdown or fail-fast sibling cancellation cancelled