# `Jido.Chat.Adapters.Threading`
[🔗](https://github.com/agentjido/jido_chat/blob/v1.0.0/lib/jido/chat/adapters/threading.ex#L1)

Behaviour for adapter-specific threading support.

Threading is fundamental to messaging but varies significantly across platforms.
This behaviour defines how adapters can implement platform-specific threading
logic while providing a normalized output for the messaging pipeline.

## Implementation

Adapters that support threading should implement this behaviour:

    defmodule MyApp.Channels.Slack do
      @behaviour Jido.Chat.Adapter
      @behaviour Jido.Chat.Adapters.Threading

      @impl Jido.Chat.Adapters.Threading
      def supports_threads?, do: true

      @impl Jido.Chat.Adapters.Threading
      def compute_thread_root(raw) do
        # Slack uses thread_ts as the thread identifier
        raw["thread_ts"] || raw["ts"]
      end

      @impl Jido.Chat.Adapters.Threading
      def extract_thread_context(raw) do
        %{
          thread_id: raw["thread_ts"],
          is_thread_reply: raw["thread_ts"] != nil,
          thread_root_ts: raw["thread_ts"] || raw["ts"]
        }
      end
    end

## Default Implementations

All callbacks are optional. The defaults assume no threading support:

  * `supports_threads?/0` - Returns `false`
  * `compute_thread_root/1` - Returns `nil`
  * `extract_thread_context/1` - Returns empty map

# `thread_context`

```elixir
@type thread_context() :: %{
  optional(:thread_id) =&gt; String.t() | nil,
  optional(:is_thread_reply) =&gt; boolean(),
  optional(:thread_root_ts) =&gt; String.t() | nil
}
```

# `compute_thread_root`
*optional* 

```elixir
@callback compute_thread_root(raw :: map()) :: String.t() | nil
```

Computes the thread root identifier from a raw message payload.

The thread root is the first message in a thread. For messages that are
not part of a thread, this typically returns `nil` or the message's own ID.

## Parameters

  * `raw` - The raw platform-specific message payload

## Returns

The thread root identifier as a string, or `nil` if not applicable.

# `extract_thread_context`
*optional* 

```elixir
@callback extract_thread_context(raw :: map()) :: thread_context()
```

Extracts threading context from a raw message payload.

Returns a map with thread-related information that can be used for
routing decisions and context building.

## Parameters

  * `raw` - The raw platform-specific message payload

## Returns

A map that may contain:
  * `:thread_id` - The thread identifier
  * `:is_thread_reply` - Whether this message is a reply in a thread
  * `:thread_root_ts` - The timestamp/ID of the thread root message

# `supports_threads?`
*optional* 

```elixir
@callback supports_threads?() :: boolean()
```

Returns whether this adapter supports threading.

Used for capability detection and feature gating.

# `compute_thread_root`

```elixir
@spec compute_thread_root(module(), map()) :: String.t() | nil
```

Safely computes the thread root for a module.

Returns `nil` if the module doesn't implement the callback.

# `extract_thread_context`

```elixir
@spec extract_thread_context(module(), map()) :: thread_context()
```

Safely extracts thread context for a module.

Returns an empty map if the module doesn't implement the callback.

# `supports_threads?`

```elixir
@spec supports_threads?(module()) :: boolean()
```

Checks if a module implements the Threading behaviour and supports threads.

Returns `true` only if the module implements `supports_threads?/0` and it returns `true`.

---

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