# `Gralkor.Client`
[🔗](https://github.com/elimydlarz/gralkor/blob/main/lib/gralkor/client.ex#L1)

Port for talking to a Gralkor backend from Elixir.

Six operations — recall, capture, end_session, memory_search, memory_add,
health_check. Every failure is reported as `{:error, reason}` so callers
can decide how to fail open. Group IDs are sanitised at the edge
(`sanitize_group_id/1`) to satisfy Gralkor's RediSearch constraint.

The concrete adapter is resolved from `Application.get_env(:gralkor_ex, :client)`;
defaults to `Gralkor.Client.HTTP`. Tests swap in `Gralkor.Client.InMemory`.

# `group_id`

```elixir
@type group_id() :: String.t()
```

# `messages`

```elixir
@type messages() :: [Gralkor.Message.t()]
```

# `session_id`

```elixir
@type session_id() :: String.t()
```

# `build_communities`

```elixir
@callback build_communities(group_id()) ::
  {:ok, %{communities: non_neg_integer(), edges: non_neg_integer()}}
  | {:error, term()}
```

# `build_indices`

```elixir
@callback build_indices() :: {:ok, %{status: String.t()}} | {:error, term()}
```

# `capture`

```elixir
@callback capture(session_id(), group_id(), messages()) :: :ok | {:error, term()}
```

# `end_session`

```elixir
@callback end_session(session_id()) :: :ok | {:error, term()}
```

# `health_check`

```elixir
@callback health_check() :: :ok | {:error, term()}
```

# `memory_add`

```elixir
@callback memory_add(
  group_id(),
  content :: String.t(),
  source_description :: String.t() | nil
) ::
  :ok | {:error, term()}
```

# `memory_search`

```elixir
@callback memory_search(group_id(), session_id(), query :: String.t()) ::
  {:ok, String.t()} | {:error, term()}
```

# `recall`

```elixir
@callback recall(group_id(), session_id(), query :: String.t()) ::
  {:ok, String.t() | nil} | {:error, term()}
```

# `impl`

```elixir
@spec impl() :: module()
```

# `sanitize_group_id`

```elixir
@spec sanitize_group_id(String.t()) :: String.t()
```

---

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