Spaces:
Runtime error
Runtime error
| """End-to-end CLI for the ergo-agentic pipeline. | |
| Run a full assessment on one or more images. Pass image URLs (or local paths) | |
| as arguments, or omit args to run on the sample images from the bundled | |
| report-sample.json. | |
| Usage: | |
| uv run python scripts/run_assessment.py | |
| uv run python scripts/run_assessment.py https://example.com/img1.jpg https://example.com/img2.jpg | |
| Output: pretty-printed OutcomeMatrix JSON. | |
| """ | |
| from __future__ import annotations | |
| import asyncio | |
| import json | |
| import sys | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| from ergo_agentic.graph import build_graph | |
| from ergo_agentic.state import ImageInput | |
| REPORT_SAMPLE_FILE = ( | |
| Path(__file__).resolve().parents[1] / "docs" / "datasources" / "report-sample.json" | |
| ) | |
| def _sample_image_urls() -> list[str]: | |
| with REPORT_SAMPLE_FILE.open() as f: | |
| return json.load(f).get("uploadedImages", []) | |
| def _build_image_inputs(urls: list[str]) -> list[ImageInput]: | |
| return [ | |
| {"image_id": f"img_{i}", "url": url, "label": None} | |
| for i, url in enumerate(urls, start=1) | |
| ] | |
| def _print_run_header(image_count: int) -> None: | |
| from ergo_agentic.models import DEFAULT_MODEL_CONFIG as cfg | |
| print(f"Running pipeline on {image_count} image(s)...") | |
| print("Models:") | |
| print(f" image_analyzer: {cfg.image_analyzer}") | |
| print(f" vision_passes: {list(cfg.vision_passes)}") | |
| print(f" review_agent: {cfg.review_agent}") | |
| print() | |
| def _print_scene(matrix) -> None: | |
| sc = matrix.scene_config | |
| print("Scene:") | |
| print(f" work_location: {sc.work_location.value if sc.work_location else 'unknown'}") | |
| print(f" screen_count: {sc.screen_count} ({', '.join(sc.screen_types) or 'none'})") | |
| print(f" has_standing_desk: {sc.has_standing_desk}") | |
| print(f" person_detected: {sc.person_detected}") | |
| print() | |
| def _print_accessories(matrix) -> None: | |
| if not matrix.detected_accessories: | |
| return | |
| print("Detected accessories:") | |
| for acc in matrix.detected_accessories: | |
| desc = f" — {acc.description}" if acc.description else "" | |
| print(f" - {acc.type}{desc}") | |
| print() | |
| def _print_assessments(matrix) -> None: | |
| print(f"Assessments ({len(matrix.assessments)}):") | |
| for a in matrix.assessments: | |
| flag = "✓" if a.is_good_habit else "⚠" | |
| print(f" {flag} [{a.parameter_text}] {a.review_decision.value}") | |
| for o in a.final_outcomes: | |
| print(f" → {o}") | |
| if a.evidence_summary: | |
| print(f" evidence: {a.evidence_summary}") | |
| print(f" images: {a.source_images} | models: {a.source_models}") | |
| print() | |
| def _print_skipped(matrix) -> None: | |
| if not matrix.skipped_parameters: | |
| return | |
| print(f"Skipped ({len(matrix.skipped_parameters)}):") | |
| for s in matrix.skipped_parameters: | |
| print(f" - {s.parameter_text}: {s.reason}") | |
| print() | |
| def _print_matrix(matrix) -> None: | |
| print("=" * 60) | |
| print("OUTCOME MATRIX") | |
| print("=" * 60) | |
| print() | |
| _print_scene(matrix) | |
| _print_accessories(matrix) | |
| _print_assessments(matrix) | |
| _print_skipped(matrix) | |
| print("=" * 60) | |
| print("RAW JSON") | |
| print("=" * 60) | |
| print(matrix.model_dump_json(indent=2)) | |
| def main(argv: list[str]) -> int: | |
| load_dotenv() | |
| urls = argv[1:] if len(argv) > 1 else _sample_image_urls() | |
| if not urls: | |
| print("No images to process.", file=sys.stderr) | |
| return 1 | |
| images = _build_image_inputs(urls) | |
| _print_run_header(len(images)) | |
| graph = build_graph() | |
| final_state = asyncio.run(graph.ainvoke({"images": images})) | |
| _print_matrix(final_state["outcome_matrix"]) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main(sys.argv)) | |