pythonprincess commited on
Commit
cfd75bb
·
verified ·
1 Parent(s): bb09817

Delete bias_utils.py

Browse files
Files changed (1) hide show
  1. bias_utils.py +0 -190
bias_utils.py DELETED
@@ -1,190 +0,0 @@
1
- # models/bias/bias_utils.py
2
-
3
- """
4
- Bias Detection Utilities for Penny
5
-
6
- Provides zero-shot classification for detecting potential bias in text responses.
7
- Uses a classification model to identify neutral content vs. biased language patterns.
8
- """
9
-
10
- import asyncio
11
- import os
12
- import httpx
13
- from typing import Dict, Any, Optional, List
14
- import logging
15
-
16
- # --- Logging Setup ---
17
- logger = logging.getLogger(__name__)
18
-
19
- # --- Hugging Face API Configuration ---
20
- HF_API_URL = "https://api-inference.huggingface.co/models/facebook/bart-large-mnli"
21
- HF_TOKEN = os.getenv("HF_TOKEN")
22
-
23
- AGENT_NAME = "penny-bias-checker"
24
-
25
- # Define the labels for Zero-Shot Classification.
26
- CANDIDATE_LABELS = [
27
- "neutral and objective",
28
- "contains political bias",
29
- "uses emotional language",
30
- "is factually biased",
31
- ]
32
-
33
-
34
- def _is_bias_available() -> bool:
35
- """
36
- Check if bias detection service is available.
37
-
38
- Returns:
39
- bool: True if HF_TOKEN is configured
40
- """
41
- return HF_TOKEN is not None and len(HF_TOKEN) > 0
42
-
43
-
44
- async def check_bias(text: str) -> Dict[str, Any]:
45
- """
46
- Runs zero-shot classification to check for bias in the input text.
47
-
48
- Uses a pre-loaded classification model to analyze text for:
49
- - Neutral and objective language
50
- - Political bias
51
- - Emotional language
52
- - Factual bias
53
-
54
- Args:
55
- text: The string of text to analyze for bias
56
-
57
- Returns:
58
- Dictionary containing:
59
- - analysis: List of labels with confidence scores, sorted by score
60
- - available: Whether the bias detection service is operational
61
- - message: Optional error or status message
62
-
63
- Example:
64
- >>> result = await check_bias("This is neutral text.")
65
- >>> result['analysis'][0]['label']
66
- 'neutral and objective'
67
- """
68
-
69
- # Input validation
70
- if not text or not isinstance(text, str):
71
- logger.warning("check_bias called with invalid text input")
72
- return {
73
- "analysis": [],
74
- "available": False,
75
- "message": "Invalid input: text must be a non-empty string"
76
- }
77
-
78
- # Strip text to avoid processing whitespace
79
- text = text.strip()
80
- if not text:
81
- logger.warning("check_bias called with empty text after stripping")
82
- return {
83
- "analysis": [],
84
- "available": False,
85
- "message": "Invalid input: text is empty"
86
- }
87
-
88
- # Check API availability
89
- if not _is_bias_available():
90
- logger.warning(f"{AGENT_NAME}: API not configured (missing HF_TOKEN)")
91
- return {
92
- "analysis": [],
93
- "available": False,
94
- "message": "Bias detection service is currently unavailable"
95
- }
96
-
97
- try:
98
- # Prepare API request for zero-shot classification
99
- headers = {"Authorization": f"Bearer {HF_TOKEN}"}
100
- payload = {
101
- "inputs": text,
102
- "parameters": {
103
- "candidate_labels": CANDIDATE_LABELS,
104
- "multi_label": True
105
- }
106
- }
107
-
108
- # Call Hugging Face Inference API
109
- async with httpx.AsyncClient(timeout=30.0) as client:
110
- response = await client.post(HF_API_URL, json=payload, headers=headers)
111
-
112
- if response.status_code != 200:
113
- logger.error(f"Bias detection API returned status {response.status_code}")
114
- return {
115
- "analysis": [],
116
- "available": False,
117
- "message": f"Bias detection API error: {response.status_code}"
118
- }
119
-
120
- results = response.json()
121
-
122
- # Validate results structure
123
- if not results or not isinstance(results, dict):
124
- logger.error(f"Bias detection returned unexpected format: {type(results)}")
125
- return {
126
- "analysis": [],
127
- "available": True,
128
- "message": "Inference returned unexpected format"
129
- }
130
-
131
- labels = results.get('labels', [])
132
- scores = results.get('scores', [])
133
-
134
- if not labels or not scores:
135
- logger.warning("Bias detection returned empty labels or scores")
136
- return {
137
- "analysis": [],
138
- "available": True,
139
- "message": "No classification results returned"
140
- }
141
-
142
- # Build analysis results
143
- analysis = [
144
- {"label": label, "score": float(score)}
145
- for label, score in zip(labels, scores)
146
- ]
147
-
148
- # Sort by confidence score (descending)
149
- analysis.sort(key=lambda x: x['score'], reverse=True)
150
-
151
- logger.debug(f"Bias check completed successfully, top result: {analysis[0]['label']} ({analysis[0]['score']:.3f})")
152
-
153
- return {
154
- "analysis": analysis,
155
- "available": True
156
- }
157
-
158
- except httpx.TimeoutException:
159
- logger.error("Bias detection request timed out")
160
- return {
161
- "analysis": [],
162
- "available": False,
163
- "message": "Bias detection request timed out"
164
- }
165
-
166
- except asyncio.CancelledError:
167
- logger.warning("Bias detection task was cancelled")
168
- raise
169
-
170
- except Exception as e:
171
- logger.error(f"Error during bias detection inference: {e}", exc_info=True)
172
- return {
173
- "analysis": [],
174
- "available": False,
175
- "message": f"Bias detection error: {str(e)}"
176
- }
177
-
178
-
179
- def get_bias_pipeline_status() -> Dict[str, Any]:
180
- """
181
- Returns the current status of the bias detection pipeline.
182
-
183
- Returns:
184
- Dictionary with pipeline availability status
185
- """
186
- return {
187
- "agent_name": AGENT_NAME,
188
- "available": _is_bias_available(),
189
- "api_configured": HF_TOKEN is not None
190
- }