#!/usr/bin/env python3 """Run or dry-run the PixelRAG Ollama VLM replay worker.""" from __future__ import annotations import argparse import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from services.pixelrag_vlm_replay_worker_service import ( # noqa: E402 DEFAULT_MODEL, run_pixelrag_ollama_vlm_replay_worker, ) def main() -> int: parser = argparse.ArgumentParser( description="執行或 dry-run PixelRAG Ollama-first VLM replay worker。" ) parser.add_argument( "--artifact-root", help="PixelRAG visual evidence artifact root;預設使用 production/container 設定。", ) parser.add_argument( "--output-root", help="VLM replay artifact receipt output root。", ) parser.add_argument( "--platform", action="append", dest="platforms", help="限制平台,可重複指定,例如 --platform shopee_tw --platform coupang_tw。", ) parser.add_argument( "--max-age-hours", type=int, default=168, help="receipt 最大新鮮度小時數。", ) parser.add_argument( "--limit", type=int, default=25, help="最多處理 receipt 數。", ) parser.add_argument( "--tile-limit", type=int, default=4, help="每個 receipt 最多送入 VLM 的 tile 數。", ) parser.add_argument( "--model", default=DEFAULT_MODEL, help="Ollama VLM model。", ) parser.add_argument( "--timeout", type=int, default=90, help="單次 Ollama generate timeout 秒數。", ) parser.add_argument( "--execute", action="store_true", help="真的呼叫 Ollama VLM;未指定時只做 no-write dry-run。", ) parser.add_argument( "--write-receipt", action="store_true", help="execute 後寫入 VLM replay artifact receipt;不寫 DB。", ) parser.add_argument( "--no-auto-select-model", action="store_true", help="停用 execute 前的 approved route / installed model 自動選擇。", ) parser.add_argument( "--route-readiness-timeout", type=int, default=3, help="auto-select model 的 /api/tags readiness timeout 秒數。", ) parser.add_argument( "--no-probe-generate-before-execute", action="store_true", help="停用 execute 前的極小 /api/generate preflight。", ) parser.add_argument( "--route-generate-probe-timeout", type=int, default=8, help="execute 前 /api/generate preflight timeout 秒數。", ) args = parser.parse_args() payload = run_pixelrag_ollama_vlm_replay_worker( artifact_root=args.artifact_root, output_root=args.output_root, platform=tuple(args.platforms or ()), max_age_hours=args.max_age_hours, limit=args.limit, tile_limit=args.tile_limit, model=args.model, timeout=args.timeout, execute=args.execute, write_receipt=bool(args.write_receipt and args.execute), auto_select_model=not args.no_auto_select_model, route_readiness_timeout=args.route_readiness_timeout, probe_generate_before_execute=not args.no_probe_generate_before_execute, route_generate_probe_timeout=args.route_generate_probe_timeout, ) print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True)) return 0 if payload.get("success") else 1 if __name__ == "__main__": raise SystemExit(main())