ExAgent.Attachment (ExAgent v0.4.0)

Copy Markdown View Source

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

kind()

@type kind() :: :data | :path | :url | :file_ref

t()

@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

bytes(attachment)

@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.

load(attachment)

@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.

new(attachment)

@spec new(map() | t()) :: {:ok, t()} | {:error, String.t()}

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"}