New UI capability
Let an agent help with a form
s-m-r-t controls can tell a chat, voice, tutorial, or test adapter what they are, what they allow, and how to point to them without giving that adapter unchecked access to the page.
Give every control a stable address
A form has a formId and each control has a controlId, usually taken from its name. That lets an adapter refer to profile.displayName or settings.notifications without guessing from DOM position or visible wording.
- Controls publish their label, description, kind, options, constraints, and current validation state.
- A subject can connect a control to the record being edited.
- Public, personal, sensitive, and secret classifications travel with the control description.
Help without changing anything
An adapter can list the controls in a form and use safe commands to focus, reveal, highlight, explain, or validate one of them. These commands help someone navigate the interface but do not change its values.
- Highlight can point to the field being discussed in chat.
- Explain returns the control description, choices, and constraints to the adapter.
- Validate runs the same rule the visible form uses.
Propose first, then ask
Staging records a proposed value separately from the live form. Applying, clearing, or undoing an agent change requires an explicit confirmed command by default, so the UI has a natural place for a review step.
- Secret values are redacted and cannot be read or changed through the registry.
- Read-only, disabled, and non-writable controls reject mutation commands.
- Applications can supply a stricter policy for their own risk and permission rules.
Connect the adapter your product uses
The registry deliberately does not know about a particular chat model, voice service, WebMCP transport, or DOM implementation. Your adapter translates a trusted tool call or tutorial step into the small command vocabulary.
<script lang="ts">
import {
Form, FormGroup, Input,
createControlInteractionRegistry
} from '@happyvertical/smrt-ui/forms';
const controls = createControlInteractionRegistry();
async function proposeDisplayName(value: string) {
await controls.execute({
action: 'stage',
identity: { formId: 'profile', controlId: 'displayName' },
value
}, { source: 'agent' });
}
async function confirmDisplayName() {
await controls.execute({
action: 'apply',
identity: { formId: 'profile', controlId: 'displayName' }
}, { source: 'agent', confirmed: true });
}
</script>
<Form formId="profile" interactionRegistry={controls}>
<FormGroup label="Display name">
<Input name="displayName" />
</FormGroup>
</Form>Know where the boundary is today
The standardized controls, registry, safety policy, s-m-r-t Svelte form bridge, and interactive playground example are included. A product still chooses and wires the chat or voice adapter that exposes these commands; smrt-chat does not silently control every form just because both packages are installed.