defmodule A2AEx.Artifact do @moduledoc """ A file, data structure, or other resource generated by an agent during a task. """ @type t :: %__MODULE__{ id: String.t(), name: String.t() | nil, description: String.t() | nil, parts: [A2AEx.Part.t()], extensions: [String.t()] | nil, metadata: map() | nil } @enforce_keys [:id, :parts] defstruct [:id, :name, :description, :parts, :extensions, :metadata] @spec from_map(map()) :: {:ok, t()} | {:error, String.t()} def from_map(map) when is_map(map) do with {:ok, parts} <- A2AEx.Part.from_map_list(map["parts"] || []) do {:ok, %__MODULE__{ id: map["artifactId"] || A2AEx.ID.new(), name: map["name"], description: map["description"], parts: parts, extensions: map["extensions"], metadata: map["metadata"] }} end end @spec to_map(t()) :: map() def to_map(%__MODULE__{} = artifact) do %{ "artifactId" => artifact.id, "parts" => Enum.map(artifact.parts, &A2AEx.Part.to_map/1) } |> maybe_put("name", artifact.name) |> maybe_put("description", artifact.description) |> maybe_put("extensions", artifact.extensions) |> maybe_put("metadata", artifact.metadata) end defp maybe_put(map, _key, nil), do: map defp maybe_put(map, key, value), do: Map.put(map, key, value) end defimpl Jason.Encoder, for: A2AEx.Artifact do def encode(artifact, opts) do A2AEx.Artifact.to_map(artifact) |> Jason.Encode.map(opts) end end