|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os |
|
|
from urllib.parse import uses_query |
|
|
from dotenv import load_dotenv |
|
|
|
|
|
from langchain_core.messages import SystemMessage, HumanMessage |
|
|
from langchain_core.tools import tool |
|
|
from langchain_openai import ChatOpenAI |
|
|
from langgraph.prebuilt import create_react_agent |
|
|
|
|
|
|
|
|
from transformers import pipeline |
|
|
import torch |
|
|
|
|
|
import gradio as gr |
|
|
|
|
|
|
|
|
from utils import clean_text |
|
|
from html_blocks import FEATURES_HTML, NOTE_HTML |
|
|
from css_blocks import CSS_ELEMENTS |
|
|
|
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") |
|
|
OPENAI_MODEL_ID = "gpt-5-mini" |
|
|
TEXT_DETECTOR_MODEL_ID = "fakespot-ai/roberta-base-ai-text-detection-v1" |
|
|
llm = ChatOpenAI(api_key=OPENAI_API_KEY, model=OPENAI_MODEL_ID) |
|
|
|
|
|
system_message = SystemMessage("You are a helpful assistant that most accurately can tell ai written text from human written one.") |
|
|
user_input="""Brooo, you won’t believe what happened today 😭 So I’m just minding my own business, right? Grabbing coffee like a civilized human being, and this barista legit calls out “Caramel macchiato for Michael” — and I’m like “bet, that’s me,” grab it, walk out all confident… only to realize halfway down the street it says soy latte, extra shot, no whip 😭😭 Bro, I straight up stole someone’s drink and been sipping on sadness the whole way home. It was actually kinda fire tho ngl 😅 Anyway, how’s your day been? You still surviving or already plotting your escape from adulthood? |
|
|
""" |
|
|
|
|
|
|
|
|
@tool |
|
|
def detect_text(text): |
|
|
""" Process AI text detection using fakespot-ai/roberta-base-ai-text-detection-v1 model. |
|
|
It returns its result in a List[Dict] form. |
|
|
e.g. [{'label': 'AI', 'score': 0.9998624324798584}] |
|
|
""" |
|
|
classifier = pipeline( |
|
|
"text-classification", |
|
|
model=TEXT_DETECTOR_MODEL_ID |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
num_words = 300 |
|
|
batched_words = [] |
|
|
words: List = text.split() |
|
|
|
|
|
if len(text.split()) >= num_words: |
|
|
for i in range(0, len(words), num_words): |
|
|
chunk = " ".join(words[i: i + num_words]) |
|
|
batched_words.append(chunk) |
|
|
|
|
|
|
|
|
cleaned_text = classifier([clean_text(t) for t in batched_words]) |
|
|
label_result = cleaned_text[0]["label"] |
|
|
score_result = cleaned_text[0]["score"] |
|
|
|
|
|
return label_result, score_result |
|
|
else: |
|
|
cleaned_text = classifier(clean_text(text)) |
|
|
label_result = cleaned_text[0]["label"] |
|
|
score_result = cleaned_text[0]["score"] |
|
|
|
|
|
return label_result, score_result |
|
|
|
|
|
|
|
|
def generate_dynamic_query(text, label, score): |
|
|
|
|
|
query = f""" |
|
|
Detect the text of the given input: {text} |
|
|
AI-text likelihood score is given by another open source llm and the score will be given through the tool call as below: |
|
|
Label: {label} |
|
|
Score: {score:.3f} |
|
|
|
|
|
Based on all those(input text for your own analysis) and the score given by the function, |
|
|
give the final answer within 3-5 lines why it's assumed to be human or AI written text in a narrative and descriptive manner. |
|
|
""" |
|
|
return query |
|
|
|
|
|
|
|
|
def run_agent(text_input): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
label, score = detect_text(text_input) |
|
|
query = generate_dynamic_query(text_input, label, score) |
|
|
|
|
|
tools = [detect_text] |
|
|
|
|
|
|
|
|
agent_executor = create_react_agent( |
|
|
model=llm, tools=tools, prompt=system_message |
|
|
) |
|
|
|
|
|
result = agent_executor.invoke( |
|
|
{"messages": [{"role": "user", "content": query}]} |
|
|
) |
|
|
|
|
|
|
|
|
label = "🧒 Likely " + label if label == "Human" else "🤖 Likely " + label |
|
|
score = f"{score * 100: .2f}" + "%" |
|
|
|
|
|
|
|
|
return result["messages"][-1].content, label, score |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with gr.Blocks(css=CSS_ELEMENTS, title="AI WRITTEN TEXT DETECTOR") as demo: |
|
|
gr.Markdown( |
|
|
""" |
|
|
## 🕵️ AI GENERATED TEXT DETECTOR |
|
|
Analyze your text and discover how likely it is to be AI-generated. |
|
|
""", |
|
|
elem_id="app_title" |
|
|
) |
|
|
with gr.Column(): |
|
|
with gr.Row(): |
|
|
inp = gr.TextArea(placeholder="Paste your text to analyze", label="Text Input", lines=20, scale=2) |
|
|
features_desc = gr.HTML(FEATURES_HTML, elem_classes=["features_description"]) |
|
|
|
|
|
button = gr.Button("Analyze Text", elem_classes=["analyze_btn"]) |
|
|
gr.HTML(NOTE_HTML) |
|
|
|
|
|
with gr.Column(): |
|
|
with gr.Row(): |
|
|
label_output = gr.Textbox( |
|
|
label="Detected Label", |
|
|
placeholder="AI / Human", |
|
|
scale=1 |
|
|
) |
|
|
score_output = gr.Textbox( |
|
|
label="Confidence Score", |
|
|
placeholder="0.000", |
|
|
scale=1 |
|
|
) |
|
|
|
|
|
analysis_output = gr.TextArea( |
|
|
label="Analysis Result", |
|
|
placeholder="Model's explanation will appear here...", |
|
|
lines=6 |
|
|
) |
|
|
|
|
|
button.click( |
|
|
fn=run_agent, |
|
|
inputs=inp, |
|
|
outputs=[analysis_output, label_output, score_output] |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
port = os.getenv("PORT", 7860) |
|
|
demo.launch(server_name="0.0.0.0", server_port=port) |
|
|
|
|
|
|
|
|
|