# `A2A.Client`
[🔗](https://github.com/actioncard/a2a-elixir/blob/main/lib/a2a/client.ex#L2)

HTTP client for consuming remote A2A agents.

Provides discovery, synchronous messaging, SSE streaming, and task
management using the A2A JSON-RPC protocol over HTTP.

## Quick Start

    # Discover an agent
    {:ok, card} = A2A.Client.discover("https://agent.example.com")

    # Create a client and send a message
    client = A2A.Client.new(card)
    {:ok, task} = A2A.Client.send_message(client, "Hello!")

    # Stream a response
    {:ok, stream} = A2A.Client.stream_message(client, "Count to 5")
    Enum.each(stream, &IO.inspect/1)

## Convenience Overloads

All functions that accept a `%A2A.Client{}` also accept a URL string
or `%A2A.AgentCard{}`:

    {:ok, task} = A2A.Client.send_message("https://agent.example.com", "Hello!")
    {:ok, task} = A2A.Client.send_message(card, "Hello!")

## Options

Functions that send messages accept these options:

- `:task_id` — continue an existing task (multi-turn)
- `:context_id` — set the context ID
- `:configuration` — `MessageSendConfiguration` map
- `:metadata` — arbitrary metadata map
- `:headers` — additional HTTP headers
- `:timeout` — HTTP request timeout in ms

# `t`

```elixir
@type t() :: %A2A.Client{req: Req.Request.t(), url: String.t()}
```

# `target`

```elixir
@type target() :: t() | A2A.AgentCard.t() | String.t()
```

# `cancel_task`

```elixir
@spec cancel_task(target(), String.t(), keyword()) ::
  {:ok, A2A.Task.t()} | {:error, term()}
```

Cancels a task by ID via `tasks/cancel`.

## Options

- `:headers` — additional HTTP headers
- `:timeout` — HTTP request timeout in ms

## Examples

    {:ok, task} = A2A.Client.cancel_task(client, "tsk-abc123")

# `discover`

```elixir
@spec discover(
  String.t(),
  keyword()
) :: {:ok, A2A.AgentCard.t()} | {:error, term()}
```

Discovers an agent by fetching its agent card.

Sends `GET /.well-known/agent-card.json` and decodes the response
into an `%A2A.AgentCard{}`.

## Options

- `:headers` — additional HTTP headers
- `:timeout` — HTTP request timeout in ms
- `:agent_card_path` — custom discovery path
  (default: `"/.well-known/agent-card.json"`)

## Examples

    {:ok, card} = A2A.Client.discover("https://agent.example.com")
    card.name #=> "my-agent"

# `get_task`

```elixir
@spec get_task(target(), String.t(), keyword()) ::
  {:ok, A2A.Task.t()} | {:error, term()}
```

Retrieves a task by ID via `tasks/get`.

## Options

- `:history_length` — number of history entries to include
- `:headers` — additional HTTP headers
- `:timeout` — HTTP request timeout in ms

## Examples

    {:ok, task} = A2A.Client.get_task(client, "tsk-abc123")

# `new`

```elixir
@spec new(
  A2A.AgentCard.t() | String.t(),
  keyword()
) :: t()
```

Creates a new client struct.

Accepts a URL string or `%A2A.AgentCard{}`. Options are forwarded to
`Req.new/1` for customizing the HTTP client (headers, timeouts, etc.).

## Examples

    client = A2A.Client.new("https://agent.example.com")
    client = A2A.Client.new(card, headers: [{"authorization", "Bearer token"}])

# `send_message`

```elixir
@spec send_message(target(), A2A.Message.t() | String.t(), keyword()) ::
  {:ok, A2A.Task.t()} | {:error, term()}
```

Sends a message to an agent via `message/send`.

Returns `{:ok, task}` on success or `{:error, reason}` on failure.
The message can be a string, an `%A2A.Message{}`, or a list of parts.

## Options

- `:task_id` — continue an existing task
- `:context_id` — set the context ID
- `:configuration` — `MessageSendConfiguration` map
- `:metadata` — arbitrary metadata map
- `:headers` — additional HTTP headers
- `:timeout` — HTTP request timeout in ms

## Examples

    {:ok, task} = A2A.Client.send_message(client, "Hello!")
    {:ok, task} = A2A.Client.send_message(client, "More info", task_id: task.id)

# `stream_message`

```elixir
@spec stream_message(target(), A2A.Message.t() | String.t(), keyword()) ::
  {:ok, Enumerable.t()} | {:error, term()}
```

Sends a message and returns a stream of decoded SSE events.

Uses `message/stream` to receive server-sent events. Returns
`{:ok, stream}` where the stream yields decoded structs
(`%A2A.Task{}`, `%A2A.Event.StatusUpdate{}`, `%A2A.Event.ArtifactUpdate{}`,
or `%A2A.Message{}`).

## Options

Same as `send_message/3`.

## Examples

    {:ok, stream} = A2A.Client.stream_message(client, "Count to 5")
    Enum.each(stream, fn
      %A2A.Event.StatusUpdate{final: true} -> :done
      event -> IO.inspect(event)
    end)

---

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