diff --git a/deploy/governor/governor.py b/deploy/governor/governor.py index c3529af..5a37341 100644 --- a/deploy/governor/governor.py +++ b/deploy/governor/governor.py @@ -433,18 +433,45 @@ class Handler(BaseHTTPRequestHandler): if base in EXEMPT_MODELS: return "passthrough", body, est, streaming, model, chars - if HARD_CEILING > 0 and est >= HARD_CEILING: + if not isinstance(messages, list): + return "passthrough", body, est, streaming, model, chars + + has_warned = False + marker = "[GOVERNOR — SITZUNGS-LIMIT ERREICHT]" + for m in reversed(messages): + if m.get("role") == "user" and isinstance(m.get("content"), str) and marker in m["content"]: + has_warned = True + break + + is_safe = safe_to_append(messages) + + # 1. Absolutes Not-Aus bei komplettem Amoklauf + if HARD_CEILING > 0 and est >= HARD_CEILING + 10000: return "hard", body, est, streaming, model, chars - if est >= THRESHOLD and isinstance(messages, list): - if not safe_to_append(messages): - # Mitten im Werkzeug-Austausch: nicht dazwischenfunken, naechste Runde. + # 2. Sind wir am Limit? + if est >= THRESHOLD: + if not is_safe: + # Agent arbeitet gerade an einer Tool-Kette. Auf keinen Fall abbrechen! return "defer", body, est, streaming, model, chars - directive = (DIRECTIVE.replace("{est}", str(est)) - .replace("{threshold}", str(THRESHOLD))) - messages.append({"role": "user", "content": directive}) - data["messages"] = messages - return "soft", json.dumps(data).encode("utf-8"), est, streaming, model, chars + + # Es ist sicher (Tool-Kette beendet oder Agent wartet auf Input). + if HARD_CEILING > 0 and est >= HARD_CEILING: + if has_warned: + # Wir haben ihn schon gewarnt, er macht trotzdem weiter -> harter Schnitt. + return "hard", body, est, streaming, model, chars + else: + # Er hat wegen einer langen Tool-Kette direkt das Hard-Limit ueberschritten. + # Gib ihm trotzdem noch den einen Finalisier-Zug (Soft). + pass + + # Soft-Limit greift + if not has_warned: + directive = (DIRECTIVE.replace("{est}", str(est)) + .replace("{threshold}", str(THRESHOLD))) + messages.append({"role": "user", "content": directive}) + data["messages"] = messages + return "soft", json.dumps(data).encode("utf-8"), est, streaming, model, chars return "passthrough", body, est, streaming, model, chars