"""Run selected functions copied out of the course's minimal agent (via ast, no openai import) with a stub model."""
import ast, json, os, sys, tempfile
from pathlib import Path

SRC = Path(sys.argv[1])
tree = ast.parse(SRC.read_text())
keep = {"resolve_abs_path", "read_file_tool", "list_files_tool", "edit_file_tool", "extract_tool_invocations", "run_coding_agent_loop"}
nodes = [n for n in tree.body if (isinstance(n, ast.FunctionDef) and n.name in keep)
         or (isinstance(n, ast.Assign) and any(getattr(t, "id", "") in {"TOOL_REGISTRY", "YOU_COLOR", "ASSISTANT_COLOR", "RESET_COLOR"} for t in n.targets))]
ns = {}
exec("import inspect, json, os\nfrom typing import List, Dict, Any, Tuple\nfrom pathlib import Path", ns)
exec(compile(ast.Module(body=nodes, type_ignores=[]), str(SRC), "exec"), ns)

def run_loop(model_replies, user_msgs):
    replies, msgs = iter(model_replies), iter(user_msgs)
    ns["execute_llm_call"] = lambda conv: next(replies)
    ns["create_full_system_prompt"] = lambda: "stub"
    def fake_input(_):
        try: return next(msgs)
        except StopIteration: raise EOFError
    ns["input"] = fake_input
    ns["print"] = lambda *a, **k: None
    try:
        ns["run_coding_agent_loop"](); return "正常结束"
    except Exception as e:
        return f"循环崩溃：{type(e).__name__}: {e}"

with tempfile.TemporaryDirectory() as tmp:
    os.chdir(tmp)
    Path("a.txt").write_text("原有内容\n")
    r = ns["edit_file_tool"]("a.txt", "", "新内容\n")
    print("1 old_str 为空、文件已存在 ->", r["action"], "| 文件现在是:", repr(Path("a.txt").read_text()))
    print("2 extract_tool_invocations 解析未知工具 ->", ns["extract_tool_invocations"]('tool: run_tests({"path":"."})'))
    print("3 模型调用未知工具 ->", run_loop(['tool: run_tests({"path":"."})'], ["跑一下测试"]))
    print("4 读不存在的文件 ->", run_loop(['tool: read_file({"filename":"missing.py"})'], ["读 missing.py"]))
    print("5 正常读文件后作答 ->", run_loop(['tool: read_file({"filename":"a.txt"})', "读完了"], ["读 a.txt"]))
