A2UICore.RPC (A2UICore v0.1.1)

Copy Markdown View Source

The function RPC of protocol v1.0, as a value.

Two directions meet here.

The agent calls a renderer function (callRendererFunction). call_renderer_function/3 resolves the function in the catalog the call names, checks that an agent may call it, resolves its arguments against the data of the surface the call names (or against an empty data model), validates them, runs it and returns the rendererFunctionResponse message to send back. It always returns one: every failure is an error response, never an exception.

The renderer calls an agent function (callAgentFunction). call_agent_function/4 registers a pending call and returns the message to send. The call is settled later, by one of:

Each of these returns the settlements it caused: {:resolved, call_id, value} or {:rejected, call_id, error}.

Nothing here runs a process or reads a clock. A call's timeout is data (pending_timeout/2): the host starts a timer for it and reports it with timeout/2.

Error codes

Responses and rejections use INVALID_FUNCTION_CALL (an unknown surface, catalog or function, a caller or activation violation, bad arguments, a malformed call), EXECUTION_ERROR (the function failed, or an argument's expression did), TIMEOUT, CANCELLED, DISPOSED, DUPLICATE and UNKNOWN_ERROR (an agent error without a code).

Summary

Functions

Registers a call to an agent function and returns the callAgentFunction message to send.

Executes an agent's callRendererFunction and returns the rendererFunctionResponse message.

Rejects a pending call because the host abandoned it, with CANCELLED. Ignored when the call is no longer pending.

Rejects every pending call with CANCELLED and stops the handler: later renderer-function calls answer DISPOSED and agent calls fail. Idempotent.

Whether the handler has been disposed.

Settles the pending call an agent's agentFunctionResponse answers. A response to a call that is not pending is ignored.

Creates the handler over catalogs, the catalogs functions are resolved in.

The ids of the calls still waiting for the agent, sorted.

The timeout of a pending call in milliseconds, or nil when the call is not pending or has none. The host's timer is the one that fires it.

Rejects a pending call whose timer fired, with TIMEOUT. Ignored when the call is no longer pending.

Types

pending()

(since 0.1.0)
@type pending() :: %{name: String.t(), timeout_ms: number() | nil}

settlement()

(since 0.1.0)
@type settlement() ::
  {:resolved, String.t(), term()} | {:rejected, String.t(), A2UICore.Error.t()}

t()

(since 0.1.0)
@type t() :: %A2UICore.RPC{
  catalogs: [A2UICore.Catalog.t()],
  default_timeout_ms: number(),
  disposed?: boolean(),
  next_id: pos_integer(),
  pending: %{optional(String.t()) => pending()}
}

Functions

call_agent_function(rpc, surface_id, call, options \\ [])

(since 0.1.0)
@spec call_agent_function(t(), String.t(), map(), keyword()) ::
  {:ok, t(), map()} | {:error, A2UICore.Error.t()}

Registers a call to an agent function and returns the callAgentFunction message to send.

call is a function call object ("@call" or "call", "catalogId", "args"). Options: :function_call_id (a counter-based id otherwise), :timeout_ms (the handler's default otherwise) and :version.

Fails with a :rpc error — DISPOSED, INVALID_FUNCTION_CALL for a call without a name, DUPLICATE for an id that is already pending.

call_renderer_function(rpc, call, options \\ [])

(since 0.1.0)
@spec call_renderer_function(
  t(),
  A2UICore.Message.Operation.CallRendererFunction.t(),
  keyword()
) ::
  map()

Executes an agent's callRendererFunction and returns the rendererFunctionResponse message.

The function runs in the catalog the call names (catalogId). Its arguments are resolved against :context, the data context of the surface the call names (surfaceId); a call that names no surface runs in a context of its own, with an empty data model and the call's catalog as its default catalog. An argument whose expression fails makes the call fail with EXECUTION_ERROR; the resolved arguments are then validated against the function's schema.

Options:

  • :context — the A2UICore.Resolution.DataContext of the surface the call names (nil when there is no such surface, which fails the call);
  • :user_activated — whether the call happens inside a user gesture, which functions that require activation need (default false).

cancel(rpc, call_id, reason \\ "The call was cancelled.")

(since 0.1.0)
@spec cancel(t(), String.t(), String.t()) :: {t(), [settlement()]}

Rejects a pending call because the host abandoned it, with CANCELLED. Ignored when the call is no longer pending.

dispose(rpc, reason \\ "RpcHandler has been disposed.")

(since 0.1.0)
@spec dispose(t(), String.t()) :: {t(), [settlement()]}

Rejects every pending call with CANCELLED and stops the handler: later renderer-function calls answer DISPOSED and agent calls fail. Idempotent.

disposed?(rpc)

(since 0.1.0)
@spec disposed?(t()) :: boolean()

Whether the handler has been disposed.

handle_agent_function_response(rpc, response)

(since 0.1.0)
@spec handle_agent_function_response(
  t(),
  A2UICore.Message.Operation.AgentFunctionResponse.t()
) ::
  {t(), [settlement()]}

Settles the pending call an agent's agentFunctionResponse answers. A response to a call that is not pending is ignored.

new(catalogs, options \\ [])

(since 0.1.0)
@spec new([A2UICore.Catalog.t()], keyword()) :: t()

Creates the handler over catalogs, the catalogs functions are resolved in.

Options: :default_timeout_ms (default 30 000) for calls that name no timeout of their own; zero or less means no timeout.

Raises ArgumentError when catalogs is empty.

pending(rpc)

(since 0.1.0)
@spec pending(t()) :: [String.t()]

The ids of the calls still waiting for the agent, sorted.

pending_timeout(rpc, call_id)

(since 0.1.0)
@spec pending_timeout(t(), String.t()) :: number() | nil

The timeout of a pending call in milliseconds, or nil when the call is not pending or has none. The host's timer is the one that fires it.

timeout(rpc, call_id)

(since 0.1.0)
@spec timeout(t(), String.t()) :: {t(), [settlement()]}

Rejects a pending call whose timer fired, with TIMEOUT. Ignored when the call is no longer pending.