Current section
Files
Jump to
Current section
Files
lib/anthropic/messages/message.ex
defmodule Anthropic.Messages.Message do
@moduledoc """
A message returned by the Anthropic Messages API — the `{:ok, message}` result of
`Anthropic.Messages.create/2` or the final fold of `Anthropic.Messages.stream/2`.
"""
alias Anthropic.Messages.Content
alias Anthropic.Messages.Content.ToolUse
defstruct [
:id,
:type,
:role,
:model,
:stop_reason,
:stop_sequence,
content: [],
usage: %{}
]
@type t :: %__MODULE__{
id: String.t() | nil,
type: String.t() | nil,
role: String.t() | nil,
content: list(Content.t()),
model: String.t() | nil,
stop_reason: String.t() | nil,
stop_sequence: String.t() | nil,
usage: map()
}
@spec from_json(map()) :: t()
def from_json(body) when is_map(body) do
%__MODULE__{
id: body["id"],
type: body["type"],
role: body["role"],
content: Enum.map(body["content"] || [], &Content.from_json/1),
model: body["model"],
stop_reason: body["stop_reason"],
stop_sequence: body["stop_sequence"],
usage: body["usage"] || %{}
}
end
@doc """
Converts this message into a plain map suitable for the `messages` request param, for
continuing a conversation (tool-use loop, multi-turn chat).
"""
@spec to_param(t()) :: map()
def to_param(%__MODULE__{role: role, content: content}) do
%{role: role, content: Enum.map(content, &Content.to_json/1)}
end
@doc "True if this message is asking the caller to run tools."
@spec tool_use?(t()) :: boolean()
def tool_use?(%__MODULE__{stop_reason: "tool_use"}), do: true
def tool_use?(%__MODULE__{}), do: false
@doc "All `tool_use` content blocks in this message, in order."
@spec tool_uses(t()) :: list(ToolUse.t())
def tool_uses(%__MODULE__{content: content}) do
Enum.filter(content, &match?(%ToolUse{}, &1))
end
end