| """Agentic shell/code loop — a coding agent that runs entirely on the local GGUF. |
| |
| Give it a task; it constructs a shell command/script, EXECUTES it (guarded), reads the real |
| output, decides if it worked, and iterates — the construct -> run -> observe -> fix loop that |
| makes an agent actually accomplish things instead of just describing them. Composes with the |
| router/MoE (any code-capable expert) and adaptive reasoning (harder tasks get more steps). |
| |
| Safety: every command goes through tools.run_shell, which refuses destructive patterns and |
| runs inside a working directory. allow_exec must be set explicitly to actually run. |
| """ |
| from __future__ import annotations |
|
|
| import os |
| import re |
|
|
| from . import quality |
| from .tools import run_shell |
|
|
| _DONE = re.compile(r"\bDONE\b", re.I) |
| _LANGS = {"sh", "bash", "shell", "powershell", "ps", "ps1", "cmd", "python", "py", ""} |
|
|
| SYS = ( |
| "You are an agent that accomplishes tasks by running shell commands on this machine. " |
| "Respond with EXACTLY ONE shell command inside a ```sh code block, and nothing else. " |
| "After you see its output, either issue the next command or, if the task is fully " |
| "verified complete, reply with the single word DONE. Prefer commands that TEST/VERIFY " |
| "the result. Keep commands safe and idempotent." |
| ) |
|
|
|
|
| def _extract_command(text: str) -> str | None: |
| """Robust: handles untagged AND unclosed code fences (the bug that broke the proof).""" |
| t = text or "" |
| if "```" in t: |
| body = t.split("```", 1)[1].split("```", 1)[0] |
| lines = [l for l in body.splitlines() if l.strip()] |
| if lines and lines[0].strip().lower() in _LANGS: |
| lines = lines[1:] |
| if lines: |
| return lines[0].strip() |
| |
| for line in t.splitlines(): |
| s = line.strip().lstrip("$ ").strip() |
| if s and (not s[0].isalpha() or s.split()[0] in ( |
| "ls", "cat", "echo", "python", "git", "node", "dir", "type", "Get-ChildItem")): |
| return s |
| return None |
|
|
|
|
| def build_and_test(client, task: str, workdir: str = ".", max_steps: int = 6, |
| allow_exec: bool = False) -> dict: |
| """Run the construct->execute->verify loop. Returns trace + success flag.""" |
| os.makedirs(workdir, exist_ok=True) |
| history, trace = [], [] |
| convo = f"TASK: {task}\nWorking directory: {os.path.abspath(workdir)}" |
| success = False |
| for step in range(max_steps): |
| prompt = convo + ("\n\nPrevious results:\n" + "\n".join(history) if history else "") |
| reply = quality.clean_generate(client, prompt, system=SYS) |
| if _DONE.search(reply) and "```" not in reply: |
| success = True |
| break |
| cmd = _extract_command(reply) |
| if not cmd: |
| history.append(f"[no command parsed from model reply]") |
| continue |
| full = f"cd {workdir} && {cmd}" if os.name != "nt" else f"cd '{workdir}'; {cmd}" |
| result = run_shell(full, allow_exec=allow_exec) |
| trace.append({"step": step, "command": cmd, "result": result[:600]}) |
| history.append(f"$ {cmd}\n{result[:600]}") |
| return {"task": task, "success": success, "steps": len(trace), "trace": trace} |
|
|
|
|
| if __name__ == "__main__": |
| |
| sample = "Here is the command:\n```sh\npython --version\n```" |
| print("parsed:", _extract_command(sample)) |
| print("dry-run:", run_shell("python --version")) |
| print("exec :", run_shell("python --version", allow_exec=True)) |
| print("blocked:", run_shell("rm -rf /", allow_exec=True)) |
|
|