ACPex.Protocol.Connection (ACPex v0.1.0)

View Source

GenServer that manages the state for a single agent-client connection.

The Connection module is a core component in the ACPex OTP architecture, sitting between the transport layer and individual session processes. It is responsible for:

  • Handling connection-level protocol messages (initialize, authenticate)
  • Managing the lifecycle of session processes via a SessionSupervisor
  • Routing messages to the appropriate session based on session_id
  • Handling bidirectional JSON-RPC communication
  • Managing pending requests and matching responses

Architecture

Each connection spawns its own supervision tree:

Connection.GenServer
 SessionSupervisor
    Session.GenServer (session_id_1)
    Session.GenServer (session_id_2)
    ...

Message Flow

  1. Incoming messages arrive via {:message, json_rpc_message}
  2. Connection-level messages are handled directly by calling the handler module
  3. Session-level messages are forwarded to the appropriate session process
  4. Responses are matched with pending requests via their id field

Examples

# Start an agent connection
{:ok, pid} = Connection.start_link(
  handler_module: MyAgent,
  handler_args: [],
  role: :agent,
  transport_pid: transport_pid
)

# Send a notification to the other party
Connection.send_notification(pid, "session/update", %{
  "session_id" => "abc123",
  "update" => %{"kind" => "message", "content" => "Hello"}
})

# Send a request and await response
response = Connection.send_request(pid, "fs/read_text_file", %{
  "path" => "/tmp/file.txt"
})

Summary

Functions

Returns a specification to start this module under a supervisor.

Sends a JSON-RPC notification (one-way message) to the other party.

Sends a JSON-RPC request and asynchronously waits for the response.

Starts a new Connection GenServer.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

send_notification(pid, method, params)

@spec send_notification(pid(), String.t(), map()) :: :ok

Sends a JSON-RPC notification (one-way message) to the other party.

Notifications do not have an id field and do not expect a response.

Examples

Connection.send_notification(conn, "session/update", %{
  "session_id" => "abc",
  "update" => %{"kind" => "thought", "content" => "Thinking..."}
})

send_request(pid, method, params, timeout \\ 5000)

@spec send_request(pid(), String.t(), map(), timeout()) :: map()

Sends a JSON-RPC request and asynchronously waits for the response.

The request will have an id field and expects a response. This function blocks until the response is received or the timeout expires.

Examples

response = Connection.send_request(conn, "fs/read_text_file", %{
  "path" => "/etc/hosts"
}, 10_000)

start_link(opts)

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

Starts a new Connection GenServer.

Options

  • :handler_module - The module implementing either ACPex.Agent or ACPex.Client
  • :handler_args - Arguments passed to the handler's init/1 callback
  • :role - Either :agent or :client
  • :transport_pid - (optional) PID of an existing transport process
  • :opts - Additional GenServer options (e.g., :name)