CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-chainlit

Build production-ready conversational AI applications in minutes with rich UI components and LLM integrations

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

input-widgets.mddocs/

Input Widgets

Interactive input components for creating dynamic chat settings and user preference panels. These widgets enable users to configure application behavior through sliders, switches, dropdowns, text inputs, and custom controls.

Capabilities

Widget Base Classes

Foundation classes for creating interactive settings panels with validation and dynamic updates.

import chainlit as cl
from chainlit.input_widget import Slider, Switch, Select, TextInput, NumberInput, Tags

class InputWidget:
    """
    Base class for all input widgets used in chat settings panels.
    
    Args:
        id: str - Unique widget identifier for accessing values
        label: str - Display label shown to users  
        tooltip: Optional[str] - Hover tooltip text
        description: Optional[str] - Help text displayed below widget
        
    Returns:
        InputWidget base instance
    """
    def __init__(
        self,
        id: str,
        label: str,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

class ChatSettings:
    """
    Container for input widgets that creates a settings panel in the UI.
    
    Args:
        widgets: List[InputWidget] - List of widgets to display in panel
        
    Returns:
        ChatSettings instance for managing user preferences
    """
    def __init__(self, widgets: List[InputWidget]): ...

Boolean Controls

Toggle switches for binary settings and feature toggles.

class Switch:
    """
    Boolean toggle switch for binary settings and feature flags.
    
    Args:
        id: str - Widget identifier for accessing the boolean value
        label: str - Display label for the switch
        initial: bool - Default value (default: False)
        tooltip: Optional[str] - Hover tooltip text
        description: Optional[str] - Help text explaining the setting
        
    Returns:
        Switch widget instance
    """
    def __init__(
        self,
        id: str,
        label: str,
        initial: bool = False,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

Numeric Controls

Sliders and number inputs for numeric configuration values.

class Slider:
    """
    Numeric slider input with range constraints and step control.
    
    Args:
        id: str - Widget identifier for accessing the numeric value
        label: str - Display label for the slider
        initial: float - Default value (default: 0)
        min: float - Minimum allowed value (default: 0) 
        max: float - Maximum allowed value (default: 10)
        step: float - Step size for value increments (default: 1)
        tooltip: Optional[str] - Hover tooltip text
        description: Optional[str] - Help text explaining the setting
        
    Returns:
        Slider widget instance
    """
    def __init__(
        self,
        id: str,
        label: str,
        initial: float = 0,
        min: float = 0,
        max: float = 10,
        step: float = 1,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

class NumberInput:
    """
    Numeric input field with keyboard entry support.
    
    Args:
        id: str - Widget identifier for accessing the numeric value
        label: str - Display label for the input field
        initial: Optional[float] - Default number value
        placeholder: Optional[str] - Placeholder text when empty
        tooltip: Optional[str] - Hover tooltip text  
        description: Optional[str] - Help text explaining the setting
        
    Returns:
        NumberInput widget instance
    """
    def __init__(
        self,
        id: str,
        label: str,
        initial: Optional[float] = None,
        placeholder: Optional[str] = None,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

Selection Controls

Dropdowns and selection widgets for choosing from predefined options.

class Select:
    """
    Dropdown selection widget with predefined options.
    
    Args:
        id: str - Widget identifier for accessing selected value
        label: str - Display label for the dropdown
        values: Optional[List[str]] - Simple string options for selection
        items: Optional[Dict[str, str]] - Label-value pairs (label -> value)
        initial_index: Optional[int] - Default selection by index position
        initial_value: Optional[str] - Default selection by value
        tooltip: Optional[str] - Hover tooltip text
        description: Optional[str] - Help text explaining the options
        
    Returns:
        Select widget instance
        
    Note:
        Use either 'values' for simple strings or 'items' for label-value pairs
    """
    def __init__(
        self,
        id: str,
        label: str,
        values: Optional[List[str]] = None,
        items: Optional[Dict[str, str]] = None,
        initial_index: Optional[int] = None,
        initial_value: Optional[str] = None,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

Text Input Controls

Text fields for string input with multiline support and validation.

class TextInput:
    """
    Text input field with single-line and multi-line support.
    
    Args:
        id: str - Widget identifier for accessing text value
        label: str - Display label for the input field
        initial: Optional[str] - Default text content
        placeholder: Optional[str] - Placeholder text when empty
        multiline: bool - Enable multi-line input (default: False)
        tooltip: Optional[str] - Hover tooltip text
        description: Optional[str] - Help text explaining the input
        
    Returns:
        TextInput widget instance
    """
    def __init__(
        self,
        id: str,
        label: str,
        initial: Optional[str] = None,
        placeholder: Optional[str] = None,
        multiline: bool = False,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

Tag and Array Controls

Tag input widgets for managing lists of values and categorical data.

class Tags:
    """
    Tag input widget for managing arrays of string values.
    
    Args:
        id: str - Widget identifier for accessing tag array
        label: str - Display label for the tag input
        initial: List[str] - Default tag values (default: empty list)
        values: Optional[List[str]] - Predefined tag options for autocomplete
        tooltip: Optional[str] - Hover tooltip text
        description: Optional[str] - Help text explaining tag usage
        
    Returns:
        Tags widget instance
    """
    def __init__(
        self,
        id: str,
        label: str,
        initial: List[str] = [],
        values: Optional[List[str]] = None,
        tooltip: Optional[str] = None,
        description: Optional[str] = None
    ): ...

Usage Examples

Basic Settings Panel

Create a simple settings panel with various input types:

import chainlit as cl
from chainlit.input_widget import Slider, Switch, Select, TextInput

@cl.on_chat_start
async def setup_settings():
    """Create a settings panel for user preferences"""
    settings = cl.ChatSettings([
        # AI Model Configuration
        Select(
            id="model",
            label="AI Model",
            values=["gpt-3.5-turbo", "gpt-4", "claude-3-sonnet"],
            initial_value="gpt-3.5-turbo",
            tooltip="Choose the AI model for responses"
        ),
        
        # Response Parameters
        Slider(
            id="temperature",
            label="Response Creativity",
            initial=0.7,
            min=0.0,
            max=2.0,
            step=0.1,
            description="Higher values make responses more creative"
        ),
        
        Slider(
            id="max_tokens",
            label="Maximum Response Length",
            initial=150,
            min=50,
            max=500,
            step=25,
            tooltip="Maximum number of tokens in responses"
        ),
        
        # Feature Toggles
        Switch(
            id="stream_response",
            label="Stream Responses",
            initial=True,
            description="Show responses as they're generated"
        ),
        
        Switch(
            id="show_thinking",
            label="Show AI Thinking",
            initial=False,
            description="Display AI reasoning steps"
        ),
        
        # User Preferences
        TextInput(
            id="system_prompt",
            label="Custom System Prompt",
            multiline=True,
            placeholder="Enter custom instructions for the AI...",
            description="Custom instructions to guide AI behavior"
        )
    ])
    
    await settings.send()

@cl.on_settings_update
async def handle_settings_update(settings: Dict[str, Any]):
    """Handle changes to chat settings"""
    # Access individual settings
    model = settings.get("model", "gpt-3.5-turbo")
    temperature = settings.get("temperature", 0.7)
    max_tokens = settings.get("max_tokens", 150)
    stream_response = settings.get("stream_response", True)
    show_thinking = settings.get("show_thinking", False)
    system_prompt = settings.get("system_prompt", "")
    
    # Store in session for use in message handling
    cl.user_session.set("ai_settings", {
        "model": model,
        "temperature": temperature,
        "max_tokens": max_tokens,
        "stream_response": stream_response,
        "show_thinking": show_thinking,
        "system_prompt": system_prompt
    })
    
    await cl.Message(
        f"Settings updated! Using {model} with temperature {temperature}"
    ).send()

Advanced Configuration Panel

Create a comprehensive settings panel for a data analysis application:

import chainlit as cl
from chainlit.input_widget import Slider, Switch, Select, TextInput, NumberInput, Tags

@cl.on_chat_start
async def setup_advanced_settings():
    """Create comprehensive settings for data analysis"""
    settings = cl.ChatSettings([
        # Data Processing Settings
        Select(
            id="data_source",
            label="Data Source",
            items={
                "CSV Upload": "csv",
                "Database Connection": "database", 
                "API Endpoint": "api",
                "Sample Dataset": "sample"
            },
            initial_value="csv",
            description="Choose your data source type"
        ),
        
        # Analysis Parameters
        NumberInput(
            id="sample_size",
            label="Sample Size",
            initial=1000,
            placeholder="Enter sample size...",
            description="Number of rows to analyze (0 = all rows)"
        ),
        
        Slider(
            id="confidence_level",
            label="Confidence Level",
            initial=0.95,
            min=0.80,
            max=0.99,
            step=0.01,
            tooltip="Statistical confidence level for analysis"
        ),
        
        # Chart Configuration
        Select(
            id="chart_style",
            label="Chart Style",
            values=["seaborn", "matplotlib", "plotly", "bokeh"],
            initial_index=0,
            description="Preferred charting library"
        ),
        
        Tags(
            id="analysis_types",
            label="Analysis Types",
            initial=["descriptive", "correlation"],
            values=[
                "descriptive", "correlation", "regression", 
                "clustering", "time_series", "anomaly_detection"
            ],
            description="Select types of analysis to perform"
        ),
        
        # Processing Options
        Switch(
            id="auto_clean",
            label="Automatic Data Cleaning",
            initial=True,
            description="Automatically handle missing values and outliers"
        ),
        
        Switch(
            id="generate_report",
            label="Generate PDF Report", 
            initial=False,
            tooltip="Create downloadable analysis report"
        ),
        
        # Output Preferences
        TextInput(
            id="report_title",
            label="Report Title",
            initial="Data Analysis Report",
            placeholder="Enter report title...",
            description="Title for generated reports"
        ),
        
        Tags(
            id="export_formats",
            label="Export Formats",
            initial=["png"],
            values=["png", "pdf", "svg", "html", "json"],
            description="Chart and report export formats"
        )
    ])
    
    await settings.send()

@cl.on_settings_update
async def handle_analysis_settings(settings: Dict[str, Any]):
    """Process analysis settings updates"""
    # Extract and validate settings
    data_source = settings.get("data_source", "csv")
    sample_size = settings.get("sample_size", 1000)
    confidence_level = settings.get("confidence_level", 0.95)
    chart_style = settings.get("chart_style", "seaborn")
    analysis_types = settings.get("analysis_types", ["descriptive"])
    auto_clean = settings.get("auto_clean", True)
    generate_report = settings.get("generate_report", False)
    report_title = settings.get("report_title", "Data Analysis Report")
    export_formats = settings.get("export_formats", ["png"])
    
    # Store comprehensive settings
    cl.user_session.set("analysis_config", {
        "data_source": data_source,
        "sample_size": max(0, int(sample_size)) if sample_size else 0,
        "confidence_level": confidence_level,
        "chart_style": chart_style,
        "analysis_types": analysis_types,
        "auto_clean": auto_clean,
        "generate_report": generate_report,
        "report_title": report_title,
        "export_formats": export_formats
    })
    
    # Provide feedback on configuration
    analysis_summary = f"""
    **Analysis Configuration Updated:**
    - Data Source: {data_source}
    - Sample Size: {'All rows' if sample_size == 0 else f'{sample_size:,} rows'}
    - Analysis Types: {', '.join(analysis_types)}
    - Chart Style: {chart_style}
    - Auto-clean Data: {'Yes' if auto_clean else 'No'}
    """
    
    await cl.Message(analysis_summary).send()

Dynamic Settings with Conditional Logic

Create settings that change based on user selections:

import chainlit as cl
from chainlit.input_widget import Slider, Switch, Select, TextInput

@cl.on_settings_update
async def dynamic_settings_handler(settings: Dict[str, Any]):
    """Handle settings with dynamic updates"""
    mode = settings.get("mode", "basic")
    
    # Create different settings based on selected mode
    if mode == "basic":
        new_settings = cl.ChatSettings([
            Select(
                id="mode",
                label="Mode",
                values=["basic", "advanced", "expert"],
                initial_value="basic"
            ),
            Slider(
                id="temperature",
                label="Creativity",
                initial=0.7,
                min=0.0,
                max=1.0,
                step=0.1
            )
        ])
    
    elif mode == "advanced":
        new_settings = cl.ChatSettings([
            Select(
                id="mode",
                label="Mode", 
                values=["basic", "advanced", "expert"],
                initial_value="advanced"
            ),
            Slider(
                id="temperature",
                label="Temperature",
                initial=0.7,
                min=0.0,
                max=2.0,
                step=0.1
            ),
            Slider(
                id="top_p",
                label="Top P",
                initial=0.9,
                min=0.0,
                max=1.0,
                step=0.05
            ),
            Switch(
                id="enable_plugins",
                label="Enable Plugins",
                initial=True
            )
        ])
    
    else:  # expert mode
        new_settings = cl.ChatSettings([
            Select(
                id="mode",
                label="Mode",
                values=["basic", "advanced", "expert"],
                initial_value="expert"
            ),
            # All advanced settings plus expert options
            Slider(id="temperature", label="Temperature", initial=0.7, min=0.0, max=2.0, step=0.01),
            Slider(id="top_p", label="Top P", initial=0.9, min=0.0, max=1.0, step=0.01),
            Slider(id="top_k", label="Top K", initial=50, min=1, max=100, step=1),
            Slider(id="frequency_penalty", label="Frequency Penalty", initial=0.0, min=-2.0, max=2.0, step=0.1),
            Slider(id="presence_penalty", label="Presence Penalty", initial=0.0, min=-2.0, max=2.0, step=0.1),
            Switch(id="enable_plugins", label="Enable Plugins", initial=True),
            Switch(id="debug_mode", label="Debug Mode", initial=False),
            TextInput(id="custom_stop_sequences", label="Stop Sequences", placeholder="Enter comma-separated stop sequences...")
        ])
    
    await new_settings.send()
    
    # Store current settings
    cl.user_session.set("current_settings", settings)

Settings Integration with Message Processing

Use settings values in message handling:

import chainlit as cl

@cl.on_message
async def process_with_settings(message: cl.Message):
    """Process messages using current settings"""
    # Get current settings from session
    ai_settings = cl.user_session.get("ai_settings", {})
    analysis_config = cl.user_session.get("analysis_config", {})
    
    # Use settings in processing
    model = ai_settings.get("model", "gpt-3.5-turbo")
    temperature = ai_settings.get("temperature", 0.7)
    stream_response = ai_settings.get("stream_response", True)
    show_thinking = ai_settings.get("show_thinking", False)
    
    # Show thinking process if enabled
    if show_thinking:
        async with cl.Step(name="AI Thinking", type="llm") as thinking_step:
            thinking_step.input = f"Processing message with {model} (temp: {temperature})"
            # Simulate thinking process
            await cl.sleep(1)
            thinking_step.output = "Analyzing user request and formulating response..."
    
    # Process message with configured settings
    response = await generate_response(
        message.content,
        model=model,
        temperature=temperature,
        stream=stream_response
    )
    
    if stream_response:
        # Stream the response token by token
        msg = cl.Message("")
        await msg.send()
        
        for token in response:
            await msg.stream_token(token)
    else:
        # Send complete response
        await cl.Message(response).send()

Core Types

from typing import List, Dict, Any, Optional, Union

# Widget type definitions
InputWidgetType = Union[Slider, Switch, Select, TextInput, NumberInput, Tags]

# Settings update callback type
SettingsUpdateCallback = Callable[[Dict[str, Any]], Any]

# Widget value types
WidgetValue = Union[str, int, float, bool, List[str]]
SettingsDict = Dict[str, WidgetValue]

Install with Tessl CLI

npx tessl i tessl/pypi-chainlit

docs

advanced.md

authentication.md

callbacks.md

index.md

input-widgets.md

integrations.md

messaging.md

ui-elements.md

user-management.md

tile.json