Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chat component's auto-scroll not working when used with a web component #1121

Open
TheFirstMe opened this issue Dec 1, 2024 · 4 comments
Open
Labels
bug Something isn't working

Comments

@TheFirstMe
Copy link

TheFirstMe commented Dec 1, 2024

Describe the bug
The auto-scroll from the chat component is not working when a web component is added after the chat component.

To Reproduce
Steps to reproduce the behavior:

  1. Clone the repo from https://github.com/TheFirstMe/mesop-fastapi-chat-bug/
  2. Start the application Go to http://127.0.0.1:8000/
  3. Enter any message in the chat
  4. See error in console

Expected behavior
After user enters the message, the auto-scroll behaviour should take place.

Screenshots
Image

Desktop System Info

  • OS: Ubuntu
  • Browser Microsoft Edge
  • Version 22.04

Additional context

  • The Mesop app is mounted to a FastAPI application.
  • The Mesop app code used can be found here: https://github.com/TheFirstMe/mesop-fastapi-chat-bug/blob/main/app/ui/main.py
    @me.page(
        security_policy=me.SecurityPolicy(
            allowed_script_srcs=["https://cdn.jsdelivr.net"],
            allowed_iframe_parents=["https://google.github.io", "https://huggingface.co"],
        ),
        path="/",
        title="Mesop Demo Chat",
        on_load=on_load,
    )
    def page():
        mel.chat(transform, title="Mesop Demo Chat", bot_user="Mesop Bot")
        test_component() # Removing this line fixes the issue
  • This issue does not happen when I remove the web component from the page.
@TheFirstMe TheFirstMe added the bug Something isn't working label Dec 1, 2024
@richard-to
Copy link
Collaborator

Hmm, that's a weird issue. Not immediately clear to me why the scroll command would not be able to find the component when you add a web component.

Thanks for the repro code. I'll try to test it out some time this week.

@richard-to
Copy link
Collaborator

Ok. I took a look. I was able to repro the issue from your repo. And then repro'd against head.

I don't know the exact reason why adding a web component causes the scroll to to fail. My guess is that it maybe it slows rendering down a bit. In the mel.chat case, we have a hidden div that appears.

Here's the code in question (https://github.com/google/mesop/blob/main/mesop/web/src/shell/shell.ts). To fix the issue at least for mel.chat, I added 500 ms delay in the timeout. That seemed to work. I think at 400ms, it also worked. But 300ms did not.

However, I'm on the fence for if we should add the 500ms delay here since for use cases where the element already exists and is visible, the delay is likely not needed. And in some cases, perhaps, the delay could be larger.

            // Scroll into view
            const key = command.getScrollIntoView()!.getKey();
            // Schedule scroll into view to run after the current event loop tick
            // so that the component has time to render.
            setTimeout(() => {
              const targetElements = document.querySelectorAll(
                `[data-key="${key}"]`,
              );
              console.log(targetElements);
              if (!targetElements.length) {
                console.error(
                  `Could not scroll to component with key ${key} because no component found`,
                );
                return;
              }
              if (targetElements.length > 1) {
                console.warn(
                  'Found multiple components',
                  targetElements,
                  'to potentially scroll to for key',
                  key,
                  '. This is probably a bug and you should use a unique key identifier.',
                );
              }
              targetElements[0].parentElement!.scrollIntoView({
                behavior: 'smooth',
              });
            }, 500);

For a short term fix, you can also make a copy of mel.chat (https://github.com/google/mesop/blob/main/mesop/labs/chat.py). You can save the file as chat.py and then import it. You can then basically use it the same as mel.chat.

Some where in that file, you'll see code like this:

    output = state.output
    if output is None:
      output = []
    output.append(ChatMessage(role=_ROLE_USER, content=input))
    state.in_progress = True
    me.scroll_into_view(key="scroll-to")
    yield

    start_time = time.time()
    output_message = transform(input, state.output)
    assistant_message = ChatMessage(role=_ROLE_ASSISTANT)
    output.append(assistant_message)
    state.output = output

Basically, you can manually add a sleep here like this:

    output = state.output
    if output is None:
      output = []
    output.append(ChatMessage(role=_ROLE_USER, content=input))
    state.in_progress = True
    yield
    # Add delay before rendering the scroll into view
    time.sleep(0.5)
    me.scroll_into_view(key="scroll-to")
    yield

    start_time = time.time()
    output_message = transform(input, state.output)
    assistant_message = ChatMessage(role=_ROLE_ASSISTANT)
    output.append(assistant_message)
    state.output = output

I think I will probably update mel.chat with the custom sleep for a short term fix.

@TheFirstMe
Copy link
Author

@richard-to Thanks! The workaround fixed the issue.

@wwwillchen
Copy link
Collaborator

I'm wondering if we can use afterRender to more reliably run the scroll command: afterRender

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants