You can try with the Gmail threadId of your first email and check that thread before every follow-up. If the thread contains any message from the lead, stop.
Replies always land in the same Gmail thread. threadId is the most reliable key (better than subject or searching the inbox).
1) When you send the first email
In the Gmail Send output you get id and threadId.
Append to Sheet these fields alongside the lead:
email
threadId
status
last_contacted_at
2) Create a “reply listener” workflow (separate)
This keeps your main flow simple and avoids trying to “cancel” waits.
Gmail Trigger → New Email
IF node to ignore your own messages {{$json.from.email}} does not contain your_domain_or_email_address
Google Sheets → Lookup row by threadId = {{$json.threadId}}
IF: row found
Google Sheets → Update row status = replied, replied_at = {{$now}}
As soon as a reply comes in, the row is marked replied. You don’t need to wake/cancel the waiting execution.
The main flow will check the sheet before sending the next follow-up.
3) In your follow-up sequence (the one in your screenshot)
Right after each Wait, you already have a Lookup. Make it check by threadId or email. Then:
IFstatus == replied → Stop (don’t send).
Else → send the next follow-up, then Update row (e.g., last_contacted_at, status = pending_f1/f2, etc.).
That’s it. Replies stop the sequence because the status flips before the next send.