From c77be502f974ca578be3b7a21e3e7f8c356fc5be Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Mon, 29 Jun 2026 18:03:02 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20coding-Lane=20bleibt=20beim=20Coder=20(a?= =?UTF-8?q?gentisch)=20=E2=80=94=20nie=20heavy/fast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- backend/services/router_logic.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/backend/services/router_logic.py b/backend/services/router_logic.py index 3c2ac43..05ac53d 100644 --- a/backend/services/router_logic.py +++ b/backend/services/router_logic.py @@ -20,8 +20,9 @@ CODER = os.environ.get("MC_ROUTE_CODER", "coder") # Schwellen (Zeichen). 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_TRIVIAL_CHARS = int(os.environ.get("MC_CODING_TRIVIAL_CHARS", "240")) # coding → fast (nur ohne Code) +# coding-Lane: leichter/schneller Coder als Default (wenn gesetzt = Phase 2b), starker Coder als Eskalation. +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). 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]: - if n > CODING_HEAVY_CHARS or _CODING_HEAVY_KW.search(text): - return HEAVY, "großer/architektonischer Coding-Kontext" - if n < CODING_TRIVIAL_CHARS and not _CODE_HINT.search(text): - return FAST, "triviale Kurzfrage (kein Code)" - return CODER, "Coding-Standard" + # Agentisches Coden (OpenCode/RooCode/…) bleibt IMMER beim dedizierten Coder — NIE heavy/fast + # (das sind Allzweck-Modelle, schwächer bei Code). Die Qwen-Coder packen 256K–1M Kontext selbst, + # langer Repo-Kontext ist bei Agenten der Normalfall und darf NICHT zu heavy umrouten. + # (Phase 2b: warme schnelle Coder-Stufe CODER_LITE als Default + CODER als Eskalation.) + 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]: