(argv: list[str] | None = None)
| 512 | |
| 513 | |
| 514 | def main(argv: list[str] | None = None) -> int: |
| 515 | parser = build_parser() |
| 516 | args = parser.parse_args(argv) |
| 517 | base_dir = Path(args.workspace_dir).resolve() if args.workspace_dir else Path.cwd().resolve() |
| 518 | |
| 519 | cfg = _load_config(args.config) |
| 520 | |
| 521 | prompts = { |
| 522 | key: _resolve_prompt(cfg, key, required=required) |
| 523 | for key, required in _PROMPT_FIELDS |
| 524 | } |
| 525 | |
| 526 | images_config = cfg.get("images") or cfg.get("images_path") or [] |
| 527 | resolved_images = [ |
| 528 | _resolve_image_path(p, workspace_dir=args.workspace_dir) for p in images_config |
| 529 | ] |
| 530 | discovered_run_dir = _infer_run_dir_from_images(resolved_images) |
| 531 | |
| 532 | # If config did not provide images, fall back to the latest run's screenshots. |
| 533 | if not resolved_images: |
| 534 | discovered: list[Path] = [] |
| 535 | discovered_source = "" |
| 536 | if args.auto_latest_run: |
| 537 | auto_root = Path(args.auto_latest_run) |
| 538 | if not auto_root.is_absolute(): |
| 539 | auto_root = base_dir / auto_root |
| 540 | auto_root = auto_root.resolve() |
| 541 | discovered_run_dir, discovered = _discover_latest_run_screenshots(auto_root) |
| 542 | if discovered_run_dir is not None: |
| 543 | discovered_source = str(discovered_run_dir / "screenshots") |
| 544 | if discovered: |
| 545 | resolved_images = discovered |
| 546 | print( |
| 547 | f"[self_reflection] auto-discovered {len(resolved_images)} screenshots from {discovered_source}", |
| 548 | file=sys.stderr, |
| 549 | ) |
| 550 | |
| 551 | artifact_dir = _resolve_artifact_dir( |
| 552 | images=resolved_images, |
| 553 | discovered_run_dir=discovered_run_dir, |
| 554 | output_path=args.output, |
| 555 | workspace_dir=args.workspace_dir, |
| 556 | ) |
| 557 | action_history_log = _load_action_history_log(artifact_dir) |
| 558 | |
| 559 | if not resolved_images: |
| 560 | print( |
| 561 | "[self_reflection] warning: no images provided; final stage will run without screenshot attachments.", |
| 562 | file=sys.stderr, |
| 563 | ) |
| 564 | |
| 565 | if not action_history_log: |
| 566 | print( |
| 567 | "[self_reflection] warning: no final_script_log.txt found; final prompt will omit action history content.", |
| 568 | file=sys.stderr, |
| 569 | ) |
| 570 | |
| 571 | model_client = load_tool_model( |
no test coverage detected