5.2 KiB
5.2 KiB
stream-json output protocol
EvoSci --output-format stream-json runs a single-shot (-p) session and emits
EvoScientist's native event stream as line-delimited JSON (JSONL) on stdout —
one self-describing JSON object per line. This is the integration surface for
programmatic clients that drive EvoScientist headlessly (for example, an agent
runtime that assigns work and renders live progress).
EvoSci -p "Summarize the attention mechanism into notes.md" \
--output-format stream-json \
--auto-mode \
--workdir /path/to/task
Stream contract
- stdout is pure JSONL. Every line is one complete JSON object. Parse it with
a line reader +
json.loadsper line. Nothing else is written to stdout. - stderr carries everything human — status lines ("Loading agent…"), separators, the resume hint, and error panels. A consumer should treat stderr as logs, not protocol.
- Each object has a
typefield used for dispatch. A consumer that does not recognize atypeshould ignore that line rather than fail — new event types may be added over time, and the protocol is forward-compatible by design. - The stream ends with a
doneevent carrying the final response text. On an unhandled failure anerrorevent is emitted instead/also. - Unattended by default.
stream-jsonis headless, so--auto-modeis enabled automatically: approval andask_usergates are auto-handled and the run proceeds straight to itsdoneevent. Pass--no-auto-modeto opt out — a human-in-the-loopinterrupt/ask_useris then emitted as a normal event and the single-shot run ends right after it (… → interrupt → done → EOF). It does not block waiting for input, but it also stops before finishing the task; answering the event requires re-invoking with--resume(experimental).
Event types
Each line is a self-contained JSON object with a type field. Most fields are
scalars, but some events carry nested payloads (e.g. args, action_requests,
questions) — parse each line as a full object, not a flat key/value map. The
fields beyond type are listed below.
type |
Fields | Meaning |
|---|---|---|
thinking |
content, id |
Model reasoning text |
text |
content |
Assistant output text |
tool_call |
name, args, id |
Tool invocation |
tool_result |
name, content, success, id |
Tool result (id matches the tool_call) |
subagent_start |
name, description |
Sub-agent delegation begins |
subagent_tool_call |
subagent, name, args, id |
Tool call inside a sub-agent |
subagent_tool_result |
subagent, name, content, success, id |
Tool result inside a sub-agent |
subagent_text |
subagent, content, instance_id |
Text from a sub-agent |
subagent_end |
name |
Sub-agent delegation completes |
tool_selection |
tools |
Tool-selector middleware picked tools |
summarization_start |
— | Context summarization begins |
summarization |
content |
Context summarization output |
usage_stats |
input_tokens, output_tokens |
Token usage |
interrupt |
interrupt_id, action_requests, review_configs |
HITL approval interrupt |
ask_user |
interrupt_id, questions, tool_call_id |
Agent-initiated clarifying question |
error |
message |
Error during the run |
done |
content, response |
Final response; end of stream |
Example transcript
{"type": "thinking", "content": "I should write the notes file.", "id": 0}
{"type": "tool_call", "name": "write_file", "args": {"path": "notes.md", "content": "..."}, "id": "call_1"}
{"type": "tool_result", "name": "write_file", "content": "wrote 412 bytes", "success": true, "id": "call_1"}
{"type": "text", "content": "Done — notes.md now summarizes attention."}
{"type": "usage_stats", "input_tokens": 5123, "output_tokens": 388}
{"type": "done", "content": "Done — notes.md now summarizes attention.", "response": "Done — notes.md now summarizes attention."}
Notes for client implementers
- Read stdout line by line; do not assume a single JSON document.
- Accumulate
textevents for the running assistant message; the terminaldone.responseis the authoritative final text. tool_call/tool_resultcorrelate byid.- Token usage may arrive across multiple
usage_statsevents; sum them. - Treat unknown
typevalues and unknown fields as non-fatal.