Let retool AI send first message in chat component

Hi all, I'm looking for a way to make the AI agent send the first message into the chat component when a user lands on the app. I have set the AI chat query to run on page load, which i thought would do it. But the query runs and doesn't populate the chat box. Any ideas?

Hi @Bruce_E

I think this will require a feature request :disappointed:

Just to confirm, are you looking to start the chat with a "response" from Retool AI? It seems like the chat component currently requires a user to start the chat, and then Retool AI can respond.

My best idea for a workaround is to try to use css to hide only the first chat (which would be a dummy chat from the user) so that you only see the response from the ai agent:

Here's an example JS query that is triggered on page load and sends the first "dummy" chat message from the user

@Tess

Hi Tess,

Thanks for this great hack.

when I run the query itself it works, but the CSS edit doesn't.

Instead of not showing the first it shows the first question and answer and then the answer:

:thinking: I'm guessing the css class names have changed. This guide shows how to find the class name to use: How to use Custom CSS in Retool Apps

it's possible to do this without CSS, here's how I did it:

  1. the 'intro' message that the ai sends as the 1st message should usually be removed from the message history. this message doesn't have any previous context so it shouldn't be used... openai lets you add initial messages to a thread when using the assistants api, which end up being ignored, but since we don't know if this is being used or if Retool is managing history on its own we want to 'normalize' things so it doesn't matter
    image
  2. now we can setup a new query that will first clear the message history then it will fake sending a message from the ai which is named '__retoolAI'. we'll set this to run on page load (you might need to delay it a bit) and in the next step we'll reuse it for clicking the 'clear history' button
    image
    image
  3. next we need to edit the 'Clear History' event to use our new custom query for clearing and resetting message history (mine is named query34)
  4. finally, we need to prevent chat1_query1 from running when we add our 'default' message. this step isn't exactly needed, but if you skip it you will see an error saying something about expected input text (this is a message from the ai, so there isn't any input text) and as a result chat1_query1 fails. coincidently, it failing and not running is what we want but for our sanity when debugging we should go ahead and and prevent it from even attempting to run. we can do this by disabling the query when the chat history has 1 or fewer items (0 items means the default message hasn't been added yet and 1 item means it's the only message. in both cases we don't want to run chat1_query1.

notes:

  • i'd suggest renaming query34 to init_chat1_history, clearHistoryShowDefault, chat1_clearHistory or something similar. this is so if you need to have another button to clear message history or if you have some code somewhere that needs to clear the history you can easily reuse the query. since we're implementing our own clear message history function if you accidently call chat1.clearHistory() instead of using our custom function the default message won't appear. we can fix this though, with a bit of a hack.... since JS Code Queries don't have an automatic mode for Run Behavior, we can create a wrapper around our clearMessageHistory query which will use this automatic mode and in-turn call our clear message query whenever the wrapper runs. for this we'll use the query JSON with SQL query type

    on success event handler:
    image
    advanced tab (see Watched inputs):

    and now you can click the button to clear the message history or you can call chat1.clearHistory() anywhere in JS and the default message will pop back up so now you don't have to remember to call a specific function anytime you want to clear the history.
2 Likes

Way better than css! Thank you for this detailed walkthrough :raised_hands:

1 Like

figured I'd give a sample app since I probably typed something out wrong.
Test_Chat_Default_Message.json (16.7 KB)

you can test it by clicking the 'clear history' button or running the testManualClear query to see it working both ways. there shouldn't be any errors when sending the 'fake' message or clearing the history

I followed your instructions and the AI chat still shows the prompt message which I am trying to hide from the user. In my case I want it to say something specific without showing the prompt that I give to the AI.

Any idea why would that be the case for me? Are there any other workarounds?

Hi @GuyDev

:thinking: I'm not sure why the prompt would show. I am not seeing the same issue with @bobthebear's app export. If you share your app export, I'll take a look.

Some additions to @bobthebear's app that seem to get us closer to your use case are:

  1. Modify the disable condition on the chat1_query1 query to filter for only the user's posts:
  2. Modify the clearMessageHistory query's disable condition so that it only runs when there is no chat history: {{ chat1.messageHistory.length>0 }}
  3. Modify the clearMessageHistory query to send a message from the clearMessageHistoryWrapper query:
  4. Change the clearMessageHistoryWrapper query to an AI query with your prompt:
  5. Set the clearMessageHistoryWrapper query run behavior to automatic & modify the clearMessageHistoryWrapper query's disable condition so that it only runs when there is no chat history: {{ chat1.messageHistory.length>0 }}

Hi Tess, thank you for you response. Your explanation was very helpful. However, there are a couple of things that I still need to adjust.

First, I want to give the AI Chat a different name, so that it shows in the chat as "Intelligent Assistant" for example, and not "Retool AI".
When I try to change it in clearMessageHistory, it changes the name but does not hide the message and shows my user profile image.

In addition, I would like to have a button that would inject a prompt to the AI Chat without the user seeing the prompt. The user should be able to click on this button at any point and receive a response from the AI Chat without seeing what the prompt was.

I should also mention that I liked bobthebear's and your approach because it didn't save the prompt to the chat history, which is good because I want the user to be able to download the chat history without seeing the prompt injections. Doing it with CSS as your previous suggestion does not achieve this result.

Sorry if my request is a bit much. I will try to find solutions on my own, but if you have any ideas it will be much appreciated.

First, I want to give the AI Chat a different name, so that it shows in the chat as "Intelligent Assistant" for example, and not "Retool AI".

You can control the AI bot's name here:
CleanShot 2025-03-05 at 16.38.57@2x
You cannot control the AI bot's avatar, but you can control the end user's avatar under Add-ons:
CleanShot 2025-03-05 at 16.39.27@2x

I would like to have a button that would inject a prompt to the AI Chat without the user seeing the prompt. The user should be able to click on this button at any point and receive a response from the AI Chat without seeing what the prompt was.

You can solve this with another chat query that is similar to clearMessageHistoryWrapper in the above example except that it doesn't need the disable condition and it would be a manual query that only triggers on button click. Similar to clearMessageHistoryWrapper, it would have a success event that posts the AI response to the chat component

For the time being, I'm going to mark @bobthebear's response as a solution so that folks can easily find it. I will still reach out here if we ship a native feature for this