Spaces:
Sleeping
Sleeping
Shivappa Sangapur
feat: DebateArenaEnv complete - server/client separation, LLM multi-agent, Docker, OpenEnv compliant
b1eddd6 Download server/tasks.py from Shivacode/debatearena: direct link, hf CLI and curl.
- Browser
- Download file 7.69 kB
-
https://huggingface.co/spaces/Shivacode/debatearena/resolve/main/server/tasks.py
- Command line
-
hf download hf://spaces/Shivacode/debatearena/server/tasks.py
-
curl -L -o tasks.py https://huggingface.co/spaces/Shivacode/debatearena/resolve/main/server/tasks.py
7.69 kB
| """ | |
| DebateArenaEnv — Topic bank and adaptive curriculum. | |
| TopicRegistry tracks per-topic win-rates and escalates difficulty | |
| when the agent wins >= 70% of episodes over the last >= 3 attempts. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass, field | |
| from typing import Any, Dict, List, Optional | |
| # ────────────────────────────────────────────────────────────────────────────── | |
| # Topic dataclass | |
| # ────────────────────────────────────────────────────────────────────────────── | |
| class Topic: | |
| topic_id: str | |
| difficulty: str # "easy" | "medium" | "hard" | |
| domain: str | |
| claim: str | |
| narrative: str | |
| known_facts: Dict[str, bool] # fact_key → True/False | |
| known_fallacies: List[str] | |
| evidence_keywords: List[str] | |
| max_rounds: int = 5 | |
| self_play_seed: int = 42 | |
| def to_prompt(self) -> str: | |
| return ( | |
| f"Motion: {self.claim}\n" | |
| f"Domain: {self.domain}\n" | |
| f"Background: {self.narrative}\n" | |
| f"Max rounds: {self.max_rounds}" | |
| ) | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "topic_id": self.topic_id, | |
| "difficulty": self.difficulty, | |
| "domain": self.domain, | |
| "claim": self.claim, | |
| "narrative": self.narrative, | |
| "known_facts": self.known_facts, | |
| "known_fallacies": self.known_fallacies, | |
| "evidence_keywords": self.evidence_keywords, | |
| "max_rounds": self.max_rounds, | |
| } | |
| # ────────────────────────────────────────────────────────────────────────────── | |
| # Topic bank (3 topics: easy / medium / hard) | |
| # ────────────────────────────────────────────────────────────────────────────── | |
| TOPIC_BANK: List[Topic] = [ | |
| Topic( | |
| topic_id="easy", | |
| difficulty="easy", | |
| domain="AI Policy & Media", | |
| claim="Social media platforms should be legally required to label AI-generated content.", | |
| narrative=( | |
| "Deepfakes and synthetic media are increasingly used in disinformation campaigns. " | |
| "The EU AI Act mandates labelling; the US DEFIANCE Act is under debate. " | |
| "Proponents argue transparency protects democratic discourse." | |
| ), | |
| known_facts={ | |
| "EU_AI_Act_mandates_labelling": True, | |
| "deepfakes_used_in_elections_2024": True, | |
| "labelling_eliminates_disinformation": False, | |
| "US_DEFIANCE_Act_passed": False, | |
| }, | |
| known_fallacies=["slippery_slope", "appeal_to_fear"], | |
| evidence_keywords=[ | |
| "EU AI Act", "DEFIANCE Act", "synthetic media", | |
| "disinformation", "transparency", "deepfake", | |
| ], | |
| max_rounds=5, | |
| ), | |
| Topic( | |
| topic_id="medium", | |
| difficulty="medium", | |
| domain="Climate & Energy Policy", | |
| claim="Governments should mandate a complete phase-out of fossil fuels by 2035.", | |
| narrative=( | |
| "IPCC reports warn that net-zero by 2050 requires rapid decarbonisation. " | |
| "Several EU nations have set 2035 targets; critics cite energy security risks. " | |
| "Renewables now account for 30% of global electricity." | |
| ), | |
| known_facts={ | |
| "IPCC_net_zero_2050_target": True, | |
| "renewables_30pct_global_electricity": True, | |
| "fossil_fuel_phaseout_causes_blackouts": False, | |
| "EU_2035_fossil_fuel_ban_enacted": False, | |
| }, | |
| known_fallacies=["false_dilemma", "appeal_to_nature"], | |
| evidence_keywords=[ | |
| "IPCC", "net-zero", "decarbonisation", "renewables", | |
| "energy security", "carbon emissions", | |
| ], | |
| max_rounds=6, | |
| ), | |
| Topic( | |
| topic_id="hard", | |
| difficulty="hard", | |
| domain="Bioethics & Genomics", | |
| claim="Human germline gene editing for disease prevention should be legally permitted.", | |
| narrative=( | |
| "CRISPR-Cas9 enables heritable edits. The He Jiankui case triggered global bans. " | |
| "Proponents cite eradication of hereditary diseases; opponents warn of eugenics slippery slopes. " | |
| "WHO guidelines call for a moratorium pending governance frameworks." | |
| ), | |
| known_facts={ | |
| "CRISPR_enables_heritable_edits": True, | |
| "WHO_moratorium_on_germline_editing": True, | |
| "germline_editing_eradicates_all_disease": False, | |
| "He_Jiankui_case_led_to_global_ban": False, # led to bans in many, not all countries | |
| }, | |
| known_fallacies=["slippery_slope", "appeal_to_nature", "false_dilemma"], | |
| evidence_keywords=[ | |
| "CRISPR", "germline", "WHO", "hereditary disease", | |
| "bioethics", "eugenics", "governance", | |
| ], | |
| max_rounds=7, | |
| ), | |
| ] | |
| # Lookup by topic_id | |
| _TOPIC_MAP: Dict[str, Topic] = {t.topic_id: t for t in TOPIC_BANK} | |
| # ────────────────────────────────────────────────────────────────────────────── | |
| # Adaptive curriculum | |
| # ────────────────────────────────────────────────────────────────────────────── | |
| class TopicRegistry: | |
| """ | |
| Tracks per-topic win-rates and escalates difficulty. | |
| Escalation rule: | |
| win_rate >= 0.70 over the last >= 3 attempts → bump to next difficulty | |
| """ | |
| _history: Dict[str, List[bool]] = field(default_factory=dict) | |
| def get_topic(self, topic_id: str) -> Optional[Topic]: | |
| return _TOPIC_MAP.get(topic_id) | |
| def current_topic(self) -> Topic: | |
| """Return the easiest topic that hasn't been mastered yet.""" | |
| order = ["easy", "medium", "hard"] | |
| for tid in order: | |
| if not self._is_mastered(tid): | |
| return _TOPIC_MAP[tid] | |
| return _TOPIC_MAP["hard"] | |
| def update_curriculum(self, topic_id: str, won: bool) -> None: | |
| self._history.setdefault(topic_id, []).append(won) | |
| def win_rate(self, topic_id: str) -> float: | |
| hist = self._history.get(topic_id, []) | |
| if not hist: | |
| return 0.0 | |
| return sum(hist) / len(hist) | |
| def attempts(self, topic_id: str) -> int: | |
| return len(self._history.get(topic_id, [])) | |
| def _is_mastered(self, topic_id: str) -> bool: | |
| return self.attempts(topic_id) >= 3 and self.win_rate(topic_id) >= 0.70 | |
| def summary(self) -> Dict[str, Any]: | |
| return { | |
| tid: { | |
| "attempts": self.attempts(tid), | |
| "win_rate": round(self.win_rate(tid), 3), | |
| "mastered": self._is_mastered(tid), | |
| } | |
| for tid in _TOPIC_MAP | |
| } | |
| # Singleton used by the environment | |
| REGISTRY = TopicRegistry() | |