Why pre-fill matters
The fastest UX is one where the user confirms instead of types. Every field your backend already knows (name, email, account tier, last order date) should arrive in the form pre-populated.| Method | When the value is set | Source of truth |
|---|---|---|
1. default_value on the field | At render time, before the agent does anything | Hardcoded in form definition |
2. Session metadata + system prompt | Agent fills from metadata when opening form | Your database, passed at session start |
| 3. Agent tool arguments | Agent fills from conversation context | What the user said + metadata |
| 4. Direct data-channel publish | Your code publishes a form.{id} message with values | Your app at any point |
default_value for static stuff, metadata for known user info, tool args for conversation-derived values, direct publish for custom flows.
Method 1 — default_value on the field
Set it on the form definition itself. The widget pre-fills before the agent does anything.
Method 2 — Session metadata + system prompt
Pass user context at session start, and instruct the agent to use it.
Step 1 — Pass metadata when minting the token
Step 2 — Reference it in the system prompt
Result
When the agent opensbook-demo, it calls:
Method 3 — Agent tool arguments (conversation-derived)
Even without metadata, the agent extracts values from the conversation and passes them to the form tool:User: “Hi, I’m Bob from Widgets Co — I’d love to see a demo.” Agent → opensThis works for any field — the LLM matches user-mentioned values to field names. No code changes needed; just keep fieldbook-demowith{ "name": "Bob", "company": "Widgets Co" }
names sensible (first_name, email, company, phone) so the LLM picks the right one.
Make it more reliable
Add explicit instructions in the system prompt:Method 4 — Direct publish from your app
If you have application state the agent doesn’t know about, publish aform.{id} message yourself. The widget treats it exactly like a message from the agent.
order_id and email. The agent will see the resulting form.state and continue verbally from there.
When to prefer Method 4 over 2/3
- You have data the agent doesn’t (a current cart, a row the user clicked on)
- You want the form to open at a specific UI moment (button click), not when the LLM decides
- You’re building a hybrid UI where forms aren’t always tied to the conversation
Pre-filling a multi-step form
Pre-fill values are matched by fieldname across all steps — you can fill fields on step 3 in the initial open call, and the user will see them populated when they reach that step:
Putting it all together — recommended setup
Verifying pre-fill is working
Watch the data channel during development:form.{id}from the agent with pre-fill valuesform.statefrom the widget reflecting those values + any user typing
