Use this skill when a user starts a task in natural language and you need to decide whether more structured information is required.
If the task has enough information, proceed normally.
If information is missing, generate an external form page for the missing fields. The user opens the page, fills the form, clicks submit, copies the generated JSON, and pastes it back into the chat. Then parse the JSON and continue the task.
This skill does not require a native frontend card renderer in the agent platform.
Do not create a form for every task.
Create a form only when at least one of these is true:
Ask a normal chat question instead when only one small clarification is needed.
Default to copy-back mode:
Use backend mode only if the user or environment explicitly provides a submission endpoint/result API.
Use this logical schema:
{
"type": "external_form",
"schemaVersion": "2.0",
"interactionId": "form_task_001",
"title": "Form title",
"purpose": "Why the form is needed.",
"returnMode": "copy_back",
"fields": [],
"submitLabel": "Generate submission JSON"
}
Supported field kinds:
singlemultitexttextareaemailurlnumberdatedatetimefileEvery field must include:
kindidheaderlabelFor single and multi, every option must include:
labelvaluedescriptionReason over option value, not label.
Generate a stable unique interactionId for every form.
Examples:
form_expense_001form_project_intake_001form_deploy_config_001If this is a later step, include parentInteractionId and step.
When designing fields:
single or multi when the answer space is known.textarea for optional context.If local file creation is available, create a standalone HTML file using assets/form-template.html as the starting point.
Replace the placeholder:
__FORM_SCHEMA_JSON__
with the JSON form schema.
Save generated pages under an appropriate workspace/output directory, for example:
generated-forms/<interactionId>.html
Then give the user the local file path or hosted URL.
If file creation is not available, output the form schema and ask the host system to create a form page from it.
Use this pattern:
I need a few structured details before I can continue. I generated an external form for this step.
Form: <title>
interactionId: <interactionId>
Link: <path or URL>
Please open the form, fill it out, click submit, then paste the generated JSON back here.
Use the user's language where appropriate.
After sending this message, stop and wait for the next user message.
The form page should generate this JSON:
{
"type": "form_submission",
"source": "external_form_link",
"interactionId": "form_task_001",
"status": "submitted",
"values": {
"field_id": "value"
},
"notes": "",
"submittedAt": "2026-05-12T10:00:00.000Z"
}
Supported statuses:
submittedcancelledWhen the next user message arrives:
type is form_submission when present.interactionId matches the expected form.status.values as authoritative.notes as optional context.If the user pasted plain text instead of JSON, parse lines in this format:
field_id -> value
field_id → value
For multi, split values by English comma.
Validate lightly after receiving the submission:
single values match allowed option values.multi values all match allowed option values.email looks like an email.url starts with http:// or https:// unless otherwise allowed.number parses as a number and respects min/max when specified.date uses YYYY-MM-DD when possible.If validation fails, ask for only the missing or invalid fields. You may either:
In copy-back mode, file fields cannot upload raw files unless the page or platform supports uploads.
Use file fields for:
Do not assume you can read file content unless the runtime provides access.
User:
I want to submit an expense reimbursement.
The task needs structured details, so create a form schema:
{
"type": "external_form",
"schemaVersion": "2.0",
"interactionId": "form_expense_001",
"title": "Expense Reimbursement",
"purpose": "Collect reimbursement type, amount, purpose, and invoice status.",
"returnMode": "copy_back",
"fields": [
{
"kind": "single",
"id": "expense_type",
"header": "Type",
"label": "Select the reimbursement type",
"required": true,
"options": [
{
"label": "Travel",
"value": "travel",
"description": "Transportation, hotel, meals, and other travel costs"
},
{
"label": "Office",
"value": "office",
"description": "Office supplies, equipment, and consumables"
},
{
"label": "Entertainment",
"value": "entertainment",
"description": "Client hospitality or business meals"
},
{
"label": "Communication",
"value": "communication",
"description": "Phone, network, or communication costs"
},
{
"label": "Other",
"value": "other",
"description": "Other expense types"
}
]
},
{
"kind": "number",
"id": "amount",
"header": "Amount",
"label": "Enter the reimbursement amount",
"required": true,
"min": 0.01,
"step": 0.01
},
{
"kind": "text",
"id": "purpose",
"header": "Purpose",
"label": "Briefly describe the expense purpose",
"required": true,
"maxLength": 120
},
{
"kind": "single",
"id": "invoice_status",
"header": "Invoice",
"label": "Do you have an invoice?",
"required": true,
"options": [
{
"label": "Has invoice",
"value": "has_invoice",
"description": "A valid invoice is available"
},
{
"label": "No invoice",
"value": "no_invoice",
"description": "No invoice is currently available"
}
]
},
{
"kind": "textarea",
"id": "notes",
"header": "Notes",
"label": "Additional notes (optional)",
"required": false,
"maxLength": 500
}
],
"submitLabel": "Generate submission JSON"
}
Then generate the external HTML page and tell the user to paste the generated JSON back.
After receiving a valid submission:
If you cannot create or link an external form page, fall back to a chat-based structured form:
field_id -> value
Use the same fields and parsing rules.
共 1 个版本