Files
cad-agent/dwg_review/evidence_model.py
T
gjm 1c9fc72839 feat(review): 取证层多源化 + 视觉多图(整体+2x2 象限)
- 新增 evidence_model.py:统一证据模型(source_type + images 列表),访问器兼容旧 image_b64/image_mime 单图字段
- phases/evidence.py:新增 collect() 多源分发 seam(仅 CAD)、capture_images() 整体+等分象限多图(结束复位视口)、sub_windows()
- phases/review.py:多图逐张下采样喂 LLM,payload 增加 source_type
- config.py:EVIDENCE_DETAIL_TILES=4 / EVIDENCE_MAX_IMAGES=5(默认开启多图)
- 新增 tests/test_evidence_model.py,更新 evidence/review 断言与 fakes 归一
2026-10-15 19:48:18 +08:00

89 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""统一证据模型:多来源(CAD / PDF / 图片)证据的字段常量与访问器。
设计要点:
- evidence 是跨阶段 + 落盘的「线格式」数据,统一用 dict 承载(不用 dataclass)。
- 图片统一为 `images: [{"b64","mime","label"}]`;访问器兼容旧的 `image_b64/image_mime`
单图字段(历史 evidence.json 与旧测试构造仍可读)。
- 本模块不含任何 CAD / 工具逻辑,可被 phases、findings、__main__、tests 共同引用。
"""
SOURCE_CAD = "cad"
SOURCE_PDF = "pdf"
SOURCE_IMAGE = "image"
# 结构化证据键(CAD 侧各查询工具产出的信封);下游 handle 收集 / 派生检查统一引用,
# 避免在多处硬编码同一组键名。
STRUCTURED_SOURCES = ("entities", "texts", "dimensions", "blocks", "polylines")
def make_image(b64, mime="image/png", label=None):
"""构造 images 列表元素。"""
return {"b64": b64, "mime": mime or "image/png", "label": label}
def source_type_of(container):
"""读取来源类型,缺省视为 CAD。
container 可以是审查单元(unit)/ 图框 / evidence 等任何 dict。
"""
if isinstance(container, dict):
value = container.get("source_type")
if isinstance(value, str) and value:
return value
return SOURCE_CAD
def evidence_images(evidence):
"""规范化证据里的图片列表(单点归一)。
优先读 `images`;否则回退旧的 `image_b64` / `image_mime` 单图字段。
统一返回 `[{"b64","mime","label"}]`,过滤掉空 b64。
"""
if not isinstance(evidence, dict):
return []
images = []
raw = evidence.get("images")
if isinstance(raw, list):
for item in raw:
if not isinstance(item, dict):
continue
b64 = item.get("b64")
if not b64:
continue
images.append(
{
"b64": b64,
"mime": item.get("mime") or "image/png",
"label": item.get("label"),
}
)
if images:
return images
# 回退:旧的单图字段
b64 = evidence.get("image_b64")
if b64:
return [
{
"b64": b64,
"mime": evidence.get("image_mime") or "image/png",
"label": None,
}
]
return []
def primary_image(evidence):
"""返回首图(label == "overall" 优先),无图返回 None。"""
images = evidence_images(evidence)
if not images:
return None
for img in images:
if img.get("label") == "overall":
return img
return images[0]
def image_labels(evidence):
"""返回图片标签列表(用于日志 / payload 说明)。"""
return [img.get("label") for img in evidence_images(evidence)]