Back to Pi Mono

JSON Event Stream Mode

packages/coding-agent/docs/json.md

0.84.03.3 KB
Original Source

JSON Event Stream Mode

bash
pi --mode json "Your prompt"

Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs.

Event Types

Wire events use JsonAgentSessionEvent. It matches AgentSessionEvent except that streaming message updates omit cumulative snapshots:

typescript
type WithoutPartial<T> = T extends { partial: unknown } ? Omit<T, "partial"> : T;

type JsonAgentSessionEvent =
  | Exclude<AgentSessionEvent, { type: "message_update" }>
  | {
      type: "message_update";
      assistantMessageEvent: WithoutPartial<AssistantMessageEvent>;
    };

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.

Other base events come from AgentEvent:

typescript
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:

json
{"type":"session","version":3,"id":"uuid","timestamp":"...","cwd":"/path"}

Followed by events as they occur:

json
{"type":"agent_start"}
{"type":"turn_start"}
{"type":"message_start","message":{"role":"assistant","content":[],...}}
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}}
{"type":"message_end","message":{...}}
{"type":"turn_end","message":{...},"toolResults":[]}
{"type":"agent_end","messages":[...]}

message_update records are delta-only. They omit both the cumulative message field and assistantMessageEvent.partial to keep stream size linear. Use contentIndex and delta to assemble live text, thinking, or tool-call arguments if needed. message_end contains the final authoritative message.

Example

bash
pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'