"""验收:审查阶段是否也在「绘图区最大化」状态下进行,且结束后精确还原。 做法:在取证 `collect` 与审查 `review_frame` 入口各采一次窗口矩形, 并在 `McpClient.call_tool` 上挂计数器,统计 LLM 子循环是否真的用了放大工具。 用法:先启动已加载插件的 CAD 并打开图纸,然后 `python verify_review_maximized.py`。 """ import ctypes import sys from ctypes import wintypes from dwg_review import __main__ as cli from dwg_review.mcp_client import McpClient from dwg_review.phases import evidence as ev from dwg_review.phases import review as rv _u = ctypes.windll.user32 _u.GetWindowTextW.argtypes = [wintypes.HWND, wintypes.LPWSTR, ctypes.c_int] _u.IsWindowVisible.argtypes = [wintypes.HWND] _u.GetWindowRect.argtypes = [wintypes.HWND, ctypes.POINTER(wintypes.RECT)] _WNDENUMPROC = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM) def _find_main_window(): hit = [None] def cb(hwnd, _lparam): if not _u.IsWindowVisible(hwnd): return True n = _u.GetWindowTextLengthW(hwnd) if n == 0: return True buf = ctypes.create_unicode_buffer(n + 1) _u.GetWindowTextW(hwnd, buf, n + 1) if "AutoCAD" in buf.value and "[" in buf.value: hit[0] = hwnd return False return True _u.EnumWindows(_WNDENUMPROC(cb), 0) return hit[0] HWND = _find_main_window() if not HWND: print("[X] 未找到 AutoCAD 主窗口") sys.exit(1) def rect(): r = wintypes.RECT() _u.GetWindowRect(HWND, ctypes.byref(r)) return [r.left, r.top, r.right, r.bottom] def area(r): return (r[2] - r[0]) * (r[3] - r[1]) # --- 采样点 --------------------------------------------------------------- phase_rects = {"evidence": [], "review": []} zoom_calls = [] _orig_collect = ev.collect _orig_review = rv.review_frame _orig_call = McpClient.call_tool def collect(ctx, index, frame): phase_rects["evidence"].append(rect()) return _orig_collect(ctx, index, frame) def review(ctx, evidence, system_prompt, log=print): phase_rects["review"].append(rect()) return _orig_review(ctx, evidence, system_prompt, log=log) def call_tool(self, name, arguments=None, **kw): if name in ("zoom_to_window", "zoom_to_entity", "get_viewport_screenshot"): zoom_calls.append(name) return _orig_call(self, name, arguments, **kw) ev.collect = collect rv.review_frame = review McpClient.call_tool = call_tool before = rect() print(f"起始窗口矩形 = {before} 面积={area(before)}") rc = cli.main(["--frames", "1"]) after = rect() print() print("=== 结果 ===") print(f"取证阶段采样 = {phase_rects['evidence']}") print(f"审查阶段采样 = {phase_rects['review']}") print(f"结束窗口矩形 = {after} 面积={area(after)}") print(f"子循环取证调用 = {zoom_calls}") ok_ev = all(area(r) > area(before) for r in phase_rects["evidence"]) if phase_rects["evidence"] else False ok_rv = all(area(r) > area(before) for r in phase_rects["review"]) if phase_rects["review"] else False print() print(f"[{'PASS' if ok_ev else 'FAIL'}] 取证阶段处于最大化(面积大于基线)") print(f"[{'PASS' if ok_rv else 'FAIL'}] 审查阶段处于最大化(面积大于基线)") print(f"[{'PASS' if after == before else 'FAIL'}] 结束精确还原窗口矩形") sys.exit(0 if (ok_ev and ok_rv and after == before and rc == 0) else 1)