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

Add window.postMessage support. #1162

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

mauanga
Copy link

@mauanga mauanga commented Jul 24, 2024

Description

This update enhances the functionality of the Chainlit application when it is embedded within another web application via an iframe. By enabling message exchange between the parent and child windows, the application can now support extended features. Some examples of the use cases would be; allowing users to select datasets from their dashboard, supply saved prompts, and more.

Changes

  1. Added an event listener listening for window message events in AppWrapper.tsx.
  2. Added a callback to emit the window_message event in useChatInteract.ts
  3. Added a new decorator on_window_message to __init__.py
  4. Added the callback for the decorator in config.py
  5. Added a socket io event window_message in socket.py

@mauanga mauanga marked this pull request as ready for review July 29, 2024 07:51
@dokterbob
Copy link
Collaborator

Interesting feature!

Code looks clean, on quick review.

@mauanga Is there any chance you could add a test for this feature in https://github.com/Chainlit/chainlit/tree/main/cypress/e2e?

@dokterbob dokterbob added the enhancement New feature or request label Sep 3, 2024
@mauanga
Copy link
Author

mauanga commented Sep 6, 2024

@dokterbob Thanks for taking the time to review the PR.

I’ve made a small update to include support for 2-way messaging, which now allows messages to also be sent from the backend to a listening host window.

I'll start working on the cypress e2e test and will add it to the PR soon.

@jfperusse-bhvr
Copy link

@mauanga Just tested this PR and it's great! I would suggest initializing the context inside window_message(sid, data) so we can use cl when receiving the message. As a test, with this change, I was able to remove actions from the user interface after receiving the message in my iframe (context initialization is based on the other decorators):

@sio.on("window_message")
async def window_message(sid, data):
    """Handle a message send by the host window."""
    session = WebsocketSession.require(sid)
    context = init_ws_context(session)

    await context.emitter.task_start()

    if config.code.on_window_message:
        try:
            await config.code.on_window_message(data)
        except asyncio.CancelledError:
            pass
        finally:
            await context.emitter.task_end()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing from BaseChainlitEmitter:

    async def send_window_message(self, data: Any):
        """Stub method to send custom data to the host window."""
        pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants