Elicitation Forms FAQ
When should a form be a stored template instead of a dict?
When the same ask recurs across sessions. A template is the
dict plus slots and example_slots; cast it by name through
form_from_template or by passing template + slots to any
form-taking MCP tool, and the definition never transits the agent's
context. One-off asks stay dicts.
What are elicitation forms?
Structured, interactive turns the agent uses instead of
freeform prose: a multi-part question becomes one clickable form, a
recommendation arrives as weighable cards, a disagreement renders
side-by-side. Every form is one declarative artifact — a
FormSchema of FormQuestions built from plain data via
attune.elicitation.form_from_dict — rendered per surface and
validated the same way everywhere.
What constructs does the communication grammar have?
Four, all members of the one form model: intake (several
independent decisions as one multi-select-capable form),
decision (a recommended option with rationale and per-option
tradeoffs), pushback (the agent disagrees and offers a concrete
alternative), and progress (a done/in_flight/blocked report
whose blocked items are a picker). decision, pushback, and
progress are presentation-enriched single-selects — the answer is
always one option, validated by membership like any
single_select.
Which MCP tools expose this?
Four: elicitation_render_form (validate a form, return
batched AskUserQuestion payloads), elicitation_collect_response
(validate answers into {field_id: value}), elicitation_ask
(native MCP elicitation dialog, one call in-and-out), and
elicitation_render_widget (inline HTML for show_widget).
Which tool should I use on which surface?
Widget-capable clients (Cowork / claude.ai):
elicitation_render_widget — it renders all controls richly and is
the surface where the decision / pushback / progress framing
shows. Clients with native MCP elicitation: elicitation_ask
(returns {success: false, action: "unsupported"} if the client
can't elicit — it does not render on Claude Code today). Everywhere
else: elicitation_render_form + the real AskUserQuestion tool,
where constructs collapse to a recommendation-first single-select.
What field types are supported?
The v1 AskUserQuestion path takes four: text_input,
single_select, multi_select, boolean. The rich surfaces
(elicitation_ask, elicitation_render_widget) add textarea,
number (with minimum/maximum), date (YYYY-MM-DD), and the
construct types decision, pushback, progress.
What happens when the user's answers are malformed?
Validation is never skipped (R4).
elicitation_collect_response enforces required fields and option
membership; on failure it returns {success: false, problems}
naming exactly the offending fields, so you re-ask only those —
malformed input is never silently accepted.
How do widget answers get back to the agent?
The rendered form posts answers via sendPrompt as a
sentinel-marked JSON block (__elicitation_response__). Parse that
block and validate it with elicitation_collect_response. The
widget round-trip makes no Anthropic API call.
When should a construct fire?
The grammar defines the shape; the when lives in the
agent's Socratic rule and decision routine
(.claude/rules/attune/decision-routine.md). The short version:
build a form when two or more independent dimensions need settling
(batch them into ONE form, never N sequential turns), when there are
three or more alternatives or two with real tradeoffs, when you are
disagreeing with the user, or when the answer is a number, date, or
more than a phrase of text. A raw button-turn is right only for a
single low-stakes choice among a few options. And a form never blocks
a keyboard-only user: the terse reply vocabulary (y / go / 1)
answers any construct on any surface.
Why did a simple question render as a full form?
The widget is the default now. If you'd rather have buttons,
run attune config set keyboard_mode true — it persists for this
project. ATTUNE_KEYBOARD_MODE=1 overrides it for one shell.
Doesn't defaulting to the widget cost an extra round-trip?
Yes, and that is deliberate. Latency was the old routing axis and it made the agent quietly downgrade forms that communicated better; if a question is worth asking, it is worth asking legibly. Trivial one-off choices still go to buttons.
Do forms cost API credits?
No. Rendering and validation are pure local transforms — no model call on any surface.
Why didn't my rich form render?
The client isn't widget-capable; it fell back to the
AskUserQuestion menu. That's expected.
Is progress / decision / pushback a different answer shape?
No — each answer is one selected option, validated like a single-select.