# `Jido.Chat`
[🔗](https://github.com/agentjido/jido_chat/blob/v1.0.0/lib/jido_chat.ex#L1)

Core adapter-contract facade and lightweight event-loop state container.

`jido_chat` owns canonical chat types, adapter contracts, typed handles, and
deterministic fallback behavior. It does not define the supervised runtime or
process tree for production messaging systems; that responsibility belongs in
`jido_messaging`.

# `action_handler`

```elixir
@type action_handler() ::
  (Jido.Chat.ActionEvent.t() -&gt; term())
  | (t(), Jido.Chat.ActionEvent.t() -&gt; t() | term())
```

Action event handler callback.

# `assistant_context_changed_handler`

```elixir
@type assistant_context_changed_handler() ::
  (Jido.Chat.AssistantContextChangedEvent.t() -&gt; term())
  | (t(), Jido.Chat.AssistantContextChangedEvent.t() -&gt; t() | term())
```

Assistant context changed handler callback.

# `assistant_thread_started_handler`

```elixir
@type assistant_thread_started_handler() ::
  (Jido.Chat.AssistantThreadStartedEvent.t() -&gt; term())
  | (t(), Jido.Chat.AssistantThreadStartedEvent.t() -&gt; t() | term())
```

Assistant thread started handler callback.

# `handlers`

```elixir
@type handlers() :: %{
  mention: [mention_handler()],
  message: [{Regex.t(), message_handler()}],
  subscribed: [subscribed_handler()],
  reaction: [reaction_handler()],
  action: [action_handler()],
  modal_submit: [modal_submit_handler()],
  modal_close: [modal_close_handler()],
  slash_command: [slash_command_handler()],
  assistant_thread_started: [assistant_thread_started_handler()],
  assistant_context_changed: [assistant_context_changed_handler()]
}
```

# `mention_handler`

```elixir
@type mention_handler() ::
  (Jido.Chat.Thread.t(), Jido.Chat.Incoming.t() -&gt; term())
  | (t(), Jido.Chat.Thread.t(), Jido.Chat.Incoming.t() -&gt; t() | term())
```

Mention handler callback.

# `message_handler`

```elixir
@type message_handler() :: mention_handler()
```

Regex-routed message handler callback.

# `modal_close_handler`

```elixir
@type modal_close_handler() ::
  (Jido.Chat.ModalCloseEvent.t() -&gt; term())
  | (t(), Jido.Chat.ModalCloseEvent.t() -&gt; t() | term())
```

Modal close handler callback.

# `modal_submit_handler`

```elixir
@type modal_submit_handler() ::
  (Jido.Chat.ModalSubmitEvent.t() -&gt; term())
  | (t(), Jido.Chat.ModalSubmitEvent.t() -&gt; t() | term())
```

Modal submit handler callback.

# `reaction_handler`

```elixir
@type reaction_handler() ::
  (Jido.Chat.ReactionEvent.t() -&gt; term())
  | (t(), Jido.Chat.ReactionEvent.t() -&gt; t() | term())
```

Reaction event handler callback.

# `route_request_handler`

```elixir
@type route_request_handler() :: (Jido.Chat.WebhookRequest.t() | map(), keyword() -&gt;
                              {:ok, Jido.Chat.IngressResult.t()}
                              | {:error, Exception.t()})
```

# `slash_command_handler`

```elixir
@type slash_command_handler() ::
  (Jido.Chat.SlashCommandEvent.t() -&gt; term())
  | (t(), Jido.Chat.SlashCommandEvent.t() -&gt; t() | term())
```

Slash command handler callback.

# `subscribed_handler`

```elixir
@type subscribed_handler() :: mention_handler()
```

Subscribed-thread handler callback.

# `t`

```elixir
@type t() :: %Jido.Chat{
  adapters: %{optional(atom()) =&gt; module()},
  channel_state: %{optional(String.t()) =&gt; map()},
  dedupe: MapSet.t({atom(), String.t()}),
  dedupe_order: [{atom(), String.t()}],
  handlers: handlers(),
  id: String.t(),
  initialized: boolean(),
  metadata: map(),
  state: term(),
  state_adapter: module(),
  subscriptions: MapSet.t(String.t()),
  thread_state: %{optional(String.t()) =&gt; map()},
  user_name: String.t()
}
```

# `webhook_handler`

```elixir
@type webhook_handler() :: (t(), map(), keyword() -&gt;
                        {:ok, t(), Jido.Chat.Incoming.t()} | {:error, term()})
```

# `webhook_request_handler`

```elixir
@type webhook_request_handler() :: (Jido.Chat.WebhookRequest.t() | map(), keyword() -&gt;
                                {:ok, t(), Jido.Chat.EventEnvelope.t() | nil,
                                 Jido.Chat.WebhookResponse.t()})
```

# `webhook_request_handler_with_chat`

```elixir
@type webhook_request_handler_with_chat() :: (t(),
                                        Jido.Chat.WebhookRequest.t()
                                        | map(),
                                        keyword() -&gt;
                                          {:ok, t(),
                                           Jido.Chat.EventEnvelope.t() | nil,
                                           Jido.Chat.WebhookResponse.t()})
```

# `acquire_lock`

```elixir
@spec acquire_lock(t(), String.t(), String.t(), keyword() | map()) ::
  {:acquired | :queued | :debounced | :busy, t()}
```

Attempts to acquire a concurrency lock for a message-processing key.

# `adapter_capabilities`

```elixir
@spec adapter_capabilities(t(), atom()) ::
  {:ok, Jido.Chat.CapabilityMatrix.t()} | {:error, term()}
```

Returns adapter capability matrix wrapped in typed struct.

# `channel`

```elixir
@spec channel(t(), atom(), String.t() | integer()) :: Jido.Chat.ChannelRef.t()
```

Builds a channel reference from adapter + external channel id.

# `channel_state`

```elixir
@spec channel_state(t(), String.t()) :: map()
```

Gets channel state map by id.

# `concurrency`

```elixir
@spec concurrency(t()) :: Jido.Chat.Concurrency.t()
```

Returns normalized overlapping-message concurrency config.

# `configure_concurrency`

```elixir
@spec configure_concurrency(t(), keyword() | map()) :: t()
```

Updates chat-level concurrency configuration.

# `emoji`

```elixir
@spec emoji(
  String.t() | atom(),
  keyword()
) :: String.t()
```

Resolves a cross-platform emoji token into a rendered value.

# `force_release_lock`

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

Force-releases a concurrency lock regardless of owner.

# `from_map`

```elixir
@spec from_map(map()) :: t()
```

Builds chat state from serialized map.

# `get_adapter`

```elixir
@spec get_adapter(t(), atom()) :: {:ok, module()} | {:error, term()}
```

Returns adapter module by name.

# `handle_webhook`

```elixir
@spec handle_webhook(t(), atom(), map(), keyword()) ::
  {:ok, t(), Jido.Chat.Incoming.t()} | {:error, term()}
```

Handles a webhook payload for the given adapter.

# `handle_webhook_request`

```elixir
@spec handle_webhook_request(
  t(),
  atom(),
  Jido.Chat.WebhookRequest.t() | map(),
  keyword()
) ::
  {:ok, t(), Jido.Chat.EventEnvelope.t() | nil, Jido.Chat.WebhookResponse.t()}
```

Handles a typed webhook request for the given adapter.

Returns the updated chat state, normalized event envelope, and typed webhook response.

# `initialize`

```elixir
@spec initialize(t()) :: t()
```

Marks chat instance as initialized and initializes adapters when available.

# `lock_snapshot`

```elixir
@spec lock_snapshot(t()) :: %{locks: map(), pending_locks: map()}
```

Returns the current concurrency lock snapshot.

# `message`

```elixir
@spec message(map()) :: Jido.Chat.Message.t()
```

Creates a normalized Chat SDK-style message.

# `new`

```elixir
@spec new(keyword() | map()) :: t()
```

Creates a new chat state struct.

Supported options:
  * `:id`
  * `:user_name`
  * `:adapters` - map `%{telegram: Jido.Chat.Telegram.Adapter, ...}`
  * `:metadata`
  * `:state_adapter` - state backend module, defaults to `Jido.Chat.StateAdapters.Memory`
  * `:state_opts` - adapter-specific initialization options
  * `:state` - explicit adapter state, overrides legacy snapshot inputs

# `new_participant`

```elixir
@spec new_participant(map()) :: Jido.Chat.Participant.t()
```

# `new_room`

```elixir
@spec new_room(map()) :: Jido.Chat.Room.t()
```

# `on_action`

```elixir
@spec on_action(t(), action_handler()) :: t()
```

Registers an action-event handler.

# `on_action`

```elixir
@spec on_action(
  t(),
  String.t() | atom() | [String.t() | atom()] | Regex.t(),
  action_handler()
) :: t()
```

Registers a filtered action-event handler.

# `on_assistant_context_changed`

```elixir
@spec on_assistant_context_changed(t(), assistant_context_changed_handler()) :: t()
```

Registers assistant context changed handlers.

# `on_assistant_thread_started`

```elixir
@spec on_assistant_thread_started(t(), assistant_thread_started_handler()) :: t()
```

Registers assistant thread started handlers.

# `on_modal_close`

```elixir
@spec on_modal_close(t(), modal_close_handler()) :: t()
```

Registers a modal-close handler.

# `on_modal_close`

```elixir
@spec on_modal_close(
  t(),
  String.t() | atom() | [String.t() | atom()] | Regex.t(),
  modal_close_handler()
) :: t()
```

Registers a filtered modal-close handler.

# `on_modal_submit`

```elixir
@spec on_modal_submit(t(), modal_submit_handler()) :: t()
```

Registers a modal-submit handler.

# `on_modal_submit`

```elixir
@spec on_modal_submit(
  t(),
  String.t() | atom() | [String.t() | atom()] | Regex.t(),
  modal_submit_handler()
) :: t()
```

Registers a filtered modal-submit handler.

# `on_new_mention`

```elixir
@spec on_new_mention(t(), mention_handler()) :: t()
```

Registers a new-mention handler.

# `on_new_message`

```elixir
@spec on_new_message(t(), Regex.t() | String.t(), message_handler()) :: t()
```

Registers a new-message regex handler.

# `on_reaction`

```elixir
@spec on_reaction(t(), reaction_handler()) :: t()
```

Registers a reaction-event handler.

# `on_reaction`

```elixir
@spec on_reaction(
  t(),
  String.t() | atom() | [String.t() | atom()] | Regex.t(),
  reaction_handler()
) :: t()
```

Registers a filtered reaction-event handler.

# `on_slash_command`

```elixir
@spec on_slash_command(t(), slash_command_handler()) :: t()
```

Registers a slash-command handler.

# `on_slash_command`

```elixir
@spec on_slash_command(
  t(),
  String.t() | atom() | [String.t() | atom()] | Regex.t(),
  slash_command_handler()
) :: t()
```

Registers a filtered slash-command handler.

# `on_subscribed_message`

```elixir
@spec on_subscribed_message(t(), subscribed_handler()) :: t()
```

Registers a subscribed-thread handler.

# `open_dm`

```elixir
@spec open_dm(
  t(),
  atom() | Jido.Chat.Author.t() | map() | String.t() | integer(),
  String.t() | integer() | keyword() | map()
) :: {:ok, Jido.Chat.Thread.t()} | {:error, term()}
```

Opens a DM thread with an adapter when supported.

# `open_thread`

```elixir
@spec open_thread(
  t(),
  atom(),
  String.t() | integer(),
  String.t() | integer(),
  keyword()
) ::
  {:ok, Jido.Chat.Thread.t()} | {:error, term()}
```

Opens a native platform thread from an existing room message when supported.

# `process_action`

```elixir
@spec process_action(t(), atom(), Jido.Chat.ActionEvent.t() | map(), keyword()) ::
  {:ok, t(), Jido.Chat.ActionEvent.t()} | {:error, term()}
```

Processes normalized action events and dispatches handlers.

# `process_assistant_context_changed`

```elixir
@spec process_assistant_context_changed(
  t(),
  atom(),
  Jido.Chat.AssistantContextChangedEvent.t() | map()
) :: {:ok, t(), Jido.Chat.AssistantContextChangedEvent.t()} | {:error, term()}
```

Processes assistant context changed events and dispatches handlers.

# `process_assistant_thread_started`

```elixir
@spec process_assistant_thread_started(
  t(),
  atom(),
  Jido.Chat.AssistantThreadStartedEvent.t() | map()
) :: {:ok, t(), Jido.Chat.AssistantThreadStartedEvent.t()} | {:error, term()}
```

Processes assistant thread started events and dispatches handlers.

# `process_event`

```elixir
@spec process_event(t(), atom(), Jido.Chat.EventEnvelope.t() | map(), keyword()) ::
  {:ok, t(), Jido.Chat.EventEnvelope.t()} | {:error, term()}
```

Canonical typed event router used by webhook and gateway ingestion.

# `process_message`

```elixir
@spec process_message(
  t(),
  atom(),
  String.t(),
  Jido.Chat.Incoming.t() | map(),
  keyword()
) ::
  {:ok, t(), Jido.Chat.Incoming.t()} | {:error, term()}
```

Adapter-internal entrypoint for processing normalized incoming message events.

# `process_modal_close`

```elixir
@spec process_modal_close(
  t(),
  atom(),
  Jido.Chat.ModalCloseEvent.t() | map(),
  keyword()
) ::
  {:ok, t(), Jido.Chat.ModalCloseEvent.t()} | {:error, term()}
```

Processes normalized modal close events and dispatches handlers.

# `process_modal_submit`

```elixir
@spec process_modal_submit(
  t(),
  atom(),
  Jido.Chat.ModalSubmitEvent.t() | map(),
  keyword()
) ::
  {:ok, t(), Jido.Chat.ModalSubmitEvent.t()} | {:error, term()}
```

Processes normalized modal submit events and dispatches handlers.

# `process_reaction`

```elixir
@spec process_reaction(t(), atom(), Jido.Chat.ReactionEvent.t() | map(), keyword()) ::
  {:ok, t(), Jido.Chat.ReactionEvent.t()} | {:error, term()}
```

Processes normalized reaction events and dispatches handlers.

# `process_slash_command`

```elixir
@spec process_slash_command(
  t(),
  atom(),
  Jido.Chat.SlashCommandEvent.t() | map(),
  keyword()
) ::
  {:ok, t(), Jido.Chat.SlashCommandEvent.t()} | {:error, term()}
```

Processes normalized slash command events and dispatches handlers.

# `put_channel_state`

```elixir
@spec put_channel_state(t(), String.t(), map()) :: t()
```

Sets channel state map by id.

# `put_thread_state`

```elixir
@spec put_thread_state(t(), String.t(), map()) :: t()
```

Sets thread state map by id.

# `release_lock`

```elixir
@spec release_lock(t(), String.t(), String.t()) ::
  {{:released, [map()]} | {:error, :not_owner}, t()}
```

Releases a held concurrency lock and returns queued/debounced entries.

# `reviver`

```elixir
@spec reviver() :: (map() -&gt; term())
```

Returns a reviver function for serialized core structs.

# `route_event`

```elixir
@spec route_event(t(), atom(), Jido.Chat.EventEnvelope.t() | map() | :noop, keyword()) ::
  {:ok, Jido.Chat.IngressResult.t()} | {:error, Exception.t()}
```

Routes an event-style inbound input (polling/gateway/listener) through `process_event/4`.

This is transport-agnostic and returns a typed `IngressResult`.

# `route_request`

```elixir
@spec route_request(
  t(),
  atom(),
  Jido.Chat.WebhookRequest.t() | map(),
  keyword()
) :: {:ok, Jido.Chat.IngressResult.t()} | {:error, Exception.t()}
```

Routes a request-style inbound input through verification/parsing/event dispatch.

This is transport-agnostic and returns a typed `IngressResult`.

# `schema`

Returns the Zoi schema for Chat.

# `shutdown`

```elixir
@spec shutdown(t()) :: t()
```

Marks chat instance as shut down and shuts down adapters when available.

# `subscribe`

```elixir
@spec subscribe(t(), String.t()) :: t()
```

Subscribes a thread id.

# `subscribed?`

```elixir
@spec subscribed?(t(), String.t()) :: boolean()
```

Returns true when a thread id is currently subscribed.

# `text`

```elixir
@spec text(String.t()) :: Jido.Chat.Content.Text.t()
```

# `thread`

```elixir
@spec thread(t(), atom(), String.t() | integer(), keyword()) :: Jido.Chat.Thread.t()
```

Builds a thread reference from adapter + external room id.

# `thread_state`

```elixir
@spec thread_state(t(), String.t()) :: map()
```

Gets thread state map by id.

# `to_map`

```elixir
@spec to_map(t()) :: map()
```

Serializes chat state to a revivable map.

# `unsubscribe`

```elixir
@spec unsubscribe(t(), String.t()) :: t()
```

Unsubscribes a thread id.

# `webhooks`

```elixir
@spec webhooks(t()) :: %{optional(atom()) =&gt; webhook_request_handler()}
```

Returns adapter-keyed request-first webhook handlers.

# `webhooks_with_chat`

```elixir
@spec webhooks_with_chat(t()) :: %{
  optional(atom()) =&gt; webhook_request_handler_with_chat()
}
```

Compatibility helper returning adapter-keyed webhook handlers with explicit chat argument.

---

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