Download server/difficulty_controller.py from ProthamD/prothamd-adaptive-world-env: direct link, hf CLI and curl.
- Browser
- Download file 4.91 kB
-
https://huggingface.co/spaces/ProthamD/prothamd-adaptive-world-env/resolve/main/server/difficulty_controller.py
- Command line
-
hf download hf://spaces/ProthamD/prothamd-adaptive-world-env/server/difficulty_controller.py
-
curl -L -o difficulty_controller.py https://huggingface.co/spaces/ProthamD/prothamd-adaptive-world-env/resolve/main/server/difficulty_controller.py
4.91 kB
| """ | |
| difficulty_controller.py β Adaptive drift difficulty controller (v2). | |
| Tracks agent belief_accuracy per drift_type over a sliding window. | |
| Escalates difficulty when the agent consistently performs well above threshold. | |
| Why this matters: | |
| Prevents the agent from overfitting to 12 fixed scenarios. | |
| The environment generates effectively infinite scenarios by combining drift | |
| types and adjusting parameters based on agent competence. | |
| Escalation levels: | |
| 0 β base scenarios unchanged | |
| 1 β combine two drift types in same episode (secondary drift added 2 steps later) | |
| 2 β noisy error messages (ambiguous 422 bodies β "validation error" without field name) | |
| 3 β force silent semantic drift + noisy errors (hardest: no error signal at all) | |
| """ | |
| from __future__ import annotations | |
| from typing import Dict, List | |
| from collections import defaultdict, deque | |
| ESCALATION_THRESHOLD = 0.80 # average belief_accuracy to trigger escalation | |
| ESCALATION_WINDOW = 5 # number of recent episodes to average per drift type | |
| EASY_DRIFT_TYPES = ["field_rename", "endpoint_version", "policy_change"] | |
| HARD_DRIFT_TYPES = ["silent_semantic"] | |
| class DriftDifficultyController: | |
| """ | |
| Tracks agent performance and adaptively escalates drift difficulty. | |
| A single instance persists across all episodes for a given server process. | |
| """ | |
| def __init__(self): | |
| # belief_accuracy history per drift_type | |
| self._history: Dict[str, deque] = defaultdict( | |
| lambda: deque(maxlen=ESCALATION_WINDOW) | |
| ) | |
| self._escalation_level: int = 0 # 0=basic, 1=combined, 2=noisy, 3=silent-only | |
| def record(self, drift_type: str, belief_accuracy: float) -> None: | |
| """Call after each episode finishes to update the performance history.""" | |
| self._history[drift_type].append(belief_accuracy) | |
| self._maybe_escalate() | |
| def _maybe_escalate(self) -> None: | |
| """ | |
| Escalate if agent averages above threshold on ALL easy drift types | |
| for the last ESCALATION_WINDOW episodes. | |
| """ | |
| if self._escalation_level >= 3: | |
| return | |
| for dt in EASY_DRIFT_TYPES: | |
| hist = list(self._history[dt]) | |
| if len(hist) < ESCALATION_WINDOW: | |
| return # not enough data yet | |
| avg = sum(hist) / len(hist) | |
| if avg < ESCALATION_THRESHOLD: | |
| return # agent still struggling on this drift type | |
| self._escalation_level += 1 | |
| def get_scenario_params(self, base_scenario: dict) -> dict: | |
| """ | |
| Modify a base scenario dict based on current escalation level. | |
| Level 0: return base scenario unchanged | |
| Level 1: add secondary_drift_step 2 steps after primary (combines two drift types) | |
| Level 2: set noisy_errors=True (ambiguous error messages) | |
| Level 3: force drift_type to "silent_semantic" + noisy errors | |
| """ | |
| if self._escalation_level == 0: | |
| return base_scenario | |
| modified = dict(base_scenario) | |
| if self._escalation_level >= 1: | |
| # Add a secondary drift 2 steps after the primary drift | |
| primary_step = base_scenario.get("drift_trigger_step", 3) | |
| modified["secondary_drift_step"] = primary_step + 2 | |
| modified["secondary_drift_type"] = "policy_change" | |
| # Also set noisy_errors in initial_world if it exists | |
| if "initial_world" in modified: | |
| modified["initial_world"] = dict(modified["initial_world"]) | |
| if self._escalation_level >= 2: | |
| # Noisy errors: 422 body becomes vague | |
| modified["noisy_errors"] = True | |
| # Merge into mutated_world if present | |
| if "mutated_world" in modified: | |
| modified["mutated_world"] = dict(modified["mutated_world"]) | |
| modified["mutated_world"]["noisy_errors"] = True | |
| if self._escalation_level >= 3: | |
| # Force silent semantic only β override drift_type | |
| modified["drift_type"] = "silent_semantic" | |
| modified["noisy_errors"] = True | |
| if "mutated_world" in modified: | |
| modified["mutated_world"]["noisy_errors"] = True | |
| return modified | |
| def deescalate(self) -> None: | |
| """Manually lower escalation level (for testing or reset).""" | |
| if self._escalation_level > 0: | |
| self._escalation_level -= 1 | |
| def reset(self) -> None: | |
| """Reset all state (for testing).""" | |
| self._history.clear() | |
| self._escalation_level = 0 | |
| def level(self) -> int: | |
| return self._escalation_level | |
| def get_history_summary(self) -> Dict[str, float]: | |
| """Returns current average belief_accuracy per drift type (for logging).""" | |
| return { | |
| dt: (sum(hist) / len(hist) if hist else 0.0) | |
| for dt, hist in self._history.items() | |
| } | |