← LOGS

A Button in an AI Answer Can Change State

What a button inside an AI-generated answer can actually do, and how to distinguish a visual control from an authorized change to another system.

A dense, uniform grid of rectangular switches, with one near the center glowing significantly brighter than the surrounding switches.
A hundred small choices, but not every touch carries the same weight.

IN BRIEF

A button embedded in an AI answer might be decoration, might change only the display, or might send a request to a service that can change something outside the answer. Those are very different promises. Before trusting a consequential action, I would want to know exactly what will change, whose authority the system will use, and what the receiving service actually confirms. A click is intent, an approval is not execution, and a success message may still leave the real outcome unresolved. This is a product-design argument, not a report of a tested integration.

Imagine asking an AI assistant what to do with excess inventory. It returns a neat table: move twelve units from Store A to Store B. Below it is a button labelled Approve transfer.

I can see why this interface would appeal to someone trying to get work done. The recommendation and the next action sit in the same place. No copying numbers into another screen. No hunting for the right form.

But I'd have one question before pressing it: What does that button actually do?

Not what it looks like it does. Not what the label suggests. What happens after the click, in whose account, and how would I know?

This inventory transfer is hypothetical. I'm using it to examine a product decision, not claiming to have built, tested or witnessed such an integration.


Three buttons that look the same

The first button is only presentation. The model or interface can draw something labelled Approve, but the drawing doesn't have to be connected to any action at all. It may be as inert as a button in a screenshot.

The second is genuinely interactive, but local. Pressing it might highlight a proposed allocation, filter a table, or recalculate figures inside the displayed component. The user sees a change. That doesn't establish that an inventory record, document or account changed anywhere else.

The third sends a request beyond the component. The host application may route it to a tool or service that can consider an external operation. That is the interesting case, because it introduces a different kind of responsibility. The click can reach another system, but the existence of a request path still doesn't mean the service authorized or completed the operation.

These are not hypothetical categories invented from the appearance of a UI. OpenAI's documentation for MCP-based app interfaces describes a UI-to-host tool-call route and separately discusses widget-local state. The MCP Apps specification documents the UI, host and server message path. ChatKit's action documentation shows widgets sending named actions with payloads to handlers.

Those documents establish mechanisms an application can use. They don't establish that every button appearing in an AI answer has one of those handlers, that a connected tool is available, or that a real operation occurred.

So my first product distinction would be simple: shown, changed locally, requested externally, and changed externally are four different statements. The interface should not make the last one sound true when it has established only the first three.


An approval needs an object

Go back to the twelve units. Approve transfer is readable to a human, but as an instruction it leaves almost everything out.

Which product? Which stores? Which stock record? Which quantity, if the underlying figures have changed since the recommendation appeared? Which account is being used? Is this a draft for someone else to review, or an instruction to update inventory now?

A real inventory application would choose its own required fields. The point of the example is that a state-changing request needs a definite target and payload. A visible label is not that payload.

ChatKit's documented actions separate the button from the structured action name and payload delivered to a handler. That handler decides what to do next. A useful interface can show the user the same specificity before they approve: Transfer twelve units of item X from A to B in account Y. If the relevant values change, the previous approval may no longer describe the request being executed.

Even then, I wouldn't collapse everyone involved into the word user.

There is the person who clicked. There is the account signed into the host. There may be a tool carrying the request. And there is the service that decides whether to accept it. The person may be allowed to inspect stock but not authorize a transfer. The host may possess a credential without having permission to perform every operation it can describe.

A consent prompt answers whether someone signalled agreement. Authorization answers whether the accountable service permits this specific operation under the relevant identity and rules. Execution answers whether the service actually did it.

Those decisions can be related, but they aren't synonyms.

Tool descriptions and annotations can help a host understand what kind of operation is being offered. OpenAI's tool-definition guidance includes classification hints. Such hints are not a substitute for the receiving service checking permissions and business rules. Likewise, the Vercel AI SDK's approval features document specific SDK approval behaviour; its local-tool approval configuration should not be mistaken for a universal gate over every provider-executed tool.

That's a lot of machinery behind a tiny button.

The user shouldn't have to study the machinery. The product does have to know which part is responsible for which decision.


A green success message is not an inventory record

Suppose the person presses the button. The spinner runs, the table updates, and a green message says Transfer approved.

What can the product honestly claim at that moment?

Possibly only that the component updated itself. Possibly that the host sent a request. Perhaps the service accepted a job that is still pending. Or perhaps the actual inventory transaction has completed.

I would want the interface to distinguish those states rather than wrapping them all in the same reassuring word.

For a consequential operation, a useful result needs enough identity to tell the user what was requested, whether it was refused or accepted, whether work is pending or completed, and where an authoritative receipt or current state can be checked. The exact proof depends on the receiving service. A result returned through a UI-to-host protocol is evidence of what the tool reported, not an independent audit of the external database.

That gap exists with ordinary tools too. A previous Dream Atlas Log, The Protocol Was Not the Behavior, examines why a formally valid tool exchange still needs evidence that its claimed semantics held. Here the additional question is what a human-facing control is entitled to tell the person who clicked it.

If the service has accepted but not completed a transfer, Request submitted; awaiting inventory confirmation is more useful than Done. The first message describes a real boundary. The second may close the user's attention before the work is finished.


The more awkward case: no answer

Now imagine the click times out.

It is tempting to show Try again, because that's what interfaces commonly offer when a request fails to return. Except a timeout doesn't tell us whether the underlying operation failed.

The service may never have received it. It may have rejected it. It may also have committed the transfer and lost the response on the way back. From the screen, those can look identical.

A blind second click might do nothing, or it might submit another twelve-unit transfer. Which outcome is possible depends on how the actual service treats repeated requests.

This is where an operation identifier, a status lookup, and an idempotency mechanism can matter. An idempotency key, where supported and correctly implemented, lets the service recognize retries of the same logical request. A status endpoint can help the interface reconcile an uncertain outcome. Neither mechanism is universal, and neither guarantees that every partial or multi-step operation can be undone.

I don't think every table filter needs an approval modal, operation receipt and recovery procedure. That would turn harmless interaction into paperwork. The stakes change when a control can alter another system's records or cause a consequence that isn't easily reversed.

The honest message in the timeout case might simply be Outcome unknown; check the transfer status before trying again. Less satisfying than a bright green confirmation, but much less likely to invite a second action on top of a first one whose result is uncertain.


What the documentation proves

The documented interfaces make a particular kind of AI-assisted product possible: an answer can contain a component, a component can send an action, a host can route it, and a service may accept and perform it.

None of that verifies a particular screenshot or advertised feature. It does not prove a host has configured a tool, that an account is permitted to use it, that a deployment follows the spec securely, or that an external system's state changed. Those are facts about an exact implementation and operation, and they need their own evidence.

My product judgment is therefore about the promise made to the person looking at the button. If the control is local, say what local change it makes. If it submits a request, show the effect being requested and make the approval meaningful. If another service must authorize and complete it, don't promote the request or a tool's optimistic response into proof of completion.

The model can suggest an action. The component can make it convenient. The human can decide to ask for it. The receiving service still has to decide whether it is allowed and what happened.

A button in an AI answer can change state. Looking clickable doesn't tell us which state, or whether anything changed at all.


// End of transmission. Verify the actual effect. — ZYANE