Fix: coding-Lane bleibt beim Coder (agentisch) — nie heavy/fast

Agentisches Coden (OpenCode/RooCode/…) hat immer großen Repo-Kontext; die alte
Regel routete >24k Zeichen auf heavy (Allzweck-122B) statt auf einen Coder =
Downgrade der Coding-Fähigkeit. Jetzt: coding -> CODER immer. Optionaler leichter
schneller Coder via MC_ROUTE_CODER_LITE (Phase 2b: Qwen3-Coder-30B), Eskalation
auf den starken Coder bei Architektur-Keywords / sehr großem Kontext.
Reason-Strings header-safe gemacht (kein U+2192 → Latin-1-Crash im x-mc-Header).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-29 18:03:02 +02:00
parent ec9d1bff5b
commit c77be502f9
+10 -7
View File
@@ -20,8 +20,9 @@ CODER = os.environ.get("MC_ROUTE_CODER", "coder")
# Schwellen (Zeichen). # Schwellen (Zeichen).
HEAVY_CHARS = int(os.environ.get("MC_GATEWAY_HEAVY_CHARS", "8000")) # chat → heavy HEAVY_CHARS = int(os.environ.get("MC_GATEWAY_HEAVY_CHARS", "8000")) # chat → heavy
CODING_HEAVY_CHARS = int(os.environ.get("MC_CODING_HEAVY_CHARS", "24000")) # coding → heavy # coding-Lane: leichter/schneller Coder als Default (wenn gesetzt = Phase 2b), starker Coder als Eskalation.
CODING_TRIVIAL_CHARS = int(os.environ.get("MC_CODING_TRIVIAL_CHARS", "240")) # coding → fast (nur ohne Code) CODER_LITE = os.environ.get("MC_ROUTE_CODER_LITE", "").strip() # z.B. "coder-lite"
CODING_ESCALATE_CHARS = int(os.environ.get("MC_CODING_ESCALATE_CHARS", "120000")) # darüber → starker Coder
# Thinking auf der fast-Spur aus → flotte Alltags-Antworten (Qwen3.6 ist ein Reasoning-Modell). # Thinking auf der fast-Spur aus → flotte Alltags-Antworten (Qwen3.6 ist ein Reasoning-Modell).
FAST_NO_THINK = os.environ.get("MC_FAST_NO_THINK", "1") not in ("0", "false", "") FAST_NO_THINK = os.environ.get("MC_FAST_NO_THINK", "1") not in ("0", "false", "")
@@ -71,11 +72,13 @@ def _route_chat(text: str, n: int) -> tuple[str, str]:
def _route_coding(text: str, n: int) -> tuple[str, str]: def _route_coding(text: str, n: int) -> tuple[str, str]:
if n > CODING_HEAVY_CHARS or _CODING_HEAVY_KW.search(text): # Agentisches Coden (OpenCode/RooCode/…) bleibt IMMER beim dedizierten Coder — NIE heavy/fast
return HEAVY, "großer/architektonischer Coding-Kontext" # (das sind Allzweck-Modelle, schwächer bei Code). Die Qwen-Coder packen 256K1M Kontext selbst,
if n < CODING_TRIVIAL_CHARS and not _CODE_HINT.search(text): # langer Repo-Kontext ist bei Agenten der Normalfall und darf NICHT zu heavy umrouten.
return FAST, "triviale Kurzfrage (kein Code)" # (Phase 2b: warme schnelle Coder-Stufe CODER_LITE als Default + CODER als Eskalation.)
return CODER, "Coding-Standard" if CODER_LITE and not _CODING_HEAVY_KW.search(text) and n <= CODING_ESCALATE_CHARS:
return CODER_LITE, "Coding (schneller Coder)"
return CODER, "Coding -> starker Coder"
def choose_for_lane(lane: str, body: dict) -> tuple[str, str]: def choose_for_lane(lane: str, body: dict) -> tuple[str, str]: