Pixir.ACP.Protocol (pixir v0.1.0)

Copy Markdown View Source

JSON-RPC 2.0 framing over Jason, newline-delimited (ndjson), for the ACP agent transport (ADR 0009). Pure functions, no IO: one decoded ndjson line becomes a tagged term; result/error/notification maps become a JSON string (the caller appends "\n").

There is deliberately no JSON-RPC dependency — the wire shape is small and hand-built over Jason (one JSON object per line). stdout carries only these encoded strings; every diagnostic goes to stderr (ADR 0005 channel discipline).

Summary

Functions

Decode one ndjson line into a tagged term

Encode an error response as a JSON string (no newline). data is omitted unless non-nil. id may be nil (e.g. an unrecoverable parse error).

JSON-RPC code for an internal-error fault.

JSON-RPC code for an invalid-params fault.

JSON-RPC code for a method-not-found fault.

Encode a notification (method + params, no id) as a JSON string (no newline).

Encode an OUTBOUND request (agent→client) as a JSON string (no newline). Unlike every other encoder here, this one originates a request expecting a response — used for session/request_permission (A.2). The Server correlates the eventual {:response, id, _} against the id written here.

Encode a successful response (id + result) as a JSON string (no newline).

Types

decoded()

@type decoded() ::
  {:request, id(), method(), params()}
  | {:notification, method(), params()}
  | {:response, id(), term()}
  | {:response_error, id(), term()}
  | {:error, rpc_error()}
  | {:ignore, id() | nil}

id()

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

method()

@type method() :: String.t()

params()

@type params() :: map()

rpc_error()

@type rpc_error() :: {atom(), integer(), String.t()}

Functions

decode(line)

@spec decode(binary()) :: decoded()

Decode one ndjson line into a tagged term:

  • {:request, id, method, params} — has both "id" and "method".
  • {:notification, method, params} — has "method" and no "id".
  • {:error, {kind, code, message}} — malformed JSON or a non-2.0 envelope.
  • {:ignore, id} — a valid envelope an agent never acts on (e.g. a response).

params defaults to %{} when absent.

error(id, code, message, data \\ nil)

@spec error(id() | nil, integer(), String.t(), map() | nil) :: String.t()

Encode an error response as a JSON string (no newline). data is omitted unless non-nil. id may be nil (e.g. an unrecoverable parse error).

internal_error()

@spec internal_error() :: integer()

JSON-RPC code for an internal-error fault.

invalid_params()

@spec invalid_params() :: integer()

JSON-RPC code for an invalid-params fault.

method_not_found()

@spec method_not_found() :: integer()

JSON-RPC code for a method-not-found fault.

notification(method, params)

@spec notification(method(), params()) :: String.t()

Encode a notification (method + params, no id) as a JSON string (no newline).

request(id, method, params)

@spec request(id(), method(), params()) :: String.t()

Encode an OUTBOUND request (agent→client) as a JSON string (no newline). Unlike every other encoder here, this one originates a request expecting a response — used for session/request_permission (A.2). The Server correlates the eventual {:response, id, _} against the id written here.

result(id, result)

@spec result(id(), map()) :: String.t()

Encode a successful response (id + result) as a JSON string (no newline).