feat: add Java JRXML-to-PNG rendering pipeline with pixel-level SSIM comparison

- lib/java/: Java renderer (JrxmlRenderer) using JasperReports 6.21.0
  - JrxmlDebug for diagnostics, JrxmlGen for format reference
  - download_jars.sh for one-time dependency setup
- agent/nodes.py: _render_jrxml_to_png() and _compute_pixel_similarity()
  - Pixel comparison integrates into validate node (SSIM < 0.4 fails)
  - Pixel fidelity context injected into correct_jrxml for targeted fixes
- tests/test_pixel_comparison.py: 15 unit tests (render, SSIM, integration)
- .gitignore: exclude lib/java/*.jar, lib/java/*.class, tmp/
- CLAUDE.md: v11 changelog documenting the rendering pipeline
- All non-LLM tests pass (97/97)
This commit is contained in:
2026-05-23 15:09:55 +08:00
parent 9de75d2f25
commit bb6cc6e241
16 changed files with 837 additions and 8 deletions
+42
View File
@@ -385,3 +385,45 @@ cd frontend && npx playwright test
**MAX_RETRY 调整**: 默认值从 3 → 5(环境变量 `MAX_RETRY`),配合续写机制确保复杂报表有充分修正机会。
**JRXML 提取命名空间兼容**: `_extract_jrxml()``_generate_with_continuation()` 的完整性检查统一支持 `</ns0:jasperReport>` 等命名空间前缀闭合标签。
## 更新 (v11 — 2026-05-23)
### Java 渲染管线 + 像素级对比
**目标**: 将 JRXML 渲染为 PNG 图片,与用户上传的原始图片进行 SSIM(结构相似性)像素级对比。
**Java 依赖** (`lib/java/`):
| JAR | 用途 |
|-----|------|
| `jasperreports-6.21.0.jar` (5.8MB) | 核心库,**必须用 6.x**7.x 仅支持 Jackson XML 格式) |
| `commons-digester-2.1.jar` | XML 解析(6.x 使用 Digester 2.x |
| `commons-logging-1.3.5.jar`, `commons-collections4-4.5.0.jar`, `commons-beanutils-1.10.1.jar`, `commons-lang3-3.17.0.jar` | 基础依赖 |
| `itext-2.1.7.jar` | PDF 生成 |
| `jfreechart-1.5.5.jar` | 图表 |
| `ecj-3.38.0.jar` | Eclipse JDT 编译器(报表表达式编译) |
**Java 工具** (`lib/java/`):
| 文件 | 用途 |
|------|------|
| `JrxmlRenderer.java` | JRXML → PNG 渲染器 |
| `JrxmlDebug.java` | 诊断:SAX/JRXmlLoader/compile 三层测试 |
| `JrxmlGen.java` | 参考:程序化构建 JasperDesign → 序列化为 XML |
**Python 渲染封装** (`agent/nodes.py`):
- `_render_jrxml_to_png(jrxml, output_path, scale)` — 调用 Java `JrxmlRenderer`
- `_compute_pixel_similarity(rendered_png, reference_image)` — OpenCV + scikit-image SSIM 对比
**像素对比流程**: validate 节点 XSD 通过 → 有 `uploaded_file_path` → Java 渲染 → SSIM 对比 → SSIM < 0.4 且 diff > 60% → 标记 fail → 注入 correct_jrxml 修正上下文
**手动渲染**: `java -cp ".;jasperreports-6.21.0.jar;..." JrxmlRenderer input.jrxml output.png 2.0`
### 内容保真度 + 修正去重 (v10 补充)
- `_check_ocr_fidelity(jrxml, state)` — OCR 字段名/元素数/列数三重检查
- `correct_jrxml` 去重检测:输入输出相同 → `retry_count += 2`
- `prompts/correction.md` — 一次只修复第1个错误 + 输出不可与输入相同 + 命名空间严格指定
- `prompts/skeleton_generation.md`, `prompts/modification.md` — 明确命名空间约束
### consult_answer 前端显示修复
- `api_server.py``agent_complete` SSE 事件新增 `consult_answer` 字段