from __future__ import annotations from pathlib import Path from ..catalog import get_catalog from ..config import settings from ..coverage import get_coverage_report REQUIRED_TASKS = { "dataset.upload": "covered_by_api", "dataset.video_frames": "job", "dataset.yolo_txt_sort": "job", "segmodel.train": "job", "segmodel.predict": "job", "yolo.heatmap": "job", "yolo.predict_custom": "job", "yolo.heatmap_custom": "job", "yolo.video_visible": "job", "mmseg.flops_fps": "job", "analysis.all": "job", "visual.fps": "job", "system.check_graph_card": "job", } def evaluate_project() -> dict: """Return product/implementation suggestions for the current web platform.""" frontend = settings.project_root / "frontend" / "src" / "main.tsx" backend = settings.project_root / "backend" / "app" / "main.py" readme = settings.project_root / "README.md" catalog = get_catalog() coverage = get_coverage_report() checks = [] suggestions = [] frontend_text = frontend.read_text(encoding="utf-8") if frontend.exists() else "" backend_text = backend.read_text(encoding="utf-8") if backend.exists() else "" acceptance_text = (settings.project_root / "backend" / "app" / "acceptance.py").read_text(encoding="utf-8") readme_text = readme.read_text(encoding="utf-8") if readme.exists() else "" expectations = { "left_nav_dataset": "数据集" in frontend_text and "#datasets" in frontend_text, "upload_ui": "uploadDatasetFiles" in frontend_text and "labels" in frontend_text and "masks" in frontend_text, "dataset_quality_ui": "DatasetQuality" in frontend_text and "generateSelectedYoloYaml" in frontend_text, "uploaded_yolo_workflow_ui": "startSelectedYoloTrain" in frontend_text and "startSelectedYoloPredict" in frontend_text and "startSelectedYoloHeatmap" in frontend_text, "dataset_yolo_outputs_ui": "DatasetYoloOutputs" in frontend_text and "selectedYoloOutputs" in frontend_text and "BEST.PT READY" in frontend_text, "loss_result_ui": "loss" in frontend_text.lower() and "heatmap" in frontend_text.lower() and "CurvePanel" in frontend_text, "job_progress_ui": "JobProgressBar" in frontend_text and "progressTrack" in frontend_text, "runtime_readiness_ui": "runtimeReadiness" in frontend_text and "环境就绪" in frontend_text, "capability_matrix_ui": "capabilities" in frontend_text and "全功能矩阵" in frontend_text, "dataset_api": "/api/datasets" in backend_text and "api_upload_dataset_files" in backend_text, "dataset_quality_api": "/api/datasets/{dataset_name}/validate" in backend_text and "/api/datasets/{dataset_name}/yolo-yaml" in backend_text, "job_progress_api": "progress_from_log_path" in backend_text and '"progress"' in backend_text, "runtime_readiness_api": "/api/system/readiness" in backend_text, "capability_matrix_api": "/api/capabilities" in backend_text, "runtime_bootstrap_scripts": (settings.project_root / "scripts" / "bootstrap_conda_envs.sh").exists() and (settings.project_root / "scripts" / "verify_runtime_envs.py").exists(), "curve_api": "/api/results/curves" in backend_text, "deep_acceptance_api": "/api/acceptance/deep" in backend_text, "deep_acceptance_ui": "runDeepAcceptance" in frontend_text and "深度训练" in frontend_text, "deep_yolo_heatmap_validation": "yolo_tiny_heatmap_generation" in acceptance_text, "uploaded_yolo_workflow_acceptance": "uploaded_yolo_predict_job_runner" in acceptance_text and "uploaded_yolo_heatmap_job_runner" in acceptance_text, "agent_api": "/api/agents/evaluate" in backend_text and "/api/agents/validate" in backend_text, "agent_panel_ui": "runAgentValidation" in frontend_text and "评价建议" in frontend_text and "Validation Agent" in frontend_text, "coverage_api": "/api/coverage" in backend_text and coverage["task_build_passed"], "visual_tools": "visual.yolo11_heatmap_v2" in catalog["task_types"] and "visual.fps" in catalog["task_types"], "yolo_custom_train": "yolo.train_custom" in catalog["task_types"], "yolo_custom_predict_heatmap": "yolo.predict_custom" in catalog["task_types"] and "yolo.heatmap_custom" in catalog["task_types"], "yolo_dataset_tools": "dataset.yolo_txt_sort" in catalog["task_types"] and "dataset.yolo_resize" in catalog["task_types"], "no_weight_to_gitea": "Do not push" in readme_text and "check_no_weight_git" in readme_text, "all_core_tasks": all(task in catalog["task_types"] for task in REQUIRED_TASKS if REQUIRED_TASKS[task] == "job"), "mapped_user_scripts": not coverage["unmapped_user_scripts"], } for name, passed in expectations.items(): checks.append({"name": name, "passed": bool(passed)}) if not passed: suggestions.append(f"Improve missing capability: {name}") if len(catalog["mmseg_algorithms"]) < 31: suggestions.append("MMSeg algorithm catalog should expose all 31 algorithm generators.") if len(catalog["segmodel_architectures"]) < 12: suggestions.append("SegModel catalog should expose all 12 supported architectures.") if coverage["unmapped_user_scripts"]: suggestions.append(f"Map remaining user-facing scripts: {len(coverage['unmapped_user_scripts'])}") if not suggestions: suggestions.append("Current platform covers the requested control-plane features, uploaded YOLO dataset train/predict/heatmap actions, live uploaded-data YOLO predict/heatmap acceptance, and synthetic deep training acceptance; next focus is a real non-synthetic dataset run.") score = sum(1 for item in checks if item["passed"]) / max(len(checks), 1) return { "agent": "evaluation_suggestion_agent", "score": round(score, 3), "checks": checks, "suggestions": suggestions, }