Agent events reference

Agent events reference

index

Request shape

{"id":"1","type":"prompt","message":"check the current directory"}

zot uses its own protocol, NOT JSON-RPC 2.0. The type field is prompt,

id is a correlation string.

Raw stdout (secrets redacted, auth failed — key was placeholder)

{"command":"prompt","data":{"started":true},"id":"1","success":true,"type":"response"}

{"content":[{"text":"check the current directory","type":"text"}],"time":"2026-06-21T22:36:06.817Z","type":"user_message"}

{"step":1,"type":"turn_start"}

{"error":"deepseek: http 401: ...","stop":"error","type":"turn_end"}

{"message":"deepseek: http 401: ...","type":"error"}

{"type":"done"}

Wire format decision

Bare event objects. Each line is a plain JSON object with a type field.

No JSON-RPC envelope (no jsonrpc, method, params wrapping). This

matches glasspane's zot_event_type parser exactly — it reads

value.get("type") directly from the object.

Event types observed

Event typeGlasspane mappingStatus
response (success:true)None (no state change)✅ Correct
user_messagemessage_update✅ Tested
turn_startturn_start✅ Tested
turn_endturn_end✅ Tested
errorerror✅ Tested
doneagent_end✅ Tested

Type values NOT in the current mapping (phase 1 transcript)

None observed. All 6 event types from the transcript have mappings.

The response type with success:true correctly returns None (no state change).

Verdict (phase 1 — placeholder key)

Wire format confirmed: bare event objects, no JSON-RPC envelope. Glasspane's

parser shape is correct. The session-lifecycle events (turn_start, turn_end,

error, done, user_message, response) are validated against real output.

Tool-lifecycle events (tool_call, tool_use_, text_delta, assistant_, tool_result)

are NOT yet validated — the API key was a placeholder (DeepSeek returned 401

before reaching the agent loop). A re-run with a valid DEEPSEEK_API_KEY is

needed to capture a real tool call before the driver can trust those mappings.

Step 1 of colibri#143 is complete after the real-key re-run below. Steps 2 and 3 are unblocked.

Real-key transcript (complete tool call, 2026-06-21)

Prompt: "run uname -a and tell me the kernel version in one sentence"

61 lines, 2 turns, 1 tool call (bash), DeepSeek v4-pro, cached tokens.

Raw stdout (secrets redacted)

{"command":"prompt","data":{"started":true},"id":"1","success":true,"type":"response"}

{"content":[{"text":"run uname -a and tell me the kernel version in one sentence","type":"text"}],"time":"...","type":"user_message"}

{"step":1,"type":"turn_start"}

{"type":"assistant_start"}

{"id":"call_00_...","name":"bash","type":"tool_use_start"}

{"delta":"{","id":"call_00_...","type":"tool_use_args"}

{"delta":"\\"command\\": \\"uname -a\\"","id":"call_00_...","type":"tool_use_args"}

{"delta":"}","id":"call_00_...","type":"tool_use_args"}

{"id":"call_00_...","type":"tool_use_end"}

{"cache_read":896,...,"type":"usage"}

{"content":[{"args":{"command":"uname -a"},"id":"call_00_...","name":"bash","type":"tool_call"}],"time":"...","type":"assistant_message"}

{"args":{"command":"uname -a"},"id":"call_00_...","name":"bash","type":"tool_call"}

{"stop":"tool_use","type":"turn_end"}

{"id":"call_00_...","text":"FreeBSD osa.smilepowered.org 15.0-RELEASE-p10...\\n","type":"tool_progress"}

{"content":[{"text":"$ uname -a\\n...","type":"text"}],"id":"call_00_...","is_error":false,"type":"tool_result"}

{"step":2,"type":"turn_start"}

{"type":"assistant_start"}

{"delta":"This","type":"text_delta"}

{"delta":" system","type":"text_delta"}

... (streaming text deltas, 30+ lines) ...

{"cache_read":896,...,"type":"usage"}

{"stop":"end","type":"turn_end"}

{"type":"done"}

Full 61-line transcript is stored on OSA, outside the repository.

Confirmed event types (real-key run)

Event typeGlasspane maps toNotes
response (success:true)None (no state change)Command ack
user_messagemessage_update
turn_startturn_startstep field for turn number
assistant_startmessage_startBefore text or tool use
tool_use_starttool_execution_startCanonical entry point for tool execution start
tool_use_argstool_execution_updateDelta-streamed character by character
tool_use_endtool_execution_updateArgs complete
usageNonecache_read, cache_write, cost_usd, cumulative
assistant_messagemessage_endContains a nested tool_call content block; top-level type is still message end
tool_callNone (skipped)Skipped — tool_use_start already covers tool_execution_start
turn_endturn_endstop: "tool_use" (waiting) or "end" (finished)
tool_progresstool_execution_updateStreaming tool output
tool_resulttool_execution_endis_error field present
text_deltamessage_updateStreaming text response
doneagent_endSession end

Glasspane gaps

None. All 15 real-key event types have valid, non-duplicate mappings. Resolved (colibri#143): tool_call was previously mapped to tool_execution_start (same as tool_use_start), causing a double-fire.

The standalone tool_call event is now skipped — it returns None from the

normalizer. tool_use_start is the sole entry point for tool execution start.

Verified facts (observed, not inferred from source)

Step 1 of colibri#143 is complete — wire format and all 15 event types are

validated against real output. The tool_call double-fire gap is resolved by

skipping the duplicate standalone event in Glasspane.

See also