Stream text to ChatInterface?

@ahuang11
I think this should be an example:

  • show how to create a minimal example that uses ChatFeed (or ChatInstance),
    or a new class as a GUI only. I.e., all user system interactions are carried out
    in separate code, with the GUI used to display the messages only.
  • show how to remove all the extra ChatMessage features,
    and tighten up the spacing.
    The avatars are still too large, and so is the spacing
    between the avatar and the message
  • I am currently struggling with adding some buttons and a larger text input area.
    I am running into sizing an alignment issues.
  • Given how much effort it turned out to be trying to put this together,
    I think it should definitely be documented.

Any suggestions on how to put this together?
Incidentally, the default_avatars in message_params does not seem useful in this context. Maybe ChatFeed should have an append_message() fn
that one can stream data to? I have not been able to make that work,
Instead writing

def add_message( chat_feed, avatar = "☂️"):
    message = pn.chat.ChatMessage(
                 avatar=avatar, stylesheets=[STYLE],
                 show_user       = False,
                 show_timestamp  = False,
                 show_copy_icon  = False,
                 sizing_mode     = "stretch_width",
    )
    message.margin=(0,0)
    _ = chat_feed.send(message)
    return message

and using

txt = ""
for n in "Updating the message works, streaming to it does not.... ":
    txt += n 
    message.update(txt)

to change the displayed text.
I’d love to know what you think!

I found a bug; if object=None, it won’t stream, but this works

import time
import panel as pn


def callback(event):
    for i in range(0, 12):
        time.sleep(0.05)
        chat_feed.stream(f"new message {i}", message=base_message, replace=True)


chat_feed = pn.chat.ChatFeed()
base_message = pn.chat.ChatMessage("")
chat_feed.send(base_message)

button = pn.widgets.Button(name="Start", button_type="primary")
button.on_click(callback)
pn.Row(
    pn.Column(button, chat_feed)
).show()

Export-1710790699008

Fixed here:

1 Like

Yet another puzzle I have not yet solved: .message does not fully use the horizontal extent of .center …

Maybe .right?

unfortunately no, .right is beyond .center which I showed in black.
I can’t get .message to use all the available space in .center

In fact, it looks like .center is contained in .right?!

Do you mean this part?

.center is indeed contained in .right.

Maybe margin-right

I colored .center yellow and .right gray.
I found chat_message.css and am trying to figure out display:flex
which I had not encountered before.

Looks like the extent of center is
width: calc(100% - 15px); /* Without this, words start on a new line */
which causes the extra 5 or so gray pixels to the right.
changing this to
width: calc(100% - 5px); /* Without this, words start on a new line */
gets rid of most of the extra space in right and appears not to cause any ill effects. What does the comment Without this, words start on a new line mean exactly?

I think
it did
something
like this
without it

But maybe it’s magically fixed.

this is what I see with

.avatar {
    border-radius:50%;
    margin-top: 0;
    margin-left: 0;
    margin-right: 0;
}
.left {
    min-height: 10px;
    height: 18px;
}
.center {
    /* background-color: yellow; */
    margin-right:0px;
    width: calc(100% - 5px); 
}
.message {
    min-height: 15px;
}
.right {
  margin-left: 0;
  /* background-color: gray; */
}

1 Like

@ahuang11 I think I figured out enough about ChatMessage and ChatFeed to start tackling ChatInterface.

  • How do I set the css style for the ChatMessages that the Send button inserts in the ChatFeed area?
  • Is there functionality in ChatInterface to create and append a ChatMessage to the ChatFeed area, or do I have to create it separately with the desired style and then append it?

To your first question, I’ll need to look.

Second, I think you can use message_params to propagate message kwargs.

I tried to answer Customize chatinterface - #6 by ea42gh
with what I know so far. There are some weird issues as shown in the screenshot I added there…

@ahuang11 There seems to be some kind of a styling problem (bug?)
when using the ChatInterface send button.

As shown in the attached image, when setting STYLE in the chatinterface,
the avatar is at the bottom of .left,
whereas using the same STYLE with ChatInterface.send displays it at the top of .left

Also, I cannot figure out for the life of me how to reduce the size of the avatar.
None of the settings I tried seem to affect it?!

Yeah looks funky. Do you have some minimal code I can run?

@ahuang11

message_params = dict(
    default_avatars = {"System": "☂️", "User": "👤"},   # this does not apply to creating a ChatMessage. Does ChatFeed have a creation function?
    reaction_icons  = {},
    show_user       = False,
    show_timestamp  = False,
    show_copy_icon  = False,
    sizing_mode     = "scale_width",
)
STYLE = """
.avatar {
    border-radius:50%;
    margin-top: 0;
    margin-left: 0;
    margin-right: 0;
}
.left {
    min-height: 10px;
    height: 18px;
}
.center {
    /* background-color: yellow; */
    margin-right:0px;
    width: calc(100% - 5px); 
}
.message {
    min-height: 15px;
}
.right {
  margin-left: 0;
  /* background-color: gray; */
}
"""
gui = pn.chat.ChatInterface( message_params=message_params,
                             show_rerun=False, show_undo=False,
                             stylesheets=[STYLE],
                             #css_classes=[STYLE],
                             widgets=pn.widgets.TextAreaInput(  placeholder=">", auto_grow=True, max_rows=10 ),
                             height=500,
                           )
gui

enter some text and press the send key.
Alternatively, run

msg = gui.send( pn.chat.ChatMessage(
                 avatar          = "☂️",
                 stylesheets     = [STYLE],
                 show_user       = False,
                 show_timestamp  = False,
                 show_copy_icon  = False,
                 sizing_mode     = "stretch_width",
))
txt=""
for n in "Updating the message works, streaming to it does not.... ":
    txt += n 
    msg.update(txt)

re last for loop: will work for now, but looking forward to your streaming fix! :grinning:

Oh I think you forgot to include stylesheets in message_params; due to the shadow dom, the stylesheets don’t cascade downward :frowning:

import panel as pn

pn.extension()

STYLE = """
.avatar {
    border-radius:50%;
    margin-top: 0;
    margin-left: 0;
    margin-right: 0;
}
.left {
    min-height: 10px;
    height: 18px;
}
.center {
    /* background-color: yellow; */
    margin-right:0px;
    width: calc(100% - 5px); 
}
.message {
    min-height: 15px;
}
.right {
  margin-left: 0;
  /* background-color: gray; */
}
"""

message_params = dict(
    default_avatars={
        "System": "☂️",
        "User": "👤",
    },  # this does not apply to creating a ChatMessage. Does ChatFeed have a creation function?
    reaction_icons={},
    show_user=False,
    show_timestamp=False,
    show_copy_icon=False,
    sizing_mode="scale_width",
    stylesheets=[STYLE]
)
gui = pn.chat.ChatInterface(
    message_params=message_params,
    show_rerun=False,
    show_undo=False,
    stylesheets=[STYLE],
    # css_classes=[STYLE],
    widgets=pn.widgets.TextAreaInput(placeholder=">", auto_grow=True, max_rows=10),
    height=500,
)
gui.show()

One other note, when 1.4.0 is released, you probably don’t want to use TextAreaInput. There’s a built-in pn.chat.ChatAreaInput for submitting on enter

I don’t get it:
style_sheets was the second parameter in message_params.

I copied and pasted your code into the notebook:
it does work as expected.

I ran my original copy, it also worked as expected!?! Spooky!

Shadow dom is a new concept for me: I’ll have some reading to do.

This only leaves the avatar size issue: any idea on how I can reduce its size?

Re pn.chat.ChatAreaInput submitting on <Enter> is the behavior that I do not want:
with the app I have in mind, The user will enter several sentences.
Could submit be bound to <Shift Enter> or <Ctrl Enter>?

No, it cannot be bound to Shift Enter (feel free to submit a feature request), but Shift Enter does allow multi line.
https://holoviz-dev.github.io/panel/reference/chat/ChatAreaInput.html