Unexpected behavior of ChatInterface callback function

Unrelated Question:

  • I still can’t figure out how to set the size of the avatar?! :thinking: :unamused:
  • Sending just a space character shows some sizing issues

Part 1: define the callback functions

import panel as pn
pn.extension('texteditor', design="material")

def mk_replaceable_fn( func=lambda x: x):
    actual_function = func

    def function(*y): return actual_function(*y)

    def set_actual_function(new_actual_function ):
        nonlocal actual_function
        actual_function = new_actual_function

    return function, set_actual_function

def do_nothing(contents, user, instance):

def blue_echo(contents, user, instance):
    return f"""<strong style="color:blue;">{contents}</strong>"""

def count_chars( contents, user, instance ):
    return f"""Found {len(contents)} characters in <strong style="color:red;">{contents}</strong>"""

callback_function, set_callback_function = mk_replaceable_fn( do_nothing )
STYLE = """
.avatar {
    margin-top: 0;
    margin-left: 0;
    margin-right: 0;
    /* justify-content: top;
    align_items: top;
    margin-top: 3px;
    min_height: 10px;
    height: 10px; */
.left {
    min-height: 10px;
    height: 18px;
.center {
    /* background-color: yellow; */
    width: calc(100% - 5px);
.message {
    min-height: 15px;
.right {
  margin-left: 0;
  /* background-color: gray; */
message_params = dict(
    default_avatars={ "System": "☂️", "User": "👤", },
    sizing_mode = "scale_width",
gui = pn.chat.ChatInterface(
    callback       = callback_function,
    message_params = message_params,
    stylesheets    = [STYLE],
    show_rerun     = False,
    show_undo      = False,
    widgets        = pn.widgets.TextAreaInput(placeholder=">", auto_grow=True, max_rows=10),
    height         = 300,

Part 2: Test

# ChatMessage 0 and 1
msg = gui.send("initial callback function do_nothing, enter something",   user="System")

works as expected: the system message and user response are displayed and have the correct avatars.

# Chat message 2 and 3
msg = gui.send("setting callback function count_chars, enter something",   user="System")
import time
set_callback_function( count_chars )

yields 2 messages: the system message with the correct avatar
and a second later, the wordcount message with an unrelated system avatar

  • at the time the message is sent, the callback should still be do_nothing!
  • why the unrelated system avatar?

Last question:

  • Is it possible to set a filter on the user message, e.g., blue_echo:
    when the user sends a message using the send button, have the displayed ChatMessage
    come out in blue

I still can’t figure out how to set the size of the avatar?!

Sorry, it might be hardcoded if you’re not using emojis

Feel free to submit a GitHub issue (or even a PR :D):

For emojis/characters:

For the second part, I don’t understand what you’re asking; can you highlight what you mean by screenshots or recordings?

It was weird: with the blue_callback set, it would correctly echo the user input in blue.
resetting the callback to count_chars would immediately trigger (without any user input) and display the charcount message.

I gained control over the behavior by checking on user:

def blue_echo(contents, user, instance):
    if user == "User":
        dialogue.user_input = f"""[{user}] <strong style="color:blue;">{contents}</strong>"""