A2UIAgent.Macro (A2UIAgent v0.1.1)

Copy Markdown View Source

A macro: a component the model can write that the agent expands into components of its catalog before they reach the renderer.

import A2UIAgent.Builder.Basic

status_badge =
  A2UIAgent.Macro.new(
    "StatusBadge",
    [status: :string, title: :string],
    fn %{status: status, title: title} ->
      card(
        child:
          row(
            children: [
              text(text: String.upcase(status), variant: "caption"),
              text(text: title, variant: "h3")
            ]
          )
      )
    end,
    description: "A status badge."
  )

The model writes {"id": "badge", "component": "StatusBadge", "status": "active", "title": "Server 1"}; A2UIAgent.MacroExpander replaces it with the flattened tree, rooted at badge. The macro's catalog schema (to_json_schema/2) is derived from its parameters.

Parameters

Parameters are a keyword list of names and types, in order. A type can also be given with options, title: [type: :string, description: "..."]: :description (default: the name, spaced and capitalized), :required (default true unless a :default is given) and :default, passed for an optional parameter left out. Types:

  • :string, :integer, :number, :boolean, :object, :any, {:enum, values} and {:list, type};
  • :component, a child slot: the model passes a component id, which reaches the function as an A2UIAgent.Builder.ref/1;
  • :component_list, child slots: a list of ids, as refs;
  • :action: an event name, an event ({"name": ..., "context": ...}) or an action, as an action;
  • :dynamic_string, :dynamic_number, :dynamic_boolean, :dynamic_string_list, :dynamic_value, :data_binding, :function_call, :check_rule and :accessibility: the protocol's common types.

Any argument written as a binding ({"path": ...}) reaches the function as an A2UIAgent.Builder.bind/1.

The function gets a map of the arguments by parameter name and returns a component tree. It may call other macros with call/2.

Summary

Functions

Runs the macro with args (by parameter name, as atoms or strings) and returns its tree. Arguments are coerced as the parameters' types say (see "Parameters"); a left-out optional parameter gets its default.

A call of macro (a macro, or the name of one the flattening is given with :macros) inside a tree. The call expands where the tree is flattened, in the tree's scope: the components it makes are named after the tree's root.

Defines a macro named name (the component name the model writes). Option: :description, the component's description in the catalog.

The macro's component schema for a catalog: an object whose properties are the parameters, with references to the protocol's common types under ref_prefix.

Types

parameter()

(since 0.1.0)
@type parameter() :: %{
  name: atom(),
  type: type(),
  required: boolean(),
  default: term(),
  description: String.t()
}

t()

(since 0.1.0)
@type t() :: %A2UIAgent.Macro{
  description: String.t() | nil,
  fun: (map() -> A2UIAgent.Builder.tree()),
  name: String.t(),
  parameters: [parameter()]
}

type()

(since 0.1.0)
@type type() ::
  :string
  | :integer
  | :number
  | :boolean
  | :object
  | :any
  | {:enum, [term()]}
  | {:list, type()}
  | :component
  | :component_list
  | :action
  | :dynamic_string
  | :dynamic_number
  | :dynamic_boolean
  | :dynamic_string_list
  | :dynamic_value
  | :data_binding
  | :function_call
  | :check_rule
  | :accessibility

Functions

build(macro, args)

(since 0.1.0)
@spec build(t(), keyword() | map()) :: A2UIAgent.Builder.tree()

Runs the macro with args (by parameter name, as atoms or strings) and returns its tree. Arguments are coerced as the parameters' types say (see "Parameters"); a left-out optional parameter gets its default.

Raises ArgumentError for an unknown or missing argument, or when the function does not return a component tree.

call(macro, args \\ %{})

(since 0.1.0)
@spec call(t() | String.t(), keyword() | map()) :: A2UIAgent.Macro.Call.t()

A call of macro (a macro, or the name of one the flattening is given with :macros) inside a tree. The call expands where the tree is flattened, in the tree's scope: the components it makes are named after the tree's root.

new(name, parameters, fun, options \\ [])

(since 0.1.0)
@spec new(String.t(), keyword(), (map() -> A2UIAgent.Builder.tree()), keyword()) ::
  t()

Defines a macro named name (the component name the model writes). Option: :description, the component's description in the catalog.

Raises ArgumentError for a parameter with an unknown type.

to_json_schema(macro, ref_prefix \\ "common_types.json#/$defs/")

(since 0.1.0)
@spec to_json_schema(t(), String.t()) :: map()

The macro's component schema for a catalog: an object whose properties are the parameters, with references to the protocol's common types under ref_prefix.

iex> macro = A2UIAgent.Macro.new("Badge", [label: :dynamic_string], fn _ -> nil end)
iex> A2UIAgent.Macro.to_json_schema(macro)
%{
  "type" => "object",
  "properties" => %{
    "label" => %{"$ref" => "common_types.json#/$defs/DynamicString", "description" => "Label"}
  },
  "required" => ["label"]
}