Jido.Chat.Adapter behaviour (Jido Chat v1.0.0)

Copy Markdown View Source

Canonical adapter behavior for Chat SDK style integrations.

Thread-aware channel contract for Chat SDK integrations.

Summary

Functions

Returns adapter channel type with fallback to module name.

Returns capability matrix for adapter-native vs fallback support.

Returns a normalized typed capability matrix.

Deletes a previously-sent message when supported by adapter.

Fetches channel-level history when supported by adapter.

Fetches thread-level history when supported by adapter.

Formats a typed webhook response using adapter callback when available.

Default helper to normalize webhook payload through transform_incoming/1.

Initializes adapter resources when supported.

Lists channel thread summaries when supported by adapter.

Opens adapter-native modal when supported.

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

Parses request into a normalized event envelope.

Posts a channel-level message using adapter callback or send fallback.

Posts an ephemeral message when supported, with optional DM fallback.

Posts an ephemeral payload using the canonical outbound payload contract.

Posts a normalized outbound payload using adapter-native or core fallback behavior.

Returns a stable adapter-facing card payload.

Returns a stable adapter-facing Markdown representation.

Returns a stable adapter-facing modal payload.

Uploads and sends a file when supported by the adapter.

Shuts down adapter resources when supported.

Starts typing indicator when supported by adapter.

Streams chunked text using adapter stream callback or send fallback.

Normalizes adapter inbound transformation to Jido.Chat.Incoming.

Validates capability declaration coherence with implemented callbacks.

Verifies webhook request integrity when adapter exposes validation callback.

Types

capability_matrix()

@type capability_matrix() :: %{optional(atom()) => capability_status()}

capability_status()

@type capability_status() :: :native | :fallback | :unsupported

delete_result()

@type delete_result() :: :ok | {:error, term()}

ephemeral_result()

@type ephemeral_result() :: {:ok, Jido.Chat.EphemeralMessage.t()} | {:error, term()}

external_message_id()

@type external_message_id() :: String.t() | integer()

external_room_id()

@type external_room_id() :: String.t() | integer()

external_user_id()

@type external_user_id() :: String.t() | integer()

file_input()

@type file_input() :: Jido.Chat.FileUpload.input()

incoming_result()

@type incoming_result() :: {:ok, Jido.Chat.Incoming.t()} | {:error, term()}

listener_opts()

@type listener_opts() :: keyword()

message_page_result()

@type message_page_result() :: {:ok, Jido.Chat.MessagePage.t()} | {:error, term()}

message_result()

@type message_result() :: {:ok, Jido.Chat.Message.t()} | {:error, term()}

metadata_result()

@type metadata_result() :: {:ok, Jido.Chat.ChannelInfo.t()} | {:error, term()}

modal_result()

@type modal_result() :: {:ok, Jido.Chat.ModalResult.t()} | {:error, term()}

raw_payload()

@type raw_payload() :: map()

reaction_result()

@type reaction_result() :: :ok | {:error, term()}

send_result()

@type send_result() :: {:ok, Jido.Chat.Response.t()} | {:error, term()}

sink_mfa()

@type sink_mfa() :: {module(), atom(), [term()]}

thread_page_result()

@type thread_page_result() :: {:ok, Jido.Chat.ThreadPage.t()} | {:error, term()}

thread_result()

@type thread_result() :: {:ok, Jido.Chat.Thread.t()} | {:error, term()}

typing_result()

@type typing_result() :: :ok | {:error, term()}

Callbacks

add_reaction(external_room_id, external_message_id, emoji, opts)

(optional)
@callback add_reaction(
  external_room_id(),
  external_message_id(),
  emoji :: String.t(),
  opts :: keyword()
) :: :ok | {:ok, term()} | {:error, term()}

capabilities()

(optional)
@callback capabilities() :: capability_matrix()

channel_type()

@callback channel_type() :: atom()

delete_message(external_room_id, external_message_id, opts)

(optional)
@callback delete_message(external_room_id(), external_message_id(), opts :: keyword()) ::
  :ok | {:ok, term()} | {:error, term()}

edit_message(external_room_id, external_message_id, text, opts)

(optional)
@callback edit_message(
  external_room_id(),
  external_message_id(),
  text :: String.t(),
  opts :: keyword()
) :: send_result() | {:ok, map()} | {:error, term()}

fetch_channel_messages(external_room_id, opts)

(optional)
@callback fetch_channel_messages(external_room_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.MessagePage.t() | map()} | {:error, term()}

fetch_message(external_room_id, external_message_id, opts)

(optional)
@callback fetch_message(external_room_id(), external_message_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.Message.t() | Jido.Chat.Incoming.t() | map()}
  | {:error, term()}

fetch_messages(external_room_id, opts)

(optional)
@callback fetch_messages(external_room_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.MessagePage.t() | map()} | {:error, term()}

fetch_metadata(external_room_id, opts)

(optional)
@callback fetch_metadata(external_room_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.ChannelInfo.t() | map()} | {:error, term()}

fetch_thread(external_room_id, opts)

(optional)
@callback fetch_thread(external_room_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.Thread.t() | map()} | {:error, term()}

format_webhook_response(term, opts)

(optional)
@callback format_webhook_response(term(), opts :: keyword()) ::
  Jido.Chat.WebhookResponse.t()
  | map()
  | {:ok, Jido.Chat.WebhookResponse.t() | map()}
  | {:error, term()}

handle_webhook(chat, raw_payload, opts)

(optional)
@callback handle_webhook(chat :: Jido.Chat.t(), raw_payload(), opts :: keyword()) ::
  {:ok, Jido.Chat.t(), Jido.Chat.Incoming.t()} | {:error, term()}

initialize(opts)

(optional)
@callback initialize(opts :: keyword()) :: :ok | {:ok, term()} | {:error, term()}

list_threads(external_room_id, opts)

(optional)
@callback list_threads(external_room_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.ThreadPage.t() | map()} | {:error, term()}

listener_child_specs(bridge_id, opts)

(optional)
@callback listener_child_specs(bridge_id :: String.t(), opts :: listener_opts()) ::
  {:ok, [Supervisor.child_spec()]} | {:error, term()}

Optional listener child-spec callback for adapter-owned ingress workers.

Listener workers should emit inbound payloads/events through a sink MFA provided in opts to avoid coupling adapter packages to runtime implementations.

Expected listener opts keys:

  • :sink_mfa - sink callback MFA, typically {Module, :function, [base_args...]}
  • :bridge_id - configured bridge identifier
  • :bridge_config - resolved bridge config struct/map
  • :instance_module - runtime instance module (opaque to adapters)
  • :settings - adapter-specific ingress settings map
  • :ingress - normalized ingress mode/settings map

open_dm(external_user_id, opts)

(optional)
@callback open_dm(external_user_id(), opts :: keyword()) ::
  {:ok, external_room_id()} | {:error, term()}

open_modal(external_room_id, payload, opts)

(optional)
@callback open_modal(external_room_id(), payload :: map(), opts :: keyword()) ::
  {:ok, Jido.Chat.ModalResult.t() | map()} | {:error, term()}

open_thread(external_room_id, external_message_id, opts)

(optional)
@callback open_thread(external_room_id(), external_message_id(), opts :: keyword()) ::
  {:ok, Jido.Chat.Thread.t() | map()} | {:error, term()}

parse_event(arg1, opts)

(optional)
@callback parse_event(Jido.Chat.WebhookRequest.t() | map(), opts :: keyword()) ::
  {:ok, Jido.Chat.EventEnvelope.t() | map() | :noop | nil} | {:error, term()}

post_channel_message(external_room_id, text, opts)

(optional)
@callback post_channel_message(external_room_id(), text :: String.t(), opts :: keyword()) ::
  send_result() | {:ok, map()} | {:error, term()}

post_ephemeral(external_room_id, external_user_id, text, opts)

(optional)
@callback post_ephemeral(
  external_room_id(),
  external_user_id(),
  text :: String.t(),
  opts :: keyword()
) :: {:ok, Jido.Chat.EphemeralMessage.t() | map()} | {:error, term()}

post_message(external_room_id, payload, opts)

(optional)
@callback post_message(
  external_room_id(),
  payload :: Jido.Chat.PostPayload.t(),
  opts :: keyword()
) ::
  send_result() | {:ok, map()} | {:error, term()}

remove_reaction(external_room_id, external_message_id, emoji, opts)

(optional)
@callback remove_reaction(
  external_room_id(),
  external_message_id(),
  emoji :: String.t(),
  opts :: keyword()
) :: :ok | {:ok, term()} | {:error, term()}

send_file(external_room_id, file, opts)

(optional)
@callback send_file(external_room_id(), file :: file_input(), opts :: keyword()) ::
  send_result() | {:ok, map()} | {:error, term()}

send_message(external_room_id, text, opts)

@callback send_message(external_room_id(), text :: String.t(), opts :: keyword()) ::
  send_result() | {:ok, map()} | {:error, term()}

shutdown(opts)

(optional)
@callback shutdown(opts :: keyword()) :: :ok | {:ok, term()} | {:error, term()}

start_typing(external_room_id, opts)

(optional)
@callback start_typing(external_room_id(), opts :: keyword()) ::
  :ok | {:ok, term()} | {:error, term()}

stream(external_room_id, stream, opts)

(optional)
@callback stream(external_room_id(), stream :: Enumerable.t(), opts :: keyword()) ::
  send_result() | {:ok, map()} | {:error, term()}

transform_incoming(raw_payload)

@callback transform_incoming(raw_payload()) :: incoming_result() | {:ok, map()}

verify_webhook(arg1, opts)

(optional)
@callback verify_webhook(Jido.Chat.WebhookRequest.t() | map(), opts :: keyword()) ::
  :ok | {:error, term()}

Functions

adapter_type(adapter_module)

@spec adapter_type(module()) :: atom()

Returns adapter channel type with fallback to module name.

add_reaction(adapter_module, external_room_id, external_message_id, emoji, opts \\ [])

@spec add_reaction(
  module(),
  external_room_id(),
  external_message_id(),
  String.t(),
  keyword()
) ::
  reaction_result()

Adds a reaction when supported by adapter.

capabilities(adapter_module)

@spec capabilities(module()) :: capability_matrix()

Returns capability matrix for adapter-native vs fallback support.

capability_matrix(adapter_module)

@spec capability_matrix(module()) :: Jido.Chat.CapabilityMatrix.t()

Returns a normalized typed capability matrix.

delete_message(adapter_module, external_room_id, external_message_id, opts \\ [])

@spec delete_message(module(), external_room_id(), external_message_id(), keyword()) ::
  delete_result()

Deletes a previously-sent message when supported by adapter.

edit_message(adapter_module, external_room_id, external_message_id, text, opts \\ [])

@spec edit_message(
  module(),
  external_room_id(),
  external_message_id(),
  String.t(),
  keyword()
) ::
  send_result()

Normalizes adapter edit results to Jido.Chat.Response.

fetch_channel_messages(adapter_module, external_room_id, opts \\ [])

@spec fetch_channel_messages(module(), external_room_id(), keyword()) ::
  message_page_result()

Fetches channel-level history when supported by adapter.

fetch_message(adapter_module, external_room_id, external_message_id, opts \\ [])

@spec fetch_message(module(), external_room_id(), external_message_id(), keyword()) ::
  message_result()

Fetches a normalized message by id when supported.

fetch_messages(adapter_module, external_room_id, opts \\ [])

@spec fetch_messages(module(), external_room_id(), keyword()) :: message_page_result()

Fetches thread-level history when supported by adapter.

fetch_metadata(adapter_module, external_room_id, opts \\ [])

@spec fetch_metadata(module(), external_room_id(), keyword()) :: metadata_result()

Fetches channel metadata as Jido.Chat.ChannelInfo.

fetch_thread(adapter_module, external_room_id, opts \\ [])

@spec fetch_thread(module(), external_room_id(), keyword()) :: thread_result()

Fetches thread metadata as a normalized Jido.Chat.Thread.

format_webhook_response(adapter_module, result, opts \\ [])

@spec format_webhook_response(module(), term(), keyword()) ::
  {:ok, Jido.Chat.WebhookResponse.t()} | {:error, term()}

Formats a typed webhook response using adapter callback when available.

handle_webhook(adapter_module, chat, payload, opts \\ [])

@spec handle_webhook(module(), Jido.Chat.t(), raw_payload(), keyword()) ::
  {:ok, Jido.Chat.t(), Jido.Chat.Incoming.t()} | {:error, term()}

Default helper to normalize webhook payload through transform_incoming/1.

initialize(adapter_module, opts \\ [])

@spec initialize(
  module(),
  keyword()
) :: :ok | {:error, term()}

Initializes adapter resources when supported.

list_threads(adapter_module, external_room_id, opts \\ [])

@spec list_threads(module(), external_room_id(), keyword()) :: thread_page_result()

Lists channel thread summaries when supported by adapter.

open_modal(adapter_module, external_room_id, payload, opts \\ [])

@spec open_modal(module(), external_room_id(), Jido.Chat.Modal.t() | map(), keyword()) ::
  modal_result()

Opens adapter-native modal when supported.

open_thread(adapter_module, external_room_id, external_message_id, opts \\ [])

@spec open_thread(module(), external_room_id(), external_message_id(), keyword()) ::
  thread_result()

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

parse_event(adapter_module, request, opts \\ [])

@spec parse_event(module(), Jido.Chat.WebhookRequest.t() | map(), keyword()) ::
  {:ok, Jido.Chat.EventEnvelope.t() | :noop} | {:error, term()}

Parses request into a normalized event envelope.

post_channel_message(adapter_module, external_room_id, text, opts \\ [])

@spec post_channel_message(module(), external_room_id(), String.t(), keyword()) ::
  send_result()

Posts a channel-level message using adapter callback or send fallback.

post_ephemeral(adapter_module, external_room_id, external_user_id, text, opts \\ [])

@spec post_ephemeral(
  module(),
  external_room_id(),
  external_user_id(),
  String.t(),
  keyword()
) ::
  ephemeral_result()

Posts an ephemeral message when supported, with optional DM fallback.

post_ephemeral_message(adapter_module, external_room_id, external_user_id, input, opts \\ [])

Posts an ephemeral payload using the canonical outbound payload contract.

post_message(adapter_module, external_room_id, payload, opts \\ [])

@spec post_message(
  module(),
  external_room_id(),
  Jido.Chat.PostPayload.t() | map(),
  keyword()
) ::
  send_result()

Posts a normalized outbound payload using adapter-native or core fallback behavior.

remove_reaction(adapter_module, external_room_id, external_message_id, emoji, opts \\ [])

@spec remove_reaction(
  module(),
  external_room_id(),
  external_message_id(),
  String.t(),
  keyword()
) :: reaction_result()

Removes a reaction when supported by adapter.

render_card(card, opts \\ [])

@spec render_card(
  Jido.Chat.Card.t() | map(),
  keyword()
) :: map()

Returns a stable adapter-facing card payload.

render_markdown(markdown, opts \\ [])

@spec render_markdown(
  Jido.Chat.Markdown.t() | map() | String.t(),
  keyword()
) :: String.t()

Returns a stable adapter-facing Markdown representation.

render_modal(modal, opts \\ [])

@spec render_modal(
  Jido.Chat.Modal.t() | map(),
  keyword()
) :: map()

Returns a stable adapter-facing modal payload.

send_file(adapter_module, external_room_id, file, opts \\ [])

@spec send_file(module(), external_room_id(), file_input(), keyword()) ::
  send_result()

Uploads and sends a file when supported by the adapter.

send_message(adapter_module, external_room_id, text, opts \\ [])

@spec send_message(module(), external_room_id(), String.t(), keyword()) ::
  send_result()

Normalizes adapter send results to Jido.Chat.Response.

shutdown(adapter_module, opts \\ [])

@spec shutdown(
  module(),
  keyword()
) :: :ok | {:error, term()}

Shuts down adapter resources when supported.

start_typing(adapter_module, external_room_id, opts \\ [])

@spec start_typing(module(), external_room_id(), keyword()) :: typing_result()

Starts typing indicator when supported by adapter.

stream(adapter_module, external_room_id, chunks, opts \\ [])

@spec stream(module(), external_room_id(), Enumerable.t(), keyword()) :: send_result()

Streams chunked text using adapter stream callback or send fallback.

transform_incoming(adapter_module, payload)

@spec transform_incoming(module(), raw_payload()) :: incoming_result()

Normalizes adapter inbound transformation to Jido.Chat.Incoming.

validate_capabilities(adapter_module)

@spec validate_capabilities(module()) :: :ok | {:error, term()}

Validates capability declaration coherence with implemented callbacks.

verify_webhook(adapter_module, request, opts \\ [])

@spec verify_webhook(module(), Jido.Chat.WebhookRequest.t() | map(), keyword()) ::
  :ok | {:error, term()}

Verifies webhook request integrity when adapter exposes validation callback.