Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -11,7 +11,6 @@ def analyze_scam(message_content):
|
|
| 11 |
if not message_content.strip():
|
| 12 |
return "β Please enter a message or URL to analyze."
|
| 13 |
|
| 14 |
-
# Show loading message with animation
|
| 15 |
loading_messages = [
|
| 16 |
"π‘οΈ Initializing AI security team...",
|
| 17 |
"π Claim Extractor analyzing suspicious content...",
|
|
@@ -20,137 +19,59 @@ def analyze_scam(message_content):
|
|
| 20 |
"π¨ Generating comprehensive scam analysis..."
|
| 21 |
]
|
| 22 |
|
| 23 |
-
|
| 24 |
-
yield loading_messages[0]
|
| 25 |
|
| 26 |
try:
|
| 27 |
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0.1)
|
| 28 |
|
| 29 |
-
# Show progressive loading messages
|
| 30 |
for i, message in enumerate(loading_messages[1:], 1):
|
| 31 |
-
time.sleep(
|
| 32 |
-
yield message
|
| 33 |
|
| 34 |
-
# Specialized scam detection agents
|
| 35 |
extractor_agent = Agent(
|
| 36 |
role="Claim Extractor",
|
| 37 |
goal="Extract key claims, offers, and suspicious elements from messages or URLs",
|
| 38 |
-
backstory="Expert at parsing and identifying key claims in potentially fraudulent messages.
|
| 39 |
llm=llm,
|
| 40 |
verbose=False
|
| 41 |
)
|
| 42 |
|
| 43 |
verifier_agent = Agent(
|
| 44 |
role="Fact Checker",
|
| 45 |
-
goal="Verify claims and assess scam probability
|
| 46 |
-
backstory="Cybersecurity expert who
|
| 47 |
llm=llm,
|
| 48 |
verbose=False
|
| 49 |
)
|
| 50 |
|
| 51 |
explainer_agent = Agent(
|
| 52 |
role="Safety Advisor",
|
| 53 |
-
goal="Provide clear, actionable guidance to users
|
| 54 |
-
backstory="Digital safety educator who
|
| 55 |
llm=llm,
|
| 56 |
verbose=False
|
| 57 |
)
|
| 58 |
|
| 59 |
-
# Scam detection tasks
|
| 60 |
extract_task = Task(
|
| 61 |
-
description=f""
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
Content: {message_content}
|
| 65 |
-
|
| 66 |
-
1. KEY CLAIMS AND PROMISES:
|
| 67 |
-
- Specific offers or promises made
|
| 68 |
-
- Money, prizes, or rewards mentioned
|
| 69 |
-
- Time-sensitive offers or deadlines
|
| 70 |
-
- Requirements for personal information
|
| 71 |
-
|
| 72 |
-
2. SUSPICIOUS ELEMENTS:
|
| 73 |
-
- URLs and links present
|
| 74 |
-
- Contact information requests
|
| 75 |
-
- Payment or banking details requests
|
| 76 |
-
- Urgency indicators and pressure tactics
|
| 77 |
-
|
| 78 |
-
3. LANGUAGE PATTERNS:
|
| 79 |
-
- Threatening language about account suspension
|
| 80 |
-
- Too-good-to-be-true offers
|
| 81 |
-
- Spelling and grammar issues
|
| 82 |
-
- Official-sounding but suspicious language
|
| 83 |
-
|
| 84 |
-
Extract and categorize all suspicious elements found.
|
| 85 |
-
""",
|
| 86 |
-
expected_output="Structured summary of extracted claims, suspicious elements, and language patterns",
|
| 87 |
agent=extractor_agent
|
| 88 |
)
|
| 89 |
|
| 90 |
verify_task = Task(
|
| 91 |
-
description=""
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
1. SCAM PATTERN ANALYSIS:
|
| 95 |
-
- Check for common phishing patterns
|
| 96 |
-
- Identify fake urgency tactics
|
| 97 |
-
- Detect impersonation attempts
|
| 98 |
-
- Analyze too-good-to-be-true claims
|
| 99 |
-
|
| 100 |
-
2. URL AND CONTACT ANALYSIS:
|
| 101 |
-
- Evaluate suspicious domain patterns
|
| 102 |
-
- Check for URL shorteners or redirects
|
| 103 |
-
- Assess contact method legitimacy
|
| 104 |
-
- Identify potential malicious links
|
| 105 |
-
|
| 106 |
-
3. RISK SCORING:
|
| 107 |
-
- Calculate overall scam probability (0-100%)
|
| 108 |
-
- Identify specific red flags
|
| 109 |
-
- Categorize risk level (Low/Medium/High)
|
| 110 |
-
- List concerning elements found
|
| 111 |
-
|
| 112 |
-
Provide comprehensive risk assessment with specific evidence.
|
| 113 |
-
""",
|
| 114 |
-
expected_output="Risk assessment with scam probability score, red flags, and evidence",
|
| 115 |
agent=verifier_agent,
|
| 116 |
context=[extract_task]
|
| 117 |
)
|
| 118 |
|
| 119 |
explain_task = Task(
|
| 120 |
-
description=""
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
1. EXECUTIVE SUMMARY:
|
| 124 |
-
- Clear verdict: LIKELY SCAM / SUSPICIOUS / PROCEED WITH CAUTION
|
| 125 |
-
- Risk level and confidence score
|
| 126 |
-
- Primary red flags in simple terms
|
| 127 |
-
|
| 128 |
-
2. EXPLANATION:
|
| 129 |
-
- Why this appears to be a scam
|
| 130 |
-
- Specific tactics being used
|
| 131 |
-
- What makes it suspicious
|
| 132 |
-
- Common patterns identified
|
| 133 |
-
|
| 134 |
-
3. RECOMMENDED ACTIONS:
|
| 135 |
-
- Immediate steps to take
|
| 136 |
-
- What NOT to do
|
| 137 |
-
- How to report if applicable
|
| 138 |
-
- General safety tips
|
| 139 |
-
|
| 140 |
-
4. NEXT STEPS:
|
| 141 |
-
- Block sender/source
|
| 142 |
-
- Report to authorities
|
| 143 |
-
- Verify independently if needed
|
| 144 |
-
- Stay vigilant for similar attempts
|
| 145 |
-
|
| 146 |
-
Provide clear, actionable guidance in plain English.
|
| 147 |
-
""",
|
| 148 |
-
expected_output="User-friendly safety report with clear recommendations and next steps",
|
| 149 |
agent=explainer_agent,
|
| 150 |
context=[extract_task, verify_task]
|
| 151 |
)
|
| 152 |
|
| 153 |
-
# Create scam detection crew
|
| 154 |
crew = Crew(
|
| 155 |
agents=[extractor_agent, verifier_agent, explainer_agent],
|
| 156 |
tasks=[extract_task, verify_task, explain_task],
|
|
@@ -158,90 +79,92 @@ def analyze_scam(message_content):
|
|
| 158 |
process="sequential"
|
| 159 |
)
|
| 160 |
|
| 161 |
-
#
|
| 162 |
-
yield "π― AI agents collaborating on final analysis..."
|
| 163 |
|
| 164 |
result = crew.kickoff()
|
| 165 |
-
yield str(result)
|
| 166 |
|
| 167 |
except Exception as e:
|
| 168 |
-
yield f"β Scam analysis failed: {str(e)}"
|
| 169 |
|
| 170 |
def create_gradio_interface():
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
gr.HTML("""
|
| 176 |
<div style="text-align: center; padding: 2rem 0;">
|
| 177 |
-
<h1 style="font-size: 3rem; margin-bottom:
|
| 178 |
-
<p style="font-size: 1.2rem; color: #
|
| 179 |
AI-powered protection against phishing and fraudulent messages
|
| 180 |
</p>
|
| 181 |
</div>
|
| 182 |
""")
|
| 183 |
-
|
| 184 |
-
#
|
| 185 |
gr.HTML("""
|
| 186 |
-
<div style="background: #
|
| 187 |
-
<h3 style="text-align:
|
| 188 |
-
|
| 189 |
-
|
|
|
|
|
|
|
| 190 |
<div style="font-size: 2rem;">π</div>
|
| 191 |
-
<strong>Claim Extractor</strong>
|
| 192 |
-
<p style="font-size: 0.9rem;
|
| 193 |
</div>
|
| 194 |
-
<div style="text-align:
|
| 195 |
<div style="font-size: 2rem;">βοΈ</div>
|
| 196 |
-
<strong>Fact Checker</strong>
|
| 197 |
-
<p style="font-size: 0.9rem;
|
| 198 |
</div>
|
| 199 |
-
<div style="text-align:
|
| 200 |
<div style="font-size: 2rem;">π</div>
|
| 201 |
-
<strong>Safety Advisor</strong>
|
| 202 |
-
<p style="font-size: 0.9rem;
|
| 203 |
</div>
|
| 204 |
</div>
|
| 205 |
</div>
|
| 206 |
""")
|
| 207 |
-
|
| 208 |
-
#
|
| 209 |
-
gr.HTML("""
|
| 210 |
-
<h3 style="text-align: center; margin-bottom: 1rem;">
|
| 211 |
-
π± Analyze Suspicious Message or URL
|
| 212 |
-
</h3>
|
| 213 |
-
""")
|
| 214 |
-
|
| 215 |
message_input = gr.Textbox(
|
| 216 |
label="π¨ Suspicious Message or URL",
|
| 217 |
-
placeholder="Paste the suspicious message, email content, or URL
|
| 218 |
lines=5
|
| 219 |
)
|
| 220 |
-
|
| 221 |
analyze_btn = gr.Button("π Analyze for Scams", variant="primary", size="lg")
|
| 222 |
-
|
| 223 |
-
#
|
| 224 |
-
output = gr.
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
show_copy_button=True,
|
| 228 |
-
placeholder="""Your detailed scam analysis will appear here...\n\nπ― ANALYSIS SUMMARY\nβ’ Scam verdict and confidence level\nβ’ Primary red flags identified\nβ’ Risk assessment score\n\nπ DETAILED FINDINGS\nβ’ Suspicious claims extracted\nβ’ Pattern matching results\nβ’ Technical analysis of links/contacts\n\nπ SAFETY RECOMMENDATIONS\nβ’ Immediate actions to take\nβ’ What to avoid doing\nβ’ How to report the scam\nβ’ Prevention tips for future\n\nEnter a suspicious message above to begin analysis."""
|
| 229 |
-
)
|
| 230 |
-
|
| 231 |
-
# Simple Examples
|
| 232 |
gr.Examples(
|
| 233 |
examples=[
|
| 234 |
["URGENT: Your account will be suspended! Click here immediately to verify: http://suspicious-bank-verify.tk/login"],
|
| 235 |
["Congratulations! You've won $10,000! Claim your prize now by clicking this link and entering your bank details."],
|
| 236 |
["Your package is held at customs. Pay $50 shipping fee to release: https://bit.ly/customs-fee-pay"],
|
| 237 |
-
["FINAL NOTICE: IRS requires immediate payment of $2,500 or face legal action. Call now: 555-SCAM"],
|
| 238 |
-
["Hello dear, I am Prince Williams from Nigeria with $10 million to share with you..."],
|
| 239 |
],
|
| 240 |
inputs=message_input,
|
| 241 |
label="π§ͺ Try These Example Scams"
|
| 242 |
)
|
| 243 |
-
|
| 244 |
-
#
|
| 245 |
gr.HTML("""
|
| 246 |
<div style="text-align: center; padding: 2rem; margin-top: 2rem; border-top: 1px solid #eee;">
|
| 247 |
<p><strong>Scam-Signal Verifier</strong> β’ AI-Powered Fraud Detection</p>
|
|
@@ -250,31 +173,22 @@ def create_gradio_interface():
|
|
| 250 |
</p>
|
| 251 |
</div>
|
| 252 |
""")
|
| 253 |
-
|
| 254 |
-
#
|
| 255 |
analyze_btn.click(
|
| 256 |
fn=analyze_scam,
|
| 257 |
inputs=[message_input],
|
| 258 |
-
outputs=output
|
| 259 |
-
show_progress=True
|
| 260 |
)
|
| 261 |
-
|
| 262 |
message_input.submit(
|
| 263 |
fn=analyze_scam,
|
| 264 |
inputs=[message_input],
|
| 265 |
-
outputs=output
|
| 266 |
-
show_progress=True
|
| 267 |
)
|
| 268 |
-
|
| 269 |
return interface
|
| 270 |
|
| 271 |
-
# Launch the application
|
| 272 |
if __name__ == "__main__":
|
| 273 |
app = create_gradio_interface()
|
| 274 |
-
app.launch(
|
| 275 |
-
share=False,
|
| 276 |
-
server_name="0.0.0.0",
|
| 277 |
-
server_port=7860,
|
| 278 |
-
show_api=False,
|
| 279 |
-
inbrowser=False
|
| 280 |
-
)
|
|
|
|
| 11 |
if not message_content.strip():
|
| 12 |
return "β Please enter a message or URL to analyze."
|
| 13 |
|
|
|
|
| 14 |
loading_messages = [
|
| 15 |
"π‘οΈ Initializing AI security team...",
|
| 16 |
"π Claim Extractor analyzing suspicious content...",
|
|
|
|
| 19 |
"π¨ Generating comprehensive scam analysis..."
|
| 20 |
]
|
| 21 |
|
| 22 |
+
yield f"<span style='color:#1d4ed8; font-weight:bold;'>{loading_messages[0]}</span>"
|
|
|
|
| 23 |
|
| 24 |
try:
|
| 25 |
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0.1)
|
| 26 |
|
|
|
|
| 27 |
for i, message in enumerate(loading_messages[1:], 1):
|
| 28 |
+
time.sleep(1.5)
|
| 29 |
+
yield f"<span style='color:#1d4ed8; font-weight:bold;'>{message}</span>"
|
| 30 |
|
|
|
|
| 31 |
extractor_agent = Agent(
|
| 32 |
role="Claim Extractor",
|
| 33 |
goal="Extract key claims, offers, and suspicious elements from messages or URLs",
|
| 34 |
+
backstory="Expert at parsing and identifying key claims in potentially fraudulent messages.",
|
| 35 |
llm=llm,
|
| 36 |
verbose=False
|
| 37 |
)
|
| 38 |
|
| 39 |
verifier_agent = Agent(
|
| 40 |
role="Fact Checker",
|
| 41 |
+
goal="Verify claims and assess scam probability",
|
| 42 |
+
backstory="Cybersecurity expert who identifies scam patterns.",
|
| 43 |
llm=llm,
|
| 44 |
verbose=False
|
| 45 |
)
|
| 46 |
|
| 47 |
explainer_agent = Agent(
|
| 48 |
role="Safety Advisor",
|
| 49 |
+
goal="Provide clear, actionable guidance to users",
|
| 50 |
+
backstory="Digital safety educator who simplifies complex issues.",
|
| 51 |
llm=llm,
|
| 52 |
verbose=False
|
| 53 |
)
|
| 54 |
|
|
|
|
| 55 |
extract_task = Task(
|
| 56 |
+
description=f"Analyze and extract suspicious elements from:\n\n{message_content}",
|
| 57 |
+
expected_output="Structured suspicious elements",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
agent=extractor_agent
|
| 59 |
)
|
| 60 |
|
| 61 |
verify_task = Task(
|
| 62 |
+
description="Conduct scam risk assessment",
|
| 63 |
+
expected_output="Risk score and red flags",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
agent=verifier_agent,
|
| 65 |
context=[extract_task]
|
| 66 |
)
|
| 67 |
|
| 68 |
explain_task = Task(
|
| 69 |
+
description="Create a user-friendly scam safety report",
|
| 70 |
+
expected_output="Clear report with guidance",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
agent=explainer_agent,
|
| 72 |
context=[extract_task, verify_task]
|
| 73 |
)
|
| 74 |
|
|
|
|
| 75 |
crew = Crew(
|
| 76 |
agents=[extractor_agent, verifier_agent, explainer_agent],
|
| 77 |
tasks=[extract_task, verify_task, explain_task],
|
|
|
|
| 79 |
process="sequential"
|
| 80 |
)
|
| 81 |
|
| 82 |
+
yield "<span style='color:#1d4ed8; font-weight:bold;'>π― AI agents collaborating on final analysis...</span>"
|
|
|
|
| 83 |
|
| 84 |
result = crew.kickoff()
|
| 85 |
+
yield f"<div style='color:#111827; font-size:1rem; line-height:1.5;'>{str(result)}</div>"
|
| 86 |
|
| 87 |
except Exception as e:
|
| 88 |
+
yield f"<span style='color:red; font-weight:bold;'>β Scam analysis failed: {str(e)}</span>"
|
| 89 |
|
| 90 |
def create_gradio_interface():
|
| 91 |
+
with gr.Blocks(
|
| 92 |
+
title="Scam-Signal Verifier | AI Security Analysis",
|
| 93 |
+
theme=gr.themes.Soft(primary_hue="blue", secondary_hue="gray")
|
| 94 |
+
) as interface:
|
| 95 |
+
|
| 96 |
+
# Custom CSS for output box contrast
|
| 97 |
+
gr.HTML("""
|
| 98 |
+
<style>
|
| 99 |
+
#output-box textarea {
|
| 100 |
+
background-color: #ffffff !important;
|
| 101 |
+
color: #111827 !important;
|
| 102 |
+
font-size: 1rem !important;
|
| 103 |
+
line-height: 1.5 !important;
|
| 104 |
+
}
|
| 105 |
+
</style>
|
| 106 |
+
""")
|
| 107 |
+
|
| 108 |
+
# Header
|
| 109 |
gr.HTML("""
|
| 110 |
<div style="text-align: center; padding: 2rem 0;">
|
| 111 |
+
<h1 style="font-size: 3rem; margin-bottom: 0.5rem; color:#1e3a8a;">π‘οΈ Scam-Signal Verifier</h1>
|
| 112 |
+
<p style="font-size: 1.2rem; color: #374151;">
|
| 113 |
AI-powered protection against phishing and fraudulent messages
|
| 114 |
</p>
|
| 115 |
</div>
|
| 116 |
""")
|
| 117 |
+
|
| 118 |
+
# AI Security Team section with better contrast
|
| 119 |
gr.HTML("""
|
| 120 |
+
<div style="background: #f0f4f8; padding: 1.5rem; border-radius: 15px; margin-bottom: 2rem;">
|
| 121 |
+
<h3 style="text-align:center; color: #1e3a8a; font-weight: 700; font-size: 1.4rem;">
|
| 122 |
+
π€ Your AI Security Team
|
| 123 |
+
</h3>
|
| 124 |
+
<div style="display:flex; flex-wrap:wrap; justify-content:center; gap:1.5rem; color: #1f2937;">
|
| 125 |
+
<div style="flex:1; min-width:200px; text-align:center;">
|
| 126 |
<div style="font-size: 2rem;">π</div>
|
| 127 |
+
<strong style="color:#111827;">Claim Extractor</strong>
|
| 128 |
+
<p style="font-size: 0.9rem; color:#374151;">Identifies suspicious content & claims</p>
|
| 129 |
</div>
|
| 130 |
+
<div style="flex:1; min-width:200px; text-align:center;">
|
| 131 |
<div style="font-size: 2rem;">βοΈ</div>
|
| 132 |
+
<strong style="color:#111827;">Fact Checker</strong>
|
| 133 |
+
<p style="font-size: 0.9rem; color:#374151;">Verifies claims & calculates risk</p>
|
| 134 |
</div>
|
| 135 |
+
<div style="flex:1; min-width:200px; text-align:center;">
|
| 136 |
<div style="font-size: 2rem;">π</div>
|
| 137 |
+
<strong style="color:#111827;">Safety Advisor</strong>
|
| 138 |
+
<p style="font-size: 0.9rem; color:#374151;">Gives clear guidance & next steps</p>
|
| 139 |
</div>
|
| 140 |
</div>
|
| 141 |
</div>
|
| 142 |
""")
|
| 143 |
+
|
| 144 |
+
# Input section
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
message_input = gr.Textbox(
|
| 146 |
label="π¨ Suspicious Message or URL",
|
| 147 |
+
placeholder="Paste the suspicious message, email content, or URL...",
|
| 148 |
lines=5
|
| 149 |
)
|
| 150 |
+
|
| 151 |
analyze_btn = gr.Button("π Analyze for Scams", variant="primary", size="lg")
|
| 152 |
+
|
| 153 |
+
# Output section with styling
|
| 154 |
+
output = gr.HTML(label="π Scam Analysis Report", elem_id="output-box")
|
| 155 |
+
|
| 156 |
+
# Examples
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
gr.Examples(
|
| 158 |
examples=[
|
| 159 |
["URGENT: Your account will be suspended! Click here immediately to verify: http://suspicious-bank-verify.tk/login"],
|
| 160 |
["Congratulations! You've won $10,000! Claim your prize now by clicking this link and entering your bank details."],
|
| 161 |
["Your package is held at customs. Pay $50 shipping fee to release: https://bit.ly/customs-fee-pay"],
|
|
|
|
|
|
|
| 162 |
],
|
| 163 |
inputs=message_input,
|
| 164 |
label="π§ͺ Try These Example Scams"
|
| 165 |
)
|
| 166 |
+
|
| 167 |
+
# Footer
|
| 168 |
gr.HTML("""
|
| 169 |
<div style="text-align: center; padding: 2rem; margin-top: 2rem; border-top: 1px solid #eee;">
|
| 170 |
<p><strong>Scam-Signal Verifier</strong> β’ AI-Powered Fraud Detection</p>
|
|
|
|
| 173 |
</p>
|
| 174 |
</div>
|
| 175 |
""")
|
| 176 |
+
|
| 177 |
+
# Events
|
| 178 |
analyze_btn.click(
|
| 179 |
fn=analyze_scam,
|
| 180 |
inputs=[message_input],
|
| 181 |
+
outputs=output
|
|
|
|
| 182 |
)
|
| 183 |
+
|
| 184 |
message_input.submit(
|
| 185 |
fn=analyze_scam,
|
| 186 |
inputs=[message_input],
|
| 187 |
+
outputs=output
|
|
|
|
| 188 |
)
|
| 189 |
+
|
| 190 |
return interface
|
| 191 |
|
|
|
|
| 192 |
if __name__ == "__main__":
|
| 193 |
app = create_gradio_interface()
|
| 194 |
+
app.launch(server_name="0.0.0.0", server_port=7860)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|