h2oai / wave

Realtime Web Apps and Dashboards for Python and R
https://wave.h2o.ai
Apache License 2.0
4.01k stars 328 forks source link

Swap chatbot card sides - user on right, bot on left #1983

Closed maxjeblick closed 1 year ago

maxjeblick commented 1 year ago

Wave SDK Version, OS

Wave nightly, see H2O LLm Studio.

Actual behavior

After moving the user input to the right side in H2O LLm Studio (see here), the user prompt shortly appears on the left before moving to the right hand side. After discussion with @pascal-pfeiffer, we think this may be an issue related to wave. Also note that Pascal does not see this particular behavior.

Attached is a short recording of the actual issue: chat_wave.zip

Expected behavior

Chat immediately appears on the right.

Steps To Reproduce

  1. Start H2O Llm studio and run an experiment
  2. After the experiment has finished, go to chat window and start chatting
mturoci commented 1 year ago

Thanks for reporting @maxjeblick! Can we get a min repro code? Based on video, it seems like the fromUser is changed dynamically during streaming, but not sure. Cannot repro on our simple example code.

maxjeblick commented 1 year ago

Hi Martin, thanks for looking into this! Below is a minimal example. The important part is the sleep before saving the page, otherwise it is not noticeable.

import time

from h2o_wave import main, app, Q, ui, data  # NOQA

USER = False
BOT = True

@app('/')
async def serve(q: Q):
    if not q.client.initialized:
        # Use map buffer with sortable keys to store messages - allows indexing + streaming the chat messages.
        q.client.msg_num = "0"
        map_buffer = data(fields='msg fromUser', rows={'0': ['Hey!', BOT]})
        q.page['example'] = ui.chatbot_card(box='1 1 5 5', data=map_buffer, name='chatbot')
        q.page['meta'] = ui.meta_card(box='', theme='h2o-dark')
        q.client.initialized = True

    # A new message arrived.
    if q.args.chatbot:
        # Append user message.
        q.client.msg_num += "1"
        q.page['example'].data[q.client.msg_num] = [q.args.chatbot, USER]

        # Append bot response.
        q.client.msg_num += "1"
        chatbot_response = 'I am a fake chatbot.'
        q.page['example'].data[q.client.msg_num] = [chatbot_response, BOT]
        time.sleep(0.5)
        await q.page.save()

    await q.page.save()
mturoci commented 1 year ago

@maxjeblick seems like a user error. If you look closer at the data buffer fields, you can see that the second param is called fromUser which means, if True, the message should be rendered on the "user side".

Seems like swapping

USER = False
BOT = True

to

BOT= False
USER = True

resolves the problem. I am still looking for feedback on how to make this chatbot card more user-friendly and less confusing.

pascal-pfeiffer commented 1 year ago

Thank you for looking into this @mturoci

The switch was intentional to have the same experience as in WhatsApp and other messengers where we have the user input on the right side. The question is: Why are the two sides not exchangeable? The even cleaner solution would probably be a new flag that allows to swap the sides and also swaps the color scheme. The above code was only meant as a workaround.

mturoci commented 1 year ago

I see.

Why are the two sides not exchangeable?

The reason is consistency between Wave apps. I am fine with whatever default most people agree to. I learned that the less control people have over these, the better.

pascal-pfeiffer commented 1 year ago

I see, that makes sense. Then, I would vote for swapping the sides (as it seems to be the default for chat apps) and closing this issue.