基座(cad_mcp_frame): - 新增 RecvOneFrame: 以 '\n' 为消息边界分帧,去掉单次 recv(2048) 限制(上限 8MB); 用 select 短探测兼容不发 '\n' 的旧客户端;clientSocket 设 SO_RCVTIMEO 防卸载卡死 - JSON-RPC id 支持 string/number;无 id 的通知不回包 - isError 映射: 协议级错误保留顶层 error,工具执行错误转 result.isError=true - 响应补 '\n' 作为消息边界 Agent(新增 dwg_review 包): - mcp_client: 唯一 TCP/JSON-RPC 封装(单飞锁/分帧/重试/兼容 error 与 isError) - cad_tools: 从 tools/list 动态建表,含 15 个只读白名单 - phases: planning -> evidence -> review(受控只读取证子循环)-> report - annotator: 批注回写 AI_REVIEW 层,支持 dry-run 与撤销 - config: 配置全部走环境变量;Windows 下回退读注册表以读到新设的系统变量 其它: 新增 verify_mcp_frame.py 验证脚本;.gitignore 补 Python/AutoCAD 锁文件规则; ai.memory 记录架构决策与实测结论
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
"""阶段 2:逐图框取证(确定性、串行)。
|
|
|
|
对每个图框:缩放到该框 → 取结构化数据(实体/文字/标注/块/多段线)→ 截取视口。
|
|
结构化数据是权威依据,截图仅作视觉上下文。
|
|
"""
|
|
|
|
import time
|
|
|
|
from .. import config
|
|
from ..mcp_client import result_images, result_json
|
|
|
|
|
|
def bbox_to_window(bbox):
|
|
"""[minx,miny,maxx,maxy] -> window 对象。"""
|
|
return {
|
|
"min_x": float(bbox[0]),
|
|
"min_y": float(bbox[1]),
|
|
"max_x": float(bbox[2]),
|
|
"max_y": float(bbox[3]),
|
|
}
|
|
|
|
|
|
def collect_frame(ctx, index, frame):
|
|
"""采集单个图框的证据;bbox 无效时返回 None。"""
|
|
bbox = frame.get("bbox")
|
|
if not bbox or len(bbox) != 4:
|
|
return None
|
|
|
|
win = bbox_to_window(bbox)
|
|
limit = ctx.frame_limit
|
|
|
|
# a. 缩放到图框(给 CAD 留渲染时间)
|
|
ctx.tools.call("zoom_to_window", dict(win, margin=0.02))
|
|
time.sleep(config.RENDER_WAIT)
|
|
|
|
# b. 结构化数据(权威)
|
|
entities = result_json(ctx.tools.call("query_entities", {"window": win, "limit": limit}), {})
|
|
texts = result_json(ctx.tools.call("get_text_content", {"window": win, "limit": limit}), {})
|
|
dimensions = result_json(ctx.tools.call("get_dimensions", {"window": win, "limit": limit}), {})
|
|
blocks = result_json(
|
|
ctx.tools.call("get_block_references", {"window": win, "limit": limit}), {}
|
|
)
|
|
polylines = result_json(
|
|
ctx.tools.call("get_polylines_info", {"window": win, "limit": limit}), {}
|
|
)
|
|
|
|
# c. 视口截图(视觉上下文)
|
|
shot = ctx.tools.call("get_viewport_screenshot", {})
|
|
images = result_images(shot)
|
|
image_b64, image_mime = images[0] if images else (None, None)
|
|
|
|
return {
|
|
"index": index,
|
|
"frame": frame,
|
|
"window": win,
|
|
"entities": entities,
|
|
"texts": texts,
|
|
"dimensions": dimensions,
|
|
"blocks": blocks,
|
|
"polylines": polylines,
|
|
"image_b64": image_b64,
|
|
"image_mime": image_mime,
|
|
}
|