Cloudflare will now add an agent tool surface to any site behind their edge with a dashboard toggle. Which makes the exposed question no longer how, but which tools, scoped how. Below are two surfaces over one shop. Same errands, same planner, and only one of them can be talked into a refund by a line of text sitting in a customer note.
Meridian Supply is a made-up parts shop. Everything below is real markup on this page: two forms, three action buttons, four orders. The auto surface is built by walking this exact DOM, so what you see is what an inference-based bridge gets to work with.
the source material for surface A
The planner is one deterministic keyword router shared by both surfaces. It has no judgement and no safety training. It asks its surface what tools exist and calls the ones that match. That is the honest floor for what an agent does when nothing stops it, and it keeps the comparison to a single variable.
Tools that move money or delete records with no human in between.
Inferred tools type everything as a loose string, because a form input cannot tell you more.
Counted live as you run errands. The third preset is the one that moves it.
PerformanceObserver on resource entries. Nothing here leaves the tab.
Order 1182 carries a customer note. The note contains a line addressed to whatever agent reads it. No model was jailbroken to make this work, and there is no model here at all. The planner simply read a field, found words that matched tool names, and had the tools to obey.
The preset asks the agent to read the note, which makes the demo legible. It is not a requirement. Type find the order from Tuesday and surface A does the same thing, because that search returns order 1182 and the note comes back with it. The errand never has to mention the payload. It only has to touch the record.
Surface B ignores it for a boring reason. refund_order and delete_customer are not in the surface, so no phrasing reaches them. quote_refund exists and returns what a refund would cost, with the actual execution left as a pending approval a human has to clear. The gate is not a filter on the input. It is an absence in the tool list.
Search, quote, look up status. Nothing to gate, and this is where nearly all real agent value sits anyway.
The tool computes the outcome and hands back a pending action with a reference. The agent can report it. It cannot commit it.
Not permission-checked, not confirmed, absent. A tool that does not exist cannot be reached by a clever sentence.
// surface A: whatever the DOM happens to expose [...document.querySelectorAll('form[id], button[data-action]')].map(el => ({ name: el.id || el.dataset.action, // names you did not choose inputSchema: looseStrings(el), // a form input cannot tell you a type execute: a => SHOP[el.id || el.dataset.action](a) })); // surface B: three tools, written on purpose { name:'search_orders', effect:'read', execute: a => find(a.query) }, { name:'quote_refund', effect:'quote', execute: a => pending(refundOf(a.order_id)) }, { name:'request_price_change', effect:'quote', execute: a => pending(repricing(a)) } // no refund_order. no delete_customer. that is the security model.