chainlit
chainlit copied to clipboard
Add Toggle-able Buttons on Chat and Enhance information panel persistence and state management and step Collapse
trafficstars
Separate toggleable buttons from commands This commit implements a complete separation between toggleable buttons and standard commands, allowing developers to independently define and configure these two distinct types of interactive UI elements.
Key features:
- Created dedicated IToggleCommand interface distinct from ICommand
- Added new backend method set_toggle_commands for setting toggleable buttons
- Implemented toggleCommandsState for frontend state management
- Updated frontend components to use the new toggle command state
- Added persistent toggle functionality that preserves state between message submissions
Technical implementation:
- Added ToggleCommandDict type in backend and removed toggleable property from CommandDict
- Created toggleCommandsState for frontend state management
- Modified ToggleableButtons component to use the new toggleCommand state
- Added socket event handling for set_toggle_commands events
- Implemented automatic reset of non-persistent toggles after message submission
- Created demo example showing how to use separated toggle commands
Usage example:
commands = [
{"id": "Search", "icon": "globe", "description": "Web search", "button": True}
]
toggle_commands = [
{"id": "Debug", "icon": "bug", "description": "Show debug info", "persistent": True},
{"id": "Thinking", "icon": "brain", "description": "Show thinking process"}
]
@cl.on_chat_start
async def start():
await cl.context.emitter.set_commands(commands)
await cl.context.emitter.set_toggle_commands(toggle_commands)
This implementation enhances UI interaction flexibility and provides developers with more granular control options.
feat(InfoPanel): Enhance information panel persistence and state management
- Implement localStorage for saving panel data and title
- Add visibility change listeners to restore state when returning from other tabs
- Optimize state update logic to reduce unnecessary re-renders
- Maintain global state in backend to ensure panel visibility after message interactions
- Add data validation logic to prevent rendering with empty data
These improvements ensure users can continuously view the information panel throughout their chat session, including after sending messages, refreshing the page, and navigating back from other pages.
import chainlit as cl
@cl.header_auth_callback
def header_auth_callback(username: str):
# Verify the signature of a token in the header (ex: jwt token)
# or check that the value is matching a row from your database
if username == "test-value":
return cl.User(identifier="admin", metadata={"role": "admin", "provider": "header"})
else:
return cl.User(identifier="guest", metadata={})
from chainlit.sidebar import InfoPanelSidebar
import logging
import inspect
# 配置日志
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
@cl.on_chat_start
async def on_chat_start():
"""
在聊天开始时,设置信息面板并发送到前端
"""
logger.info(f"Chat started - preparing to send info panel data (function: {inspect.currentframe().f_code.co_name})")
# 信息面板数据,以键值对形式定义
info_data = {
"性别": "男",
"年龄": "58岁",
"MRN": "002737777",
"Episode": "2238787",
}
# 发送信息面板数据到前端显示
logger.info(f"Sending info panel data to frontend: {info_data}")
try:
await InfoPanelSidebar.set_info_panel(info_data, title="患者信息")
logger.info("Info panel data sent successfully")
except Exception as e:
logger.error(f"Error sending info panel data: {e}", exc_info=True)
await cl.Message(
content="您好,我是医疗助手。信息已经显示在左侧,请问有什么需要帮助的?"
).send()
@cl.on_message
async def on_message(message: cl.Message):
pass