hashirlodhi commited on
Commit
8dc41a0
Β·
verified Β·
1 Parent(s): b333f8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -141
app.py CHANGED
@@ -3,6 +3,7 @@ import openai
3
  import os
4
  from dotenv import load_dotenv
5
  from typing import Dict, List
 
6
 
7
  # Load environment variables
8
  load_dotenv()
@@ -21,39 +22,13 @@ class ForensicAgent:
21
  def __init__(self, role: str, expertise: str):
22
  self.role = role
23
  self.expertise = expertise
24
- self.findings = []
25
 
26
  def analyze(self, text: str) -> Dict:
27
  """Perform analysis and return findings"""
28
  raise NotImplementedError
29
 
30
- class StylometricAgent(ForensicAgent):
31
- """Analyzes writing style characteristics"""
32
- def __init__(self):
33
- super().__init__("Dr. Styles", "Stylometric Analysis Expert")
34
-
35
- def analyze(self, text: str) -> Dict:
36
- prompt = f"""
37
- As a {self.role}, {self.expertise}, analyze this text for stylometric patterns:
38
-
39
- {text}
40
-
41
- Evaluate:
42
- 1. Sentence length variation (human: high, AI: low)
43
- 2. Lexical diversity (human: contextual, AI: generic)
44
- 3. Punctuation usage patterns
45
- 4. Paragraph structure complexity
46
-
47
- Return findings in this format:
48
- {{
49
- "verdict": "Human/AI/Uncertain",
50
- "confidence": "0-100%",
51
- "evidence": ["list", "of", "key", "findings"]
52
- }}
53
- """
54
- return self._get_analysis(prompt)
55
-
56
  def _get_analysis(self, prompt: str) -> Dict:
 
57
  try:
58
  if new_openai:
59
  response = client.chat.completions.create(
@@ -65,7 +40,7 @@ class StylometricAgent(ForensicAgent):
65
  temperature=0.1,
66
  response_format={"type": "json_object"}
67
  )
68
- return eval(response.choices[0].message.content)
69
  else:
70
  response = openai.ChatCompletion.create(
71
  model="gpt-4",
@@ -76,9 +51,28 @@ class StylometricAgent(ForensicAgent):
76
  temperature=0.1,
77
  response_format={"type": "json_object"}
78
  )
79
- return eval(response['choices'][0]['message']['content'])
80
  except Exception as e:
81
- return {"error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  class CognitiveAgent(ForensicAgent):
84
  """Analyzes cognitive and psychological markers"""
@@ -87,23 +81,15 @@ class CognitiveAgent(ForensicAgent):
87
 
88
  def analyze(self, text: str) -> Dict:
89
  prompt = f"""
90
- As {self.role}, {self.expertise}, analyze this text for cognitive markers:
91
-
92
  {text}
93
 
94
- Evaluate:
95
- 1. Presence of hedging language ("perhaps", "I think")
96
- 2. Use of personal pronouns and anecdotes
97
- 3. Emotional expression patterns
98
- 4. Confidence markers ("undoubtedly", "clearly")
99
- 5. Metacognitive statements ("I'm not sure but...")
100
-
101
- Return findings in this format:
102
- {{
103
- "verdict": "Human/AI/Uncertain",
104
- "confidence": "0-100%",
105
- "evidence": ["list", "of", "key", "findings"]
106
- }}
107
  """
108
  return self._get_analysis(prompt)
109
 
@@ -114,23 +100,15 @@ class SemanticAgent(ForensicAgent):
114
 
115
  def analyze(self, text: str) -> Dict:
116
  prompt = f"""
117
- As {self.role}, {self.expertise}, analyze this text for semantic patterns:
118
-
119
  {text}
120
 
121
- Evaluate:
122
- 1. Metaphor and idiom density
123
- 2. Contextual anchoring (specific vs vague references)
124
- 3. Temporal references (specific dates vs generic time)
125
- 4. Cultural reference depth
126
- 5. Error patterns (typos vs semantic inconsistencies)
127
-
128
- Return findings in this format:
129
- {{
130
- "verdict": "Human/AI/Uncertain",
131
- "confidence": "0-100%",
132
- "evidence": ["list", "of", "key", "findings"]
133
- }}
134
  """
135
  return self._get_analysis(prompt)
136
 
@@ -145,58 +123,46 @@ class ForensicCrew:
145
 
146
  def analyze_text(self, text: str) -> str:
147
  """Coordinate multi-agent analysis"""
148
- if len(text.split()) < 30:
149
- return "⚠️ Please provide at least 150 characters for accurate analysis."
150
 
151
- # Gather all agent findings
152
- findings = [agent.analyze(text) for agent in self.agents]
153
-
154
- # Have the chief analyst synthesize the results
155
- return self._synthesize_findings(text, findings)
156
-
 
 
 
 
 
 
 
 
157
  def _synthesize_findings(self, text: str, findings: List[Dict]) -> str:
158
- """Have a chief analyst compile the final report"""
159
- synthesis_prompt = f"""
160
- [TEXT UNDER ANALYSIS]
161
- {text}
162
-
163
- [AGENT FINDINGS]
164
- {findings}
165
-
166
- As Chief Forensic Analyst Dr. Lexica, synthesize these findings into a comprehensive report:
167
-
168
- # πŸ•΅οΈβ€β™‚οΈ Forensic Text Analysis Report (CrewAI Approach)
169
-
170
- ## πŸ” Composite Verdict
171
- **Origin:** {{Human/AI/Inconclusive}}
172
- **Confidence Level:** {{XX%}}
173
-
174
- ## πŸ“Š Agent Consensus
175
- {self._format_agent_summary(findings)}
176
-
177
- ## 🧐 Detailed Findings
178
- ### 1️⃣ Stylometric Evidence
179
- {{Summary of stylometric findings}}
180
-
181
- ### 2️⃣ Cognitive Patterns
182
- {{Summary of cognitive findings}}
183
-
184
- ### 3️⃣ Semantic Fingerprints
185
- {{Summary of semantic findings}}
186
-
187
- ## πŸ’‘ Expert Conclusion
188
- {{3-4 sentence authoritative conclusion synthesizing all evidence}}
189
-
190
- ⚠️ **Disclaimer:** This analysis combines multiple forensic techniques with {self._calculate_confidence(findings)}% consensus confidence.
191
- """
192
-
193
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  if new_openai:
195
  response = client.chat.completions.create(
196
  model="gpt-4",
197
  messages=[
198
  {"role": "system", "content": "You are Dr. Lexica, Chief Forensic Analyst."},
199
- {"role": "user", "content": synthesis_prompt}
200
  ],
201
  temperature=0.1,
202
  max_tokens=800
@@ -207,34 +173,14 @@ class ForensicCrew:
207
  model="gpt-4",
208
  messages=[
209
  {"role": "system", "content": "You are Dr. Lexica, Chief Forensic Analyst."},
210
- {"role": "user", "content": synthesis_prompt}
211
  ],
212
  temperature=0.1,
213
  max_tokens=800
214
  )
215
  return response['choices'][0]['message']['content']
216
  except Exception as e:
217
- return f"πŸ”΄ Analysis failed. Error: {str(e)}"
218
-
219
- def _format_agent_summary(self, findings: List[Dict]) -> str:
220
- """Format agent findings for the report"""
221
- summary = []
222
- agent_names = ["Stylometric Analyst", "Cognitive Linguist", "Semantic Expert"]
223
-
224
- for idx, finding in enumerate(findings):
225
- if "error" in finding:
226
- summary.append(f"πŸ”΄ {agent_names[idx]}: Error - {finding['error']}")
227
- else:
228
- verdict = finding.get("verdict", "Unknown")
229
- confidence = finding.get("confidence", "0%")
230
- summary.append(f"πŸ”΅ {agent_names[idx]}: {verdict} ({confidence} confidence)")
231
-
232
- return "\n".join(summary)
233
-
234
- def _calculate_confidence(self, findings: List[Dict]) -> int:
235
- """Calculate average confidence from valid agent responses"""
236
- valid = [int(f.get("confidence", "0%").strip('%')) for f in findings if "error" not in f]
237
- return sum(valid) // len(valid) if valid else 0
238
 
239
  # Initialize the forensic crew
240
  crew = ForensicCrew()
@@ -242,39 +188,44 @@ crew = ForensicCrew()
242
  # Gradio Interface
243
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="emerald")) as app:
244
  gr.Markdown("""
245
- # πŸ”¬ AI/Human Text Forensic Analyzer (CrewAI Approach)
246
- *Multi-agent forensic analysis combining stylometric, cognitive, and semantic techniques*
247
  """)
248
 
249
  with gr.Row():
250
  with gr.Column():
251
- input_text = gr.Textbox(label="πŸ“ Text to Analyze",
252
- lines=7,
253
- placeholder="Paste any text (minimum 150 characters for accurate analysis)...",
254
- elem_id="input_box")
 
255
  with gr.Row():
256
  analyze_btn = gr.Button("πŸ§ͺ Analyze Text", variant="primary")
257
  clear_btn = gr.Button("πŸ”„ Clear")
258
 
259
  with gr.Column():
260
- output_text = gr.Markdown(label="πŸ“œ CrewAI Analysis Report",
261
- elem_id="output_panel")
 
 
262
 
 
263
  gr.Examples(
264
  examples=[
265
- ["Walking through the old cobblestone streets of Prague last summer, I was struck by how the golden light of dusk made the ancient buildings look like they were glowing from within - a memory that still makes me smile months later."],
266
- ["The utilization of advanced neural network architectures enables the generation of coherent textual outputs through the application of transformer-based deep learning paradigms."],
267
- ["Honestly, I'm not entirely sure about this whole thing. It seems kinda complicated to me, but maybe that's just because I've never been good with technology."]
268
  ],
269
  inputs=input_text,
270
- label="πŸ’‘ Try these examples:",
271
- examples_per_page=3
272
  )
273
 
 
274
  analyze_btn.click(
275
  fn=crew.analyze_text,
276
  inputs=input_text,
277
- outputs=output_text
 
278
  )
279
 
280
  clear_btn.click(
@@ -283,4 +234,16 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="emerald")) as app:
283
  outputs=[input_text, output_text]
284
  )
285
 
286
- app.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  import os
4
  from dotenv import load_dotenv
5
  from typing import Dict, List
6
+ import json
7
 
8
  # Load environment variables
9
  load_dotenv()
 
22
  def __init__(self, role: str, expertise: str):
23
  self.role = role
24
  self.expertise = expertise
 
25
 
26
  def analyze(self, text: str) -> Dict:
27
  """Perform analysis and return findings"""
28
  raise NotImplementedError
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  def _get_analysis(self, prompt: str) -> Dict:
31
+ """Generic OpenAI request handler"""
32
  try:
33
  if new_openai:
34
  response = client.chat.completions.create(
 
40
  temperature=0.1,
41
  response_format={"type": "json_object"}
42
  )
43
+ return json.loads(response.choices[0].message.content)
44
  else:
45
  response = openai.ChatCompletion.create(
46
  model="gpt-4",
 
51
  temperature=0.1,
52
  response_format={"type": "json_object"}
53
  )
54
+ return json.loads(response['choices'][0]['message']['content'])
55
  except Exception as e:
56
+ return {"error": str(e), "verdict": "Error", "confidence": "0%"}
57
+
58
+ class StylometricAgent(ForensicAgent):
59
+ """Analyzes writing style characteristics"""
60
+ def __init__(self):
61
+ super().__init__("Dr. Styles", "Stylometric Analysis Expert")
62
+
63
+ def analyze(self, text: str) -> Dict:
64
+ prompt = f"""
65
+ Analyze this text for stylometric patterns:
66
+ {text}
67
+
68
+ Return JSON with: verdict (Human/AI/Uncertain), confidence (0-100%), and evidence list.
69
+ Focus on:
70
+ - Sentence length variation
71
+ - Lexical diversity
72
+ - Punctuation patterns
73
+ - Paragraph structure
74
+ """
75
+ return self._get_analysis(prompt)
76
 
77
  class CognitiveAgent(ForensicAgent):
78
  """Analyzes cognitive and psychological markers"""
 
81
 
82
  def analyze(self, text: str) -> Dict:
83
  prompt = f"""
84
+ Analyze this text for cognitive markers:
 
85
  {text}
86
 
87
+ Return JSON with: verdict (Human/AI/Uncertain), confidence (0-100%), and evidence list.
88
+ Focus on:
89
+ - Hedging language
90
+ - Personal pronouns/anecdotes
91
+ - Emotional expressions
92
+ - Confidence markers
 
 
 
 
 
 
 
93
  """
94
  return self._get_analysis(prompt)
95
 
 
100
 
101
  def analyze(self, text: str) -> Dict:
102
  prompt = f"""
103
+ Analyze this text for semantic patterns:
 
104
  {text}
105
 
106
+ Return JSON with: verdict (Human/AI/Uncertain), confidence (0-100%), and evidence list.
107
+ Focus on:
108
+ - Metaphor/idiom density
109
+ - Contextual references
110
+ - Temporal references
111
+ - Error patterns
 
 
 
 
 
 
 
112
  """
113
  return self._get_analysis(prompt)
114
 
 
123
 
124
  def analyze_text(self, text: str) -> str:
125
  """Coordinate multi-agent analysis"""
126
+ if len(text.strip()) < 30:
127
+ return "⚠️ Please provide at least 50 characters for accurate analysis."
128
 
129
+ try:
130
+ # Get all agent findings
131
+ findings = []
132
+ for agent in self.agents:
133
+ result = agent.analyze(text)
134
+ findings.append(result)
135
+ if "error" in result:
136
+ print(f"Agent {agent.role} error: {result['error']}")
137
+
138
+ # Generate final report
139
+ return self._synthesize_findings(text, findings)
140
+ except Exception as e:
141
+ return f"πŸ”΄ System Error: {str(e)}"
142
+
143
  def _synthesize_findings(self, text: str, findings: List[Dict]) -> str:
144
+ """Generate final report"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  try:
146
+ prompt = f"""
147
+ Text under analysis:
148
+ {text}
149
+
150
+ Agent findings:
151
+ {json.dumps(findings, indent=2)}
152
+
153
+ Compile a forensic report with:
154
+ 1. Composite verdict (Human/AI/Uncertain)
155
+ 2. Confidence score (average of agent confidences)
156
+ 3. Key evidence from each agent
157
+ 4. Final conclusion
158
+ """
159
+
160
  if new_openai:
161
  response = client.chat.completions.create(
162
  model="gpt-4",
163
  messages=[
164
  {"role": "system", "content": "You are Dr. Lexica, Chief Forensic Analyst."},
165
+ {"role": "user", "content": prompt}
166
  ],
167
  temperature=0.1,
168
  max_tokens=800
 
173
  model="gpt-4",
174
  messages=[
175
  {"role": "system", "content": "You are Dr. Lexica, Chief Forensic Analyst."},
176
+ {"role": "user", "content": prompt}
177
  ],
178
  temperature=0.1,
179
  max_tokens=800
180
  )
181
  return response['choices'][0]['message']['content']
182
  except Exception as e:
183
+ return f"πŸ”΄ Report Generation Failed: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  # Initialize the forensic crew
186
  crew = ForensicCrew()
 
188
  # Gradio Interface
189
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="emerald")) as app:
190
  gr.Markdown("""
191
+ # πŸ”¬ AI/Human Text Forensic Analyzer (CrewAI)
192
+ *Multi-agent analysis combining stylometric, cognitive, and semantic techniques*
193
  """)
194
 
195
  with gr.Row():
196
  with gr.Column():
197
+ input_text = gr.Textbox(
198
+ label="πŸ“ Text to Analyze",
199
+ lines=7,
200
+ placeholder="Paste any text (50+ characters recommended)..."
201
+ )
202
  with gr.Row():
203
  analyze_btn = gr.Button("πŸ§ͺ Analyze Text", variant="primary")
204
  clear_btn = gr.Button("πŸ”„ Clear")
205
 
206
  with gr.Column():
207
+ output_text = gr.Markdown(
208
+ label="πŸ“œ Forensic Analysis Report",
209
+ elem_classes=["output-panel"]
210
+ )
211
 
212
+ # Example texts
213
  gr.Examples(
214
  examples=[
215
+ ["The rain tapped gently against the window as I reminisced about childhood summers - those endless days that now seem like someone else's memory."],
216
+ ["Large language models utilize transformer architectures to generate human-like text through probabilistic prediction mechanisms."],
217
+ ["I dunno... it's kinda weird how phones these days track everything. Makes me uncomfortable tbh."]
218
  ],
219
  inputs=input_text,
220
+ label="πŸ’‘ Try these examples:"
 
221
  )
222
 
223
+ # Button actions
224
  analyze_btn.click(
225
  fn=crew.analyze_text,
226
  inputs=input_text,
227
+ outputs=output_text,
228
+ api_name="analyze"
229
  )
230
 
231
  clear_btn.click(
 
234
  outputs=[input_text, output_text]
235
  )
236
 
237
+ # Launch with debug mode
238
+ if __name__ == "__main__":
239
+ print("πŸš€ Starting Forensic Analyzer...")
240
+ try:
241
+ # Test API connection
242
+ test_prompt = "Hello, world!"
243
+ test_result = crew.analyze_text(test_prompt)
244
+ print(f"Test analysis result: {test_result[:100]}...")
245
+
246
+ # Launch app
247
+ app.launch(server_port=7860, show_error=True)
248
+ except Exception as e:
249
+ print(f"❌ Failed to launch: {str(e)}")