ExMCP.ACP.Agent.Handler behaviour (ex_mcp v0.10.0)

View Source

Behaviour for native Elixir ACP agents.

Implement this behaviour and run it with ExMCP.ACP.Agent. Prompt callbacks may either reply immediately or return {:noreply, state} and finish the prompt later with ExMCP.ACP.Agent.finish_prompt/3 after streaming updates.

Summary

Callbacks

Optionally authenticate a client.

Optionally handle session/cancel.

Optionally customize the initialize response.

Optionally list resumable sessions.

Optionally load an existing session and replay history.

Optionally log out a client.

Optionally resume an existing session without replaying history.

Optionally switch a session mode.

Called when the handler starts.

Called when the handler runner terminates.

Types

callback_reply()

@type callback_reply() :: map() | [map()] | String.t() | nil

callback_result()

@type callback_result() ::
  {:reply, callback_reply(), state()}
  | {:ok, callback_reply(), state()}
  | {:noreply, state()}
  | {:error, any(), state()}

context()

@type context() :: %{
  :agent => GenServer.server(),
  :request_id => integer() | String.t(),
  optional(:prompt_id) => integer() | String.t(),
  optional(:session_id) => String.t(),
  optional(:client_info) => map() | nil,
  optional(:client_capabilities) => map() | nil,
  optional(:protocol_version) => pos_integer()
}

state()

@type state() :: any()

Callbacks

handle_authenticate(params, context, state)

(optional)
@callback handle_authenticate(params :: map(), context(), state()) :: callback_result()

Optionally authenticate a client.

handle_cancel(session_id, context, state)

(optional)
@callback handle_cancel(session_id :: String.t(), context(), state()) :: callback_result()

Optionally handle session/cancel.

If this callback is not implemented, the runtime immediately completes the active prompt with "cancelled".

handle_close_session(session_id, context, state)

(optional)
@callback handle_close_session(session_id :: String.t(), context(), state()) ::
  callback_result()

Optionally close a session.

handle_initialize(params, context, state)

(optional)
@callback handle_initialize(params :: map(), context(), state()) :: callback_result()

Optionally customize the initialize response.

handle_list_sessions(params, context, state)

(optional)
@callback handle_list_sessions(params :: map(), context(), state()) :: callback_result()

Optionally list resumable sessions.

handle_load_session(params, context, state)

(optional)
@callback handle_load_session(params :: map(), context(), state()) :: callback_result()

Optionally load an existing session and replay history.

handle_logout(context, state)

(optional)
@callback handle_logout(context(), state()) :: callback_result()

Optionally log out a client.

handle_new_session(params, context, state)

@callback handle_new_session(params :: map(), context(), state()) :: callback_result()

Called for session/new.

Return either a session ID string or a full response map containing "sessionId".

handle_prompt(session_id, prompt, context, state)

@callback handle_prompt(
  session_id :: String.t(),
  prompt :: [map()],
  context(),
  state()
) :: callback_result()

Called for session/prompt.

The prompt_id in the context is the ID to pass to ExMCP.ACP.Agent.finish_prompt/3 when returning {:noreply, state}.

handle_resume_session(params, context, state)

(optional)
@callback handle_resume_session(params :: map(), context(), state()) :: callback_result()

Optionally resume an existing session without replaying history.

handle_set_config_option(session_id, config_id, value, context, state)

(optional)
@callback handle_set_config_option(
  session_id :: String.t(),
  config_id :: String.t(),
  value :: any(),
  context(),
  state()
) :: callback_result()

Optionally update a session config option.

handle_set_mode(session_id, mode_id, context, state)

(optional)
@callback handle_set_mode(
  session_id :: String.t(),
  mode_id :: String.t(),
  context(),
  state()
) :: callback_result()

Optionally switch a session mode.

init(opts)

@callback init(opts :: keyword()) :: {:ok, state()} | {:error, any()}

Called when the handler starts.

terminate(reason, state)

(optional)
@callback terminate(reason :: any(), state()) :: :ok

Called when the handler runner terminates.