defmodule Planck.AI.Message do
@moduledoc """
A single conversation turn with a role and a list of typed content parts.
Content is always a list of tagged tuples, mirroring the Anthropic API's
multi-part message format. An assistant message may contain both text and
tool calls interleaved.
## Content part types
- `{:text, text}` — plain text
- `{:image, data, mime_type}` — binary image data with MIME type
- `{:image_url, url}` — image referenced by URL
- `{:file, data, mime_type}` — binary file/document (PDF, etc.)
- `{:video_url, url}` — video referenced by URL (Google Gemini only)
- `{:tool_call, id, name, args}` — a tool call emitted by the model
- `{:tool_result, id, result}` — the result of executing a tool call
- `{:thinking, text}` — extended thinking / reasoning block
## Examples
iex> %Planck.AI.Message{
...> role: :user,
...> content: [{:text, "What is the weather in Lisbon?"}]
...> }
"""
@type role :: :user | :assistant | :tool_result
@type content_part ::
{:text, String.t()}
| {:image, binary(), String.t()}
| {:image_url, String.t()}
| {:file, binary(), String.t()}
| {:video_url, String.t()}
| {:tool_call, String.t(), String.t(), map()}
| {:tool_result, String.t(), term()}
| {:thinking, String.t()}
@type t :: %__MODULE__{
role: role(),
content: [content_part()]
}
defstruct [:role, content: []]
end