feat: TextToModel.py als CLI-Programm mit main(), gruppierten Optionen und Defaults

- main(argv) -> int, build_parser() mit Gruppen Eingabe/Modus/Ablauf/LLM/Solver/Ausgabe,
  Hilfe mit Defaults, Umgebungsvariablen, Beispielen und Exit-Codes
- Optionen für bisher reine Umgebungsvariablen (--solver-timeout, --sandbox, --max-tokens,
  --llm-timeout, --reasoning, --solver-retries, --understand-retries, --infeasible-recheck)
- -o/--json und -a/--ausgabe PRÄFIX; im Terminal Kurzfassung statt JSON
- Exit-Codes: 1 Eingabefehler, 64 Aufruffehler (nicht argparse' 2 = unzuverlässig), 130 Abbruch
- solver_stage: Zeitlimit-Default zur Aufrufzeit auflösen, damit --solver-timeout wirkt
- tests/test_cli.py

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-09-18 18:34:42 +02:00
commit 422360ffa5

View file

@ -572,8 +572,9 @@ def solver_env(tmp: str) -> dict:
return {**env, "HOME": tmp, "TMPDIR": tmp, "PYTHONDONTWRITEBYTECODE": "1"}
def run_solver_code(code: str, timeout: int = SOLVER_TIMEOUT, data: dict | None = None,
def run_solver_code(code: str, timeout: int | None = None, data: dict | None = None,
data_files=()) -> SolverRun:
timeout = timeout or SOLVER_TIMEOUT # zur Aufrufzeit, damit --solver-timeout wirkt
try:
validate_imports(code)
except CodeRejected as exc:
@ -815,7 +816,7 @@ def check_text_quality(run, summary: str = "") -> list:
MAX_SCENARIOS = 5 # jedes Szenario kostet einen weiteren Programmlauf (kein LLM-Aufruf)
def verify_scenarios(run, code: str, timeout: int = SOLVER_TIMEOUT, data_files=()) -> list:
def verify_scenarios(run, code: str, timeout: int | None = None, data_files=()) -> list:
"""Jedes Szenario mit übersteuerten Daten NEU rechnen und den gemeldeten Zielwert bestätigen.
Ein Szenario ist eine Datenvariante desselben Programms – dieselbe Maschinerie wie `--resolve`.
@ -1163,7 +1164,7 @@ def _check_and_run(code: str, timeout: int, spec: OptimizationModelSpecification
def solve(session: LLMSession, task: str, spec: OptimizationModelSpecification,
retries: int = 2, timeout: int = SOLVER_TIMEOUT, log=lambda msg: None, understanding=None,
retries: int = 2, timeout: int | None = None, log=lambda msg: None, understanding=None,
data_files=(), data_prompt: str = "") -> tuple:
"""Code erzeugen und ausführen; bei Fehlern bis zu `retries` Reparaturversuche.