Skip to main content

Kinds

prompt — proposes a message the user reviews and sends from their composer (works with any key); http — a server-side GET/POST to a fixed https URL with an input schema (GET → query, POST → JSON body) and an output schema the response must satisfy; headers/query values may reference the user’s secrets by name ({ “secret”: “<name>” }).

Binding from a template

  • ACTION — an element may carry “action”: { “ref”: “<shared action name>” } or an inline { “definition”: { “kind”: “prompt”, “text”: [“Show the forecast for ”, { “bind”: “city” }] } } / { “definition”: { “kind”: “http”, “method”: “GET”, “url”: “https://…”, “input”: <schema>, “output”: <schema> } }, plus “input”: { “<field>”: “<path>” | { “const”: <value> } } and “output”: { “mode”?: “replace”|“merge”|“patch”, “path”?, “map”? }. An output map projects the response before the mode applies; when the response is an ARRAY the map entries resolve against EACH ITEM and the projection is the array of per-item results, so a list response can be reshaped without replacing it raw — a per-item projection is a LIST, so pair it with mode replace or patch (merge needs an object). A ”.” target SELECTS first: alone it is the whole projection (e.g. { ”.”: “0” }); beside other entries it names the value they map, so an enveloped list projects per item ({ ”.”: “data”, “ask”: “ask” }). Any source that starts with an index (“0.ask”) addresses the list itself, not its items. Bindings resolve at render time; buttons and links (never both href and action) become activatable in Apps hosts. A widget-level “load” (http GET only) runs once when the widget first renders
Put “action”: { “ref”: “<shared action name>” } or { “definition”: <inline definition> } on a button or link (never together with href), plus “input”: { “<field>”: “<data path>” | { “const”: <value> } } resolved at render time in the element’s scope ($root/$parent/$index available) and “output”: { “mode”: “merge”|“replace”|“patch”, “path”?, “map”? } whose map projects per ITEM when the response is an array. Arguments must be declared in the action’s input schema and must not share a name with a fixed query parameter. Discover the user’s saved actions with list_actions and prefer a ref to an inline definition — when nothing listed fits, DESCRIBE the action for the user to create instead of inventing one (the why and the hand-off: see sharedAction.workflow). A widget-level “load” accepts http GET only.

Execution

http actions run only in Apps hosts that proxy widget tool calls AND under an API key carrying the ‘execute’ scope (opt-in when the key is created). A render for a read-only key marks them disabled: “scope” (the key lacks execute), “unresolved” (a referenced shared action does not exist). The frame calls execute_action itself; agents never do. After each http action the widget posts its new payload to the model’s context.

Request limits

http targets must be public https hosts (no private/loopback/link-local, no redirects); the whole request has an 8 s deadline and a 256 KiB response cap; the response must be application/json (or application/*+json); a 204/empty body arrives as null. Design the output schema for exactly that response.

Secrets

Secrets are named, write-only, envelope-encrypted, and injected server-side at execution; they never appear in templates, results or logs.

Vocabulary