Agent events reference
Request shape
Section titled “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)
Section titled “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
Section titled “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
Section titled “Event types observed”| Event type | Glasspane mapping | Status |
|---|---|---|
response (success:true) | None (no state change) | ✅ Correct |
user_message | message_update | ✅ Tested |
turn_start | turn_start | ✅ Tested |
turn_end | turn_end | ✅ Tested |
error | error | ✅ Tested |
done | agent_end | ✅ Tested |
Type values NOT in the current mapping (phase 1 transcript)
Section titled “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)
Section titled “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)
Section titled “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)
Section titled “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)
Section titled “Confirmed event types (real-key run)”| Event type | Glasspane maps to | Notes |
|---|---|---|
response (success:true) | None (no state change) | Command ack |
user_message | message_update | |
turn_start | turn_start | step field for turn number |
assistant_start | message_start | Before text or tool use |
tool_use_start | tool_execution_start | Canonical entry point for tool execution start |
tool_use_args | tool_execution_update | Delta-streamed character by character |
tool_use_end | tool_execution_update | Args complete |
usage | None | cache_read, cache_write, cost_usd, cumulative |
assistant_message | message_end | Contains a nested tool_call content block; top-level type is still message end |
tool_call | None (skipped) | Skipped — tool_use_start already covers tool_execution_start |
turn_end | turn_end | stop: “tool_use” (waiting) or “end” (finished) |
tool_progress | tool_execution_update | Streaming tool output |
tool_result | tool_execution_end | is_error field present |
text_delta | message_update | Streaming text response |
done | agent_end | Session end |
Glasspane gaps
Section titled “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)
Section titled “Verified facts (observed, not inferred from source)”tool_use_start/args/endfor streamed tool calls- standalone
tool_callappears aftertool_use_start; Glasspane skips it to avoid a duplicate start text_deltastreams response text character by characterassistant_messageappears in two contexts (tool block + final text)turn_end.stopdistinguishes “tool_use” vs “end”tool_resultcarriesis_errorbooleanusagecarriescache_read,cache_write,cost_usd,cumulative
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
Section titled “See also”- agent-harness — the zot / Colibri split and autospawn model
- glasspane — the state machine that consumes these events