58 lines
2.7 KiB
Markdown
58 lines
2.7 KiB
Markdown
# Authoring web forms (CustomInputForm)
|
|
|
|
Flows that should render a web form start with a `CustomInputForm` node
|
|
(this package — the `kirche` category in the Langflow palette). The API
|
|
derives a JSON Schema + uiSchema from the node's template
|
|
(`app/flows/input_schema.py`) and the webapp renders it with RJSF.
|
|
|
|
## Adding a new form field
|
|
|
|
1. Open the Langflow authoring UI (http://localhost:7860) and load the
|
|
flow from `LANGFLOW_LOAD_FLOWS_PATH` (canonical files are preloaded).
|
|
2. Edit the `CustomInputForm` node: every entry in its `inputs` list is
|
|
one web-form field. Add an `lfx.io` input, e.g.
|
|
```python
|
|
from lfx.io import DropdownInput
|
|
|
|
DropdownInput(
|
|
name="room", # JSON-Schema property key
|
|
display_name="Room", # form label (title)
|
|
info="Where should it take place", # help text (description)
|
|
options=["Chapel", "Hall"], # dropdown choices (enum)
|
|
value="Chapel", # prefill (default)
|
|
required=True, # marks the field required
|
|
)
|
|
```
|
|
Supported input types → widgets: `StrInput`/`MessageTextInput` → text,
|
|
`MultilineInput` → textarea, `SecretStrInput` → password,
|
|
`IntInput` → integer, `FloatInput` → number, `BoolInput` → checkbox,
|
|
`DropdownInput` → select, `MultiselectInput` → multi-select,
|
|
`SliderInput` → slider (needs `range_spec`), `FileInput` → text stub
|
|
(real upload later).
|
|
3. Add the new field to `collect()` so it reaches the JSON output.
|
|
4. **Wire the envelope**: keep the `ChatInput → form_values` edge (hidden
|
|
input, `show=False`). Submitted web-form values arrive there as
|
|
`{"payload": {...}}` and are merged over the defaults. Never make form
|
|
fields required *with* an incoming edge — that's the envelope's job.
|
|
5. Export the flow (JSON) into `backend/flows/<name>.json` and commit.
|
|
The API watcher syncs + deploys it automatically; the form schema is
|
|
regenerated per version.
|
|
|
|
## Conventions the pipeline relies on
|
|
|
|
- `required=True` on a template field: `lfx validate --level 4` demands a
|
|
value or an edge, so the canonical-flow generator
|
|
(`backend/scripts/make_flow_fixtures.py`) writes a single-space
|
|
sentinel value for such fields. The form parser treats whitespace-only
|
|
values as "no default" — don't ship real whitespace defaults.
|
|
- Field key = `name` (stable); label = `display_name`; help = `info`.
|
|
- Unknown future input types degrade to a plain text field in the web
|
|
form (parser fallback), so adding exotic lfx inputs never breaks runs.
|
|
|
|
## Regenerating the bundled fixtures
|
|
|
|
After editing the component source (`form_inputs.py`), refresh the
|
|
canonical + test-fixture exports:
|
|
|
|
docker compose exec api /opt/venv/bin/python scripts/make_flow_fixtures.py
|
|
docker compose exec -T api uv run pytest tests/test_lfx_validate.py
|