Skip to content

Commit a24f7b2

Browse files
author
safenestdev
committed
feat: add message_analysis to DetectionResult and GroomingResult
Add MessageAnalysis dataclass for per-message breakdown returned by conversation-aware detection endpoints. Update README with usage example.
1 parent 6f2d3a3 commit a24f7b2

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ result = await client.detect_grooming(
115115

116116
if result.grooming_risk == GroomingRisk.HIGH:
117117
print(f"Flags: {result.flags}") # ["secrecy", "isolation"]
118+
119+
# Per-message breakdown (optional, returned on conversation-aware endpoints)
120+
if result.message_analysis:
121+
for m in result.message_analysis:
122+
print(f"Message {m.message_index}: risk={m.risk_score}, flags={m.flags}, summary={m.summary}")
118123
```
119124

120125
### Unsafe Content Detection

tuteliq/models.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class GroomingResult:
234234
rationale: str
235235
risk_score: float
236236
recommended_action: str
237+
message_analysis: Optional[list[MessageAnalysis]] = None
237238
language: Optional[str] = None
238239
language_status: Optional[str] = None
239240
credits_used: Optional[int] = None
@@ -243,13 +244,17 @@ class GroomingResult:
243244
@classmethod
244245
def from_dict(cls, data: dict[str, Any]) -> "GroomingResult":
245246
"""Create from API response dictionary."""
247+
msg_analysis = None
248+
if "message_analysis" in data and data["message_analysis"]:
249+
msg_analysis = [MessageAnalysis.from_dict(m) for m in data["message_analysis"]]
246250
return cls(
247251
grooming_risk=GroomingRisk(data["grooming_risk"]),
248252
confidence=data["confidence"],
249253
flags=data["flags"],
250254
rationale=data["rationale"],
251255
risk_score=data["risk_score"],
252256
recommended_action=data["recommended_action"],
257+
message_analysis=msg_analysis,
253258
language=data.get("language"),
254259
language_status=data.get("language_status"),
255260
credits_used=data.get("credits_used"),
@@ -1199,6 +1204,26 @@ class DetectionInput:
11991204
metadata: Optional[dict[str, Any]] = None
12001205

12011206

1207+
@dataclass
1208+
class MessageAnalysis:
1209+
"""Per-message analysis from conversation-aware detection."""
1210+
1211+
message_index: int
1212+
risk_score: float
1213+
flags: list[str]
1214+
summary: str
1215+
1216+
@classmethod
1217+
def from_dict(cls, data: dict[str, Any]) -> "MessageAnalysis":
1218+
"""Create from API response dictionary."""
1219+
return cls(
1220+
message_index=data["message_index"],
1221+
risk_score=data["risk_score"],
1222+
flags=data["flags"],
1223+
summary=data["summary"],
1224+
)
1225+
1226+
12021227
@dataclass
12031228
class DetectionCategory:
12041229
"""A detected category with tag and confidence."""
@@ -1243,6 +1268,7 @@ class DetectionResult:
12431268
language_status: str
12441269
evidence: Optional[list[DetectionEvidence]] = None
12451270
age_calibration: Optional[AgeCalibration] = None
1271+
message_analysis: Optional[list[MessageAnalysis]] = None
12461272
credits_used: Optional[int] = None
12471273
processing_time_ms: Optional[float] = None
12481274
external_id: Optional[str] = None
@@ -1270,6 +1296,9 @@ def from_dict(cls, data: dict[str, Any]) -> "DetectionResult":
12701296
age_group=ac.get("age_group"),
12711297
multiplier=ac.get("multiplier"),
12721298
)
1299+
msg_analysis = None
1300+
if "message_analysis" in data and data["message_analysis"]:
1301+
msg_analysis = [MessageAnalysis.from_dict(m) for m in data["message_analysis"]]
12731302
return cls(
12741303
endpoint=data["endpoint"],
12751304
detected=data["detected"],
@@ -1284,6 +1313,7 @@ def from_dict(cls, data: dict[str, Any]) -> "DetectionResult":
12841313
language_status=data["language_status"],
12851314
evidence=evidence,
12861315
age_calibration=age_cal,
1316+
message_analysis=msg_analysis,
12871317
credits_used=data.get("credits_used"),
12881318
processing_time_ms=data.get("processing_time_ms"),
12891319
external_id=data.get("external_id"),

0 commit comments

Comments
 (0)