Build production-ready conversational AI applications in minutes with rich UI components and LLM integrations
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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]): ...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
): ...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
): ...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 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 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
): ...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()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()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)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()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