feat: stufen-spezifisches Token-Limit für die Solver-Stufe (LLM_MAX_TOKENS_SOLVER)

Die Solver-Stufe erzeugt langen Python-Code plus Reasoning. Bei komplexen
Aufgaben (Portfoliomanagement: 4× je ~26k Reasoning-Tokens am 32k-Limit
abgeschnitten, $0,28 für nichts) reichte das globale Limit nicht. DeepSeek
V4.1 Flash unterstützt bis 393k Output-Tokens (OpenRouter).

Neu: LLM_MAX_TOKENS_SOLVER (Default 65536, 0 = globales Limit gilt auch
für den Solver). Wirkt nur für die Stufen 'Solver-Code' und 'Solver-Reparatur'.
CLI-Option --max-tokens-solver. 438 Tests grün.
This commit is contained in:
Dieter Schlüter 2026-09-18 21:48:18 +02:00
commit e7a2b8de81

View file

@ -554,6 +554,9 @@ def build_parser() -> argparse.ArgumentParser:
help="Denkaufwand, nur OpenRouter (LLM_REASONING_EFFORT, Modellvorgabe)")
ki.add_argument("--max-tokens", type=int, metavar="N",
help=f"Antwortlänge je Aufruf (LLM_MAX_TOKENS, {llm.LLM_MAX_TOKENS})")
ki.add_argument("--max-tokens-solver", type=int, metavar="N",
help=f"Antwortlänge für die Solver-Stufe, 0 = wie --max-tokens "
f"(LLM_MAX_TOKENS_SOLVER, {llm.LLM_MAX_TOKENS_SOLVER})")
ki.add_argument("--llm-timeout", type=int, metavar="SEK",
help=f"Zeitlimit je Aufruf (LLM_TIMEOUT, {llm.LLM_TIMEOUT})")
@ -594,8 +597,8 @@ def _check_args(parser: argparse.ArgumentParser, args: argparse.Namespace) -> No
("--solver-retries", args.solver_retries)):
if wert < 0:
parser.error(f"{name} darf nicht negativ sein")
for name, wert in (("--max-tokens", args.max_tokens), ("--llm-timeout", args.llm_timeout),
("--solver-timeout", args.solver_timeout)):
for name, wert in (("--max-tokens", args.max_tokens), ("--max-tokens-solver", args.max_tokens_solver),
("--llm-timeout", args.llm_timeout), ("--solver-timeout", args.solver_timeout)):
if wert is not None and wert <= 0:
parser.error(f"{name} muss positiv sein")
eingaben = [args.aufgabe if args.aufgabe != "-" else None, args.von[1] if args.von else None,
@ -620,6 +623,8 @@ def apply_settings(args: argparse.Namespace) -> None:
llm.REASONING_EFFORT = args.reasoning
if args.max_tokens:
llm.LLM_MAX_TOKENS = args.max_tokens
if args.max_tokens_solver is not None:
llm.LLM_MAX_TOKENS_SOLVER = args.max_tokens_solver
if args.llm_timeout:
llm.LLM_TIMEOUT = args.llm_timeout
if args.solver_timeout: