JSON Event Stream Mode
elyra --mode json "Your prompt"
Outputs all session events as JSON lines to stdout. Useful for integrating elyra into other tools or custom UIs.
The prompt can also be piped on stdin, which keeps it out of the process list:
echo "Your prompt" | elyra --mode json
To continue an earlier session, pass its id (or a unique prefix) or file path with --session. --resume takes no value; it opens an interactive picker and needs a terminal.
echo "Now add tests" | elyra --mode json --session 01a15593
Run it from the directory the session was created in. A session id that only matches a session from another directory exits with code 1; use --fork <id> to continue it in the current directory.
Event Types
Events are defined in AgentSessionEvent:
type AgentSessionEvent =
| AgentEvent
| { type: "queue_update"; steering: readonly string[]; followUp: readonly string[] }
| { type: "compaction_start"; reason: "manual" | "threshold" | "overflow" | "mid-turn" }
| { type: "compaction_end"; reason: "manual" | "threshold" | "overflow" | "mid-turn"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string }
| { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }
| { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string }
| { type: "session_info_changed"; name: string | undefined }
| { type: "thinking_level_changed"; level: ThinkingLevel }
| { type: "decisions_extracted"; recorded: { id: string; title: string }[]; candidates: { title: string }[] }
| { type: "smart_routing"; tier: ComplexityTier; reason: string; fromModel: string; toModel: string };
queue_update emits the full pending steering and follow-up queues whenever they change. compaction_start and compaction_end cover both manual and automatic compaction. Consumers should ignore event types they do not recognize; new ones are added over time.
Base events from AgentEvent:
type AgentEvent =
// Agent lifecycle
| { type: "agent_start" }
| { type: "agent_end"; messages: AgentMessage[] }
// Turn lifecycle
| { type: "turn_start" }
| { type: "turn_end"; message: AgentMessage; toolResults: ToolResultMessage[] }
// Message lifecycle
| { type: "message_start"; message: AgentMessage }
| { type: "message_update"; message: AgentMessage; assistantMessageEvent: AssistantMessageEvent }
| { type: "message_end"; message: AgentMessage }
// Tool execution
| { type: "tool_execution_start"; toolCallId: string; toolName: string; args: any }
| { type: "tool_execution_update"; toolCallId: string; toolName: string; args: any; partialResult: any }
| { type: "tool_execution_end"; toolCallId: string; toolName: string; result: any; isError: boolean };
Message Types
Base messages from packages/ai/src/types.ts:
UserMessage(line 134)AssistantMessage(line 140)ToolResultMessage(line 152)
Extended messages from packages/coding-agent/src/core/messages.ts:
BashExecutionMessage(line 29)CustomMessage(line 46)BranchSummaryMessage(line 55)CompactionSummaryMessage(line 62)
Output Format
Each line is a JSON object. The first line is the session header:
{"type":"session","version":3,"id":"uuid","timestamp":"...","cwd":"/path"}
Followed by events as they occur:
{"type":"agent_start"}
{"type":"turn_start"}
{"type":"message_start","message":{"role":"assistant","content":[],...}}
{"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_delta","delta":"Hello",...}}
{"type":"message_end","message":{...}}
{"type":"turn_end","message":{...},"toolResults":[]}
{"type":"agent_end","messages":[...]}
Reading a Run
- Session id: only in the header (
id), the first line. Events do not repeat it. - Tool calls:
tool_execution_starthastoolNameandargs;tool_execution_endhasresult.content[]andisError. - Final answer: there is no separate result event. Use
agent_end.messages: the lastassistantmessage holds the answer incontent[](blocks withtype: "text"). With automatic retry, a failed attempt ends with its ownagent_end; the last one is the outcome. - Failure: the last assistant message has
stopReason"error"or"aborted"and anerrorMessage. The process then exits with code 1 and writes the error to stderr. - Cost: each assistant message carries
usage(input,output,cacheRead,cacheWrite,cost.totalin USD, already priced). Tools that call a model themselves (oracle,read_session) report it asdetails.modelUsageon theirtoolResultmessage. Sum both for the cost of a run. message_updatefires for every streamed chunk; most consumers only needmessage_end.
Example
elyra --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'