mirror of
https://github.com/YuuKi-OS/Yuu-Box.git
synced 2026-02-18 21:51:10 +00:00
pos nomas
This commit is contained in:
15
yuubox/__init__.py
Normal file
15
yuubox/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""YuuBox - Self-Healing Code Execution System"""
|
||||
|
||||
__version__ = "1.0.0"
|
||||
|
||||
from yuubox.executor import YuuBox, ExecutionResult, ResourceLimits
|
||||
from yuubox.exceptions import YuuBoxError, ExecutionError
|
||||
|
||||
__all__ = [
|
||||
"__version__",
|
||||
"YuuBox",
|
||||
"ExecutionResult",
|
||||
"ResourceLimits",
|
||||
"YuuBoxError",
|
||||
"ExecutionError",
|
||||
]
|
||||
59
yuubox/analyzer.py
Normal file
59
yuubox/analyzer.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import re
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
class ErrorAnalyzer:
|
||||
"""Analyzes execution errors"""
|
||||
|
||||
def analyze(self, stderr: str, language: str, code: str) -> Dict[str, Any]:
|
||||
if language == "python":
|
||||
return self._analyze_python(stderr)
|
||||
elif language in ["javascript", "js", "node"]:
|
||||
return self._analyze_javascript(stderr)
|
||||
elif language == "rust":
|
||||
return self._analyze_rust(stderr)
|
||||
else:
|
||||
return self._generic_analysis(stderr)
|
||||
|
||||
def _analyze_python(self, stderr: str) -> Dict[str, Any]:
|
||||
lines = stderr.split("\n")
|
||||
for i, line in enumerate(lines):
|
||||
if "Traceback" in line:
|
||||
last_line = lines[-1] if lines[-1].strip() else lines[-2]
|
||||
match = re.match(r"(\w+Error): (.+)", last_line)
|
||||
if match:
|
||||
line_match = re.search(r'line (\d+)', stderr)
|
||||
return {
|
||||
"type": match.group(1),
|
||||
"message": match.group(2),
|
||||
"line": int(line_match.group(1)) if line_match else None,
|
||||
"stack_trace": stderr,
|
||||
}
|
||||
return self._generic_analysis(stderr)
|
||||
|
||||
def _analyze_javascript(self, stderr: str) -> Dict[str, Any]:
|
||||
match = re.search(r"(\w+Error): (.+)", stderr)
|
||||
if match:
|
||||
return {
|
||||
"type": match.group(1),
|
||||
"message": match.group(2),
|
||||
"stack_trace": stderr,
|
||||
}
|
||||
return self._generic_analysis(stderr)
|
||||
|
||||
def _analyze_rust(self, stderr: str) -> Dict[str, Any]:
|
||||
if "error[E" in stderr:
|
||||
match = re.search(r"error\[E\d+\]: (.+)", stderr)
|
||||
if match:
|
||||
return {
|
||||
"type": "CompilerError",
|
||||
"message": match.group(1),
|
||||
"stack_trace": stderr,
|
||||
}
|
||||
return self._generic_analysis(stderr)
|
||||
|
||||
def _generic_analysis(self, stderr: str) -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "ExecutionError",
|
||||
"message": stderr[:300].strip(),
|
||||
"stack_trace": stderr,
|
||||
}
|
||||
42
yuubox/api.py
Normal file
42
yuubox/api.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from typing import Optional
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
from yuubox import YuuBox, ResourceLimits
|
||||
|
||||
app = FastAPI(title="YuuBox API", version="1.0.0")
|
||||
|
||||
class ExecuteRequest(BaseModel):
|
||||
code: str
|
||||
language: str
|
||||
max_iterations: Optional[int] = 5
|
||||
timeout: Optional[int] = 60
|
||||
memory_mb: Optional[int] = 256
|
||||
no_healing: Optional[bool] = False
|
||||
|
||||
@app.post("/execute")
|
||||
async def execute(request: ExecuteRequest):
|
||||
"""Execute code with self-healing"""
|
||||
box = YuuBox(max_iterations=request.max_iterations)
|
||||
|
||||
result = box.execute(
|
||||
code=request.code,
|
||||
language=request.language,
|
||||
limits=ResourceLimits(
|
||||
memory_mb=request.memory_mb,
|
||||
timeout_seconds=request.timeout,
|
||||
),
|
||||
no_healing=request.no_healing,
|
||||
)
|
||||
|
||||
return {
|
||||
"success": result.success,
|
||||
"stdout": result.stdout,
|
||||
"stderr": result.stderr,
|
||||
"iterations": result.iterations,
|
||||
"execution_time": result.execution_time,
|
||||
}
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "healthy"}
|
||||
69
yuubox/cli.py
Normal file
69
yuubox/cli.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import sys
|
||||
import click
|
||||
from rich.console import Console
|
||||
from rich.progress import Progress, SpinnerColumn, TextColumn
|
||||
|
||||
from yuubox import YuuBox, ResourceLimits
|
||||
|
||||
console = Console()
|
||||
|
||||
@click.group()
|
||||
@click.version_option("1.0.0")
|
||||
def cli():
|
||||
"""YuuBox - Self-Healing Code Execution"""
|
||||
pass
|
||||
|
||||
@cli.command()
|
||||
@click.argument("file", type=click.Path(exists=True))
|
||||
@click.option("--language", "-l")
|
||||
@click.option("--max-iterations", default=5)
|
||||
@click.option("--no-healing", is_flag=True)
|
||||
@click.option("--timeout", default=60)
|
||||
@click.option("--memory", default=256)
|
||||
def run(file, language, max_iterations, no_healing, timeout, memory):
|
||||
"""Execute code file with self-healing"""
|
||||
|
||||
with open(file) as f:
|
||||
code = f.read()
|
||||
|
||||
if not language:
|
||||
if file.endswith(".py"):
|
||||
language = "python"
|
||||
elif file.endswith(".js"):
|
||||
language = "javascript"
|
||||
elif file.endswith(".rs"):
|
||||
language = "rust"
|
||||
else:
|
||||
console.print("[red]Cannot detect language. Use --language[/red]")
|
||||
sys.exit(1)
|
||||
|
||||
console.print(f"\n[bold blue]Executing {file}[/bold blue]")
|
||||
console.print(f"[dim]Language: {language}, Max iterations: {max_iterations}[/dim]\n")
|
||||
|
||||
box = YuuBox(max_iterations=max_iterations)
|
||||
|
||||
with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
|
||||
task = progress.add_task("Running...", total=None)
|
||||
result = box.execute(
|
||||
code, language,
|
||||
limits=ResourceLimits(memory_mb=memory, timeout_seconds=timeout),
|
||||
no_healing=no_healing,
|
||||
)
|
||||
progress.remove_task(task)
|
||||
|
||||
if result.success:
|
||||
console.print(f"\n[bold green]✓ Success after {result.iterations} iteration(s)[/bold green]\n")
|
||||
if result.stdout:
|
||||
console.print("[bold]Output:[/bold]")
|
||||
console.print(result.stdout)
|
||||
else:
|
||||
console.print(f"\n[bold red]✗ Failed after {result.iterations} iteration(s)[/bold red]\n")
|
||||
console.print("[bold]Error:[/bold]")
|
||||
console.print(result.stderr[:500])
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
cli()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
15
yuubox/exceptions.py
Normal file
15
yuubox/exceptions.py
Normal file
@@ -0,0 +1,15 @@
|
||||
class YuuBoxError(Exception):
|
||||
"""Base exception"""
|
||||
pass
|
||||
|
||||
class ExecutionError(YuuBoxError):
|
||||
"""Execution failed"""
|
||||
pass
|
||||
|
||||
class DockerError(YuuBoxError):
|
||||
"""Docker error"""
|
||||
pass
|
||||
|
||||
class HealingError(YuuBoxError):
|
||||
"""Healing failed"""
|
||||
pass
|
||||
128
yuubox/executor.py
Normal file
128
yuubox/executor.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import time
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional
|
||||
|
||||
try:
|
||||
from yuubox.yuubox_core import ContainerExecutor as RustExecutor
|
||||
except ImportError:
|
||||
RustExecutor = None
|
||||
|
||||
from yuubox.analyzer import ErrorAnalyzer
|
||||
from yuubox.healer import YuukiHealer
|
||||
from yuubox.exceptions import ExecutionError
|
||||
|
||||
@dataclass
|
||||
class ResourceLimits:
|
||||
memory_mb: int = 256
|
||||
cpu_quota: float = 1.0
|
||||
timeout_seconds: int = 60
|
||||
|
||||
@dataclass
|
||||
class ErrorReport:
|
||||
error_type: str
|
||||
error_message: str
|
||||
iteration: int
|
||||
line_number: Optional[int] = None
|
||||
|
||||
@dataclass
|
||||
class ExecutionResult:
|
||||
success: bool
|
||||
stdout: str
|
||||
stderr: str
|
||||
exit_code: int
|
||||
iterations: int
|
||||
execution_time: float
|
||||
final_code: str
|
||||
error_history: List[ErrorReport] = field(default_factory=list)
|
||||
|
||||
class YuuBox:
|
||||
"""Self-healing code executor (Rust + Python hybrid)"""
|
||||
|
||||
def __init__(self, max_iterations: int = 5, yuuki_api_url: Optional[str] = None):
|
||||
if RustExecutor is None:
|
||||
raise ImportError("Rust core not compiled. Run: maturin develop")
|
||||
|
||||
self.max_iterations = max_iterations
|
||||
self.rust_executor = RustExecutor()
|
||||
self.analyzer = ErrorAnalyzer()
|
||||
self.healer = YuukiHealer(yuuki_api_url)
|
||||
|
||||
def execute(
|
||||
self,
|
||||
code: str,
|
||||
language: str,
|
||||
limits: Optional[ResourceLimits] = None,
|
||||
no_healing: bool = False,
|
||||
) -> ExecutionResult:
|
||||
limits = limits or ResourceLimits()
|
||||
current_code = code
|
||||
error_history = []
|
||||
start_time = time.time()
|
||||
|
||||
for iteration in range(1, self.max_iterations + 1):
|
||||
# Execute in Rust (FAST!)
|
||||
result = self.rust_executor.execute(
|
||||
current_code,
|
||||
language,
|
||||
limits.memory_mb,
|
||||
limits.cpu_quota,
|
||||
limits.timeout_seconds,
|
||||
)
|
||||
|
||||
if result.exit_code == 0:
|
||||
return ExecutionResult(
|
||||
success=True,
|
||||
stdout=result.stdout,
|
||||
stderr=result.stderr,
|
||||
exit_code=0,
|
||||
iterations=iteration,
|
||||
execution_time=time.time() - start_time,
|
||||
final_code=current_code,
|
||||
error_history=error_history,
|
||||
)
|
||||
|
||||
if no_healing:
|
||||
return ExecutionResult(
|
||||
success=False,
|
||||
stdout=result.stdout,
|
||||
stderr=result.stderr,
|
||||
exit_code=result.exit_code,
|
||||
iterations=1,
|
||||
execution_time=time.time() - start_time,
|
||||
final_code=current_code,
|
||||
error_history=error_history,
|
||||
)
|
||||
|
||||
# Analyze error (Python)
|
||||
error = self.analyzer.analyze(result.stderr, language, current_code)
|
||||
error_report = ErrorReport(
|
||||
error_type=error["type"],
|
||||
error_message=error["message"],
|
||||
iteration=iteration,
|
||||
line_number=error.get("line"),
|
||||
)
|
||||
error_history.append(error_report)
|
||||
|
||||
# Heal with Yuuki (Python)
|
||||
try:
|
||||
fixed_code = self.healer.fix(current_code, error, language, error_history)
|
||||
if not fixed_code or fixed_code == current_code:
|
||||
break
|
||||
current_code = fixed_code
|
||||
except Exception as e:
|
||||
break
|
||||
|
||||
return ExecutionResult(
|
||||
success=False,
|
||||
stdout=result.stdout,
|
||||
stderr=result.stderr,
|
||||
exit_code=result.exit_code,
|
||||
iterations=iteration,
|
||||
execution_time=time.time() - start_time,
|
||||
final_code=current_code,
|
||||
error_history=error_history,
|
||||
)
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup resources"""
|
||||
self.rust_executor.cleanup()
|
||||
90
yuubox/healer.py
Normal file
90
yuubox/healer.py
Normal file
@@ -0,0 +1,90 @@
|
||||
from typing import Optional, List, Dict, Any
|
||||
import requests
|
||||
|
||||
class YuukiHealer:
|
||||
"""Heals code using Yuuki AI"""
|
||||
|
||||
DEFAULT_API = "https://opceanai-yuuki-api.hf.space"
|
||||
|
||||
def __init__(self, api_url: Optional[str] = None):
|
||||
self.api_url = (api_url or self.DEFAULT_API).rstrip("/")
|
||||
self.session = requests.Session()
|
||||
|
||||
def fix(
|
||||
self,
|
||||
code: str,
|
||||
error: Dict[str, Any],
|
||||
language: str,
|
||||
error_history: List,
|
||||
) -> str:
|
||||
prompt = self._build_prompt(code, error, language, error_history)
|
||||
|
||||
try:
|
||||
response = self.session.post(
|
||||
f"{self.api_url}/generate",
|
||||
json={
|
||||
"prompt": prompt,
|
||||
"max_new_tokens": 1000,
|
||||
"temperature": 0.3,
|
||||
"model": "yuuki-best",
|
||||
},
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
if not response.ok:
|
||||
return code
|
||||
|
||||
data = response.json()
|
||||
fixed = self._extract_code(data)
|
||||
return fixed if fixed else code
|
||||
|
||||
except Exception:
|
||||
return code
|
||||
|
||||
def _build_prompt(self, code: str, error: Dict, language: str, history: List) -> str:
|
||||
parts = [
|
||||
f"Fix this {language} code that has an error.",
|
||||
"",
|
||||
"Code:",
|
||||
f"```{language}",
|
||||
code,
|
||||
"```",
|
||||
"",
|
||||
f"Error: {error['type']}",
|
||||
f"Message: {error['message']}",
|
||||
]
|
||||
|
||||
if len(history) > 1:
|
||||
parts.append(f"\nPrevious {len(history)-1} attempts failed.")
|
||||
|
||||
parts.extend([
|
||||
"",
|
||||
"Provide ONLY the corrected code without explanations.",
|
||||
])
|
||||
|
||||
return "\n".join(parts)
|
||||
|
||||
def _extract_code(self, data) -> str:
|
||||
if isinstance(data, str):
|
||||
code = data
|
||||
elif isinstance(data, dict):
|
||||
code = data.get("generated_text") or data.get("response") or ""
|
||||
else:
|
||||
return ""
|
||||
|
||||
code = code.strip()
|
||||
if code.startswith("```"):
|
||||
lines = code.split("\n")
|
||||
lines = lines[1:]
|
||||
if lines and lines[-1].strip() == "```":
|
||||
lines = lines[:-1]
|
||||
code = "\n".join(lines)
|
||||
|
||||
for cutoff in ["User:", "System:", "\nUser", "\nSystem"]:
|
||||
if cutoff in code:
|
||||
idx = code.index(cutoff)
|
||||
if idx > 0:
|
||||
code = code[:idx].strip()
|
||||
break
|
||||
|
||||
return code.strip()
|
||||
Reference in New Issue
Block a user