research-agent / agent /tools /credibility_tool.py
pymite6941's picture
Initial commit
57086e9
Raw
History Blame Contribute Delete
2.41 kB
import json
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
from credibility.scorer import score_source
import config
class CredibilityInput(BaseModel):
sources_json: str = Field(
description="JSON string of list of source dicts with keys: url, title, content, published_date"
)
fast_moving_topic: bool = Field(
default=False,
description="True if topic is time-sensitive (news, recent tech), False for evergreen topics"
)
class CredibilityScorerTool(BaseTool):
name: str = "Source Credibility Scorer"
description: str = (
"Score a list of sources for credibility (0.0–1.0). "
"Filters out unreliable sources. Returns only accepted sources with their scores. "
"Sources below 0.35 are dropped. Sources 0.35–0.55 are flagged low-confidence."
)
args_schema: type[BaseModel] = CredibilityInput
def _run(self, sources_json: str, fast_moving_topic: bool = False) -> str:
try:
sources = json.loads(sources_json)
except json.JSONDecodeError as e:
return json.dumps({"error": f"Invalid JSON: {e}", "accepted": [], "dropped": []})
accepted = []
dropped = []
for src in sources:
result = score_source(
url=src.get("url", ""),
title=src.get("title", ""),
content=src.get("content", ""),
pub_date=src.get("published_date"),
fast_moving=fast_moving_topic,
)
if result.get("blocked") or result["score"] < config.CREDIBILITY_CUTOFF:
dropped.append({"url": src.get("url"), "score": result["score"], "reason": "below threshold"})
continue
confidence = (
"high" if result["score"] >= config.LOW_CONFIDENCE_CUTOFF else "low"
)
accepted.append({
**src,
"credibility_score": result["score"],
"confidence": confidence,
"score_breakdown": result.get("breakdown", {}),
})
accepted.sort(key=lambda x: x["credibility_score"], reverse=True)
accepted = accepted[:config.MAX_ACCEPTED_SOURCES]
return json.dumps({
"accepted": accepted,
"dropped_count": len(dropped),
"accepted_count": len(accepted),
})