A2UIAgent.MacroExpander (A2UIAgent v0.1.1)

Copy Markdown View Source

Puts macros (A2UIAgent.Macro) in front of a catalog: the model sees a catalog with the macros as components, and the renderer gets the base catalog's components they expand to.

expander = A2UIAgent.MacroExpander.new(basic_catalog, [status_badge])

# For the prompt: the base catalog with the macros added.
{:ok, inference_catalog} = A2UIAgent.MacroExpander.inference_catalog(expander)

# For the renderer: the model's messages with the macros expanded.
{:ok, messages} = A2UIAgent.MacroExpander.to_transport(expander, model_messages)

A macro component the model writes, {"id": "badge", "component": "StatusBadge", ...} (or with its arguments under "parameters"), is replaced by its macro's tree, flattened with the macro component's id as the root id (A2UIAgent.Builder.flatten/2) and checked against the base catalog. Components the expansion makes may be macros themselves; they are expanded in turn, up to a depth of 16.

A macro that fails (an argument it cannot take, a component the catalog rejects) leaves its component as it was, and the failure is logged. Expansion deeper than the limit fails the whole call.

Option :passthrough_components limits the base catalog's components the model sees: nil (the default) keeps them all, a list keeps the ones named, and [] leaves only the macros.

Summary

Functions

The catalog the model writes for: the base catalog's components (those :passthrough_components keeps) and the macros, which are also added to its anyComponent union. Same id and protocol version as the base catalog.

A catalog of the macros alone, under the id https://a2ui.org/catalogs/macros, in the base catalog's protocol version.

An expander for macros over the base catalog. Option: :passthrough_components.

Messages going the other way, which need no change: returns them as they are.

The model's messages with every macro component expanded (in the components of createSurface and updateComponents messages). Bindings and function calls are written for each message's version.

Types

t()

(since 0.1.0)
@type t() :: %A2UIAgent.MacroExpander{
  catalog: A2UICore.Catalog.t(),
  macros: [A2UIAgent.Macro.t()],
  passthrough: MapSet.t(String.t()) | nil,
  table: %{optional(String.t()) => A2UIAgent.Macro.t()}
}

Functions

inference_catalog(expander)

(since 0.1.0)
@spec inference_catalog(t()) ::
  {:ok, A2UICore.Catalog.t()} | {:error, A2UICore.Error.t()}

The catalog the model writes for: the base catalog's components (those :passthrough_components keeps) and the macros, which are also added to its anyComponent union. Same id and protocol version as the base catalog.

Fails with a :catalog error when a macro has the name of a base component.

macro_catalog(macro_expander)

(since 0.1.0)
@spec macro_catalog(t()) :: A2UICore.Catalog.t()

A catalog of the macros alone, under the id https://a2ui.org/catalogs/macros, in the base catalog's protocol version.

new(catalog, macros, options \\ [])

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

An expander for macros over the base catalog. Option: :passthrough_components.

Raises ArgumentError when two macros have the same name.

to_inference(macro_expander, messages)

(since 0.1.0)
@spec to_inference(t(), [map()]) :: [map()]

Messages going the other way, which need no change: returns them as they are.

to_transport(expander, messages)

(since 0.1.0)
@spec to_transport(t(), [map()]) :: {:ok, [map()]} | {:error, A2UICore.Error.t()}

The model's messages with every macro component expanded (in the components of createSurface and updateComponents messages). Bindings and function calls are written for each message's version.

Fails with a :recursion error when expansion goes deeper than 16.