File size: 1,657 Bytes
37f9abc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ea15e09
37f9abc
 
 
 
 
 
 
ea15e09
37f9abc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from multi_agent_sdlc.runtime.environment import build_sandbox_environment
from pathlib import Path
import subprocess


def normalise_process_output(
    output: str | bytes | None,
) -> str:
    """Convert subprocess output to a clean string."""
    if output is None:
        return ""

    if isinstance(output, bytes):
        return output.decode(
            "utf-8",
            errors="replace",
        ).strip()

    return output.strip()


def execute_process(
    command: list[str],
    project_directory: Path,
    timeout_seconds: int,
    stdin_text: str | None = None,
) -> dict[str, object]:
    """Execute an internally constructed command inside the project."""
    try:
        result = subprocess.run(
            command,
            cwd=project_directory,
            env=build_sandbox_environment(),
            input=stdin_text,
            capture_output=True,
            text=True,
            timeout=timeout_seconds,
            shell=False,
            check=False,
        )

    except subprocess.TimeoutExpired as error:
        return {
            "command": command,
            "exit_code": None,
            "stdout": normalise_process_output(error.stdout),
            "stderr": normalise_process_output(error.stderr),
            "timed_out": True,
            "message": (
                f"Command exceeded the {timeout_seconds}-second timeout. "
                "The process was stopped."
            ),
        }

    return {
        "command": command,
        "exit_code": result.returncode,
        "stdout": result.stdout.strip(),
        "stderr": result.stderr.strip(),
        "timed_out": False,
    }