Files
JARVIS/backend/app/tools/runtime/native_runtime.py

94 lines
2.6 KiB
Python
Raw Permalink Normal View History

"""
Native Runtime
Native binary execution runtime for system executables.
"""
import asyncio
import stat
from pathlib import Path
from typing import Any, Dict, List
from tools.runtime.base import BaseRuntime
class NativeRuntime(BaseRuntime):
"""Native binary execution runtime"""
def get_name(self) -> str:
return "native"
async def validate(self, entry: str) -> bool:
"""Validate native binary exists and is executable"""
path = Path(entry)
if not path.exists():
return False
# Check if file is executable
file_stat = path.stat()
executable_bit = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
if not (file_stat.st_mode & executable_bit):
return False
return True
async def execute(
self,
entry: str,
command: str,
parameters: Dict[str, Any],
timeout: int,
) -> Dict[str, Any]:
"""Execute a native binary"""
try:
# Build argument list
args = [entry, command] + self._format_args(parameters)
process = await asyncio.create_subprocess_exec(
*args,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout=timeout / 1000,
)
if process.returncode != 0:
return {
"status": "error",
"error": stderr.decode() if stderr else f"Exit code: {process.returncode}",
}
return {
"status": "success",
"result": stdout.decode() if stdout else "",
}
except asyncio.TimeoutError:
return {
"status": "error",
"error": f"Execution timed out after {timeout}ms",
}
except Exception as e:
return {
"status": "error",
"error": str(e),
}
def _format_args(self, parameters: Dict[str, Any]) -> List[str]:
"""Format parameters as command-line arguments"""
args: List[str] = []
for key, value in parameters.items():
# Use --key=value format
if isinstance(value, bool):
if value:
args.append(f"--{key}")
elif isinstance(value, (list, tuple)):
for item in value:
args.extend([f"--{key}", str(item)])
else:
args.extend([f"--{key}", str(value)])
return args