← Về thư mục
📄 / / profiles / r-and-d / raw_evidence / scientific-agent-skills / skills / pi-agent / references / json.md

JSON Event Stream Mode

Source: https://pi.dev/docs/latest/json

Use JSON mode for one-shot prompts that output all session events as JSON lines to stdout.

pi --mode json "Your prompt"

Event Types

Wire events use JsonAgentSessionEvent, which matches AgentSessionEvent except that streaming message updates omit cumulative snapshots:

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

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

AgentSessionEvent is AgentEvent plus session-level events:

Base AgentEvent types:

Output Format

First line is the session header:

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

Then events as they occur:

{"type":"agent_start"}
{"type":"turn_start"}
{"type":"message_start","message":{"role":"assistant","content":[]}}
{"type":"message_update","usage":{},"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. The top-level usage field carries the latest cumulative provider-reported usage and may stay zero when a provider only reports usage at completion. Assemble live text, thinking, or tool-call arguments from contentIndex and delta; message_end holds the final authoritative message.

Example

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

For bidirectional control, use RPC instead of JSON mode.