Repository navigation
JSON events
The event stream printed by malac --json, one JSON object per line.
malac --json prints every event of the main agent and its subagents as one JSON object per line. The same events drive the terminal, the web UI and the VS Code extension. See Plain mode and scripting for usage.
Every line has these fields, plus the fields of its event type:
| Field | Type | Meaning |
|---|---|---|
agent |
string | Id of the agent the event belongs to; empty for update
|
seq |
integer | Sequence number, increasing across all agents |
at |
string | Timestamp, RFC 3339 in UTC |
type |
string | Event type, below |
Agent ids are the session ids used by malac -r and malac sessions show.
| Type | Fields | When |
|---|---|---|
agent_started |
label, parent, model, cwd
|
An agent starts. parent is null for the main agent. |
model_changed |
model |
The agent switched models |
user_message |
text |
A prompt or follow-up arrives |
text_delta |
text |
Streamed answer text |
thinking_delta |
text |
Streamed reasoning |
tool_call_streaming |
tool |
The model is writing a tool call |
assistant_message |
message |
A complete assistant message |
tool_started |
call_id, tool, summary, input
|
A tool call starts |
tool_finished |
call_id, tool, output, is_error, millis
|
A tool call ends. output is a preview of the result. |
permission_requested |
request_id, call_id, tool, summary, input
|
A call waits for approval |
permission_resolved |
request_id, allowed
|
The approval was answered |
todos |
items |
The task list changed; each item has content and status
|
usage |
turn, total, context_tokens
|
Token usage after a model request |
compacted |
summary |
The conversation was compacted |
notice |
level (info, warning, error), message
|
A message for the user, such as a retry |
turn_finished |
status, text
|
A turn ended; text is the final answer |
agent_finished |
status, report
|
A subagent finished; report is what it returned |
update |
status |
A newer malac is available or installed |
status in turn_finished and agent_finished is completed, cancelled or failed.
Count tool calls by tool:
jq -r 'select(.type == "tool_started") | .tool' events.jsonl | sort | uniq -cFail a CI step when any approval was refused (calls blocked by a deny rule never ask, so they produce no permission events; the refusal goes back to the model as the tool's result):
if jq -e 'select(.type == "permission_resolved" and .allowed == false)' events.jsonl > /dev/null; then
echo "a tool call was denied"
exit 1
fiShow what each subagent reported:
jq -r 'select(.type == "agent_finished") | "\(.agent): \(.report)"' events.jsonlNote
The event format is not versioned. Fields may be added; parse defensively. Daemon clients get the same events wrapped in event messages; see Protocol.
Getting started
Tutorials
- Tutorials
- Tutorial 1: Your first task
- Tutorial 2: Delegating to subagents
- Tutorial 3: Automating a browser
- Tutorial 4: Long-term memory with Milvus
- Tutorial 5: Running malac unattended
- Tutorial 6: Customizing malac
- Tutorial 7: Running malac on a server
Using malac
- Workspaces, tabs and the daemon
- The terminal UI
- Plain mode and scripting
- Sessions
- Jobs
- Permissions and autopilot
- Subagents
- Memory
- Project context
- Plugins and marketplaces
- Computer and browser control
- Web UI
- VS Code
- Remote access
- Mobile (preview)
- MCP servers
- Configure malac by asking
- Updating
Reference
- CLI
- Slash commands
- Configuration
- Tools
- Control service tools
- JSON events
- Protocol
- Environment variables
Guides
- Using an LLM gateway
- Running models locally
- Vector memory with Milvus
- Controlling a remote machine
- Writing agent types, skills and commands
- Security model
- Things to know
Project