import gradio as gr import modelscope_studio.components.antd as antd import modelscope_studio.components.antdx as antdx import modelscope_studio.components.base as ms def create_bubble_item(i: int): is_ai = i % 2 != 0 content = 'Mock AI content. ' * 20 if is_ai else f'Mock User content `{i}`.' return { "role": "ai" if is_ai else "user", "content": content, "key": i - 1 } def add_bubble(state_value): history_len = len(state_value["history"]) state_value["history"].append(create_bubble_item(history_len + 1)) return gr.update(value=state_value), gr.update( items=state_value["history"]) def refresh(state_value, e: gr.EventData): clicked_key = e._data["component"]["key"] gr.Info(f"You clicked refresh button, item {clicked_key}") state_value["history"][clicked_key]["content"] = "Refreshed" return gr.update(value=state_value), gr.update( items=state_value["history"]) def like(state_value, e: gr.EventData): clicked_key = e._data["component"]["key"] gr.Info(f"You clicked like button, item {clicked_key}") state_value["history"][clicked_key]["meta"] = { "action": "like", } return gr.update(value=state_value), gr.update( items=state_value["history"]) def dislike(state_value, e: gr.EventData): clicked_key = e._data["component"]["key"] gr.Info(f"You clicked dislike button, item {clicked_key}") state_value["history"][clicked_key]["meta"] = { "action": "dislike", } return gr.update(value=state_value), gr.update( items=state_value["history"]) default_history = [ create_bubble_item(1), create_bubble_item(2), create_bubble_item(3) ] with gr.Blocks() as demo: with ms.Application(): state = gr.State({"history": default_history}) with antdx.XProvider(): with antd.Flex(gap="small", vertical=True): with antd.Flex(gap="small", elem_style=dict(alignSelf="flex-end")): add_bubble_btn = antd.Button("Add Bubble") scroll_btn = antd.Button("Scroll To First") with antdx.Bubble.List(items=default_history, elem_style=dict(maxHeight=500), elem_id="chatbot") as bubble_list: # Define Roles with ms.Slot("roles"): with antdx.Bubble.List.Role( role="ai", placement="start", typing=dict(step=5, interval=20), styles=dict(footer=dict(width="100%")), elem_style=dict(maxWidth=600)): with ms.Slot("avatar"): with antd.Avatar(elem_style=dict( backgroundColor="#fde3cf")): with ms.Slot("icon"): antd.Icon("UserOutlined") # use messageRender to render markdown content with ms.Slot( "messageRender", params_mapping="""content => content"""): ms.Markdown() # render footer with ms.Slot("footer", params_mapping="""(item) => { return { copy: { copyable: { text: item.content, tooltips: false } } ,refresh: { key: item.key }, like: { key: item.key, color: item.meta?.action === "like" ? 'primary' : 'default' }, dislike: { key: item.key, color: item.meta?.action === "dislike" ? 'primary' : 'default' } } }"""): with antd.Typography.Text( copyable=dict(tooltips=False), as_item="copy"): with ms.Slot("copyable.icon"): with antd.Button(value=None, size="small", color="default", variant="text"): with ms.Slot("icon"): antd.Icon("CopyOutlined") with antd.Button(value=None, size="small", color="default", variant="text"): with ms.Slot("icon"): antd.Icon("CheckOutlined") with antd.Button( value=None, size="small", color="default", variant="text", as_item="refresh") as refresh_btn: with ms.Slot("icon"): antd.Icon("SyncOutlined") refresh_btn.click(fn=refresh, inputs=[state], outputs=[state, bubble_list]) with antd.Button(value=None, size="small", variant="text", as_item="like") as like_btn: with ms.Slot("icon"): antd.Icon("SmileOutlined") like_btn.click(fn=like, inputs=[state], outputs=[state, bubble_list]) with antd.Button( value=None, size="small", variant="text", as_item="dislike") as dislike_btn: with ms.Slot("icon"): antd.Icon("FrownOutlined") dislike_btn.click(fn=dislike, inputs=[state], outputs=[state, bubble_list]) with antdx.Bubble.List.Role( role="user", placement="end", ): with ms.Slot("avatar"): with antd.Avatar(elem_style=dict( backgroundColor="#87d068")): with ms.Slot("icon"): antd.Icon("UserOutlined") with ms.Slot( "messageRender", params_mapping="(content) => content"): ms.Markdown() add_bubble_btn.click(fn=add_bubble, inputs=[state], outputs=[state, bubble_list]) scroll_btn.click(fn=None, js="""() => { const bubbleList = document.getElementById("chatbot"); bubbleList.scrollTo({ top:0, behavior:'smooth' }); }""") if __name__ == "__main__": demo.queue().launch()