from __future__ import annotations import argparse import json import sys from datetime import date from pathlib import Path from typing import Any REPO_ROOT = Path(__file__).resolve().parents[1] SRC_ROOT = REPO_ROOT / "src" OUTPUT_ROOT = REPO_ROOT / "outputs" REFERENCE_OUTPUT_ROOT = OUTPUT_ROOT / "reference" if str(SRC_ROOT) not in sys.path: sys.path.insert(0, str(SRC_ROOT)) from summary_mcp.models import OpenClawCandidateInput, build_openclaw_delivery_payload def _load_json(path: Path) -> dict[str, Any]: return json.loads(path.read_text(encoding="utf-8-sig")) def _save_json(path: Path, payload: dict[str, Any]) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") def _collect_input_paths(inputs: list[Path], input_dir: Path | None, pattern: str) -> list[Path]: resolved = list(inputs) if input_dir is not None: resolved.extend(sorted(input_dir.glob(pattern))) seen: set[Path] = set() unique_paths: list[Path] = [] for path in resolved: normalized = path.resolve() if normalized in seen: continue seen.add(normalized) unique_paths.append(path) return unique_paths def main() -> None: parser = argparse.ArgumentParser(description="Build an OpenClaw batch delivery payload from slim candidate JSON files.") parser.add_argument("--inputs", nargs="*", type=Path, default=[], help="One or more OpenClaw candidate input JSON files") parser.add_argument("--input-dir", type=Path, default=None, help="Directory containing OpenClaw candidate input JSON files") parser.add_argument( "--pattern", type=str, default="*.openclaw-candidate-input.json", help="Glob pattern used together with --input-dir", ) parser.add_argument("--run-id", type=str, default=None, help="Optional delivery run id") parser.add_argument("--date", type=str, default=None, help="Optional delivery date in YYYY-MM-DD format") parser.add_argument("--sort-by-rank", action="store_true", help="Sort candidates by digest_rank descending") parser.add_argument( "--output", type=Path, default=REFERENCE_OUTPUT_ROOT / "candidates" / "openclaw-delivery-payload.json", help="Where to save the OpenClaw delivery payload", ) args = parser.parse_args() input_paths = _collect_input_paths(args.inputs, args.input_dir, args.pattern) if not input_paths: raise SystemExit("No candidate input files found. Pass --inputs or --input-dir.") candidates = [OpenClawCandidateInput.model_validate(_load_json(path)) for path in input_paths] if args.sort_by_rank: candidates.sort(key=lambda candidate: candidate.digest_rank, reverse=True) payload = build_openclaw_delivery_payload( candidates, run_id=args.run_id, for_date=date.fromisoformat(args.date) if args.date else None, ) _save_json(args.output, payload.model_dump(mode="json")) print(f"Saved OpenClaw delivery payload with {len(candidates)} candidates to {args.output}") if __name__ == "__main__": main()