sbik
sbik

Reputation: 55

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

Upvotes: 1

Views: 192

Answers (1)

Jan
Jan

Reputation: 9348

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)

Upvotes: 1

Related Questions