mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-10 05:01:28 -10:00
* fix(openai): handle reasoning alias in stream deltas * test(cli): assert reasoning event order --------- Co-authored-by: Ashwin <[email protected]>
76 lines
4.0 KiB
Markdown
76 lines
4.0 KiB
Markdown
# Zero Stream-JSON Protocol
|
|
|
|
Zero stream-json is a line-delimited protocol for headless clients such as
|
|
editor extensions and automation wrappers.
|
|
|
|
Every line is one JSON object. Empty input lines are ignored. Output events are
|
|
redacted before they are written to stdout.
|
|
|
|
## Version
|
|
|
|
Current schema version: `2`
|
|
|
|
Every input and output event must include:
|
|
|
|
```json
|
|
{ "schemaVersion": 2, "type": "..." }
|
|
```
|
|
|
|
Output events also include `runId`.
|
|
|
|
## Input Events
|
|
|
|
`zero exec --input-format stream-json` accepts these JSONL events from stdin or
|
|
`--file`.
|
|
|
|
```json
|
|
{ "schemaVersion": 2, "type": "message", "role": "user", "content": "Inspect this repo." }
|
|
{ "schemaVersion": 2, "type": "prompt", "content": "Return only blockers." }
|
|
```
|
|
|
|
Zero combines accepted input event content in order, separated by blank lines.
|
|
Unknown fields are rejected so protocol clients catch drift early.
|
|
|
|
Schema version `2` renamed sandbox permission metadata from `violation` to
|
|
`block`. Clients should read the optional `block` object on permission and tool
|
|
events when present.
|
|
|
|
## Output Events
|
|
|
|
`zero exec --output-format stream-json` emits schema-versioned JSONL events.
|
|
|
|
```json
|
|
{ "schemaVersion": 2, "type": "run_start", "runId": "run_20260603_abc123", "sessionId": "zero_20260603100000_abc123", "cwd": "/repo", "provider": "openai", "model": "gpt-4.1", "apiModel": "gpt-4.1" }
|
|
{ "schemaVersion": 2, "type": "reasoning", "runId": "run_20260603_abc123", "delta": "Thinking..." }
|
|
{ "schemaVersion": 2, "type": "text", "runId": "run_20260603_abc123", "delta": "..." }
|
|
{ "schemaVersion": 2, "type": "tool_call", "runId": "run_20260603_abc123", "id": "call_1", "name": "read_file", "args": { "path": "README.md" }, "sideEffect": "read" }
|
|
{ "schemaVersion": 2, "type": "permission_request", "runId": "run_20260603_abc123", "id": "call_2", "name": "write_file", "action": "prompt", "permission": "prompt", "permissionMode": "ask", "sideEffect": "write", "reason": "Creates or overwrites files." }
|
|
{ "schemaVersion": 2, "type": "permission_decision", "runId": "run_20260603_abc123", "id": "call_2", "name": "write_file", "action": "allow", "permission": "prompt", "permissionGranted": true, "decisionReason": "approved in TUI" }
|
|
{ "schemaVersion": 2, "type": "tool_result", "runId": "run_20260603_abc123", "id": "call_1", "status": "ok", "output": "...", "truncated": false }
|
|
{ "schemaVersion": 2, "type": "usage", "runId": "run_20260603_abc123", "promptTokens": 12, "completionTokens": 8, "totalTokens": 20 }
|
|
{ "schemaVersion": 2, "type": "final", "runId": "run_20260603_abc123", "text": "..." }
|
|
{ "schemaVersion": 2, "type": "run_end", "runId": "run_20260603_abc123", "status": "success", "exitCode": 0 }
|
|
```
|
|
|
|
`reasoning` events carry live model reasoning/status deltas for providers that
|
|
stream them separately from answer text. They are liveness/progress events only:
|
|
they are not folded into `text` or the final answer.
|
|
|
|
Permission events may include structured sandbox metadata:
|
|
|
|
```json
|
|
{ "schemaVersion": 2, "type": "permission_request", "runId": "run_20260603_abc123", "id": "call_3", "name": "bash", "action": "prompt", "permission": "prompt", "permissionMode": "ask", "sideEffect": "shell", "reason": "network access requires approval", "risk": { "level": "critical", "categories": ["network"] }, "block": { "code": "network", "toolName": "bash", "action": "prompt", "risk": { "level": "critical", "categories": ["network"] }, "reason": "network access requires approval", "recoverable": true } }
|
|
```
|
|
|
|
Errors are part of the protocol and are followed by `run_end`.
|
|
|
|
Headless `exec` has no interactive permission responder. If a prompt-gated tool
|
|
is not pre-approved, Zero may emit `permission_request` followed by a denied
|
|
`tool_result`; interactive surfaces emit `permission_decision` when the user
|
|
allows, denies, or always-allows the request.
|
|
|
|
```json
|
|
{ "schemaVersion": 2, "type": "error", "runId": "run_20260603_abc123", "code": "provider_error", "message": "...", "recoverable": false }
|
|
{ "schemaVersion": 2, "type": "run_end", "runId": "run_20260603_abc123", "status": "error", "exitCode": 3 }
|
|
```
|