Spinning icon effect that appears when the user sends a message in ChatInterface

Please, friends, I need some help. How do I activate the spinning icon effect that appears when the user sends a message? I forward it via the ‘send’ function of ChatInterface, but this effect doesn’t show up, only when I send the message using the send button.

Hi there! I think I would need more information/minimal example to answer this like whether you are using async/sync.

If the callback executes fast, there, the placeholder will not show up. You can adjust placeholder_threshold though.

1 Like

Hi, Andrew. Thanks for your help.

The following code and video illustrate my question.

import panel as pn
import time

pn.extension()

def callback(context, user, instance):
    time.sleep(3) # Simulate a long running process
    return f'{context} echo'

chat = pn.chat.ChatInterface(callback=callback)

def btn_click(event):    
    chat.send('Example message', respond=True)

btn = pn.widgets.Button(name='Click here for an example message', button_type='primary', on_click=btn_click)

pn.Column(btn, chat).servable()

Thank you.

1 Like

The next release of Panel (scheduled for tomorrow) should fix this. In the meantime, you may want to set placeholder_threshold=0.001 or something:

import panel as pn
import time

pn.extension()

def callback(context, user, instance):
    time.sleep(3) # Simulate a long running process
    return f'{context} echo'

chat = pn.chat.ChatInterface(callback=callback, placeholder_threshold=0.001)

def btn_click(event):    
    chat.send('Example message', respond=True)

btn = pn.widgets.Button(name='Click here for an example message', button_type='primary', on_click=btn_click)

pn.Column(btn, chat).show()
1 Like

Thanks, I’m going to wait for the next release.

v1.3.5 is now released!

Demos here:
https://twitter.com/IAteAnDrew1/status/1736885406359339133

1 Like

I had the spinning icon effect working fine in Panel 1.3.4 but it does not work in 1.3.5 or 1.3.6. I tried adding placeholder_threshold=0.001, but no change.

async def callback(contents: str, user: str, instance: pn.chat.ChatInterface):
    result = chain.astream({"question": contents})
    message = ""
    async for chunk in result:
        if chunk.content is not None:
            if len(chunk.content) > 0:
                message += chunk.content
                yield message

chat_interface = pn.chat.ChatInterface(
    callback=callback,
    callback_exception="verbose",
    callback_user="ChatGPT",
    avatar="📈",
    show_button_name=False,
    show_rerun=False,
    show_undo=False,
    width=1280,
    auto_scroll_limit=5,
    placeholder_threshold=0.001
)

I noticed that when I use generator functions (yield ), the spinning icon effect doesn’t work. It functions correctly when I use “return,” but I don’t achieve the streaming effect.

2 Likes

Thank you for that insight:

This does seem to work:

import panel as pn
import asyncio

pn.extension()

async def callback(context, user, instance):
    await asyncio.sleep(3) # Simulate a long running process
    return f'{context} echo'

chat = pn.chat.ChatInterface(callback=callback)

def btn_click(event):    
    chat.send('Example message', respond=True)

btn = pn.widgets.Button(name='Click here for an example message', button_type='primary', on_click=btn_click)

pn.Column(btn, chat).servable()

But not when I yield instead of return.

In the mean time, if you need to stream

import panel as pn
import asyncio

pn.extension()

async def callback(context, user, instance):
    await asyncio.sleep(3) # Simulate a long running process
    output_content = f'{context} echo'

    message = None
    for char in output_content:
        instance.stream(char, message=message)

chat = pn.chat.ChatInterface(callback=callback)

def btn_click(event):    
    message = chat.send('Example message', respond=True)

btn = pn.widgets.Button(name='Click here for an example message', button_type='primary', on_click=btn_click)

pn.Column(btn, chat).servable()
1 Like

Fix submitted here:

3 Likes

Fix works in my case with async streaming. Thank you.

1 Like

Great hopefully it’ll be in by 1.4.0

It worked! Just correcting a little bit mistake on return of stream method:

import panel as pn
import asyncio

pn.extension()

async def callback(context, user, instance):
    await asyncio.sleep(3) # Simulate a long running process
    output_content = f'{context} echo'

    message = None
    for char in output_content:
        message = instance.stream(char, message=message)

chat = pn.chat.ChatInterface(callback=callback)

def btn_click(event):    
    message = chat.send('Example message', respond=True)

btn = pn.widgets.Button(name='Click here for an example message', button_type='primary', on_click=btn_click)

pn.Column(btn, chat).servable()

Thank you very much.