Spaces:
Runtime error
Runtime error
| """Dynamic component resolution for OpenRange. | |
| Loads Builder, NPC, and Validator implementations at startup from | |
| dotted class paths specified in YAML config. | |
| """ | |
| from __future__ import annotations | |
| import importlib | |
| import inspect | |
| from pathlib import Path | |
| from typing import Any, Type | |
| import yaml | |
| from open_range.protocols import ( | |
| NPCBehavior, | |
| SnapshotBuilder, | |
| ValidatorCheck, | |
| ) | |
| # Default validator checks when none specified in config | |
| DEFAULT_CHECKS: list[dict[str, Any]] = [ | |
| {"class": "open_range.validator.build_boot.BuildBootCheck"}, | |
| {"class": "open_range.validator.exploitability.ExploitabilityCheck"}, | |
| {"class": "open_range.validator.patchability.PatchabilityCheck"}, | |
| {"class": "open_range.validator.evidence.EvidenceCheck"}, | |
| {"class": "open_range.validator.reward_grounding.RewardGroundingCheck"}, | |
| {"class": "open_range.validator.isolation.IsolationCheck"}, | |
| ] | |
| def _missing_methods(instance: Any, protocol: Type) -> list[str]: | |
| """Return protocol method names missing from instance.""" | |
| missing = [] | |
| for name, method in inspect.getmembers(protocol, predicate=inspect.isfunction): | |
| if name.startswith("_"): | |
| continue | |
| if not hasattr(instance, name) or not callable(getattr(instance, name)): | |
| missing.append(name) | |
| return missing | |
| def resolve_component(class_path: str, kwargs: dict, protocol: Type) -> Any: | |
| """Import class by dotted path, instantiate, verify protocol compliance. | |
| Args: | |
| class_path: Dotted Python class path (e.g. "open_range.builder.builder.LLMSnapshotBuilder") | |
| kwargs: Constructor keyword arguments | |
| protocol: Protocol class to check against | |
| Returns: | |
| Instantiated component satisfying the protocol. | |
| Raises: | |
| TypeError: If the class doesn't satisfy the protocol. | |
| ImportError: If the module can't be imported. | |
| AttributeError: If the class doesn't exist in the module. | |
| """ | |
| module_name, _, class_name = class_path.rpartition(".") | |
| module = importlib.import_module(module_name) | |
| cls = getattr(module, class_name) | |
| instance = cls(**kwargs) | |
| if not isinstance(instance, protocol): | |
| missing = _missing_methods(instance, protocol) | |
| raise TypeError( | |
| f"{class_path} does not satisfy {protocol.__name__} protocol. " | |
| f"Missing methods: {missing}" | |
| ) | |
| return instance | |
| def load_agent_config(config_path: str) -> dict: | |
| """Load agent configuration from YAML file. | |
| Returns the 'agents' block from the config, or empty dict. | |
| """ | |
| path = Path(config_path) | |
| if not path.exists(): | |
| return {} | |
| with open(path) as f: | |
| config = yaml.safe_load(f) or {} | |
| return config.get("agents", {}) | |
| def build_components( | |
| config: dict, | |
| ) -> tuple[SnapshotBuilder, NPCBehavior, list[ValidatorCheck]]: | |
| """Resolve all infrastructure components from config dict. | |
| Args: | |
| config: The 'agents' block from openrange.yaml | |
| Returns: | |
| (builder, npc_behavior, validator_checks) tuple | |
| """ | |
| builder_cfg = config.get("builder", {}) | |
| builder = resolve_component( | |
| builder_cfg.get("class", "open_range.builder.builder.LLMSnapshotBuilder"), | |
| builder_cfg.get("kwargs", {}), | |
| SnapshotBuilder, | |
| ) | |
| npc_cfg = config.get("npc_behavior", {}) | |
| npc = resolve_component( | |
| npc_cfg.get("class", "open_range.builder.npc.npc_agent.NullNPCBehavior"), | |
| npc_cfg.get("kwargs", {}), | |
| NPCBehavior, | |
| ) | |
| checks: list[ValidatorCheck] = [] | |
| for check_cfg in config.get("validator_checks", DEFAULT_CHECKS): | |
| checks.append( | |
| resolve_component( | |
| check_cfg["class"], | |
| check_cfg.get("kwargs", {}), | |
| ValidatorCheck, | |
| ) | |
| ) | |
| return builder, npc, checks | |