Cyclium.Conversations (Cyclium v0.5.2)

Copy Markdown View Source

Context module for managing interactive conversations. Provides start, claim, resolve, abandon, and query operations.

Summary

Functions

Claim a conversation (for :pool and :any audience modes). Sets the principal and transitions status to :open.

Fetch a conversation on behalf of a principal.

Whether principal (a map with "type"/"id", string or atom keys) is the principal this conversation belongs to. The id must match; the type must match when both sides carry one. A conversation with no principal yet (awaiting_participant, or never claimed) matches nobody.

Resolve a conversation with an outcome and result.

Start a new conversation.

Functions

abandon(conversation_id, reason \\ "user_abandoned")

@spec abandon(binary(), binary()) ::
  {:ok, Cyclium.Schemas.Conversation.t()} | {:error, term()}

check_constraints(conv)

@spec check_constraints(Cyclium.Schemas.Conversation.t()) ::
  :ok | {:warn, :last_turn} | {:error, :budget_exceeded}

claim(conversation_id, principal)

@spec claim(binary(), map()) ::
  {:ok, Cyclium.Schemas.Conversation.t()}
  | {:error, :already_claimed | :not_found}

Claim a conversation (for :pool and :any audience modes). Sets the principal and transitions status to :open.

get(id)

@spec get(binary()) :: Cyclium.Schemas.Conversation.t() | nil

get!(id)

get_for_principal(id, principal, opts \\ [])

@spec get_for_principal(binary(), map() | nil, keyword()) ::
  {:ok, Cyclium.Schemas.Conversation.t()} | {:error, :not_found | :forbidden}

Fetch a conversation on behalf of a principal.

Returns {:ok, conversation} when the row exists and its principal matches (principal_matches?/2), {:error, :not_found} when it does not exist (an unparseable id counts as not found), and {:error, :forbidden} otherwise. Pass skip_principal_check: true for an operator view that may read any conversation.

increment_turn(conversation_id, tokens \\ 0)

@spec increment_turn(binary(), non_neg_integer()) ::
  {:ok, Cyclium.Schemas.Conversation.t()} | {:error, :not_found}

list_awaiting(opts \\ [])

@spec list_awaiting(keyword()) :: [Cyclium.Schemas.Conversation.t()]

list_for_actor(actor_id, opts \\ [])

@spec list_for_actor(
  binary() | atom(),
  keyword()
) :: [Cyclium.Schemas.Conversation.t()]

list_for_principal(principal_id, opts \\ [])

@spec list_for_principal(
  binary(),
  keyword()
) :: [Cyclium.Schemas.Conversation.t()]

principal_matches?(conversation, principal)

@spec principal_matches?(Cyclium.Schemas.Conversation.t(), map() | nil) :: boolean()

Whether principal (a map with "type"/"id", string or atom keys) is the principal this conversation belongs to. The id must match; the type must match when both sides carry one. A conversation with no principal yet (awaiting_participant, or never claimed) matches nobody.

resolve(conversation_id, outcome, result \\ %{})

@spec resolve(binary(), binary(), map()) ::
  {:ok, Cyclium.Schemas.Conversation.t()} | {:error, term()}

Resolve a conversation with an outcome and result.

start(attrs)

@spec start(map()) ::
  {:ok, Cyclium.Schemas.Conversation.t()} | {:error, Ecto.Changeset.t()}

Start a new conversation.

Required fields

  • :actor_id — which interactive actor handles this conversation
  • :name — display name

Optional fields

  • :principal — map with "type", "id", "label"
  • :goal — GoalSpec map (JSON-encoded on write)
  • :origin — Origin map
  • :audience_target — AudienceTarget map

timeout(conversation_id)

@spec timeout(binary()) :: {:ok, Cyclium.Schemas.Conversation.t()} | {:error, term()}

update_collected_fields(conversation_id, new_fields)

@spec update_collected_fields(binary(), map()) ::
  {:ok, Cyclium.Schemas.Conversation.t()} | {:error, term()}