Interact with dashboard
Receive the list of widgets on the current dashboard (secondary
) and any explicitly selected (primary
). Summarize what’s available and fetch data for a chosen widget.
Reference implementation in this GitHub repository.
Example that highlights that the agent has access to data on the dashboard (secondary) and that there are no tabs.

Example that highlights that the agent still has access to data on the dashboard (secondary) but also has explicit context (primary) as a multi-file viewer widget.

Example that highlights that the agent has access to data that lives on the dashboard (and on all the tabs!).

Architecture
Receive dashboard metadata and selected widgets, summarize what's available, and fetch a sample widget's data.
agents.json
configuration with widget-dashboard-select
enabled so it accepts explicit context and widget-dashboard-search
so it can retrieve widgets from the dashboard.
return JSONResponse(content={
"vanilla_agent_dashboard_widgets": {
"endpoints": {"query": "http://localhost:7777/v1/query"},
"features": {
"widget-dashboard-select": True,
"widget-dashboard-search": True,
},
}
})
Query flow
- Access both
widgets.primary
(user-selected) andwidgets.secondary
(dashboard) widget collections - Combine widget lists for comprehensive dashboard overview
- Check
workspace_state.current_dashboard_info
for tab information - Stream formatted widget inventory with
message_chunk()
:- Widget names, types, and parameter configurations
- Tab organization if present
- Data availability status
- Demonstrate data retrieval by fetching sample widget with
get_widget_data()
- Process returned data and show preview with metadata
OpenBB AI SDK
WidgetCollection
: Containsprimary
,secondary
, andextra
widget groupsWidget
: Individual widget withuuid
,name
,type
, andparams
WidgetParam
: Parameter definition withname
,type
,current_value
get_widget_data(widget_requests)
: Fetches data from specified widgetsWorkspaceState
: Provides dashboard context and tab informationmessage_chunk(text)
: Streams widget summaries and data previews
Core logic
Unify primary and secondary widgets, render a summary, then fetch data for one widget:
from openbb_ai import get_widget_data, WidgetRequest, message_chunk
from openbb_ai.models import QueryRequest
async def query(request: QueryRequest) -> EventSourceResponse:
async def execution_loop():
# Combine all available widgets
all_widgets = []
primary_count = 0
secondary_count = 0
if request.widgets:
if request.widgets.primary:
all_widgets.extend(request.widgets.primary)
primary_count = len(request.widgets.primary)
if request.widgets.secondary:
all_widgets.extend(request.widgets.secondary)
secondary_count = len(request.widgets.secondary)
if not all_widgets:
yield message_chunk("No widgets found on your dashboard.").model_dump()
return
# Stream dashboard overview
dashboard_info = ""
if request.workspace_state and request.workspace_state.current_dashboard_info:
dashboard_name = request.workspace_state.current_dashboard_info.name
tab_count = len(request.workspace_state.current_dashboard_info.tabs)
dashboard_info = f"Dashboard: **{dashboard_name}** ({tab_count} tabs)\n\n"
widget_summary = f"""# Dashboard Widget Analysis
{dashboard_info}## Widget Inventory
- **Selected widgets (primary)**: {primary_count}
- **Dashboard widgets (secondary)**: {secondary_count}
- **Total available**: {len(all_widgets)}
## Available Widgets
"""
for i, widget in enumerate(all_widgets[:5]): # Show first 5
widget_type = "🎯 Selected" if i < primary_count else "📊 Dashboard"
param_count = len(widget.params) if widget.params else 0
widget_summary += f"- **{widget.name}** ({widget_type}) - {param_count} parameters\n"
if len(all_widgets) > 5:
widget_summary += f"- ... and {len(all_widgets) - 5} more widgets\n"
yield message_chunk(widget_summary + "\n").model_dump()
# Demonstrate data retrieval with last widget
if all_widgets:
sample_widget = all_widgets[-1]
yield message_chunk(f"Let me fetch data from **{sample_widget.name}** as an example:\n\n").model_dump()
yield get_widget_data([
WidgetRequest(
widget=sample_widget,
input_arguments={p.name: p.current_value for p in sample_widget.params} if sample_widget.params else {}
)
]).model_dump()
return EventSourceResponse(execution_loop(), media_type="text/event-stream")