fciannella's picture
Working with service run on 7860
53ea588
raw
history blame
9.46 kB
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: BSD 2-Clause License
"""Custom view frames."""
import json
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
from pipecat.frames.frames import DataFrame
from pydantic import BaseModel, Field
from nvidia_pipecat.frames.action import (
StartActionFrame,
StopActionFrame,
UserActionFrame,
)
# Block types
class Block(BaseModel, ABC):
"""A block is a modular component that can be rendered in the UI.
Multiple blocks can be rendered at a time.
Args:
id (str): A unique id for the block.
"""
id: str
@abstractmethod
def get_type(self) -> str:
"""Get the type of the block.
Type indicates what data is included in the block and is used to determine how to render the block in the UI.
"""
class HeaderBlock(Block):
"""A header block displays a header or subheader in the UI.
Args:
header (str): The text to display in the header.
level (int): The level of the header, corresponding to HTML element tags for header (h1, h2, etc.).
Must be between 1 and 6.
"""
header: str
level: int = Field(ge=1, le=6)
def get_type(self) -> str:
"""Get the type of the block."""
return "header"
class TextBlock(Block):
"""A text block displays text as a paragraph in the UI.
Args:
text (str): The text to display in the paragraph.
"""
text: str
def get_type(self) -> str:
"""Get the type of the block."""
return "paragraph"
class Image(BaseModel):
"""Specifies the data needed to render an image. file and data fields are mutually exclusive.
Args:
url (str | None): The URL of the image.
data (str | None): The image base64 data.
"""
url: str | None = None
data: str | None = None
class ImageBlock(Block):
"""An image block displays an image in the UI.
Args:
image (Image): The image to display.
caption (str | None): The caption to display in place of the image if the image cannot be rendered.
"""
image: Image
caption: str | None = None
def get_type(self) -> str:
"""Get the type of the block."""
return "image"
class ImagePosition(str, Enum):
"""Enum for image position."""
LEFT = "left"
RIGHT = "right"
class ImageWithTextBlock(Block):
"""An image with text block displays an image and text in the UI.
Args:
image (Image): The image to display.
text (str): The text to display next to the image.
image_position (ImagePosition): The position of the image relative to the text.
"""
image: Image
text: str
image_position: ImagePosition
def get_type(self) -> str:
"""Get the type of the block."""
return "paragraph_with_image"
class TableBlock(Block):
"""A table block displays a table in the UI.
Args:
headers (list[str]): The headers of the table.
rows (list[list[str]]): The rows of the table.
"""
headers: list[str]
rows: list[list[str]]
def get_type(self) -> str:
"""Get the type of the block."""
return "table"
class Hint(BaseModel):
"""A hint is an example of how the user can interact with the system.
Args:
name (str): The name of the hint. This is used to identify the hint in the UI.
text (str): The text of the hint. The text is what is displayed to the user.
"""
name: str
text: str
class HintCarouselBlock(Block):
"""A hint carousel block.
The block rotates through a list of hints, displaying
them one at a time to the user.
Args:
hints (list[Hint]): A list of hints to display.
"""
hints: list[Hint]
def get_type(self) -> str:
"""Get the type of the block."""
return "hint_carousel"
class ButtonVariant(str, Enum):
"""Enum for button variant styles."""
OUTLINED = "outlined"
CONTAINED = "contained"
TEXT = "text"
class Button(BaseModel):
"""Data format with information about a button.
Args:
id (str): The id of the button.
active (bool): Whether the button is active. If false, the button will be grayed out and not clickable.
toggled (bool): Whether the button is toggled. If true, the button will be toggled on.
variant (ButtonVariant): The variant of the button.
text (str): The text of the button.
"""
id: str
active: bool
toggled: bool
variant: ButtonVariant
text: str
class ButtonListBlock(Block):
"""A button list block displays a list of buttons.
Args:
buttons (list[Button]): A list of buttons to display.
"""
buttons: list[Button]
def get_type(self) -> str:
"""Get the type of the block."""
return "button_list"
class SelectableOption(BaseModel):
"""Data format for a selectable option. Can include an image and/or text.
Args:
id (str): The id of the selectable option.
image (Image | None): The image to display within the option.
text (str): The text to display within the option.
active (bool): Whether the option is active. If false, the option will be grayed out and not clickable.
toggled (bool): Whether the option is toggled. If true, the option will be toggled on.
"""
id: str
image: Image | None = None
text: str
active: bool
toggled: bool
class SelectableOptionsGridBlock(Block):
"""A selectable options grid block.
This block displays a grid of interactive options to the user.
A user may select and deselect any number of options as they choose.
Args:
options (list[SelectableOption]): A list of selectable options to display.
"""
buttons: list[SelectableOption]
def get_type(self) -> str:
"""Get the type of the block."""
return "selectable_options_grid"
class TextInputBlock(Block):
"""A text input block displays a text input to the user.
Args:
id (str): The id of the text input.
default_value (str): The default value of the text input.
value (str): The value of the text input.
label (str): The label of the text input.
input_type (str): The type of the text input.
"""
id: str
default_value: str
value: str
label: str
input_type: str
def get_type(self) -> str:
"""Get the type of the block."""
return "text_input"
@dataclass
class StartCustomViewFrame(StartActionFrame):
"""Sends data to the UI in the form of modular components to be rendered.
Args:
blocks (list[Block] | None): A list of modular components to display in the UI.
style (Style | None): The style of the UI.
"""
blocks: list[Block] | None = None
def to_json(self) -> str:
"""Convert the frame to a JSON string.
This is intended to be used for serializing the frame for transmission over a WebSocket connection to the UI.
"""
the_json = {}
if self.blocks:
blocks_list_json = []
for block in self.blocks:
block_json = {
"id": block.id,
"type": block.get_type(),
"data": block.model_dump(exclude={"id"}, exclude_none=True),
}
blocks_list_json.append(block_json)
the_json["blocks"] = blocks_list_json
return json.dumps(the_json)
@dataclass
class StopCustomViewFrame(StopActionFrame):
"""A frame that stops the custom view from being rendered in the UI."""
@dataclass
class UIInterimTextInputFrame(UserActionFrame, DataFrame):
"""Interim text input frame from the UI.
Receives data from the UI in the form of text inputted into a textbox
by the user prior to submission.
Args:
component_id (str): The id of the text input which is currently being typed in.
interim_input (str): The interim input of the text input.
"""
component_id: str
interim_input: str
@dataclass
class UITextInputFrame(UserActionFrame, DataFrame):
"""A frame that receives data from the UI in the form of a text inputted into a textbox.
This is triggered when the user submits their input.
Args:
enter_pressed (bool): True if the enter key was pressed to submit the text input,
false if the user navigated away from the text input.
component_id (str): The id of the text input which was submitted.
input (str): The input of the text input.
"""
enter_pressed: bool
component_id: str
input: str
@dataclass
class UIButtonPressFrame(UserActionFrame, DataFrame):
"""A frame that receives data from the UI in the form of a button press.
Args:
component_id (str): The id of the button which was pressed.
"""
component_id: str
@dataclass
class UISelectableOptionPressFrame(UserActionFrame, DataFrame):
"""A frame that receives data from the UI in the form of a selectable option press.
Args:
component_id (str): The id of the selectable option which was pressed.
toggled (bool): Whether the option is toggled. If true, the option will be toggled on.
"""
component_id: str
toggled: bool