feat(tools): Phase T.1-T.4 complete - manifest system, registry, implementations, runtime, collaboration, scheduler
This commit is contained in:
93
backend/app/tools/runtime/native_runtime.py
Normal file
93
backend/app/tools/runtime/native_runtime.py
Normal file
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
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
|
||||
Reference in New Issue
Block a user