Inference Logoinference.sh

Widget Actions

Trigger actions on the backend from user interactions in your widgets.

Actions are a way for the widget SDK frontend to trigger responses without the user submitting a message. They can also be used to trigger side-effects outside the chat interface.

Triggering Actions

From Widget Buttons

Actions can be triggered by attaching a WidgetAction to buttons in the widget's action bar:

go
1widget := &models.Widget{2    Type:  models.WidgetTypeUI,3    Title: "Confirm Action",4    Children: []models.WidgetNode{5        {Type: models.WidgetNodeTypeText, Value: "Are you sure you want to proceed?"},6    },7    Actions: []models.WidgetActionButton{8        {9            Label:   "Cancel",10            Variant: "outline",11            Action: models.WidgetAction{12                Type: "cancel",13            },14        },15        {16            Label:   "Confirm",17            Variant: "default",18            Action: models.WidgetAction{19                Type:    "confirm",20                Payload: map[string]interface{}{"item_id": "123"},21            },22        },23    },24}

From Inline Buttons

Actions can also be triggered from buttons within the widget content:

go
1children := []models.WidgetNode{2    {3        Type:    models.WidgetNodeTypeButton,4        Label:   "Click Me",5        Variant: "secondary",6        Action: &models.WidgetAction{7            Type:    "button_clicked",8            Payload: map[string]interface{}{"source": "inline"},9        },10    },11}

Handling Actions

Frontend

Capture widget events with the onAction callback in your widget renderer:

typescript
1<WidgetRenderer2  widget={widget}3  onAction={async (action, formData) => {4    await fetch('/api/widget-action', {5      method: 'POST',6      headers: { 'Content-Type': 'application/json' },7      body: JSON.stringify({ action, formData }),8    });9  }}10/>

Backend

Handle widget actions in your agent:

go
1func (e *Executor) HandleWidgetAction(ctx context.Context, action models.WidgetAction, formData map[string]interface{}) error {2    switch action.Type {3    case "confirm":4        itemID := action.Payload["item_id"].(string)5        return e.confirmItem(ctx, itemID)6    case "cancel":7        return e.cancelAction(ctx)8    default:9        return fmt.Errorf("unknown action type: %s", action.Type)10    }11}

Action Types

Built-in Actions

TypeDescription
confirmUser confirmed the action
cancelUser cancelled the action
submitForm submission

Custom Actions

You can define any custom action type:

go
1Action: models.WidgetAction{2    Type: "my_custom_action",3    Payload: map[string]interface{}{4        "custom_field": "value",5        "nested": map[string]interface{}{6            "data": 123,7        },8    },9}

Form Data

When a widget contains form inputs (input, select, checkbox), the form data is collected and passed to the action handler:

go
1widget := &models.Widget{2    Type:        models.WidgetTypeUI,3    Interactive: true,4    Children: []models.WidgetNode{5        {Type: models.WidgetNodeTypeInput, Name: "email", Placeholder: "Enter email"},6        {Type: models.WidgetNodeTypeSelect, Name: "role", Options: []models.WidgetSelectOption{7            {Label: "Admin", Value: "admin"},8            {Label: "User", Value: "user"},9        }},10    },11    Actions: []models.WidgetActionButton{12        {13            Label: "Submit",14            Action: models.WidgetAction{Type: "submit"},15        },16    },17}

When submitted, formData will contain:

json
1{2  "email": "[email protected]",3  "role": "admin"4}

Best Practices

1. Use Descriptive Action Types

go
1// Good2Action: models.WidgetAction{Type: "approve_request"}3 4// Avoid5Action: models.WidgetAction{Type: "action1"}

2. Include Necessary Context in Payload

go
1Action: models.WidgetAction{2    Type: "approve_request",3    Payload: map[string]interface{}{4        "request_id": request.ID,5        "approval_level": "manager",6    },7}

3. Validate Action Data

Always validate action payloads and form data on the backend:

go
1func (e *Executor) HandleAction(action models.WidgetAction, formData map[string]interface{}) error {2    // Validate required fields3    requestID, ok := action.Payload["request_id"].(string)4    if !ok || requestID == "" {5        return fmt.Errorf("request_id is required")6    }7    8    // ... handle action9}

we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.