Spaces:
Running
Running
Deploy Aureon OS (deploy/selfhost stack: nginx edge + fusion API x2 + console + HNC organ + redis + postgres; paper mode) (part 3)
1ccf652 verified Download aureon/code_architect/executor.py from GaryLeckey/aureon-os: direct link, hf CLI and curl.
- Browser
- Download file 16 kB
-
https://huggingface.co/spaces/GaryLeckey/aureon-os/resolve/main/aureon/code_architect/executor.py
- Command line
-
hf download hf://spaces/GaryLeckey/aureon-os/aureon/code_architect/executor.py
-
curl -L -o executor.py https://huggingface.co/spaces/GaryLeckey/aureon-os/resolve/main/aureon/code_architect/executor.py
16 kB
| """ | |
| SkillExecutor β runs validated skills in the safe exec sandbox | |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Executes skills against: | |
| β’ A VMControlDispatcher (VM target) | |
| β’ The local system (local target β future; currently the same | |
| dispatcher can be pointed at a real Windows VM via WinRM) | |
| For compound / workflow / role skills, the executor resolves dependencies | |
| via the SkillLibrary and caches compiled function objects to avoid | |
| recompiling on every call. | |
| Safety: | |
| β’ Uses `primitives.get_safe_globals(dispatcher, thought_bus, executor)` | |
| as the exec globals dict (SAFE_BUILTINS only). | |
| β’ Re-runs the static safety check before first execution. | |
| β’ Bounded recursion depth (max 10) to prevent infinite compound chains. | |
| β’ Per-execution timeout via watchdog thread (soft β Python can't hard | |
| cancel arbitrary code, but we record and flag long runs). | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| import threading | |
| import time | |
| import traceback | |
| from dataclasses import dataclass, field | |
| from typing import Any, Callable, Dict, List, Optional | |
| from aureon.code_architect.skill import Skill, SkillStatus | |
| from aureon.code_architect.skill_library import SkillLibrary | |
| from aureon.code_architect.primitives import get_safe_globals | |
| from aureon.code_architect.validator import SkillValidator | |
| logger = logging.getLogger("aureon.code_architect.executor") | |
| MAX_DEPTH = 10 | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Result dataclass | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class SkillExecutionResult: | |
| skill_name: str = "" | |
| ok: bool = False | |
| return_value: Any = None | |
| error: Optional[str] = None | |
| traceback: Optional[str] = None | |
| duration_s: float = 0.0 | |
| depth: int = 0 | |
| timestamp: float = field(default_factory=time.time) | |
| sub_results: List[Dict[str, Any]] = field(default_factory=list) | |
| def to_dict(self) -> Dict[str, Any]: | |
| return { | |
| "skill_name": self.skill_name, | |
| "ok": self.ok, | |
| "return_value": self.return_value, | |
| "error": self.error, | |
| "traceback": self.traceback, | |
| "duration_s": round(self.duration_s, 4), | |
| "depth": self.depth, | |
| "timestamp": self.timestamp, | |
| "sub_results_count": len(self.sub_results), | |
| } | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # SkillExecutor | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class SkillExecutor: | |
| """ | |
| Runs skills in a safe exec sandbox. | |
| Attributes: | |
| library : the SkillLibrary (source of skills) | |
| dispatcher : the VMControlDispatcher (backends for vm_* primitives) | |
| validator : the SkillValidator (re-runs static safety on first use) | |
| thought_bus: optional ThoughtBus for emit_event primitive | |
| """ | |
| def __init__( | |
| self, | |
| library: Optional[SkillLibrary] = None, | |
| dispatcher: Any = None, | |
| validator: Optional[SkillValidator] = None, | |
| thought_bus: Any = None, | |
| require_static_check: bool = True, | |
| ): | |
| self.library = library | |
| self.dispatcher = dispatcher | |
| self.validator = validator or SkillValidator() | |
| self.thought_bus = thought_bus | |
| self.require_static_check = require_static_check | |
| self._compiled_cache: Dict[str, Callable] = {} # skill_name β entry function | |
| self._lock = threading.RLock() | |
| # Metrics | |
| self._total_executions = 0 | |
| self._successes = 0 | |
| self._failures = 0 | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Compilation | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _safe_globals(self) -> Dict[str, Any]: | |
| return get_safe_globals( | |
| dispatcher=self.dispatcher, | |
| thought_bus=self.thought_bus, | |
| executor=self, | |
| ) | |
| def _compile(self, skill: Skill) -> Callable: | |
| """Compile a skill's source into a callable (cached).""" | |
| with self._lock: | |
| cached = self._compiled_cache.get(skill.name) | |
| if cached is not None: | |
| return cached | |
| # Belt & braces: re-run static check before compile | |
| if self.require_static_check: | |
| safe, errors = self.validator.static_check(skill.code) | |
| if not safe: | |
| raise RuntimeError(f"skill {skill.name} failed static safety: {errors[:3]}") | |
| # exec inside a *fresh* globals dict for compilation so function refs | |
| # are properly bound. The execution will use _safe_globals() again. | |
| compile_globals = self._safe_globals() | |
| local_scope: Dict[str, Any] = {} | |
| try: | |
| compiled_code = compile(skill.code, f"<skill:{skill.name}>", "exec") | |
| exec(compiled_code, compile_globals, local_scope) | |
| except Exception as e: | |
| raise RuntimeError(f"skill {skill.name} compile failed: {e}") | |
| entry = skill.entry_function or skill.name | |
| func = local_scope.get(entry) | |
| if not callable(func): | |
| raise RuntimeError(f"skill {skill.name} has no callable entry function '{entry}'") | |
| with self._lock: | |
| self._compiled_cache[skill.name] = func | |
| return func | |
| def invalidate_cache(self, skill_name: Optional[str] = None) -> None: | |
| with self._lock: | |
| if skill_name is None: | |
| self._compiled_cache.clear() | |
| else: | |
| self._compiled_cache.pop(skill_name, None) | |
| def _execution_is_simulated(self, params: Optional[Dict[str, Any]]) -> bool: | |
| """Return True only when the selected dispatcher session is in-memory.""" | |
| if self.dispatcher is None: | |
| return False | |
| try: | |
| session_id = (params or {}).get("session_id") | |
| controller = self.dispatcher.get_session(session_id) | |
| session = getattr(controller, "session", None) | |
| return str(getattr(session, "backend", "")).casefold() == "simulated" | |
| except Exception: | |
| return False | |
| def _blocked_execution( | |
| self, | |
| skill: Skill, | |
| *, | |
| error: str, | |
| depth: int, | |
| started_at: float, | |
| ) -> SkillExecutionResult: | |
| self.invalidate_cache(skill.name) | |
| result = SkillExecutionResult( | |
| skill_name=skill.name, | |
| ok=False, | |
| error=error, | |
| depth=depth, | |
| duration_s=time.time() - started_at, | |
| ) | |
| self._failures += 1 | |
| if self.library: | |
| self.library.record_execution( | |
| skill.name, | |
| success=False, | |
| duration_s=result.duration_s, | |
| error=result.error, | |
| ) | |
| return result | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Execution | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def execute( | |
| self, | |
| skill: Skill, | |
| params: Optional[Dict[str, Any]] = None, | |
| _depth: int = 0, | |
| ) -> SkillExecutionResult: | |
| """Execute a Skill object.""" | |
| if _depth > MAX_DEPTH: | |
| return SkillExecutionResult( | |
| skill_name=skill.name, | |
| ok=False, | |
| error=f"max_recursion_depth_exceeded: {_depth}", | |
| depth=_depth, | |
| ) | |
| self._total_executions += 1 | |
| start = time.time() | |
| result = SkillExecutionResult(skill_name=skill.name, depth=_depth) | |
| status_value = str(getattr(skill.status, "value", skill.status) or "").casefold() | |
| non_executable_statuses = { | |
| "proposed", | |
| "pending", | |
| "pending_review", | |
| "rejected", | |
| "blocked", | |
| "deprecated", | |
| } | |
| if status_value in non_executable_statuses: | |
| return self._blocked_execution( | |
| skill, | |
| error=f"skill_status_not_executable:{status_value or 'unknown'}", | |
| depth=_depth, | |
| started_at=start, | |
| ) | |
| tags = set(skill.tags or []) | |
| if ( | |
| "requires_explicit_approval" in tags | |
| and status_value not in {SkillStatus.APPROVED.value, SkillStatus.ACTIVE.value} | |
| ): | |
| return self._blocked_execution( | |
| skill, | |
| error="skill_approval_required", | |
| depth=_depth, | |
| started_at=start, | |
| ) | |
| if "live_execution_disabled" in tags and not self._execution_is_simulated(params): | |
| return self._blocked_execution( | |
| skill, | |
| error="skill_live_execution_disabled", | |
| depth=_depth, | |
| started_at=start, | |
| ) | |
| # Compile (uses cache) | |
| try: | |
| func = self._compile(skill) | |
| except Exception as e: | |
| result.ok = False | |
| result.error = str(e) | |
| result.traceback = traceback.format_exc() | |
| result.duration_s = time.time() - start | |
| self._failures += 1 | |
| if self.library: | |
| self.library.record_execution(skill.name, success=False, | |
| duration_s=result.duration_s, | |
| error=result.error) | |
| return result | |
| # We need the globals dict from the compiled function so primitives | |
| # like call_skill/emit_event see the right executor. The function | |
| # was exec'd with our globals, so it already captures them. | |
| # Run the entry function | |
| try: | |
| ret = func(**(params or {})) | |
| result.ok = True | |
| result.return_value = ret | |
| self._successes += 1 | |
| except Exception as e: | |
| result.ok = False | |
| result.error = str(e) | |
| result.traceback = traceback.format_exc() | |
| self._failures += 1 | |
| result.duration_s = time.time() - start | |
| if self.library: | |
| self.library.record_execution( | |
| name=skill.name, | |
| success=result.ok, | |
| duration_s=result.duration_s, | |
| error=result.error, | |
| ) | |
| # Publish | |
| self._publish(skill, result) | |
| return result | |
| def execute_by_name( | |
| self, | |
| skill_name: str, | |
| params: Optional[Dict[str, Any]] = None, | |
| _depth: int = 0, | |
| ) -> SkillExecutionResult: | |
| """Look up a skill by name and execute it.""" | |
| if self.library is None: | |
| return SkillExecutionResult( | |
| skill_name=skill_name, | |
| ok=False, | |
| error="no_library", | |
| ) | |
| skill = self.library.get(skill_name) | |
| if not skill: | |
| return SkillExecutionResult( | |
| skill_name=skill_name, | |
| ok=False, | |
| error="skill_not_found", | |
| ) | |
| return self.execute(skill, params=params, _depth=_depth) | |
| def execute_with_dependencies( | |
| self, | |
| skill_name: str, | |
| params: Optional[Dict[str, Any]] = None, | |
| ) -> SkillExecutionResult: | |
| """ | |
| Resolve the dependency tree and execute the top-level skill. | |
| The dependencies themselves are executed lazily via call_skill, | |
| but this method pre-compiles them for speed. | |
| """ | |
| if self.library is None: | |
| return SkillExecutionResult( | |
| skill_name=skill_name, | |
| ok=False, | |
| error="no_library", | |
| ) | |
| deps = self.library.resolve_dependencies(skill_name) | |
| # Pre-compile all dependencies so call_skill finds them ready | |
| for dep in deps: | |
| try: | |
| self._compile(dep) | |
| except Exception as e: | |
| logger.warning("Failed to pre-compile dep %s: %s", dep.name, e) | |
| return self.execute_by_name(skill_name, params=params) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Publishing | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _publish(self, skill: Skill, result: SkillExecutionResult) -> None: | |
| if not self.thought_bus: | |
| return | |
| try: | |
| from aureon.core.aureon_thought_bus import Thought | |
| self.thought_bus.publish(Thought( | |
| source="code_architect.executor", | |
| topic=f"skill.executed.{'ok' if result.ok else 'fail'}", | |
| payload={ | |
| "skill_name": skill.name, | |
| "level": skill.level.name, | |
| "ok": result.ok, | |
| "duration_s": result.duration_s, | |
| "depth": result.depth, | |
| "error": result.error, | |
| }, | |
| )) | |
| except Exception: | |
| pass | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Status | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def get_status(self) -> Dict[str, Any]: | |
| return { | |
| "total_executions": self._total_executions, | |
| "successes": self._successes, | |
| "failures": self._failures, | |
| "success_rate": ( | |
| self._successes / self._total_executions if self._total_executions > 0 else 0.0 | |
| ), | |
| "cached_compilations": len(self._compiled_cache), | |
| "dispatcher_wired": self.dispatcher is not None, | |
| } | |