Post

[HAI5016] Your daily menu briefing

[HAI5016] Your daily menu briefing

In our final class, we will connect the last pieces of the semester into one end-to-end workflow. First we add a menu scraping function from GitHub and run it with GitHub Actions, then we add a parser and database table in the same way, and finally we give our agent a SQL tool so it can query the data directly.

Disclaimer: This blog provides instructions and resources for the workshop part of my lectures. It is not a replacement for attending class; it may not include some critical steps and the foundational background of the techniques and methodologies used. The information may become outdated over time as I do not update the instructions after class.

Model switch: I decided to switch the base model for our Agent and other scripts from gpt-5-nano to gpt-5-mini. While the nano is cheaper and faster, I found that the mini produces more accurate and relevant responses for our use case, especially when it comes to parsing and SQL queries. The mini is still very affordable and should work well within our budget, while providing a better experience for our agent’s capabilities.

So you may deploy the gpt-5-mini model in your Azure Foundry first, and then update your .env file with the following line:

1
AZURE_OPENAI_DEPLOYMENT_NAME="gpt-5-mini"

Before you move on with the GitHub actions below, make sure that you have added the required secrets to your environment variables in GitHub, as described in last week’s class.

1. Menu scraper and GitHub Actions

  1. Make sure the scrape.py file in your project looks similar to the one in my GitHub repository, which you can find here: scrape.py
  2. Have Copilot create a new GitHub Actions workflow in your repository that runs the scraper every morning at 7am.
  3. Commit and push the changes to GitHub
  4. On github.com, go to the Actions tab of your repository and check that the workflow is listed there.
  5. Trigger the workflow manually for the first time to make sure it runs without errors

GitHub Actions - Daily Scrape That’s what success looks like

If any errors show up in the workflow run, check the logs to see what went wrong. Common issues might be related to missing secrets, incorrect file paths, or issues with the scraper code itself. Fix any errors and try running the workflow again until it completes successfully. Of course you can ask Copilot for help if you get stuck!

After a successful run, check your Supabase database to see if the scraped data has been stored correctly.

  1. Go to the database in your Supabase dashboard
  2. Click on Table editor in the left sidebar
  3. Open the scraped_html_snapshots table
  4. In the top filter bar, set the filter to scrape_date is 2026-06-04 (or the current date) and apply the filter

Supabase Table Filter scrape_date = 2026-06-04

Alternatively, you can use the SQL editor to run the query below in the SQL editor:

1
2
SELECT * FROM public.scraped_html_snapshots 
WHERE scrape_date = '2026-06-04';

2. Parser, table creation, and GitHub Actions

To catch up with the parsed menu data from my previous runs, let’s create a ‘campus_menu_items` and populate it with the parsed data from my previous runs.

Create the table and insert historical data

  1. Make sure you have your table editor open in the Supabase dashboard
  2. To create the table for parsed menu items, run the SQL script found at supabase/create_menu_items_table.sql in the SQL editor of your Supabase dashboard. This will create a new table called campus_menu_items with the appropriate structure to store the parsed menu data.
  3. To fill the table with the parsed data from my previous runs, run the SQL script found at supabase/insert_menu_items.sql in the SQL editor. This will insert the parsed menu items from my previous runs into your campus_menu_items table, so you can have some data to work with when we add the SQL tool to our agent.

Now check your campus_menu_items table in the table editor to see if the parsed menu items have been inserted correctly. You should see a list of around 350 menu items with their names, descriptions, dates, and other relevant information.

Add and test the parser

  1. Copy the parser code parse_menu_items.py from my GitHub repository into your project’s root directory
  2. Run the parser and examine the logs
  3. If the run was successful, check the campus_menu_items table in your Supabase dashboard to see if the parsed menu items have been inserted correctly. You should see new entries for the current date with the parsed menu data.

Menu Parser log How many rows were inserted?

Add the parser to GitHub Actions

If time allows, you can also add the parser to your GitHub Actions workflow so that it runs automatically after the scraper. You can modify your existing workflow file (e.g., daily-scrape.yml) to include a step that runs the parser after the scraping step. Make sure to test the workflow again to ensure that both the scraper and parser run successfully and that the parsed data is stored in your Supabase database. Of course, you can ask Copilot to help you with this.


3. Add a SQL tool to the agent

Your Repository

To speed things up I have vibe-coded the get_menu function before class, so you can copy the code from [getmenus.py] to your repository along with final_agent.ipynb which looks very similar to first_agent.ipynb but with the SQL tool added and tested. You can find both files in my GitHub repository:

  1. Copy the getmenus.py file from my GitHub repository into your project’s root directory
  2. Copy the final_agent.ipynb file from my GitHub repository into your project’s root directory
  3. Open final_agent.ipynb and run the cells to test the agent’s ability to answer menu-related questions using the SQL tool that queries the campus_menu_items table in your Supabase database

Curious what the Agent is doing behind the scenes when it receives a question about the menu? Check the logs in the logs/ directory to see the agent’s thought process, or check your LangSmith dashboard to see the agent’s actions and tool calls in real time!


4. Send the daily menu per email

This section is optional and can be skipped if you don’t have time, but it would be a nice finishing touch to have the agent email the daily menu to you automatically.

SMTP2GOVerified Sender

Create an SMTP2GO account and API key

  1. Go to https://www.smtp2go.com/
  2. Create a free account and verify your email address
  3. Login to the dashboard and add your @skku.edu email as a Single sender email
  4. Check your email for the verification email and click the link to verify
  5. In the dashboard go to API Keys and click Add API Key
  6. Copy the generated API key and add it as SMTP2GO_API_KEY in your .env file
  7. Also add your @skku.edu email as SMTP2GO_SENDER_EMAIL in the .env file
  8. Back in the dashboard write a description for the API key and click Add API Key

Now let’s add a very simple email sending function to our project:

Make sure your .env file has the following variables set:

1
2
3
SMTP2GO_API_KEY="api-YOURKEYHERE"
SMTP2GO_SENDER_EMAIL="your_verified_email"
SMTP2GO_RECIPIENT_EMAIL="where_you_want_to_receive_the_menu"
  1. Find the Send an email instructions in the SMTP2GO API docs
  2. In the upper right, click on Copy page
  3. Select a cell or location in our project where you want to add the email function, ask Copilot to

    Write a function that sends the agent's response as an html_body via SMTP2GO API to SMTP2GO_RECIPIENT_EMAIL from SMTP2GO_SENDER_EMAIL using the SMTP2GO_API_KEY found in the .env file. Don't forget to log every step in logs/ with loguru like the rest of the code. Refer to the following documentation:

    and paste the copied page into the prompt

Then, test the function. Did you get an email?

Convert the notebook into a python script

In order to run the script in GitHub Actions, we need to convert the final_agent.ipynb notebook into a python script. You can easily do this in Visual Studio Code:

  1. Open the final_agent.ipynb notebook in VS Code
  2. In the upper right corner of the notebook editor, click on the Export button
  3. Select Export to Python from the dropdown menu
  4. This will create a new file called final_agent.py in the same directory as the notebook
  5. Open the final_agent.py file and make sure it runs without errors

Project History

This post is licensed under CC BY 4.0 by the author.