# `ADK.Plugin.RateLimit`
[🔗](https://github.com/zeroasterisk/adk-elixir/blob/main/lib/adk/plugin/rate_limit.ex#L1)

A sliding-window rate limiter plugin.

Tracks call timestamps per bucket key and halts execution when the limit
is exceeded within the configured time window.

## Configuration

    # Default — 100 calls per minute, bucketed by agent name
    ADK.Plugin.register({ADK.Plugin.RateLimit, []})

    # Custom — 10 calls per 30 seconds, bucketed by user ID
    ADK.Plugin.register({ADK.Plugin.RateLimit,
      limit: 10,
      window_ms: 30_000,
      key_fn: fn context -> context.user_id || "anonymous" end
    })

## Options

- `:limit` — maximum calls allowed in the window. Default `100`.
- `:window_ms` — window size in milliseconds. Default `60_000` (1 minute).
- `:key_fn` — function `context -> key` to bucket by. Default uses agent name or `"global"`.

## Behaviour

- `before_run/2` — prunes expired timestamps, checks if the limit is exceeded.
  Returns `{:halt, {:error, :rate_limited}, state}` when over limit.
- `after_run/3` — no-op pass-through.

# `config`

```elixir
@type config() :: [
  limit: pos_integer(),
  window_ms: pos_integer(),
  key_fn: (ADK.Context.t() -&gt; term())
]
```

# `state`

```elixir
@type state() :: %{
  limit: pos_integer(),
  window_ms: pos_integer(),
  key_fn: (ADK.Context.t() -&gt; term()),
  call_log: %{required(term()) =&gt; [integer()]}
}
```

---

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