Skip to content

Message Protocol

%Message{
id: "uuid",
parent_id: nil | "uuid", # forms a tree
role: :user | :assistant | :system,
content: [content_block],
timestamp: DateTime.t(),
metadata: %{}
}
{:text, "hello"}
{:thinking, "let me reason..."}
{:tool_use, %{id: "tc_1", name: "shell", arguments: %{"command" => "ls"}}}
{:image, mime_type, base64_data}
%ToolCall{
id: "tc_1",
name: "shell",
arguments: %{"command" => "ls -la"}
}
%ToolResult{
tool_call_id: "tc_1",
name: "shell",
content: "total 42\ndrwxr-xr-x ...",
is_error: false
}
{:text_delta, "partial text"}
{:thinking_delta, "partial thinking"}
{:tool_call_start, id, name}
{:tool_call_delta, id, json_fragment}
{:tool_call_end, id}
{:usage, %{input: 1234, output: 567}}

Tool call JSON fragments are buffered until tool_call_end, then decoded with Jason.decode!/1.