FormInput generates a validated form from a Pydantic model. The user fills it out, and the submission is validated against the model before being returned. Structured elicitation that can’t be hallucinated.

| Tool | Visibility | Purpose |
|---|---|---|
collect_bugreport | Model | Opens the form UI |
submit_form | App only | Validates and processes the submission |
collect_{modelname}. So BugReport becomes collect_bugreport, ShippingAddress becomes collect_shippingaddress. Use tool_name to override if needed. The LLM calls it with a prompt explaining what it needs, and the user gets a form with fields matching the model.
Field Mapping
FormInput uses Prefab’s Form.from_model(), which maps Pydantic types to form components:
| Python type | Form component |
|---|---|
str | Text input |
int, float | Number input |
bool | Checkbox |
datetime.date | Date picker |
Literal[...] | Select dropdown |
SecretStr | Password input |
Field() metadata to control labels (title), placeholders (description), and validation (min_length, max_length, ge, le). Use json_schema_extra={"ui": {"type": "textarea"}} for multiline text.
Callback
By default, the validated model is returned as JSON. Provide anon_submit callback to process the data server-side:
Configuration
send_message=True to push the result back into the conversation via SendMessage, triggering the LLM’s next turn. Without it, the result is just the tool return value.

