pythonchatbotequationpy-shiny

How to get Shiny Chat's response to display formatted math equations?


I am trying to get this example app to output formated math equations. The shiny chat tutorial here suggests a custom response display, but I am unable to get the suggested @chat.transform_assistant_response to modify the formating. I used the code below as is:

@chat.transform_assistant_response
def _(content: str) -> ui.HTML:
    return ui.markdown(content)

adding transform_assistant=True to chat.messages() but I saw no change of the formating of the response. I need help getting formated math equations of the reponse.

As is, submitting for example 'solve x^2-4=0' will return something like this: enter image description here


Solution

  • A possibility is that you add MathJax and set it up accordingly. And then one important point is that after a message is appended, we send a typeset queue such that the newly inserted content is rendered correctly.

    Here it is implemented that we can send a message and use inlineMath (using $) and displayMath (using $$) to render the input mathematically.

    Extending the output using @chat.transform_assistant_response is possible, however, in the below example it is not needed.

    enter image description here

    from shiny import App, Inputs, Outputs, Session, ui
    
    mathjax = ui.head_content(
        ui.tags.script(
            src="https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
        ),
        ui.tags.script("""if (window.MathJax) {
            MathJax.Hub.Config({
                tex2jax: {
                    inlineMath: [["$", "$"], ["\\\\(", "\\\\)"]],
                    displayMath: [["$$", "$$"], ["\\[", "\\]"]],
                    processEscapes: true
                },
                config: ["MMLorHTML.js"],
                jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"],
                extensions: ["MathMenu.js", "MathZoom.js"]
            });
            $(function() {
                Shiny.addCustomMessageHandler("typeset", function(message) {
                    MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
                });
            });
            }
            """),
    )
    
    app_ui = ui.page_fillable(
        mathjax,
        ui.panel_title("Hello $\LaTeX$ Shiny Chat"),
        ui.chat_ui("chat"),  
        fillable_mobile=True,
    )
    
    def server(input: Inputs, output: Outputs, session: Session):
        # Create a chat instance and display it
        chat = ui.Chat(id="chat")
    
        # Define a callback to run when the user submits a message
        @chat.on_user_submit  
        async def _():
            # Simply echo the user's input back to them
            await chat.append_message(f"""Input rendered as math: <br> 
                                      {chat.user_input()}
                                      """) 
            # trigger MathJax typeset 
            await session.send_custom_message("typeset", {"msg": "dummy"})
    
    app = App(app_ui, server)