AG-UI Features
Soliplex uses the AG-UI protocol to communicate
with web and TUI clients. AG-UI carries a free-form state mapping
between client and server; AG-UI features are the contracts that
define the schema and write semantics for individual top-level keys
within that mapping.
Each feature is described by an AGUI_Feature dataclass
(soliplex.config.agui.AGUI_Feature) carrying:
name-- the key under which the feature's data appears in the AG-UIstatemapping.model_klass-- a Pydantic model class defining the schema for the feature's data.source-- one ofclient,server, oreither, describing which party is allowed to write the feature's portion of the AG-UI state.
The AGUI_FEATURES_BY_NAME Registry
soliplex.config.agui.AGUI_FEATURES_BY_NAME is a module-level
dict[str, AGUI_Feature] that maps each feature's name to its
registration. The registry starts empty and is populated by mutation
during application startup.
The registry is the single source of truth for "which AG-UI features does this installation know about?" Code elsewhere in Soliplex (and in the TUI client) looks features up here whenever it needs the schema, default value, or write-direction for a particular state key.
How the Registry Gets Populated
The registry is filled from three sources, applied in this order during installation load:
1. Soliplex-Builtin Registrations
Importing soliplex.config.skills (which happens transitively
whenever soliplex.config is imported) registers Soliplex's own
built-in features. As of this writing, that includes the
bwrap-sandbox skill's state namespace, registered with
source=server.
These registrations happen at module-import time and are present before any installation YAML is parsed.
2. Entrypoint Skill Discovery
When an InstallationConfig is loaded,
_load_entrypoint_skill_configs walks every Haiku skill discovered
via Python entry points. For each skill whose state_namespace is
set, it adds an entry to the registry using skill.state_type as
model_klass and server as source -- but only if the
state_namespace is not already present in the registry. This
makes entrypoint discovery a no-op for features that have already
been registered by other means.
3. The meta.agui_features YAML Stanza
Finally, the
meta.agui_features
stanza of the installation YAML is processed by
InstallationConfigMeta.__post_init__. Each entry produces an
AGUI_Feature which is unconditionally written into the
registry, overwriting any earlier entry with the same name.
This ordering means installation YAML wins over both built-in
registrations and entrypoint discovery, so site operators can
override the default model_klass or source for any feature
shipped by Soliplex or by an installed skill package.
How the Application Uses the Registry After Startup
Once the installation is loaded, the registry is read (never written) by the runtime. The main consumers are:
InstallationConfig.agui_features
The InstallationConfig.agui_features property simply returns
list(AGUI_FEATURES_BY_NAME.values()). This is the canonical
"what features does this installation expose?" accessor.
The Installation Runtime Model
soliplex.models.Installation.from_config converts each entry
from InstallationConfig.agui_features into a serializable
models.AGUI_Feature carrying name, description, source,
and json_schema. The result is exposed to clients through the
installation views, so a Soliplex client can introspect the full
set of features (and their JSON schemas) without reading the
server's YAML.
Initial AG-UI State Synthesis
When a new AG-UI thread is started without a client-supplied
state, soliplex.views.agui builds a default state by iterating
over the room's agui_feature_names and, for each name,
instantiating AGUI_FEATURES_BY_NAME[name].model_klass() with no
arguments and dumping it to a dict. The TUI client
(soliplex.tui.main) does the same thing on its side when
opening a new room.
This means every model class registered in the registry must be constructible with no arguments -- typically by giving every field a default value.
Schema Export
The soliplex-cli agui-feature-schemas command iterates the
registry (via installation._config.agui_features) and emits a
JSON document mapping each feature name to {source, json_schema}.
Downstream client projects might consume this output to generate
type-safe client code.
YAML Round-Trip
InstallationConfigMeta.as_yaml walks the registry to emit a
meta.agui_features block recording every registered feature
(including those that arrived via paths #1 and #2 above). This is
used by soliplex-cli export commands so that a fully expanded
configuration can be written back to disk.
Notes for Test and Plugin Authors
-
Because the registry is a module-level mutable global, unit tests must isolate themselves from each other. The standard fixture is
patched_agui_featuresintests/unit/conftest.py, which usesmock.patch.dictto give each test a fresh empty registry. -
A name listed in a room's
agui_feature_namesthat is not present in the registry will raiseKeyErrorwhen the server tries to synthesize an initial AG-UI state for a new thread. Runsoliplex-cli audit rooms <installation.yaml>to detect this before deploying; each room's aggregate feature names are listed withOKorUNREGISTERED. -
Plugin authors who want to register a feature have two options: ship it as an entrypoint skill (path #2 above), or document a
meta.agui_featuresentry that operators can paste into their installation YAML (path #3).