Source code for fermilink.cli.parser_workflows

from __future__ import annotations

import argparse
from collections.abc import Callable


CommandHandler = Callable[[argparse.Namespace], int]


[docs] def register_workflow_parsers( subparsers: argparse._SubParsersAction[argparse.ArgumentParser], # type: ignore[attr-defined] *, cmd_reproduce: CommandHandler, cmd_research: CommandHandler, ) -> None: """ Register parser arguments for workflow. Parameters ---------- subparsers : argparse._SubParsersAction[argparse.ArgumentParser] Subparser collection created from the root parser. cmd_reproduce : CommandHandler Command handler for `reproduce` subcommands. cmd_research : CommandHandler Command handler for `research` subcommands. Returns ------- None No return value; parser objects are mutated in place. """ reproduce_parser = subparsers.add_parser( "reproduce", help=( "Run paper-level orchestration: generate/audit a multi-task plan, then " "execute each task via fermilink loop until all tasks are done." ), ) reproduce_parser.add_argument( "prompt", nargs="+", help=( "Either paper request text, or a path to a file containing source content " "(e.g. paper.tex, paper.md, notes.txt)." ), ) reproduce_parser.add_argument( "--package", dest="package_id", help="Pin one installed package id and skip auto routing.", ) reproduce_parser.add_argument( "--sandbox", default=None, help=( "Override sandbox mode for planning/auditing/loop runs. " "When omitted, uses `fermilink agent` policy." ), ) reproduce_parser.add_argument( "--task-max-runs", type=int, default=5, help="Maximum outer loop reruns per task when loop is not done (default: 5).", ) reproduce_parser.add_argument( "--planner-max-tries", type=int, default=2, help="Maximum planner retries to obtain valid plan JSON (default: 2).", ) reproduce_parser.add_argument( "--auditor-max-tries", type=int, default=2, help="Maximum auditor retries to obtain valid plan JSON (default: 2).", ) reproduce_parser.add_argument( "--max-iterations", type=int, default=10, help="Forwarded to inner loop: max iterations per loop run (default: 10).", ) reproduce_parser.add_argument( "--wait-seconds", type=float, default=1.0, help=( "Forwarded to inner loop polling interval for " "<pid_number>/<slurm_job_number> waits; " "also used as fallback sleep when no wait tags are returned " "(default: 1)." ), ) reproduce_parser.add_argument( "--max-wait-seconds", type=float, default=6000.0, help=( "Forwarded to inner loop hard cap for per-iteration pid/slurm polling " "and waits " "(default: 6000)." ), ) reproduce_parser.add_argument( "--pid-stall-seconds", type=float, default=900.0, help=( "Forwarded to inner loop local-pid stall timeout. If > 0, a pid with no " "CPU-time progress for this long triggers early next-iteration handoff " "(default: 900; set 0 to disable)." ), ) reproduce_parser.add_argument( "--hpc-profile", default=None, help=( "Optional JSON file with `slurm_default_partition`, `slurm_defaults`, " "and `slurm_resource_policy`; when set, workflow planning/task " "prompts/reporting are constrained to this HPC profile." ), ) reproduce_parser.add_argument( "--plan-only", action="store_true", help="Only generate and persist plan/prompts; do not execute tasks.", ) reproduce_parser.add_argument( "--report-only", action="store_true", help=( "Only generate/audit top-level report from existing run artifacts " "(requires --resume)." ), ) reproduce_parser.add_argument( "--skip-report", action="store_true", help="Skip final report generation after all tasks complete.", ) resume_group = reproduce_parser.add_mutually_exclusive_group(required=False) resume_group.add_argument( "--resume", dest="resume", action="store_true", default=True, help="Resume the latest matching in-progress reproduce run (default).", ) resume_group.add_argument( "--restart", dest="resume", action="store_false", help="Start a fresh reproduce run and ignore resumable state.", ) reproduce_parser.add_argument( "--init-git", action="store_true", help="Auto-run git init when current directory is not a git repository.", ) reproduce_parser.add_argument( "--no-init-git", action="store_true", help="Fail instead of prompting/initializing when git repository is missing.", ) reproduce_parser.set_defaults(func=cmd_reproduce) research_parser = subparsers.add_parser( "research", help=( "Run research orchestration: generate/audit a multi-task research plan, then " "execute each task via fermilink loop until all tasks are done." ), ) research_parser.add_argument( "prompt", nargs="+", help=( "Either research request text, or a path to a file containing source content " "(e.g. idea.md, proposal.txt)." ), ) research_parser.add_argument( "--package", dest="package_id", help="Pin one installed package id and skip auto routing.", ) research_parser.add_argument( "--sandbox", default=None, help=( "Override sandbox mode for planning/auditing/loop runs. " "When omitted, uses `fermilink agent` policy." ), ) research_parser.add_argument( "--task-max-runs", type=int, default=5, help="Maximum outer loop reruns per task when loop is not done (default: 5).", ) research_parser.add_argument( "--planner-max-tries", type=int, default=2, help="Maximum planner retries to obtain valid plan JSON (default: 2).", ) research_parser.add_argument( "--auditor-max-tries", type=int, default=2, help="Maximum auditor retries to obtain valid plan JSON (default: 2).", ) research_parser.add_argument( "--max-iterations", type=int, default=10, help="Forwarded to inner loop: max iterations per loop run (default: 10).", ) research_parser.add_argument( "--wait-seconds", type=float, default=0.0, help=( "Forwarded to inner loop polling interval for " "<pid_number>/<slurm_job_number> waits; " "also used as fallback sleep when no wait tags are returned " "(default: 0)." ), ) research_parser.add_argument( "--max-wait-seconds", type=float, default=600.0, help=( "Forwarded to inner loop hard cap for per-iteration pid/slurm polling " "and waits " "(default: 600)." ), ) research_parser.add_argument( "--pid-stall-seconds", type=float, default=900.0, help=( "Forwarded to inner loop local-pid stall timeout. If > 0, a pid with no " "CPU-time progress for this long triggers early next-iteration handoff " "(default: 900; set 0 to disable)." ), ) research_parser.add_argument( "--hpc-profile", default=None, help=( "Optional JSON file with `slurm_default_partition`, `slurm_defaults`, " "and `slurm_resource_policy`; when set, workflow planning/task " "prompts/reporting are constrained to this HPC profile." ), ) research_parser.add_argument( "--plan-only", action="store_true", help="Only generate and persist plan/prompts; do not execute tasks.", ) research_parser.add_argument( "--report-only", action="store_true", help=( "Only generate/audit top-level report from existing run artifacts " "(requires --resume)." ), ) research_parser.add_argument( "--skip-report", action="store_true", help="Skip final report generation after all tasks complete.", ) research_resume_group = research_parser.add_mutually_exclusive_group(required=False) research_resume_group.add_argument( "--resume", dest="resume", action="store_true", default=True, help="Resume the latest matching in-progress research run (default).", ) research_resume_group.add_argument( "--restart", dest="resume", action="store_false", help="Start a fresh research run and ignore resumable state.", ) research_parser.add_argument( "--init-git", action="store_true", help="Auto-run git init when current directory is not a git repository.", ) research_parser.add_argument( "--no-init-git", action="store_true", help="Fail instead of prompting/initializing when git repository is missing.", ) research_parser.set_defaults(func=cmd_research)