Skip to main content
Develop your tool response to return the following types of widgets:
  • Form widgets
    Interactive forms with various input field types including text inputs, text areas, number inputs, date pickers, date range pickers, radio buttons, checkboxes, combo boxes, file uploads, and tables for structured data collection.
    For interactive forms, you can handle data from form submission with the on_event callback. This is how you capture and process user input from form submissions.
  • Custom widgets (user_defined)
    Custom UI components with flexible rendering. This option is supported in embedded chat only.

Forms with interactive widgets

Form widgets provide structured input forms with various field types. You can create forms using either the FormWidget class or the dictionary format with the _meta field.

Widget contract with FormWidget class

The FormWidget class provides a Python-based approach to creating form widgets when using the ToolResult return format.
Import
Import the FormWidget class and input components to create forms in your Python tools:
Constructor parameters
title
str
required
The form title displayed to users.The following example sets the form title that appears at the top of the form:
inputs
List[InputWidget]
required
List of input widgets that define the form fields. Supported input types include:
  • TextInput
  • TextArea
  • NumberInput
  • DatePicker
  • DateRangePicker
  • RadioButton
  • Checkbox
The following example defines a list of input widgets for the form, including a required email field and an optional comments field:
For more details on each input widget, see Additional features of Python tools: Creating a form tool.
description
str
Optional description text displayed below the form title.The following example adds a description that appears below the form title to provide additional context:
submit_text
str
Custom text for the submit button. Defaults to “Submit”.The following example customizes the submit button text:
cancel_text
str
Custom text for the cancel button. Defaults to “Cancel”.The following example customizes the cancel button text:
on_event
List[Union[ToolEvent, MessageEvent]]
List of event handlers that define actions when the form is submitted. For more information, see Handling data from form submission.These examples show how to configure event handlers for form submission using either ToolEvent or MessageEvent:

Widget contract with dictionary format

When using the dictionary return format, widget contracts are defined in the _meta["com.ibm.orchestrate/widget"] field.
_meta
Dict[str, Any]
Additional metadata for custom extensions or context. Widget contracts in _meta["com.ibm.orchestrate/widget"] require the following fields:The following example shows the basic structure of a tool response with a form widget using the dictionary format:
JSON Schema details
The json_schema field defines the structure, validation rules, and metadata for form fields. Implement the following properties to determine what data the form collects and how it must be validated:
properties definition
Each field in the properties object can include:The following example demonstrates a complete JSON Schema for a user registration form with required fields, validation rules, and data types:
UI schema details
The ui_schema field specifies how form renders widget type and appearance for each field. You can define the following properties:The ui_schema and json_schema work together to define form fields. They reference the same field names as keys:
  • JSON schema (json_schema.properties.fieldName) defines the data structure, type, validation rules, and metadata for a field.
  • UI schema (ui_schema.fieldName) specifies how that same field must be rendered as a widget.
For example, if you define a field called "firstName" in your JSON Schema properties, you must use the same key "firstName" in your UI Schema to specify its widget type. The field name acts as the connection point between the two schemas.The following example shows how the same field name ("firstName") is used consistently across all three schema objects:
All three objects (json_schema.properties, ui_schema, and form_data) use the same field name as the key to reference the same form field.
Form data details
The form_data field provides pre-populated default values for form fields. These values appear in the form when it’s first displayed to the user, providing sensible defaults to guide users and pre-populating fields with known user data when available. Consider the following implementation details for form data:
  • Field names in form_data must match the field names defined in json_schema.properties.
  • Values must match the data type specified in the JSON schema.
  • Optional fields can be omitted or set to empty values. Use empty strings ("") for optional text fields.
  • For array fields such as date ranges or tables, provide an array of values.
  • For date fields, use ISO 8601 format (YYYY-MM-DD).
  • For selection widgets, ensure default values match one of the enum options.
  • For file upload fields, provide an object with fileName and url properties.
The following example demonstrates pre-populated form data with various field types including text, numbers, dates, and file uploads:

Handling data from form submission

The on_event defines actions triggered when users interact with the form. This is how you capture and process user input from form submissions:

on_event parameters

type
string
required
The action type to perform. Implement the code based on the format:
  • If you use the dictionary format, set the type value to either "tool" or "message".
  • If you use the FormWidget() class, you must call either ToolEvent() or MessageEvent() to perform the action.
tool
string
The name of the tool to invoke. Required when type is "tool".
parameters
object
Key-value pairs mapping form field names to their values. Required when type is "tool". Values are populated automatically from form data.
map_input_to
string
required
The event trigger. Use "submit" to trigger the action when the form is submitted.
message
string
The message to send to the agent. Required when type is "message".

Tool call

The ToolEvent() or type: "tool" actions invoke another tool with form data as parameters when the form is submitted. This is the most common approach for processing form submissions. You can use this approach when you need to process form data with custom logic, validate inputs, make API calls, or perform complex operations. The tool specified must accept parameters matching the form field names. When the user submits the form, this tool is automatically called with the form data.

Using ToolEvent() with FormWidget

When using the FormWidget class, configure on_event by using the ToolEvent class.
ToolEvent class
The ToolEvent class defines a tool invocation event that triggers when a form is submitted. Use this class with FormWidget to process form data through another tool.
Import
Import the ToolEvent class to define tool invocation events:
Constructor parameters
tool
str
required
The name of the tool to invoke when the event is triggered. This tool must be defined in your agent and accept parameters matching the form field names.The following example specifies the tool to invoke when the form is submitted:
parameters
Dict[str, str]
required
Dictionary mapping form field names to their parameter names in the target tool. Keys must match the name attributes of form inputs. Values are typically empty strings that get populated with form data on submission.The following example maps form field names to tool parameters that will be populated with form data:
map_input_to
str
required
The event trigger type. Use "submit" to trigger the action when the form is submitted.The following example sets the event trigger to activate when the form is submitted:
The following example shows how to create a ToolEvent instance for processing form submissions:
This complete example demonstrates a contact form with ToolEvent handling:

Using type: "tool" with dictionary format

When using the dictionary return format, configure on_event within the _meta field: The following example shows the basic structure of a tool event configuration in dictionary format:
This complete example demonstrates a two-tool workflow where the first tool displays a registration form and the second tool processes the submitted data:

Message call

The MessageEvent() or type: "message" actions send a predefined message to the agent instead of calling a tool. The agent processes this message as if the user had typed it. You can use this approach when you want to trigger a conversational flow or simple acknowledgment without custom processing logic.

Using MessageEvent() with FormWidget

The MessageEvent class defines a message event that sends a predefined message to the agent when a form is submitted. Use this class with FormWidget to trigger conversational flows without custom processing logic.
Import
Import the MessageEvent class to define message events:
Constructor parameters
message
str
required
The message to send to the agent when the event is triggered. The agent processes this message as if the user had typed it.The following example defines the message that will be sent to the agent when the form is submitted:
map_input_to
str
required
The event trigger type. Use "submit" to trigger the action when the form is submitted.The following example sets the event trigger to activate when the form is submitted:
Example
The following example demonstrates a survey form using MessageEvent to send a thank you message upon submission:

Using type: "message" with dictionary format

When using the dictionary return format, configure on_event within the _meta field: The following example shows the basic structure of a message event configuration in dictionary format:
The following example demonstrates a feedback form that sends a message to the agent upon submission:

Custom widgets with user_defined

Create flexible UI components with custom widgets by rendering your own rich element logic. These widgets are passed through the _meta parameter and are rendered in embedded chat by using the userDefinedResponse event. Custom widgets in tool responses is a custom solution that operates independently of standardized UI protocols such as MCP-UI or A2UI. Application builders are responsible for implementing the rendering logic and managing security considerations.
The user_defined response type from tools is supported only in embedded chat. The webpage builder is responsible for implementing the rendering logic.
The following example demonstrates how to create a custom widget with user-defined response type and structured data:
Custom widget structure
When creating custom widgets, you must structure the metadata in a specific nested format that the chat can recognize and process. Place the widget data within the _meta parameter of your tool response by using the standardized namespace key to ensure proper routing to the userDefinedResponse event handler. The following example shows the required structure for custom widget metadata with detailed annotations:
Where:
  • Container structure: Nest all custom properties inside the user_defined object. This object acts as a container that isolates your custom data from the standard response structure.
  • Widget identification: Use the required user_defined_type field to identify your widget type. Your rendering logic uses this field to determine how to display the widget.
  • Flexible properties: Beyond the required user_defined_type, include any custom properties your widget needs, such as title, text, data, config, or domain-specific fields. The structure adapts to your requirements.
  • Multiple widget types: This flexible structure accommodates various widget types, from simple cards and notifications to complex dashboards and interactive components. Implement and test the rendering logic for each widget type to ensure proper display.
Rendering custom widgets
The webpage builder must implement the rendering logic for custom widgets in embedded chat. For complete implementation details, examples, and event handling, see the userDefinedResponse event documentation.