This commit is contained in:
team3
2026-07-24 11:23:18 +02:00
parent cb68cd671b
commit 1b054497ed
49 changed files with 935 additions and 408 deletions

View File

@@ -10,13 +10,9 @@ from dataclasses import dataclass, field
import httpx
from . import config, db, skills
from . import config, db, graph, skills
from .ledger import BudgetErschoepft, budget_pruefen, log_call # noqa: F401
_INFRA_MARKER = ("429", "rate limit", "rate_limit", "timeout", "timed out",
"connection", "network", "overloaded", "unavailable",
'"status_code":1002', '"status_code":1041', '"status_code":2045')
class LaufPause(Exception):
"""Infrastruktur erschöpft — Lauf pausieren, nie fail-open weiterrechnen."""
@@ -31,6 +27,7 @@ class ApiErgebnis:
rc: int
text: str = ""
err: str = ""
cap: bool = False # stop=max_tokens — strukturiert, kein String-Match
tokens: dict = field(default_factory=dict)
@@ -88,7 +85,7 @@ def _slot_frei() -> None:
def _ist_infra(err: str) -> bool:
e = err.lower()
return any(m in e for m in _INFRA_MARKER)
return any(m in e for m in config.INFRA_MARKER)
async def _api(prompt: str, role: str, timeout: float) -> ApiErgebnis:
@@ -130,6 +127,7 @@ async def _api(prompt: str, role: str, timeout: float) -> ApiErgebnis:
return ApiErgebnis(1, err=resp.text[:300], tokens=tokens)
if not text.strip():
return ApiErgebnis(1, err=f"leere Antwort (stop={daten.get('stop_reason')})",
cap=daten.get("stop_reason") == "max_tokens",
tokens=tokens)
_erfolg_melden()
return ApiErgebnis(0, text=text, tokens=tokens)
@@ -165,7 +163,7 @@ async def call(*, run_id: int, stufe: str, knoten: str, item: str,
"""Zentraler LLM-Engpass. Rückgabe: Antworttext oder None (Inhaltsfehler/cap).
Wirft LaufPause (Infra erschöpft/manuell) oder BudgetErschoepft."""
prompt, skill_hash, paare = skills.komponieren(skill_namen, werte)
timeout = config.timeout_fuer(knoten, n)
timeout = graph.timeout_fuer(knoten, n)
infra_rest = config.INFRA_MAX_RETRIES
inhalt_rest = config.INHALT_MAX_RESTARTS
@@ -197,7 +195,7 @@ async def call(*, run_id: int, stufe: str, knoten: str, item: str,
tokens, err, text = res.tokens, res.err, res.text
if res.rc == 0:
status = "ok"
elif "stop=max_tokens" in err:
elif res.cap:
status = "cap"
elif _ist_infra(err):
status = "infra"