Imp.ACP (Imp v0.5.0)

Copy Markdown View Source

Runs an Imp.Module program behind an Agent Client Protocol endpoint.

Imp.ACP owns the ACP-to-Imp boundary. ExMCP owns the protocol and stdio connection; Imp owns program execution. One adapter session process owns each ACP session's program, retained history, active supervised task, cancellation, and final-response ordering.

Prefer :program_factory so stateful programs such as persistent RLM receive a fresh instance for every ACP session:

Imp.ACP.run(
  program_factory: fn %{cwd: cwd} -> MyAgents.build(cwd) end,
  input_key: :question,
  output_key: :answer
)

:program is convenient for immutable/stateless programs, but the same value is installed into every session.

The session map a factory receives is :cwd, :mcp_servers, :session_id, :host, :meta and :requested_meta. :meta is ACP's _meta, the extension point for per-session data the protocol does not model; one endpoint can therefore answer for more than one configuration. Keys in _meta are namespaced by whoever defines them, so read your own and ignore the rest.

On session/new both keys hold the request's _meta. On session/load and session/resume they may differ: :meta is the _meta the session was created with, stored beside its history and transcript, and :requested_meta is what this request asked for. The stored value is the one installed. Both are passed so a factory can compare them and refuse a resume whose requested configuration contradicts the stored one; only the factory knows which of its own keys are identity-bearing. A session stored without _meta resumes with :meta empty.

Optional :on_cancel receives (program, session_metadata) only for an explicit active session/cancel, never on disconnect or close. It must return :ok to acknowledge application cancellation. {:error, reason}, invalid returns, or exceptions refuse cancellation with :cancel_callback_failed and leave the observer run active; the adapter does not claim the work stopped. Keep this callback bounded and idempotent.

External ReActV2 and RLM tool effects require an ACP client permission by default. Set permission_policy: :unrestricted only when the endpoint is deliberately trusted and the program's own Imp.ToolPolicy is sufficient.

Summary

Functions

Default adapter capabilities, for agents adding explicitly supported protocol features.

Runs an ACP stdio agent until its connection exits.

Starts a linked ACP agent process.

Functions

capabilities(adapter_opts \\ [])

Default adapter capabilities, for agents adding explicitly supported protocol features.

Takes the adapter options start_link/1 takes; :session_store decides whether sessions can be loaded, listed, resumed and deleted.

run(opts)

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

Runs an ACP stdio agent until its connection exits.

Takes the options start_link/1 takes, and raises ArgumentError for one it does not know before anything is started.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Starts a linked ACP agent process.

An option this function does not know raises ArgumentError.

Options

  • :program - An Imp.Module struct installed into every session. Convenient for an immutable program; use :program_factory for anything with state.

  • :program_factory (function of arity 1) - Builds each session's program from the session map (see above). Returns the program, {:ok, program}, {:ok, program, cleanup} with a 0-arity cleanup function, {:ok, program, lifecycle} with a map of 0-arity :before_turn, :after_turn and :cleanup functions and :tool_kinds, or {:error, reason}. Pass exactly one of :program and :program_factory.

  • :input_key - The program input the prompt text goes to. When absent, the signature's only input.

  • :input_mapper - fn prompt, context -> inputs end, in place of :input_key.

  • :output_key - The prediction field that becomes the response. When absent, the signature's only output.

  • :output_renderer - fn prediction, context -> text end, in place of :output_key.

  • :cleanup - fn program -> _ end, called with the session's program when the session closes; its return value is ignored.

  • :on_cancel - fn program, session_metadata -> :ok end, for an explicit session/cancel only (see above).

  • :session_store - A directory that keeps each session's history and transcript, which enables session/load, list, resume and delete.

  • :permission_policy - Who decides a ReActV2 or RLM tool call: :client asks the ACP client, :unrestricted asks no one, and a function of the request (and the session context) returns :allow, :client or {:deny, reason}. The default value is :client.

  • :authorization_timeout (pos_integer/0) - Milliseconds a permission decision may take before it is a denial. The default value is 3600000.

  • :cancel_timeout (pos_integer/0) - Milliseconds a cancelled turn's effects have to end. The default value is 5000.

  • :tool_kinds - Map of tool name to ACP tool kind (read, edit, delete, move, search, execute, think, fetch, switch_mode, other), for tools whose kind their MCP annotations do not give; it outranks a kind derived from them. The default value is %{}.

  • :name (term/0) - A GenServer name for the agent process (start_link/1 only).

  • :agent_info (map of String.t/0 keys and term/0 values) - The agentInfo announced at initialize; imp at Imp's version by default.

  • :agent_capabilities (map of String.t/0 keys and term/0 values) - The agentCapabilities announced at initialize; capabilities/1 by default.

  • :auth_methods (list of map/0) - The authMethods announced at initialize; none by default.

  • :protocol_version (pos_integer/0) - The ACP protocol version announced; ExMCP's by default.

  • :max_frame_bytes (pos_integer/0) - Largest JSON-RPC frame read or written, in bytes; ExMCP's 1 MiB by default.

  • :max_pending_requests (pos_integer/0) - Requests to the client awaiting an answer at once; ExMCP's by default.

  • :pending_request_timeout (pos_integer/0) - Milliseconds a request to the client (a permission request) may wait. The default value is 3600000.

  • :handler_request_timeout (pos_integer/0) - Milliseconds a client request may take in the adapter; ExMCP's by default.

  • :transport - :stdio (the default), {:memory, peer} for an in-VM client, or a transport module.

  • :transport_mod (atom/0) - A transport module, in place of :transport.

  • :transport_options (keyword/0) - Options for the transport, such as ExMCP.ACP.Agent.Transport.Stdio's :input and :output. The default value is [].