A normalized file attachment carried on ExAgent.Message.
Users never build this directly - pass plain maps under the :files option and
ExAgent.Message.new/1 normalizes them:
files: [
%{url: "https://cdn.example.com/invoice.png"},
%{path: "/tmp/report.pdf"},
%{data: png_bytes, mime_type: "image/png"},
%{file_ref: ref}
]:mime_type is optional and inferred from the file extension (:path, :url)
or magic bytes (:data). Supply it to override inference - an explicit value is
always authoritative.
Because a struct is also a map, provider services can keep pattern matching on
%{data: data, mime_type: mime_type} and %{file_ref: %ExAgent.FileRef{}}.
Provider options
:fps and :max_frames (video sampling) are lifted into :provider_opts,
alongside anything passed under an explicit :provider_opts map. They are
normalized here but only meaningful to providers that support video.
Summary
Functions
Returns the attachment's bytes, reading from disk if they are not yet loaded.
Loads a :path attachment's bytes into :data.
Normalizes a user-supplied attachment map into an %ExAgent.Attachment{}.
Types
@type kind() :: :data | :path | :url | :file_ref
@type t() :: %ExAgent.Attachment{ byte_size: non_neg_integer() | nil, data: binary() | nil, file_ref: ExAgent.FileRef.t() | nil, filename: String.t() | nil, kind: kind(), mime_type: String.t(), modality: ExAgent.Source.modality(), path: String.t() | nil, provider_opts: map(), url: String.t() | nil }
Functions
@spec bytes(t()) :: {:ok, binary()} | {:error, ExAgent.Error.t()}
Returns the attachment's bytes, reading from disk if they are not yet loaded.
Returns an error for :url and :file_ref attachments, which have no local
bytes by design.
@spec load(t()) :: {:ok, t()} | {:error, ExAgent.Error.t()}
Loads a :path attachment's bytes into :data.
:url and :file_ref attachments pass through untouched - they are delivered
by reference and must never be fetched.
Normalizes a user-supplied attachment map into an %ExAgent.Attachment{}.
Exactly one source key (:data, :path, :url, :file_ref) must be present.
Examples
iex> {:ok, att} = ExAgent.Attachment.new(%{url: "https://cdn.example.com/a.png"})
iex> {att.kind, att.mime_type, att.modality}
{:url, "image/png", :image}
iex> ExAgent.Attachment.new(%{})
{:error, "each attachment must have one of :data, :path, :url, or :file_ref"}