Enable Workflow Agent Teams to Generate Widgets

In your workflow, the LLM and agent nodes can generate widgets. Initial graphics and insight displays are produced by agent output blocks that carry a patternId and a widget-specific config. In App Builder, the display prompt tells the runtime agent what widget output to generate.

Enable Workflow Agent Teams

To enable workflow agent teams to generate widgets, do these steps:

  1. Go to AI Agent Studio open the Agent Teams tab.
  2. Select Edit Edit Icon to modify the workflow.
  3. Go to the LLM or agent node that should generate widgets.
  4. Edit the node and open the App Experience tab.
  5. Select the options to enable widgets for actions and communications as needed.
  6. Select the types of widget that are to be generated by the workflow agent team.
  7. Add instructions for the widget.

Types of Widgets

Here are the types of widgets an LLM or agent node can generate:

Type of Widget Sample Prompt Details Example
Card Use a cardWidget to present one important update as a clean, scannable card. Include a short subject, an optional subtitle for context, a brief summary, and if helpful a status line or time stamp, so the update feels informative without being crowded.
  • Use it for: a single alert, update, or status card
  • Required: subject
  • Common fields: summary, timestamp, badgeText, variant
  • Actions: link and optional additionalLink, each with text and action
  • Variant values: error, warning, info, or omitted for neutral

Use commands such as ora.Invoke(...).

<oraInfoDisplay key="maintenance-card">
{
  "patternId": "cardWidget",
  "config": {
    "subject": "Maintenance Complete",
    "summary": "Scheduled database maintenance finished successfully.",
    "timestamp": "1 hour ago",
    "badgeText": "Info",
    "variant": "info",
    "link": {
      "text": "View Details",
      "action": "ora.Invoke(\"viewMaintenanceSummary\")"
    }
  }
}
</oraInfoDisplay>
Messages List

Use a messageListWidget to show a short list of recent messages, alerts, or notable events. Each item should have a clear title, optional supporting context like a subtitle or summary, and a time stamp when useful, so the list feels friendly, current, and easy to scan.

  • Use it for: alerts, activity feeds, and small collections of highlight items
  • Required: items[] with at least title per item
  • Item fields: subtitle, summary, status, badgeText, priority, timestamp, image
  • Interactivity: item action and item additionalAction with text + command

Runtime behavior is considered. additionalAction is only shown when the widget is in a focused panel. Also, the runtime supports success as a priority in addition to alert, warning, and medium.

<oraInfoDisplay key="system-alerts">
{
  "patternId": "messageListWidget",
  "config": {
    "subtitle": "Real-time metrics",
    "items": [
      {
        "title": "Memory Usage Spike Detected",
        "subtitle": "82% confidence",
        "summary": "Memory consumption increased by 40% in the last 5 minutes",
        "status": "Investigating root cause",
        "badgeText": "Medium",
        "priority": "medium",
        "timestamp": "3 min ago",
        "action": "ora.Invoke(\"openMemoryIncident\", { \"metric\": \"memory\" })",
        "additionalAction": {
          "text": "View Metrics",
          "command": "ora.Invoke(\"viewMetrics\", { \"metric\": \"memory\" })"
        }
      },
      {
        "title": "Network Latency Increase",
        "summary": "Average response time increased from 120ms to 180ms.",
        "status": "Under investigation",
        "badgeText": "Warning",
        "priority": "warning",
        "timestamp": "16 min ago"
      }
    ]
  }
}
</oraInfoDisplay>
Change List Use a changeListWidget to compare a few key metrics between a previous value and a current value. Add a short subtitle to explain what’s being measured, keep the rows easy to read, and only include a message if there’s a meaningful insight or anomaly worth calling out.
  • Use it for: current-versus-previous metric comparisons
  • Required: displayType, items
  • displayType: percentage, raw, or currency
  • items[]: title, currentValue, previousValue
  • Optional: subtitle, messages

Values should stay numeric. Formatting comes from displayType, not from embedding percent signs or currency symbols inside the numbers.

<oraInfoDisplay key="campaign-change-list">
{
  "patternId": "changeListWidget",
  "config": {
    "subtitle": "Campaign performance comparison",
    "displayType": "percentage",
    "items": [
      { "title": "Email Open Rate", "currentValue": 28.2, "previousValue": 24.5 },
      { "title": "Click-through Rate", "currentValue": 4.6, "previousValue": 3.8 },
      { "title": "Conversion Rate", "currentValue": 1.9, "previousValue": 2.1 }
    ],
    "messages": [
      "Conversion rate drop may indicate landing page issues"
    ]
  }
}
</oraInfoDisplay>
Chart Use a chartWidget to visualize a simple trend, comparison, or proportion in a way that's easy to understand at a glance. Choose the chart type that fits the story, use clear labels, and include one or two short insights underneath to help explain what the chart is showing.
  • Use it for: trends, comparisons, or proportions
  • Required: type, data
  • type: line, bar, or pie
  • data.labels[]: x-axis labels or categories
  • data.datasets[]: each dataset needs label and numeric data[]
  • Optional: insights[]
<oraInfoDisplay key="sales-trend-chart">
{
  "patternId": "chartWidget",
  "config": {
    "type": "line",
    "data": {
      "labels": ["January", "February", "March", "April", "May"],
      "datasets": [
        {
          "label": "Sales Revenue",
          "data": [10000, 25000, 15000, 40000, 30000]
        }
      ]
    },
    "insights": [
      "Revenue peaked in April",
      "Steady growth trend overall"
    ]
  }
}
</oraInfoDisplay>
Record Use a recordWidget to show a structured record as a simple form that can either be reviewed or edited. Include clearly labeled fields, choose field types that match the data, and keep the layout straightforward so it feels comfortable for someone filling in or checking details.
  • Use it for: forms and read-only detail views
  • Required: id, fields[]
  • Optional: readOnly
  • Field types: text, textarea, number, date, select, system
  • Field fields: id, type, value, plus label and options when applicable

In editable mode, the runtime automatically submits the form through an ora.Agent(<oraFormSubmit ...>) command. You don't configure a separate submit command in the widget itself.

<oraInfoDisplay key="employee-form">
{
  "patternId": "recordWidget",
  "config": {
    "id": "employee_form",
    "readOnly": false,
    "fields": [
      {
        "id": "full_name",
        "type": "text",
        "label": "Full Name",
        "value": "John Doe"
      },
      {
        "id": "employee_id",
        "type": "number",
        "label": "Employee ID",
        "value": 12345
      },
      {
        "id": "department",
        "type": "select",
        "label": "Department",
        "value": "engineering",
        "options": [
          { "value": "engineering", "label": "Engineering" },
          { "value": "sales", "label": "Sales" }
        ]
      },
      {
        "id": "session_context",
        "type": "system",
        "value": { "conversation_id": "abc123" }
      }
    ]
  }
}
</oraInfoDisplay>
Multi Record Use a multiRecordWidget to present structured information in a compact table with clear columns and rows. Keep the values short and scannable, use badge-style cells for statuses when helpful, and only add row actions if the experience should explicitly support taking action from the table.
  • Use it for: tabular record lists
  • Required: cols[] and rows[]
  • Column forms: plain string, or object with label and optional showOnExpand
  • Row cells: plain string, or badge object with type, text, and priority
  • Optional row actions: action button and drillDownAction on the first column
  • Optional: subtitle for table context and accessibility

The showOnExpand columns only appear when the widget is focused. This is useful for secondary columns that should stay hidden in compact mode.

<oraInfoDisplay key="pending-approvals-table">
{
  "patternId": "multiRecordWidget",
  "config": {
    "subtitle": "Pending approvals",
    "cols": ["Request ID", "Type", "Status"],
    "rows": [
      {
        "cells": [
          "REQ-101",
          "Budget",
          { "type": "badge", "text": "PENDING", "priority": "warning" }
        ],
        "action": {
          "text": "Review",
          "command": "ora.Invoke(\"reviewRequest\", { \"id\": \"REQ-101\" })"
        },
        "drillDownAction": "ora.Invoke(\"openRequest\", { \"id\": \"REQ-101\" })"
      },
      {
        "cells": [
          "REQ-102",
          "Travel",
          { "type": "badge", "text": "PENDING", "priority": "warning" }
        ],
        "action": {
          "text": "Review",
          "command": "ora.Invoke(\"reviewRequest\", { \"id\": \"REQ-102\" })"
        }
      }
    ]
  }
}
</oraInfoDisplay>
Sankey Use a sankeyWidget to show how volume or activity flows from one stage to another across a process. Define clear node names, keep the flow easy to follow from left to right, and use realistic values so the visualization tells a simple story about where things are going.
  • Use it for: flows between stages or states
  • Required: nodes[], edges[]
  • nodes[]: id, name
  • edges[]: source, target, value

Node IDs are numeric and edges point to those IDs. Keep values positive and keep the flow easy to follow.

<oraInfoDisplay key="support-flow-sankey">
{
  "patternId": "sankeyWidget",
  "config": {
    "nodes": [
      { "id": 0, "name": "Web Visitor" },
      { "id": 1, "name": "Web Chat" },
      { "id": 2, "name": "AI Chat Bot" },
      { "id": 3, "name": "Resolved by Bot" },
      { "id": 4, "name": "Transfer to Human" },
      { "id": 5, "name": "Resolved by Human" }
    ],
    "edges": [
      { "source": 0, "target": 1, "value": 1000 },
      { "source": 1, "target": 2, "value": 1000 },
      { "source": 2, "target": 3, "value": 700 },
      { "source": 2, "target": 4, "value": 300 },
      { "source": 4, "target": 5, "value": 300 }
    ]
  }
}
</oraInfoDisplay>

Interactive widgets

For interactive widgets, use ora.Invoke("actionCode", payload), which represents the app-defined action path.