from __future__ import annotations
import argparse
from collections.abc import Callable
CommandHandler = Callable[[argparse.Namespace], int]
[docs]
def register_exec_loop_parsers(
subparsers: argparse._SubParsersAction[argparse.ArgumentParser], # type: ignore[attr-defined]
*,
cmd_exec: CommandHandler,
cmd_loop: CommandHandler,
) -> None:
"""
Register parser arguments for exec loop.
Parameters
----------
subparsers : argparse._SubParsersAction[argparse.ArgumentParser]
Subparser collection created from the root parser.
cmd_exec : CommandHandler
Command handler for `exec` subcommands.
cmd_loop : CommandHandler
Command handler for `loop` subcommands.
Returns
-------
None
No return value; parser objects are mutated in place.
"""
exec_parser = subparsers.add_parser(
"exec",
help=(
"Run one prompt locally with web-like package routing, second guess, "
"package overlay symlinks, and AGENTS template sync."
),
)
exec_parser.add_argument(
"prompt",
nargs="+",
help=(
"Either prompt text, or a path to a markdown/text file containing "
"the prompt (e.g. prompt.md)."
),
)
exec_parser.add_argument(
"--package",
dest="package_id",
help="Pin one installed package id and skip auto routing.",
)
exec_parser.add_argument(
"--sandbox",
default=None,
help=(
"Override sandbox mode for this run. "
"When omitted, uses `fermilink agent` policy."
),
)
exec_parser.add_argument(
"--hpc-profile",
default=None,
help=(
"Optional JSON file with `slurm_default_partition`, `slurm_defaults`, "
"and `slurm_resource_policy`; when set, execution prompt context is "
"constrained to this HPC profile."
),
)
exec_parser.add_argument(
"--init-git",
action="store_true",
help=(
"Explicitly auto-run git init when current directory is not a git "
"repository (default behavior)."
),
)
exec_parser.add_argument(
"--no-init-git",
action="store_true",
help="Fail instead of auto-initializing when git repository is missing.",
)
exec_parser.set_defaults(func=cmd_exec)
loop_parser = subparsers.add_parser(
"loop",
help=(
"Run one autonomous loop iteration locally (web-like routing + overlay), "
"persisting state in projects/memory.md until <promise>DONE</promise>."
),
)
loop_parser.add_argument(
"prompt",
nargs="+",
help=(
"Either prompt text, or a path to a markdown file containing the prompt "
"(e.g. prompt.md)."
),
)
loop_parser.add_argument(
"--package",
dest="package_id",
help="Pin one installed package id and skip auto routing.",
)
loop_parser.add_argument(
"--sandbox",
default=None,
help=(
"Override sandbox mode for this iteration. "
"When omitted, uses `fermilink agent` policy."
),
)
loop_parser.add_argument(
"--hpc-profile",
default=None,
help=(
"Optional JSON file with `slurm_default_partition`, `slurm_defaults`, "
"and `slurm_resource_policy`; when set, execution prompt context is "
"constrained to this HPC profile."
),
)
loop_parser.add_argument(
"--max-iterations",
type=int,
default=10,
help="Maximum loop iterations to run before stopping (default: 10).",
)
loop_parser.add_argument(
"--wait-seconds",
type=float,
default=1.0,
help=(
"Polling interval seconds for <pid_number>/<slurm_job_number> waits; "
"also used as fallback sleep between iterations when no wait tags are returned "
"(default: 1)."
),
)
loop_parser.add_argument(
"--max-wait-seconds",
type=float,
default=6000.0,
help=(
"Hard cap on per-iteration waiting for pid/slurm polling and wait "
"hints (default: 6000)."
),
)
loop_parser.add_argument(
"--pid-stall-seconds",
type=float,
default=900.0,
help=(
"If > 0, treat local pid polling as stalled when process CPU time does not "
"advance for this many seconds and continue to next iteration early "
"(default: 900; set 0 to disable)."
),
)
loop_parser.add_argument(
"--init-git",
action="store_true",
help=(
"Explicitly auto-run git init when current directory is not a git "
"repository (default behavior)."
),
)
loop_parser.add_argument(
"--no-init-git",
action="store_true",
help="Fail instead of auto-initializing when git repository is missing.",
)
loop_parser.set_defaults(func=cmd_loop)
[docs]
def register_exploop_parser(
subparsers: argparse._SubParsersAction[argparse.ArgumentParser], # type: ignore[attr-defined]
*,
cmd_exploop: CommandHandler,
) -> None:
"""
Register parser arguments for experimental measurement loop mode.
Parameters
----------
subparsers : argparse._SubParsersAction[argparse.ArgumentParser]
Subparser collection created from the root parser.
cmd_exploop : CommandHandler
Command handler for `exploop` subcommands.
Returns
-------
None
No return value; parser objects are mutated in place.
"""
exploop_parser = subparsers.add_parser(
"exploop",
help=(
"Run a minimal experimental measurement loop using local skills, "
"projects/memory.md, and Windows-ready PID polling."
),
)
exploop_parser.add_argument(
"prompt",
nargs="+",
help=(
"Either prompt text, or a path to a markdown/text file containing "
"the experimental measurement goal (e.g. goal.md)."
),
)
exploop_parser.add_argument(
"--sandbox",
default=None,
help=(
"Override sandbox mode for this run. "
"When omitted, uses `fermilink agent` policy."
),
)
exploop_parser.add_argument(
"--max-iterations",
type=int,
default=30,
help="Maximum exploop iterations to run before stopping (default: 30).",
)
exploop_parser.add_argument(
"--wait-seconds",
type=float,
default=1.0,
help=(
"Polling interval seconds for <pid_number> waits; also used as "
"fallback sleep between iterations when no wait tags are returned "
"(default: 1)."
),
)
exploop_parser.add_argument(
"--max-wait-seconds",
type=float,
default=86400.0,
help=(
"Hard cap on per-iteration waiting for PID polling and wait hints "
"(default: 86400, or one day)."
),
)
exploop_parser.set_defaults(func=cmd_exploop)
[docs]
def register_drvloop_parser(
subparsers: argparse._SubParsersAction[argparse.ArgumentParser], # type: ignore[attr-defined]
*,
cmd_drvloop: CommandHandler,
) -> None:
"""
Register parser arguments for derivation loop mode.
Parameters
----------
subparsers : argparse._SubParsersAction[argparse.ArgumentParser]
Subparser collection created from the root parser.
cmd_drvloop : CommandHandler
Command handler for `drvloop` subcommands.
Returns
-------
None
No return value; parser objects are mutated in place.
"""
drvloop_parser = subparsers.add_parser(
"drvloop",
help=(
"Run a minimal derivation loop using compact projects/memory.md "
"for stepwise analytical work."
),
)
drvloop_parser.add_argument(
"prompt",
nargs="+",
help=(
"Either prompt text, or a path to a markdown/text file containing "
"the derivation goal (e.g. goal.md)."
),
)
drvloop_parser.add_argument(
"--sandbox",
default=None,
help=(
"Override sandbox mode for this run. "
"When omitted, uses `fermilink agent` policy."
),
)
drvloop_parser.add_argument(
"--max-iterations",
type=int,
default=30,
help="Maximum drvloop iterations to run before stopping (default: 30).",
)
drvloop_parser.add_argument(
"--proof-depth",
choices=("quick", "standard", "publication"),
default="publication",
help=(
"Derivation workflow rigor: quick is validator-only, standard "
"requires staged derivation, publication requires multi-route "
"population and review (default: publication)."
),
)
drvloop_parser.set_defaults(func=cmd_drvloop)
[docs]
def register_chat_parser(
subparsers: argparse._SubParsersAction[argparse.ArgumentParser], # type: ignore[attr-defined]
*,
cmd_chat: CommandHandler,
) -> None:
"""
Register parser arguments for chat.
Parameters
----------
subparsers : argparse._SubParsersAction[argparse.ArgumentParser]
Subparser collection created from the root parser.
cmd_chat : CommandHandler
Command handler for `chat` subcommands.
Returns
-------
None
No return value; parser objects are mutated in place.
"""
chat_parser = subparsers.add_parser(
"chat",
help=(
"Run interactive multi-turn local chat with web-like package routing, "
"second guess, and package overlays."
),
)
chat_parser.add_argument(
"--package",
dest="package_id",
help="Pin one installed package id for all turns and skip auto routing.",
)
chat_parser.add_argument(
"--sandbox",
default=None,
help=(
"Override sandbox mode for this chat session. "
"When omitted, uses `fermilink agent` policy."
),
)
chat_parser.add_argument(
"--init-git",
action="store_true",
help=(
"Explicitly auto-run git init when current directory is not a git "
"repository (default behavior)."
),
)
chat_parser.add_argument(
"--no-init-git",
action="store_true",
help="Fail instead of auto-initializing when git repository is missing.",
)
chat_parser.set_defaults(func=cmd_chat)