Current section

Files

Jump to
claude_code lib claude_code content tool_result.ex
Raw

lib/claude_code/content/tool_result.ex

defmodule ClaudeCode.Content.ToolResult do
@moduledoc """
Represents a tool result content block within a Claude message.
Tool result blocks contain the output from a tool execution, which can be
either successful results or error messages.
"""
@enforce_keys [:type, :tool_use_id, :content, :is_error]
defstruct [:type, :tool_use_id, :content, :is_error]
@type t :: %__MODULE__{
type: :tool_result,
tool_use_id: String.t(),
content: String.t(),
is_error: boolean()
}
@doc """
Creates a new ToolResult content block from JSON data.
## Examples
iex> ToolResult.new(%{"type" => "tool_result", "tool_use_id" => "123", "content" => "OK"})
{:ok, %ToolResult{type: :tool_result, tool_use_id: "123", content: "OK", is_error: false}}
iex> ToolResult.new(%{"type" => "text"})
{:error, :invalid_content_type}
"""
@spec new(map()) :: {:ok, t()} | {:error, atom() | {:missing_fields, [atom()]}}
def new(%{"type" => "tool_result"} = data) do
required = ["tool_use_id", "content"]
missing = Enum.filter(required, &(not Map.has_key?(data, &1)))
if Enum.empty?(missing) do
result = %__MODULE__{
type: :tool_result,
tool_use_id: data["tool_use_id"],
content: data["content"],
is_error: Map.get(data, "is_error", false)
}
{:ok, result}
else
{:error, {:missing_fields, Enum.map(missing, &String.to_atom/1)}}
end
end
def new(_), do: {:error, :invalid_content_type}
@doc """
Type guard to check if a value is a ToolResult content block.
"""
@spec tool_result_content?(any()) :: boolean()
def tool_result_content?(%__MODULE__{type: :tool_result}), do: true
def tool_result_content?(_), do: false
end