feat(codex-bridge): Jev routes a blocked step down the layer combos, no exceptions
Katman-1..3 answers are checked by Jev each step; a blocked step is redone by the next layer combo. Katman-4 is delivered unasked. The technical-obstacle, question and third-party exemptions and the settings overrides are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f4f2de428
commit
be0b33e89b
3 files changed
+160
-182
No files matched your search
@@ -871,51 +871,56 @@ class H(http.server.BaseHTTPRequestHandler):
|
||||
self.send_header("Transfer-Encoding", "chunked")
|
||||
self.end_headers()
|
||||
|
||||
def _denetimli_akis(self, resp, tag, rewriter, izle, istek, ayar, yedek):
|
||||
"""Adim denetimi (jev_denetim.py): cevap istemciye verilmeden once tamami okunur ve Jev'e sorulur.
|
||||
Gecerse oldugu gibi verilir; gecmezse atilir ve ayni adimi yedek model yapar (yedek(): (resp, rewriter, tag)).
|
||||
Beklerken istemciye SSE yorum satiri gider ki Codex akisi kopmus saymasin."""
|
||||
def _denetimli_akis(self, resp, tag, rewriter, izle, istek, sira, ac):
|
||||
"""Katman denetimi (jev_denetim.py): cevap istemciye verilmeden once tamami okunur ve Jev'e sorulur.
|
||||
Gecerse oldugu gibi verilir; gecmezse atilir ve ayni adimi siradaki katman yapar (ac(ad): (resp, rewriter,
|
||||
tag)). Son katmanin cevabi sorulmadan akar. Beklerken SSE yorum satiri gider ki Codex akisi kopmus saymasin."""
|
||||
self._akis_basligi(resp, resp.status)
|
||||
parcalar, okuyan, son_yazi = [], yarim.Izleyici("", ""), time.time()
|
||||
kalan, son_yazi = list(sira), time.time()
|
||||
|
||||
def w(b):
|
||||
if b:
|
||||
self.wfile.write(b"%x\r\n" % len(b) + b + b"\r\n"); self.wfile.flush()
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
chunk = resp.read1(4096)
|
||||
except (OSError, http.client.HTTPException) as e:
|
||||
log(f"{tag} ust kaynak koptu (denetim tamponu, {sum(map(len, parcalar))} bayt): {type(e).__name__}: {e}")
|
||||
self.close_connection = True
|
||||
return
|
||||
if not chunk:
|
||||
parcalar, okuyan = [], yarim.Izleyici("", "")
|
||||
while True:
|
||||
try:
|
||||
chunk = resp.read1(4096)
|
||||
except (OSError, http.client.HTTPException) as e:
|
||||
log(f"{tag} ust kaynak koptu (denetim tamponu, {sum(map(len, parcalar))} bayt): {type(e).__name__}: {e}")
|
||||
self.close_connection = True
|
||||
return
|
||||
if not chunk:
|
||||
break
|
||||
parcalar.append(chunk)
|
||||
okuyan.feed(chunk)
|
||||
if time.time() - son_yazi >= 10:
|
||||
w(b": denetim\n\n"); son_yazi = time.time()
|
||||
metin = okuyan.metin.strip()
|
||||
gecmedi = False
|
||||
if metin:
|
||||
t0 = time.time()
|
||||
puan = jev_denetim.sor(istek, metin, jev_denetim.anahtar())
|
||||
if puan is None:
|
||||
log(f"{tag} katman denetimi: Jev'e sorulamadi, cevap oldugu gibi geciyor")
|
||||
else:
|
||||
gecmedi = jev_denetim.karar(puan)
|
||||
log(f"{tag} katman denetimi: ret={puan['ret']:.2f} sart={puan['sart']:.2f} -> "
|
||||
f"{'GECMEDI' if gecmedi else 'gecti'} ({time.time() - t0:.1f} sn, {len(metin)} karakter)")
|
||||
yeni = None
|
||||
while gecmedi and kalan and yeni is None:
|
||||
ad = kalan.pop(0)
|
||||
try:
|
||||
yeni = ac(ad)
|
||||
except Exception as e:
|
||||
log(f"{tag} katman denetimi: {ad} acilamadi ({type(e).__name__}: {str(e)[:120]})")
|
||||
if yeni is None:
|
||||
break
|
||||
parcalar.append(chunk)
|
||||
okuyan.feed(chunk)
|
||||
if time.time() - son_yazi >= 10:
|
||||
w(b": denetim\n\n"); son_yazi = time.time()
|
||||
metin = okuyan.metin.strip()
|
||||
gecmedi = False
|
||||
if metin and istek:
|
||||
t0 = time.time()
|
||||
puan = jev_denetim.sor(istek, metin, jev_denetim.anahtar(), float(ayar.get("sure") or jev_denetim.SURE))
|
||||
if puan is None:
|
||||
log(f"{tag} adim denetimi: Jev'e sorulamadi, cevap oldugu gibi geciyor")
|
||||
else:
|
||||
gecmedi = jev_denetim.karar(puan, ayar)
|
||||
log(f"{tag} adim denetimi: ret={puan['ret']:.2f} sart={puan['sart']:.2f} teknik={puan['teknik']:.2f} "
|
||||
f"soru={puan['soru']:.2f} -> {'GECMEDI' if gecmedi else 'gecti'} ({time.time() - t0:.1f} sn, {len(metin)} karakter)")
|
||||
if gecmedi:
|
||||
try:
|
||||
yeni = yedek()
|
||||
except Exception as e:
|
||||
yeni = None
|
||||
log(f"{tag} adim denetimi: yedek model acilamadi ({type(e).__name__}: {str(e)[:120]}); ilk cevap veriliyor")
|
||||
if yeni is not None:
|
||||
resp2, rewriter2, tag2 = yeni
|
||||
log(f"{tag} adim denetimi: adim yedek modele verildi -> {tag2}")
|
||||
return self._stream(resp2, resp2.status, tag2, rewriter2, izle, basliksiz=True)
|
||||
resp, rewriter, tag = yeni
|
||||
log(f"{tag} katman denetimi: adim bu katmana verildi")
|
||||
if not kalan:
|
||||
return self._stream(resp, resp.status, tag, rewriter, izle, basliksiz=True)
|
||||
for chunk in parcalar:
|
||||
if izle is not None:
|
||||
izle.feed(chunk)
|
||||
@@ -1012,7 +1017,7 @@ class H(http.server.BaseHTTPRequestHandler):
|
||||
"ide_model": int((sayi.split() or ["0"])[0]),
|
||||
"ozet": bool((CFG.get("ozet_kopru") or {}).get("enabled", False)),
|
||||
"is_hatti": bool(HAT_KOMUT[0]),
|
||||
"adim_denetimi": bool(jev_denetim.ayar_oku(CFG.get("jev_denetim"))[0] and jev_denetim.anahtar())})
|
||||
"adim_denetimi": bool(jev_denetim.anahtar())})
|
||||
if self.command == "POST" and path.rstrip("/").endswith("/stop"):
|
||||
self._send_json(200, {"ok": True})
|
||||
log("AITURK IDE istegiyle kapatiliyor")
|
||||
@@ -1563,25 +1568,19 @@ class H(http.server.BaseHTTPRequestHandler):
|
||||
open(os.path.join(LOGDIR, f"{n:04d}_req.json"), "wb").write(data)
|
||||
hdrs = {"Authorization": f"Bearer {route['key']}", "Content-Type": "application/json", "Accept": "text/event-stream", "User-Agent": UA}
|
||||
last = None
|
||||
# Adim denetimi (jev_denetim.py): Jev'in gecirmedigi adimi yedek model yapar. Yedek ayni gecitteyse ve
|
||||
# secili model zaten yedek degilse acilir; ozet isteginde ve Jev anahtari yokken kapalidir.
|
||||
jev_yedek = None
|
||||
jev_acik, jev_hedef, jev_ayar = jev_denetim.ayar_oku(CFG.get("jev_denetim"))
|
||||
jev_esleme = MODEL_MAP.get(jev_hedef)
|
||||
if (jev_acik and not ozet_tetik and slug != jev_hedef and jev_esleme and jev_esleme[0] == route_name
|
||||
and rewriter is not None and jev_denetim.anahtar()):
|
||||
jev_istek = jev_denetim.son_istek(req)
|
||||
# Katman denetimi (jev_denetim.py): Katman-1..3 cevabini Jev gecirmezse adimi siradaki katman yapar.
|
||||
# Katman-4 ve katman olmayan modeller sorulmaz.
|
||||
jev_sira = [] if ozet_tetik or rewriter is None or not jev_denetim.anahtar() else jev_denetim.sonrakiler(target)
|
||||
jev_istek = jev_denetim.son_istek(req) if jev_sira else ""
|
||||
|
||||
def jev_yedek():
|
||||
yedek_req = json.loads(data)
|
||||
yedek_req["model"] = jev_esleme[1]
|
||||
yanit = urllib.request.urlopen(urllib.request.Request(
|
||||
route["url"], data=json.dumps(yedek_req, ensure_ascii=False).encode("utf-8"), headers=hdrs, method="POST"),
|
||||
timeout=UPSTREAM_IDLE_TIMEOUT)
|
||||
return (yanit, SseRewriter(custom, hedef=jev_esleme[1], tasma=self._tasma_ogren, aracsiz=self._aracsiz_ogren),
|
||||
f"[{n} {route_name.upper()} {slug}=>{jev_esleme[1]}]")
|
||||
if not jev_istek:
|
||||
jev_yedek = None
|
||||
def jev_ac(ad):
|
||||
katman_req = json.loads(data)
|
||||
katman_req["model"] = ad
|
||||
yanit = urllib.request.urlopen(urllib.request.Request(
|
||||
route["url"], data=json.dumps(katman_req, ensure_ascii=False).encode("utf-8"), headers=hdrs, method="POST"),
|
||||
timeout=UPSTREAM_IDLE_TIMEOUT)
|
||||
return (yanit, SseRewriter(custom, hedef=ad, tasma=self._tasma_ogren, aracsiz=self._aracsiz_ogren),
|
||||
f"[{n} {route_name.upper()} {slug}=>{ad}]")
|
||||
# A 9Router combo (Fusion-*, no provider prefix) runs a whole panel upstream. Once it may
|
||||
# have started (timeout, 504, cut stream) resending it runs and bills it twice (28 Sep 2026);
|
||||
# only failures before the work starts (no connection, 500/502/503/529) are retried.
|
||||
@@ -1634,8 +1633,8 @@ class H(http.server.BaseHTTPRequestHandler):
|
||||
sonuc = self._stream(resp, resp.status, tag, akis)
|
||||
log(f"{tag} ozet kopru: {akis.sonuc_notu()}")
|
||||
return sonuc
|
||||
if jev_yedek is not None and resp.status == 200:
|
||||
return self._denetimli_akis(resp, tag, rewriter, izle, jev_istek, jev_ayar, jev_yedek)
|
||||
if jev_sira and jev_istek and resp.status == 200:
|
||||
return self._denetimli_akis(resp, tag, rewriter, izle, jev_istek, jev_sira, jev_ac)
|
||||
return self._stream(resp, resp.status, tag, rewriter, izle)
|
||||
self._send_json(503, {"error": {"message": f"bridge: hedef ulasilamadi {last}"}})
|
||||
|
||||
|
||||
Reference in new issue
Block a user