"""Execution context helpers for isolated runtime tool execution.""" from __future__ import annotations import os import shutil import sys from pathlib import Path from typing import Any from opc.core.config import OPCConfig def platform_key() -> str: if sys.platform.startswith("win"): return "windows" if sys.platform == "darwin": return "macos" return "linux" def venv_python_path(venv_path: str | Path) -> Path: base = Path(venv_path) if platform_key() == "windows": return base / "Scripts" / "python.exe" return base / "bin" / "python" def build_task_execution_context( *, workspace_root: str | Path | None, output_root: str | Path | None = None, comms_root: str | Path | None = None, config: OPCConfig | None = None, venv_path: str | Path | None = None, python_executable: str | Path | None = None, venv_provider: str = "", preparation_error: str = "", ) -> dict[str, Any]: workspace = Path(workspace_root or os.getcwd()).resolve() output = Path(output_root).resolve() if output_root else workspace resolved_comms_root = Path(comms_root).resolve() if comms_root else (workspace / ".opc-comms") resolved_venv = Path(venv_path).resolve() if venv_path else None resolved_python = Path(python_executable).resolve() if python_executable else None return { "workspace_root": str(workspace), "output_root": str(output), "comms_root": str(resolved_comms_root), "venv_path": str(resolved_venv) if resolved_venv else "", "python_executable": str(resolved_python) if resolved_python else "", "venv_provider": str(venv_provider or "").strip(), "preparation_error": str(preparation_error or "").strip(), "sandbox": resolve_sandbox_config(config), } def ensure_task_execution_context(task: Any, config: OPCConfig | None = None) -> dict[str, Any]: metadata = getattr(task, "metadata", {}) or {} existing = dict(metadata.get("_execution_context", {}) or {}) if existing: return existing workspace_root = ( str(metadata.get("workspace_root", "") or "").strip() or str(metadata.get("comms_workspace_root", "") or "").strip() or str(metadata.get("target_output_dir", "") or "").strip() or os.getcwd() ) output_root = ( str(metadata.get("output_root", "") or "").strip() or str(metadata.get("target_output_dir", "") or "").strip() or workspace_root ) comms_root = ( str(metadata.get("comms_root", "") or "").strip() or (str(Path(workspace_root).resolve() / ".opc-comms") if workspace_root else "") ) context = build_task_execution_context( workspace_root=workspace_root, output_root=output_root, comms_root=comms_root, config=config, ) metadata["_execution_context"] = context setattr(task, "metadata", metadata) return context def resolve_task_execution_context(task: Any = None) -> dict[str, Any]: if task is None: return {} metadata = getattr(task, "metadata", {}) or {} context = dict(metadata.get("_execution_context", {}) or {}) if not context: workspace_root = ( str(metadata.get("workspace_root", "") or "").strip() or str(metadata.get("comms_workspace_root", "") or "").strip() or str(metadata.get("target_output_dir", "") or "").strip() ) if workspace_root: output_root = ( str(metadata.get("output_root", "") or "").strip() or str(metadata.get("target_output_dir", "") or "").strip() or workspace_root ) context = { "workspace_root": str(Path(workspace_root).resolve()), "output_root": str(Path(output_root).resolve()), "comms_root": str(Path(workspace_root).resolve() / ".opc-comms"), } inherited = metadata.get("inherited_environment") if isinstance(inherited, dict): env_vars = inherited.get("env_vars") if isinstance(env_vars, dict) and env_vars: existing = dict(context.get("inherited_env_vars", {}) or {}) existing.update(env_vars) context["inherited_env_vars"] = existing manifest = metadata.get("environment_manifest") if isinstance(manifest, dict): env_vars = manifest.get("env_vars") if isinstance(env_vars, dict) and env_vars: existing = dict(context.get("inherited_env_vars", {}) or {}) existing.update(env_vars) context["inherited_env_vars"] = existing return context def resolve_sandbox_config(config: OPCConfig | None = None) -> dict[str, Any]: platform = platform_key() if config is None: return { "platform": platform, "enabled": False, "mode": "off", "wrapper": "none", "fail_if_unavailable": False, "allow_direct_fallback": True, "allow_network": True, } sandbox_cfg = config.system.native_runtime.execution_environment.sandbox platform_cfg = getattr(sandbox_cfg, platform) mode = platform_cfg.mode if platform_cfg.mode != "inherit" else sandbox_cfg.default_mode wrapper = platform_cfg.wrapper if not sandbox_cfg.enabled: mode = "off" wrapper = "none" return { "platform": platform, "enabled": bool(sandbox_cfg.enabled), "mode": mode, "wrapper": wrapper, "fail_if_unavailable": bool(sandbox_cfg.fail_if_unavailable), "allow_direct_fallback": bool(sandbox_cfg.allow_direct_fallback), "allow_network": bool(sandbox_cfg.allow_network), } def build_subprocess_env(context: dict[str, Any] | None = None) -> dict[str, str]: env = dict(os.environ) context = dict(context or {}) inherited_env = dict(context.get("inherited_env_vars", {}) or {}) if inherited_env: env.update({str(k): str(v) for k, v in inherited_env.items()}) venv_path = str(context.get("venv_path", "") or "").strip() python_path = str(context.get("python_executable", "") or "").strip() if not venv_path or not python_path: return env if not Path(python_path).exists(): return env bin_dir = str(Path(python_path).resolve().parent) env["VIRTUAL_ENV"] = venv_path env["PATH"] = bin_dir + os.pathsep + env.get("PATH", "") env.setdefault("UV_PROJECT_ENVIRONMENT", venv_path) return env def resolve_python_executable(context: dict[str, Any] | None = None) -> str: context = dict(context or {}) configured = str(context.get("python_executable", "") or "").strip() if configured and Path(configured).exists(): return configured return shutil.which("python3") or shutil.which("python") or sys.executable def wrap_command_for_context( args: list[str], *, cwd: str, context: dict[str, Any] | None = None, ) -> tuple[list[str], dict[str, Any]]: context = dict(context or {}) sandbox = dict(context.get("sandbox", {}) or {}) mode = str(sandbox.get("mode", "off") or "off").strip().lower() or "off" requested_wrapper = str(sandbox.get("wrapper", "auto") or "auto").strip().lower() or "auto" platform = str(sandbox.get("platform", "") or platform_key()).strip() or platform_key() meta = { "platform": platform, "requested_mode": mode, "effective_mode": mode, "requested_wrapper": requested_wrapper, "effective_wrapper": "none", "available": True, "fallback_used": False, } if mode in {"", "off", "elevated"}: return args, meta wrapper = requested_wrapper if wrapper in {"", "auto"}: if platform == "linux" and shutil.which("bwrap"): wrapper = "bwrap" elif platform == "macos" and shutil.which("sandbox-exec"): wrapper = "sandbox-exec" else: wrapper = "none" meta["effective_wrapper"] = wrapper if wrapper == "bwrap": return _wrap_with_bwrap(args, cwd=cwd, context=context, meta=meta), meta if wrapper == "sandbox-exec": return _wrap_with_sandbox_exec(args, cwd=cwd, context=context, meta=meta), meta return _handle_unavailable_sandbox(args, sandbox=sandbox, meta=meta) def _handle_unavailable_sandbox( args: list[str], *, sandbox: dict[str, Any], meta: dict[str, Any], ) -> tuple[list[str], dict[str, Any]]: meta["available"] = False allow_direct = bool(sandbox.get("allow_direct_fallback", True)) if bool(sandbox.get("fail_if_unavailable", False)) and not allow_direct: raise RuntimeError( f"Sandbox mode `{meta['requested_mode']}` is unavailable on {meta['platform']} and direct fallback is disabled." ) meta["fallback_used"] = True meta["effective_mode"] = "off" meta["effective_wrapper"] = "none" return args, meta def _wrap_with_bwrap( args: list[str], *, cwd: str, context: dict[str, Any], meta: dict[str, Any], ) -> list[str]: workspace = str(Path(context.get("workspace_root") or cwd).resolve()) wrapped = [ "bwrap", "--die-with-parent", "--new-session", "--ro-bind", "/", "/", "--bind", workspace, workspace, "--proc", "/proc", "--dev", "/dev", "--tmpfs", "/tmp", "--chdir", cwd, ] sandbox = dict(context.get("sandbox", {}) or {}) if not bool(sandbox.get("allow_network", True)): wrapped.append("--unshare-net") wrapped.extend(args) meta["available"] = True return wrapped def _wrap_with_sandbox_exec( args: list[str], *, cwd: str, context: dict[str, Any], meta: dict[str, Any], ) -> list[str]: sandbox = dict(context.get("sandbox", {}) or {}) workspace = str(Path(context.get("workspace_root") or cwd).resolve()) escaped_workspace = workspace.replace("\\", "\\\\").replace('"', '\\"') allow_network = bool(sandbox.get("allow_network", True)) profile_lines = [ "(version 1)", "(deny default)", "(import \"system.sb\")", "(allow process-exec)", "(allow process-fork)", "(allow signal (target self))", "(allow file-read*)", f"(allow file-write* (subpath \"{escaped_workspace}\") (subpath \"/tmp\") (subpath \"/private/tmp\"))", ] if allow_network: profile_lines.append("(allow network*)") meta["available"] = True return ["sandbox-exec", "-p", "\n".join(profile_lines), *args]