Packages
claude_code
0.35.0
0.36.5
0.36.4
0.36.3
0.36.2
0.36.1
0.36.0
0.35.0
0.34.0
0.33.1
0.32.2
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.1
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Claude Agent SDK for Elixir – Build AI agents with Claude Code
Current section
Files
Jump to
Current section
Files
lib/claude_code/content/document_block.ex
defmodule ClaudeCode.Content.DocumentBlock do
@moduledoc """
Represents a document content block within a Claude message.
Document blocks contain document data (PDF, plain text) either inline or by
reference. They appear in user messages and can also appear within server tool
results (e.g., web fetch).
## Source types
* `"base64"` — inline document with `data` and `media_type`
* `"text"` — inline plain text with `data` and `media_type`
* `"url"` — remote document referenced by `url`
* `"content"` — structured content with nested blocks
"""
use ClaudeCode.JSONEncoder
@enforce_keys [:type, :source]
defstruct [:type, :source, :title, :context, :citations]
@type source ::
%{
type: :base64,
media_type: String.t(),
data: String.t()
}
| %{
type: :text,
media_type: String.t(),
data: String.t()
}
| %{
type: :url,
url: String.t()
}
| %{
type: :content,
content: list() | String.t()
}
@type t :: %__MODULE__{
type: :document,
source: source(),
title: String.t() | nil,
context: String.t() | nil,
citations: map() | nil
}
@spec new(map()) :: {:ok, t()} | {:error, atom() | {:missing_fields, [atom()]}}
def new(%{"type" => "document", "source" => source} = data) when is_map(source) do
case parse_source(source) do
{:ok, parsed_source} ->
{:ok,
%__MODULE__{
type: :document,
source: parsed_source,
title: data["title"],
context: data["context"],
citations: data["citations"]
}}
error ->
error
end
end
def new(%{"type" => "document"}), do: {:error, {:missing_fields, [:source]}}
def new(_), do: {:error, :invalid_content_type}
defp parse_source(%{"type" => type, "data" => data, "media_type" => media_type}) when type in ["base64", "text"],
do: {:ok, %{type: String.to_atom(type), media_type: media_type, data: data}}
defp parse_source(%{"type" => type} = s) when type in ["base64", "text"],
do: {:error, {:missing_fields, missing_keys(s, ["data", "media_type"])}}
defp parse_source(%{"type" => "url", "url" => url}) when is_binary(url), do: {:ok, %{type: :url, url: url}}
defp parse_source(%{"type" => "url"}), do: {:error, {:missing_fields, [:url]}}
defp parse_source(%{"type" => "content", "content" => content}), do: {:ok, %{type: :content, content: content}}
defp parse_source(%{"type" => "content"}), do: {:error, {:missing_fields, [:content]}}
defp parse_source(%{"type" => _}), do: {:error, :unknown_source_type}
defp parse_source(_), do: {:error, {:missing_fields, [:type]}}
defp missing_keys(map, keys), do: for(k <- keys, not Map.has_key?(map, k), do: String.to_atom(k))
end
defimpl String.Chars, for: ClaudeCode.Content.DocumentBlock do
def to_string(%{title: title}) when is_binary(title), do: "[document: #{title}]"
def to_string(%{source: %{type: type}}), do: "[document: #{type}]"
end