def _prep_text(s: str) -> str: """Remove punctuation and lowercase string.""" punctuation = set("""!()-[]{};:'"\,<>./?@#$%^&*_~""") # Remove the punctuation from the string no_punct = "".join(char for char in s if char not in punctuation) return no_punct.lower() def is_text_a_likely_chatgpt_balk(text: str) -> bool: """Try to determine whether text represents ChatGPT's refusal to answer a prompt.""" # this is admittedly an inelegant way to solve this problem. However, we want to be very high # precision here in order to avoid blocking legitimate lyrics that sound similar to a GPT balk, so we # elect to keep a list of hard-coded phrases and update them (increasingly rarely) over time. positive_tells = [ "im really sorry", "im sorry but", "sorry i couldnt understand", "but im unable", "i am not able to", "im unable to", "can only generate", "i cant provide", "cant write lyrics", "have lyrics", "couldnt generate", "unable to generate", "able to generate", "generate lyrics", "able to provide", "provide lyrics", "generate song lyrics", "unable to provide", "not familiar with", "currently unable to", "sorry i cant", "sorry im not able", "not capable of", "ai model", "ai language model", "language model", "ai textbased model", "sure i can help", "i can help with that", "not programmed to", "a bit more detail", "fulfill this request", "fulfill that request", "to create lyrics", "to write lyrics", "write lyrics for", "didnt quite understand", "i couldnt quite understand", "couldn't understand the prompt", "couldn't understand your prompt", "happy to help", "able to access", "please provide", "sure thing", "some lyrics", "do not include the genre or musical style in the lyrics", ] negative_tells = ["weve"] prepped_text = _prep_text(text) score = sum(tell in prepped_text for tell in positive_tells) - sum( tell in prepped_text for tell in negative_tells ) num_lines = len(text.split("\n")) if num_lines <= 2: # a short response is highly likely to be a refusal score += 1 return score >= 2