a2ui-project / a2ui-project/a2ui
[FEATURE]: Declare semantic action class on interactive components
- 主要语言
- TypeScript
- 星标
- 16.4k
- 派生
- 1.3k
- 平均合并
- 2 天 13 小时
- 30 天内合并 PR
- 134
描述
- [x] I have searched the existing issues to make sure this is not a duplicate.
## Is your feature request related to a problem? Please describe.
The closed catalog eliminates code execution and markup injection, which is the
right foundation. But interactive components declare only a *visual* variant,
never their *semantic* intent:
- `Button.variant`: `default` | `primary` | `borderless`
- `TextField.variant`: `longText` | `number` | `shortText` | `obscured`
Per `specification/v0_9_1/catalogs/basic/catalog.json`, no component in the basic
catalog carries a role, importance, or destructiveness indicator. The v1.0
candidate adds `actionResponse` / `actionId` / `callFunction`, but no action
semantics.
Two consequences:
**1. The deceptive-control threat class is unrepresentable, not merely
unenforced.** The published MAESTRO threat model for AG-UI/A2UI names Layer 7
"UI Confusion / Deceptive Interfaces", with the example of a "View Details"
button that triggers deletion. Detecting that requires comparing a control's
declared semantics against its label. With only an opaque event name and a
visual variant there is nothing to compare against, so a conforming validator
cannot detect the shape at all.
**2. Human-in-the-loop approval gates have nothing to key on.** A host that wants
to route destructive actions to a confirmation step, or an audit record that
wants to state a destructive action was presented, must first identify which
actions are destructive. That never crosses the wire today, leaving hosts to
infer intent by matching event-name strings the agent itself chooses.
Concretely: I ported a set of nine generative-UI trust conformance vectors to
v0.9.1. Six port cleanly. Three are inexpressible, all for this single reason.
## Describe the solution you'd like
An **optional** semantic class on components carrying an action. Optional means
purely additive — not a breaking change to the candidate spec, and renderers
that ignore it behave exactly as today.
```json
{
"id": "delete-btn",
"component": "Button",
"child": "delete-label",
"role": "destructive",
"action": { "event": { "name": "delete_account", "context": {} } }
}
```
Minimal viable enum:
| value | meaning |
|---|---|
| `neutral` | default; no declared semantics (current behaviour) |
| `confirm` | affirmative, non-destructive |
| `cancel` | backs out without effect |
| `destructive` | irreversible effect |
`approve` / `reject` / `submit` could be added if useful or collapsed into
`confirm` / `cancel`. The minimum that unlocks policy is the
affirmative / negative / destructive distinction.
This lets a renderer or a policy layer above it:
- reject a label that contradicts its declared role, before render
- route `destructive` to a confirmation step, or deny it by host policy
- record in an audit trail what class of action a user was actually shown
## Describe alternatives you've considered
- **Label heuristics alone** — inspect the Button's child `Text` for destructive
words. This is what a policy layer must do today and it is weak: the label is
exactly the surface an injected agent controls, it is language-specific, and
with no second signal it cannot distinguish mislabeled from honestly labeled.
- **Host-side allow-list of event names** — brittle, doesn't generalize, and
every host maintains its own list of names the agent picks.
- **Custom catalogs with semantic components** — works, but fragments the
ecosystem and loses the portability that motivates a framework-agnostic spec.
- **Do nothing** — leaves a named threat class structurally undetectable and
leaves every host to reinvent the same inference layer.
## Additional context
Conformance vectors, including the six that port cleanly and the three that
don't, with per-vector reasoning:
https://github.com/punarduttrajput/wovyr/tree/main/generative-ui-conformance/a2ui
Caveat stated up front: those A2UI frames were constructed against
`catalog.json` and the shipped example gallery, and are **not yet validated
against a live renderer**. If any fails to validate, that is a bug in the
vectors and I would like to know.
A related but separate concern I would rather not conflate here: the basic
catalog's own `examples/09_login-form.json` is structurally a credential-
collecting surface, and nothing in the wire format distinguishes an agent
legitimately rendering it from an injected agent rendering the same thing. That
is a question about surface provenance rather than action semantics — happy to
file it separately if useful.
贡献指南
评估
这个 Issue 还没有评估数据。