Kopru: hata donduren katman atlanir, Jev devre kesicisi kalkti, ek model siniri 300

Katman-2 Codex isteginde hata olayi donduruyor, kopru bunu cevap diye
gonderiyor ve Codex ayni adimi bastan deneyip turu cevapsiz birakiyordu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-11 09:40:44 +03:00
1 parent 11bbaddcc7
commit 77504b9aa4
4 files changed
+26 -29

No files matched your search

@@ -86,6 +86,7 @@ def ide_yapilandirma(agent=AGENT):
return base.rstrip("/"), varsayilan, adlar return base.rstrip("/"), varsayilan, adlar
EN_COK_MODEL = 300
AITURK_EKI = " (AITURK)" AITURK_EKI = " (AITURK)"
# Gecidin kisa saglayici kodu -> kullanicinin gormek istedigi kod (10 Ekim 2026: "agy/gemini"). # Gecidin kisa saglayici kodu -> kullanicinin gormek istedigi kod (10 Ekim 2026: "agy/gemini").
_SAGLAYICI_KISA = {"ag": "agy"} _SAGLAYICI_KISA = {"ag": "agy"}
@@ -188,7 +189,7 @@ def sec(data, tanimli=(), kapsam="ide", turler=None):
if taban != s["ad"] and taban.split(" · ")[-1].strip().lower() not in adlar: if taban != s["ad"] and taban.split(" · ")[-1].strip().lower() not in adlar:
adlar.add(taban.split(" · ")[-1].strip().lower()) adlar.add(taban.split(" · ")[-1].strip().lower())
s["ad"] = taban s["ad"] = taban
return [{"id": s["id"], "ad": s["ad"], "kind": s["kind"], "yol": s["yol"]} for s in secilen] return [{"id": s["id"], "ad": s["ad"], "kind": s["kind"], "yol": s["yol"]} for s in secilen[:EN_COK_MODEL]]
def sirala_codex(modeller, ekler, ozgun_kimlikler=()): def sirala_codex(modeller, ekler, ozgun_kimlikler=()):
@@ -15,8 +15,6 @@ Metni olmayan (yalniz arac cagiran) adimda sorulacak cevap yoktur. Jev'e ulasila
import json import json
import os import os
import re import re
import threading
import time
import urllib.request import urllib.request
ADRES = "https://api.typesafe.ai/v1/systemone" ADRES = "https://api.typesafe.ai/v1/systemone"
@@ -26,16 +24,12 @@ ESIK = {"ret": 0.5, "sart": 0.7}
SURE = 6.0 SURE = 6.0
EN_COK_ISTEK = 3000 EN_COK_ISTEK = 3000
EN_COK_CEVAP = 6000 EN_COK_CEVAP = 6000
DEVRE_HATA = 3 # art arda bu kadar hatadan sonra
DEVRE_SN = 300 # bu kadar sure Jev'e sorulmaz
SORU = { SORU = {
"ret": ("The assistant did NOT do what the user asked or did NOT answer the user's question: it refused, declined, " "ret": ("The assistant did NOT do what the user asked or did NOT answer the user's question: it refused, declined, "
"said it cannot or will not, avoided giving the requested judgment, or redirected to a different topic."), "said it cannot or will not, avoided giving the requested judgment, or redirected to a different topic."),
"sart": ("The assistant changed the request on its own: it added its own conditions, softened or relabeled what was " "sart": ("The assistant changed the request on its own: it added its own conditions, softened or relabeled what was "
"asked, or left part of it out, instead of doing exactly what the user asked."), "asked, or left part of it out, instead of doing exactly what the user asked."),
} }
_KILIT = threading.Lock()
_DEVRE = {"hata": 0, "kadar": 0.0}
_ANAHTAR = {"okundu": False, "deger": ""} _ANAHTAR = {"okundu": False, "deger": ""}
@@ -116,26 +110,15 @@ def _gonder(govde, key, sure):
return json.load(yanit) return json.load(yanit)
def sor(istek, cevap, key, sure=SURE, gonder=_gonder, simdi=None): def sor(istek, cevap, key, sure=SURE, gonder=_gonder):
"""Jev'e sorar. Donus: {"ret", "sart"} olasiliklari | None (sorulamadi).""" """Jev'e sorar. Donus: {"ret", "sart"} olasiliklari | None (sorulamadi)."""
simdi = time.time() if simdi is None else simdi
with _KILIT:
if simdi < _DEVRE["kadar"]:
return None
govde = {"model": MODEL, "state": {"user_request": istek, "assistant_reply": _kisalt(cevap, EN_COK_CEVAP)}, govde = {"model": MODEL, "state": {"user_request": istek, "assistant_reply": _kisalt(cevap, EN_COK_CEVAP)},
"questions": {k: {"type": "noul", "instructions": v} for k, v in SORU.items()}} "questions": {k: {"type": "noul", "instructions": v} for k, v in SORU.items()}}
try: try:
yanitlar = (gonder(govde, key, sure) or {}).get("answers") or {} yanitlar = (gonder(govde, key, sure) or {}).get("answers") or {}
sonuc = {k: float(yanitlar[k]["noul"]) for k in SORU} return {k: float(yanitlar[k]["noul"]) for k in SORU}
except Exception: except Exception:
with _KILIT:
_DEVRE["hata"] += 1
if _DEVRE["hata"] >= DEVRE_HATA:
_DEVRE.update(hata=0, kadar=simdi + DEVRE_SN)
return None return None
with _KILIT:
_DEVRE["hata"] = 0
return sonuc
def karar(puan): def karar(puan):
+10 -1
View File
@@ -876,7 +876,7 @@ class H(http.server.BaseHTTPRequestHandler):
Gecerse oldugu gibi verilir; gecmezse atilir ve ayni adimi siradaki katman yapar (ac(ad): (resp, rewriter, 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.""" tag)). Son katmanin cevabi sorulmadan akar. Beklerken SSE yorum satiri gider ki Codex akisi kopmus saymasin."""
self._akis_basligi(resp, resp.status) self._akis_basligi(resp, resp.status)
kalan, son_yazi = list(sira), time.time() kalan, son_yazi, katmanda = list(sira), time.time(), False
def w(b): def w(b):
if b: if b:
@@ -908,6 +908,14 @@ class H(http.server.BaseHTTPRequestHandler):
gecmedi = jev_denetim.karar(puan) gecmedi = jev_denetim.karar(puan)
log(f"{tag} katman denetimi: ret={puan['ret']:.2f} sart={puan['sart']:.2f} -> " 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)") f"{'GECMEDI' if gecmedi else 'gecti'} ({time.time() - t0:.1f} sn, {len(metin)} karakter)")
elif katmanda:
# Katman cevap yerine hata dondurduyse (or. arac cagrisi desteklemeyen model "upstream 400")
# acilamamis sayilir; hata cevap diye verilirse Codex ayni adimi bastan dener ve tur cevapsiz kalir.
govde = b"".join(parcalar)
if (b"event: error" in govde or b'"type":"error"' in govde or b'"type": "error"' in govde
or b"response.failed" in govde):
gecmedi = True
log(f"{tag} katman denetimi: katman hata dondurdu, siradakine geciliyor: {govde[-200:]!r}")
yeni = None yeni = None
while gecmedi and kalan and yeni is None: while gecmedi and kalan and yeni is None:
ad = kalan.pop(0) ad = kalan.pop(0)
@@ -918,6 +926,7 @@ class H(http.server.BaseHTTPRequestHandler):
if yeni is None: if yeni is None:
break break
resp, rewriter, tag = yeni resp, rewriter, tag = yeni
katmanda = True
log(f"{tag} katman denetimi: adim bu katmana verildi") log(f"{tag} katman denetimi: adim bu katmana verildi")
if not kalan: if not kalan:
return self._stream(resp, resp.status, tag, rewriter, izle, basliksiz=True) return self._stream(resp, resp.status, tag, rewriter, izle, basliksiz=True)
@@ -86,9 +86,6 @@ class Istek(unittest.TestCase):
class Sor(unittest.TestCase): class Sor(unittest.TestCase):
def setUp(self):
jev_denetim._DEVRE.update(hata=0, kadar=0.0)
def test_request_shape_and_scores(self): def test_request_shape_and_scores(self):
seen = {} seen = {}
@@ -100,16 +97,15 @@ class Sor(unittest.TestCase):
self.assertEqual(seen["govde"]["state"]["user_request"], "istek") self.assertEqual(seen["govde"]["state"]["user_request"], "istek")
self.assertLess(len(seen["govde"]["state"]["assistant_reply"]), 6100) self.assertLess(len(seen["govde"]["state"]["assistant_reply"]), 6100)
def test_failures_return_none_and_open_the_breaker(self): def test_failures_return_none_every_time(self):
calls = [] calls = []
def bozuk(govde, key, sure): def bozuk(govde, key, sure):
calls.append(1) calls.append(1)
raise OSError("ulasilamadi") raise OSError("ulasilamadi")
for _ in range(jev_denetim.DEVRE_HATA): for _ in range(5):
self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk, simdi=1000.0)) self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk))
self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk, simdi=1001.0)) self.assertEqual(len(calls), 5)
self.assertEqual(len(calls), jev_denetim.DEVRE_HATA)
def test_key_is_read_from_env_or_file(self): def test_key_is_read_from_env_or_file(self):
self.assertEqual(jev_denetim.anahtar({"TYPESAFE_API_KEY": " a "}), "a") self.assertEqual(jev_denetim.anahtar({"TYPESAFE_API_KEY": " a "}), "a")
@@ -208,6 +204,14 @@ class Akis(unittest.TestCase):
self.assertEqual(self.opened, ["Katman-2", "Katman-3"]) self.assertEqual(self.opened, ["Katman-2", "Katman-3"])
self.assertEqual(self.sent(), self.cevap["Katman-3"]) self.assertEqual(self.sent(), self.cevap["Katman-3"])
def test_a_layer_that_answers_with_an_error_is_skipped(self):
self.puanlar = [{"ret": 0.9, "sart": 0.0}]
self.cevap["Katman-2"] = b'event: error\ndata: {"type":"error","error":{"type":"upstream_error","message":"upstream 400"}}\n\n'
self.calistir(sse("hayir"))
self.assertEqual(self.opened, ["Katman-2", "Katman-3"])
self.assertEqual(self.sent(), self.cevap["Katman-3"])
self.assertNotIn(b"upstream 400", self.h.wfile.getvalue())
def test_a_step_without_text_is_not_sent_to_jev(self): def test_a_step_without_text_is_not_sent_to_jev(self):
body = b'event: response.output_item.done\ndata: {"type": "response.output_item.done", "item": {"type": "function_call"}}\n\n' + sse() body = b'event: response.output_item.done\ndata: {"type": "response.output_item.done", "item": {"type": "function_call"}}\n\n' + sse()
self.calistir(body) self.calistir(body)