Skip to main content
praisonai run --output stream-json emits a per-step NDJSON event stream for CI pipelines, scripts, and observability tools. This works for single-agent runs and YAML / AgentTeam runs — team member events are fanned in on a single stream and tagged with the emitting agent’s agent_id.
The user runs the CLI with stream-json output; each agent step emits a versioned NDJSON line for scripts and CI.

Quick Start

1

Run with stream-json output

Each line of stdout is one JSON event object. The stream ends when the run completes.
2

Filter events with jq

Use jq to watch only the events that matter to your pipeline.
3

Process events in Python


How It Works

Each run wires a StreamEventBridge between the agent’s internal StreamEventEmitter and the OutputController. Every agent action — tool calls, text deltas, errors — becomes an NDJSON line on stdout. Run-level lifecycle events (run.start, agent.message, run.result, run.error) are driven directly by the CLI. Per-step events (tool.*, text.delta, reasoning.delta) come through the StreamEventBridge callback. On YAML / AgentTeam runs, the bridge attaches to team.stream_emitter — a lazy aggregate StreamEventEmitter that fans in every member agent’s events and tags each with the emitting agent_id.

YAML / Multi-Agent Runs

YAML and AgentTeam runs emit the same NDJSON contract as single-agent runs, with an extra agent_id field on per-step events.
Every team member’s events fan in on one stream, and each per-step event carries an agent_id so consumers can attribute activity to a specific member.
Each member agent forwards its per-step events onto team.stream_emitter, which the bridge turns into NDJSON on stdout.

Example NDJSON for a team run

Group events by agent

Filter one member’s events with jq:
Route deltas to per-agent buffers in Python:

Event Schema (schema_version = 1)

Every NDJSON line is a JSON object with event and data keys. Every data object contains schema_version: 1.

Optional fields

Example NDJSON output


Examples per Event Type

Emitted once at the start of every run. Contains the target prompt, model, and framework.
Emitted once per agent invocation, immediately before the agent starts processing.
Emitted each time the agent calls a tool. args contains the tool’s input arguments.
Emitted when a tool returns. ok is true unless the tool reported an error.
Streaming text chunks from the model. reasoning.delta is used when is_reasoning=True.
Emitted before the retry wait, so consumers can render a live countdown instead of a silent-looking hang. Fires on rate-limit / transient-error backoff.
This is the CLI-facing form of the RETRY stream event — same signal, surfaced as NDJSON.
Emitted once when the run completes successfully. result is the agent’s final output.
Emitted when a run-level, streaming, or transport failure occurs. Also emitted for core error events.
On YAML / AgentTeam runs, run.error is now emitted when team.astart() raises. This lets stream-json consumers distinguish a failed team run from an incomplete / still-running one. The original exception is always re-raised — the run.error emit is best-effort and does not mask it.

Stability and Versioning

Every event’s data object includes schema_version: 1. This version is bumped only on backward-incompatible schema changes.
Pin your consumer against schema_version: 1. Future backward-incompatible changes will increment this value so you can detect and handle them gracefully.
The agent_id field on per-step events is a new optional field — a forward-compatible addition that does not change schema_version. Consumers can ignore it and keep working on both single-agent and team runs.

When to Use Which Output Mode


Common Patterns

Filter for specific events with jq

Watch only tool calls and the final result:

Detect run.error in CI

Exit with a non-zero code if the run fails:

Build a progress UI fed by text.delta

Concatenate text.delta chunks to show a live streamed response:

Best Practices

Before processing events, verify data.schema_version == 1. This guards your consumer against future breaking changes.
A run.error event means the run failed. Check ok == false and surface the error field to your observability system.
In text, json, silent, and verbose modes the bridge is a no-op — zero per-step callback overhead. Only enable stream-json when a downstream consumer actually reads the events.
Concatenating text.delta chunks is useful for live display, but run.result.data.result is the single authoritative final output string. Prefer it when you only need the end result.

CLI Run

CLI run reference and output modes

CLI Backend Protocol

Backend protocol for custom CLI integrations

YAML / Team Session Continuity

Resume and continue YAML / AgentTeam runs across sessions

Multi-Agent Output

How multi-agent runs structure and surface their output