# `A2A.JSON`
[🔗](https://github.com/actioncard/a2a-elixir/blob/main/lib/a2a/json.ex#L1)

Codec for converting between Elixir structs and the A2A v0.3 camelCase JSON wire format.

Produces intermediate maps (not JSON strings) suitable for composing with
JSON-RPC envelopes. Use `Jason.encode!/1` on the result when you need a string.

## Encoding

    iex> part = A2A.Part.Text.new("hello")
    iex> {:ok, map} = A2A.JSON.encode(part)
    iex> map
    %{"kind" => "text", "text" => "hello"}

## Decoding

    iex> {:ok, part} = A2A.JSON.decode(%{"kind" => "text", "text" => "hello"}, :part)
    iex> part
    %A2A.Part.Text{text: "hello", metadata: %{}}

# `decode_type`

```elixir
@type decode_type() ::
  :task
  | :status
  | :message
  | :artifact
  | :part
  | :file_content
  | :event
  | :status_update_event
  | :artifact_update_event
```

# `encode_result`

```elixir
@type encode_result() :: {:ok, map()} | {:error, term()}
```

# `decode`

```elixir
@spec decode(map(), decode_type()) :: {:ok, struct()} | {:error, term()}
```

Decodes a JSON map into an Elixir struct of the given type.

Returns `{:ok, struct}` on success or `{:error, reason}` on failure.

The `:part` type dispatches on the `"kind"` field, or infers the type
from content fields (`"text"`, `"file"`, `"data"`) when `"kind"` is
absent (v0.3 format). The `:event` type dispatches on `"kind"` to one
of `"status-update"`, `"artifact-update"`, `"task"`, or `"message"`.

# `decode!`

```elixir
@spec decode!(map(), decode_type()) :: struct()
```

Decodes a JSON map into an Elixir struct, raising on failure.

# `decode_agent_card`

```elixir
@spec decode_agent_card(map()) :: {:ok, A2A.AgentCard.t()} | {:error, term()}
```

Decodes a JSON map into an `%A2A.AgentCard{}` struct.

Returns `{:ok, agent_card}` on success or `{:error, reason}` on failure.

## Example

    iex> map = %{
    ...>   "name" => "test",
    ...>   "description" => "A test agent",
    ...>   "url" => "https://example.com",
    ...>   "version" => "1.0.0",
    ...>   "skills" => [
    ...>     %{"id" => "s1", "name" => "Skill", "description" => "Does things", "tags" => []}
    ...>   ]
    ...> }
    iex> {:ok, card} = A2A.JSON.decode_agent_card(map)
    iex> card.name
    "test"

# `decode_state`

```elixir
@spec decode_state(String.t()) ::
  {:ok, atom()} | {:error, {:invalid_state, String.t()}}
```

Decodes a wire-format state string to an atom.

Accepts both v0.3 (`"TASK_STATE_WORKING"`) and legacy (`"working"`)
formats.

# `encode`

```elixir
@spec encode(struct()) :: encode_result()
```

Encodes an Elixir struct to a JSON-ready map.

Returns `{:ok, map}` on success or `{:error, reason}` on failure.
Optional `nil` fields and empty collections are omitted from the output.

# `encode!`

```elixir
@spec encode!(struct()) :: map()
```

Encodes an Elixir struct to a JSON-ready map, raising on failure.

# `encode_agent_card`

```elixir
@spec encode_agent_card(
  A2A.Agent.card(),
  keyword()
) :: map()
```

Encodes an agent card map with options into the AgentCard JSON format.

## Options

- `:url` — the agent's endpoint URL (required)
- `:capabilities` — `AgentCapabilities` map (default: `%{}`)
- `:default_input_modes` — list of MIME types (default: `["text/plain"]`)
- `:default_output_modes` — list of MIME types (default: `["text/plain"]`)
- `:provider` — `%{organization: ..., url: ...}` map
- `:documentation_url` — URL string
- `:icon_url` — URL string
- `:protocol_version` — protocol version string
- `:supported_interfaces` — list of `%{url: ..., protocol_binding: ...,
  protocol_version: ...}` maps. Defaults to a single JSON-RPC interface
  derived from `:url`.
- `:security_schemes` — `%{name => %SecurityScheme.X{}}` map
- `:security` — list of `%{name => scopes}` maps (OpenAPI-style)

# `encode_known_keys`

```elixir
@spec encode_known_keys(map(), [{String.t(), atom()}]) :: map()
```

Converts an Elixir map with atom keys to a camelCase JSON map.

Each mapping is a `{json_key, atom_key}` pair. Keys whose values are `nil`
(or absent) are omitted from the result. Looks up both the atom key and the
JSON-string key so the function works with either representation.

# `valid_state_strings`

```elixir
@spec valid_state_strings() :: [String.t()]
```

Returns the list of valid v0.3 wire-format state strings.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
