"""Keep a saved geometry discoverable even when its inline response is shortened.""" from uuid import NAMESPACE_URL, uuid5 from app.mcp.models import QueryResult def saved_burst_result_preview(result: QueryResult, task_id: str) -> dict | None: """Keep durable full-network results usable without copying node arrays inline.""" if result.source != "run_burst_simulation" or not result.evidence_id: return None data = result.data if isinstance(result.data, dict) else {} analysis = data.get("result", {}) impact = analysis.get("impact") if isinstance(analysis, dict) else None if not isinstance(impact, dict): return None summary = {key: value for key, value in impact.items() if key not in {"comparisons", "grades", "unavailable_node_ids"}} summary["unavailable_node_count"] = len(impact.get("unavailable_node_ids", [])) summary["grades"] = [ {**{key: value for key, value in grade.items() if key != "node_ids"}, "node_count": len(grade.get("node_ids", []))} for grade in impact.get("grades", []) ] preview = { "resource_uri": f"tjwater://tasks/{task_id}/evidence/{result.evidence_id}", "parameters": data.get("parameters", {}), "result": {"impact": summary}, } presentation = saved_presentation_preview(result) if presentation is not None: preview["presentation"] = presentation return preview def saved_presentation_preview(result: QueryResult) -> dict | None: if result.source not in {"generate_node_coverage", "run_burst_simulation", "run_contaminant_simulation"} or not result.evidence_id: return None analysis = result.data.get("result") if isinstance(result.data, dict) else None if not isinstance(analysis, dict): return None payload = analysis.get("map_payload") if not isinstance(payload, dict) or not payload.get("features"): return None coverage = analysis.get("coverage", {}) burst = result.source == "run_burst_simulation" contaminant = result.source == "run_contaminant_simulation" if burst and analysis.get("impact", {}).get("phase") != "after_burst_before_intervention": return None if contaminant and analysis.get("impact", {}).get("phase") != "after_contamination_before_intervention": return None return { "command": { "action": "set_overlay", "mode": "geometry", "evidence_id": result.evidence_id, "overlay_id": f"node-coverage-{uuid5(NAMESPACE_URL, result.evidence_id)}", "title": ("爆管后、处置前的预计影响范围(米水头)" if burst else "水污染传播预计影响范围(处置前情景)" if contaminant else "节点空间覆盖示意"), }, "display_only": True, "coverage_status": coverage.get("status"), "groups": {role: { "node_count": len(group.get("node_ids", [])), "mapped_node_count": group.get("mapped_node_count", 0), "missing_node_count": len(group.get("missing_node_ids", [])), } for role, group in coverage.get("groups", {}).items()}, }