Skip to main content

Omni

The Omni widget is a versatile widget type that can dynamically return different content formats (markdown, tables, or charts). Unlike other widgets that use GET requests, the Omni widget uses POST requests and passes all parameters in the request body. This widget requires the prompt parameter to be passed in the params section of the widget configuration.

Key Features

  • Dynamic Output Control: Can return different content types (text, table, chart)
  • Create Widgets from Responses: Create widgets directly from the response types returned by the backend.
  • POST Request Method: Uses POST instead of GET, with parameters passed in the request body
  • Citation Support: Built-in support for adding citations and source information
  • Flexible Parameter Handling: All widget parameters are passed in the POST data

Basic Omni Widget

Below is an example of a basic Omni widget that demonstrates the versatility by returning different content types based on the type parameter. In a real world example you might choose to dynamically return different content types based on your backend logic.

Omni Widget Example
from pydantic import BaseModel, Field
from typing import Any, List, Literal
from uuid import UUID
from fastapi import FastAPI, Body, Query
import json

class DataFormat(BaseModel):
data_type: str
parse_as: Literal["text", "table", "chart"]

class ExtraCitation(BaseModel):
source_info: SourceInfo | None = Field(default=None)
details: List[dict] | None = Field(default=None)

class OmniWidgetResponse(BaseModel):
content: Any
data_format: DataFormat
extra_citations: list[ExtraCitation] | None = Field(default_factory=list)
citable: bool = Field(default=True)

@register_widget({
"name": "Omni Widget Example",
"description": "A versatile omni widget that can display multiple types of content",
"category": "General",
"type": "omni",
"endpoint": "omni-widget",
"params": [
{
"paramName": "prompt",
"type": "text",
"description": "The prompt to send to the LLM to make queries or ask questions.",
"label": "Prompt",
"show": False
},
{
"paramName": "type",
"type": "text",
"description": "Type of content to return",
"label": "Content Type",
"show": True,
"options": [
{"value": "markdown", "label": "Markdown"},
{"value": "chart", "label": "Chart"},
{"value": "table", "label": "Table"}
]
}
],
"gridData": {"w": 30, "h": 12}
})
@app.post("/omni-widget")
async def get_omni_widget(
data: str | dict = Body(...)
):
if isinstance(data, str):
data = json.loads(data)

# Return table format
if data.get("type") == "table":
content = [
{"col1": "value1", "col2": "value2", "col3": "value3", "col4": "value4"},
{"col1": "value5", "col2": "value6", "col3": "value7", "col4": "value8"},
{"col1": "value9", "col2": "value10", "col3": "value11", "col4": "value12"},
]

return OmniWidgetResponse(
content=content,
data_format=DataFormat(data_type="object", parse_as="table")
)

# Return chart format
if data.get("type") == "chart":
content = {
"data": [
{"x": [1, 2, 3], "y": [4, 1, 2], "type": "bar"},
{"x": [1, 2, 3], "y": [2, 4, 5], "type": "bar"},
{"x": [1, 2, 3], "y": [2, 3, 6], "type": "bar"},
],
"layout": {
"title": "Dynamic Chart",
"template": "plotly_dark"
},
}

return OmniWidgetResponse(
content=content,
data_format=DataFormat(data_type="object", parse_as="chart")
)

# Return markdown format (default)
content = f"""### Dynamic Omni Widget Response

**Input Parameters:**
- **Search Query:** `{search}`
- **Content Type:** `{data.get('type', 'markdown')}`
- **Prompt:** `{data.get('prompt', 'No prompt provided')}`

#### Raw Data:
{json.dumps(data, indent=2)}

"""

return OmniWidgetResponse(
content=content,
data_format=DataFormat(data_type="object", parse_as="text")
)

Omni Widget with Citations

This example demonstrates how to add citation support to your Omni widget, which is useful when you want to use the widget in conjunction with an agent. The citations are added to the response if the citable parameter is set to True. This is shown in the example below and returned when the user is interacting with the widget through an agent.

Omni Widget with Citations Example
@register_widget({
"name": "Omni Widget with Citations",
"description": "An omni widget that includes citation information",
"category": "General",
"type": "omni",
"endpoint": "omni-widget-citations",
"params": [
{
"paramName": "prompt",
"type": "text",
"description": "The prompt to send to the LLM to make queries or ask questions.",
"label": "Prompt",
"show": True
},
{
"paramName": "include_metadata",
"type": "boolean",
"description": "Include metadata in response",
"label": "Include Metadata",
"show": True,
"value": True
}
],
"gridData": {"w": 30, "h": 15}
})
@app.post("/omni-widget-citations")
async def get_omni_widget_with_citations(
data: str | dict = Body(...)
):
if isinstance(data, str):
data = json.loads(data)

# Create citation information
source_info = SourceInfo(
type="widget",
widget_id="omni_widget_citations",
origin="custom_backend",
name="Omni Widget with Citations",
description="Example widget demonstrating citation functionality",
metadata={
"prompt": data.get("prompt", ""),
"search_term": search,
"timestamp": "2024-01-01T00:00:00Z",
"data_source": "Custom API"
}
)

extra_citation = ExtraCitation(
source_info=source_info,
details=[
{
"Source": "Custom Backend API",
"Prompt": data.get("prompt", ""),
"Search": search,
"Metadata_Included": data.get("include_metadata", False),
"Response_Type": "Dynamic Content"
}
]
)

# Generate content based on parameters
content = f"""# Query Results

**Search Query:** {search}
**User Prompt:** {data.get('prompt', 'No prompt provided')}

## Results
This is dynamically generated content based on your input parameters.

### Metadata
"""

if data.get("include_metadata"):
content += f"""
- **Widget ID:** omni_widget_citations
- **Timestamp:** 2024-01-01T00:00:00Z
- **Data Source:** Custom API
- **Parameters:** {json.dumps(data, indent=2)}
"""
else:
content += "Metadata hidden (set 'Include Metadata' to true to view)"

return OmniWidgetResponse(
content=content,
data_format=DataFormat(data_type="object", parse_as="text"),
extra_citations=[extra_citation],
citable=True
)

Important Implementation Notes

POST Request Method

Unlike other widget types that use GET requests, the Omni widget uses POST requests. This allows for more complex parameter handling and larger payloads:

@app.post("/omni-widget")  # Note: POST, not GET
async def omni_endpoint(
data: str | dict = Body(...) # Main parameters in request body
):
# Handle both string and dict formats
if isinstance(data, str):
data = json.loads(data)

# All widget parameters are available in the 'data' object
param_value = data.get("paramName")

Dynamic Output Control

The Omni widget can return different content types based on the parse_as field in the DataFormat:

"text": For markdown/text content "table": For tabular data (list of dictionaries) "chart": For Plotly chart objects

# Text/Markdown output
return OmniWidgetResponse(
content="# Markdown content",
data_format=DataFormat(data_type="object", parse_as="text")
)
# Table output
return OmniWidgetResponse(
content=[{"col1": "val1", "col2": "val2"}],
data_format=DataFormat(data_type="object", parse_as="table")
)
# Chart output
return OmniWidgetResponse(
content={"data": [...], "layout": {...}},
data_format=DataFormat(data_type="object", parse_as="chart")
)

Parameter Handling

All widget parameters defined in the widget configuration are passed in the POST request body, and the prompt parameter is required:

{
"params": [
{
// Required parameter for the LLM to make queries or ask questions
"paramName": "prompt",
"type": "text",
"description": "The prompt to send to the LLM to make queries or ask questions.",
"label": "Prompt",
"show": False
}
{
"paramName": "user_input",
"type": "text",
"label": "User Input"
},
{
"paramName": "option_select",
"type": "text",
"options": [...]
}
]
}

These parameters are accessible in your endpoint:

@app.post("/omni-widget")
async def omni_endpoint(data: dict = Body(...)):
user_input = data.get("user_input")
selected_option = data.get("option_select")
prompt = data.get("prompt")
# Process parameters...

Use Cases

The Omni widget is particularly useful for:

  • AI/LLM Integration: Dynamic content generation based on user prompts
  • Multi-format Data Display: Single endpoint that can return different visualizations
  • Citation-heavy Applications: Research tools that need to track data sources.