A completed message returned by the Messages API.
raw holds the response exactly as it arrived, so a field the API adds
before Claudex models it is still readable. It's hidden from inspect/1 to
keep output readable.
Summary
Functions
Adds one or more messages to the conversation.
Builds an assistant message, for putting words in Claude's mouth when you're replaying a conversation you stored somewhere.
Joins every text block in the message into one string. Use this when you just want the reply text and don't need thinking or tool-call blocks.
Turns a decoded message back into the map the API expects in messages.
Wraps tool results into the message that carries them back to Claude.
Builds a user message — a question, an instruction, anything you're sending.
Types
Functions
Adds one or more messages to the conversation.
history = Message.append(history, Message.user("What is 12 plus 30?"))
{:ok, reply} = Claudex.Messages.create(client, %{model: model, max_tokens: 1024, messages: history})
history = Message.append(history, reply)Takes a decoded %Claudex.Message{} as readily as a map you built, and turns
both into plain data on the way in. That's the point of doing it here rather
than with ++: a history you can hand to JSON.encode!/1 and read back from
a database behaves exactly like one you just built, because it's the same
shape either way.
@spec assistant(String.t() | [map() | Claudex.ContentBlock.t()]) :: map()
Builds an assistant message, for putting words in Claude's mouth when you're replaying a conversation you stored somewhere.
You don't need this for a reply you just received — a %Claudex.Message{}
goes back into messages as it is.
Joins every text block in the message into one string. Use this when you just want the reply text and don't need thinking or tool-call blocks.
iex> message = %Claudex.Message{
...> content: [
...> %Claudex.ContentBlock.Text{text: "The answer "},
...> %Claudex.ContentBlock.ToolUse{id: "toolu_1", name: "add", input: %{}},
...> %Claudex.ContentBlock.Text{text: "is 42."}
...> ]
...> }
iex> Claudex.Message.text(message)
"The answer is 42."
Turns a decoded message back into the map the API expects in messages.
Claudex.Messages.create/2 and friends run this for you, so a
%Claudex.Message{} can go straight back into the conversation:
{:ok, reply} = Claudex.Messages.create(client, %{model: model, max_tokens: 1024, messages: history})
history = history ++ [reply, %{role: "user", content: "and then?"}]A message you built yourself is passed through, with any content blocks in it
converted too — so user/1 and friends can take Claudex structs as content.
Wraps tool results into the message that carries them back to Claude.
Claudex.Message.tool_results([Claudex.Tool.result(tool_use.id, "42")])Results go back with role: "user", because they're input to Claude, not
something it said. Put every result for one reply in a single message —
splitting them teaches Claude to stop making parallel tool calls.
Claudex.ToolRunner does this for you; reach for it when you're driving the
loop yourself.
@spec user(String.t() | [map() | Claudex.ContentBlock.t()]) :: map()
Builds a user message — a question, an instruction, anything you're sending.
Claudex.Message.user("What is 12 plus 30?")
#=> %{role: "user", content: "What is 12 plus 30?"}content is a string for plain text, or a list of content blocks for
anything richer — images, documents, or Claudex.ContentBlock structs from
an earlier reply.