feat(codex-bridge): per-step check with Jev, blocked steps go to a fallback model
User decision (11 Oct 2026): every step of an added model is checked in the bridge; Jev only passes or blocks; a blocked step is redone by Uncensored-Uygulama and the next step goes back to the selected model. The bridge buffers the step's answer, asks Jev four yes/no questions and decides in code: blocked when the answer refuses or dodges the request, or changes it with its own conditions without asking; passed when it reports a concrete technical obstacle, asks the user a question, or has no text (tool calls only). While buffering the client gets SSE comment lines. Jev unreachable or fallback unavailable: the first answer is delivered. Codex's own models do not reach the bridge and are not checked. Also logs the shape of each forwarded request (not its content): the recurring "upstream 400" turned out to be Codex's trailing configuration_update item. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c8993d58cc
commit
5556ad11af
6 files changed
+451
-5
No files matched your search
@@ -0,0 +1,155 @@
|
||||
"""Adim denetimi: ek modelin her adimdaki cevabini Jev gecirir ya da gecirmez (11 Ekim 2026).
|
||||
|
||||
Kullanici karari (11 Ekim 2026): "Bu kopruye Jev koy, her model her adimda kontrol etsin ve yakaladigini qwen 3.8
|
||||
obliterated thinking versin." / "Bir prompt cok adimli olabilir; her adim kontrol edilsin. Jev sadece geciren ya da
|
||||
gecirmeyen; gecirmezse 3.8 obliterated thinking." Ardindan (ayni gun): "obliterated:thinking yerine Uncensored-Uygulama yapar
|
||||
misin" -> yedek, Uncensored-Uygulama combosudur. Yani denetim adim basinadir: Jev'in gecirmedigi adimi yedek model
|
||||
yapar, sonraki adim yine secili modele gider ve yine denetlenir.
|
||||
|
||||
Jev (TypeSafe System One) metin uretmez; bir duruma sorulan evet/hayir sorularina olasilik verir (olcum 11 Ekim
|
||||
2026: cagri basina ~0,4 sn, 13 gercek ornegin 13'u dogru ayrildi). Kural kodda durur:
|
||||
- yakalanir: cevap istegi yapmiyor/soylemiyor (ret, kacamak, konuyu degistirme) ya da istegi sormadan kendi
|
||||
sartlariyla degistiriyor;
|
||||
- yakalanmaz: somut bir teknik engel bildiren cevap (hata, eksik dosya/arac/yetki) ve kullaniciya soru ya da onay
|
||||
soran cevap; metni olmayan (yalniz arac cagiran) adim.
|
||||
|
||||
Jev'e ulasilamazsa cevap oldugu gibi gecer (is durmaz); art arda hatada bir sure hic sorulmaz.
|
||||
Codex'in kendi modelleri kopruye ugramadigi icin bu denetimin disindadir.
|
||||
|
||||
Ayar (bridge.json, istege bagli): "jev_denetim": {"enabled": false} kapatir; "hedef" yedek modelin Codex adi;
|
||||
"ret", "sart", "teknik", "soru" esikleri; "sure" saniye.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
import urllib.request
|
||||
|
||||
ADRES = "https://api.typesafe.ai/v1/systemone"
|
||||
MODEL = "jev-1.13.0"
|
||||
HEDEF = "ide/Uncensored-Uygulama"
|
||||
ESIK = {"ret": 0.7, "sart": 0.9, "teknik": 0.5, "soru": 0.5}
|
||||
SURE = 6.0
|
||||
EN_COK_ISTEK = 3000
|
||||
EN_COK_CEVAP = 6000
|
||||
DEVRE_HATA = 3 # art arda bu kadar hatadan sonra
|
||||
DEVRE_SN = 300 # bu kadar sure Jev'e sorulmaz
|
||||
SORU = {
|
||||
"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."),
|
||||
"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."),
|
||||
"teknik": ("The assistant reports a concrete technical obstacle as the reason: an error message, a failed command, "
|
||||
"a missing file, tool, permission, connection or piece of information."),
|
||||
"soru": ("The assistant's reply is mainly a question to the user: it asks for a clarification, a choice or an "
|
||||
"approval and waits for the user's answer before doing anything."),
|
||||
}
|
||||
_KILIT = threading.Lock()
|
||||
_DEVRE = {"hata": 0, "kadar": 0.0}
|
||||
_ANAHTAR = {"okundu": False, "deger": ""}
|
||||
|
||||
|
||||
def anahtar(ortam=None, dosyalar=None):
|
||||
"""TypeSafe anahtari: ortam degiskeni, sonra ~/.typesafe/typesafe.env. Yoksa "" (denetim kapali sayilir)."""
|
||||
ortam = os.environ if ortam is None else ortam
|
||||
deger = str(ortam.get("TYPESAFE_API_KEY") or "").strip()
|
||||
if deger:
|
||||
return deger
|
||||
if dosyalar is None:
|
||||
if _ANAHTAR["okundu"]:
|
||||
return _ANAHTAR["deger"]
|
||||
dosyalar = [os.path.join(os.path.expanduser("~"), ".typesafe", "typesafe.env")]
|
||||
onbellek = True
|
||||
else:
|
||||
onbellek = False
|
||||
for yol in dosyalar:
|
||||
try:
|
||||
with open(yol, encoding="utf-8", errors="replace") as f:
|
||||
for satir in f:
|
||||
m = re.match(r"^\s*TYPESAFE_API_KEY\s*=\s*(.*)$", satir)
|
||||
if m:
|
||||
deger = m.group(1).strip().strip('"').strip("'")
|
||||
break
|
||||
except OSError:
|
||||
continue
|
||||
if deger:
|
||||
break
|
||||
if onbellek:
|
||||
_ANAHTAR.update(okundu=True, deger=deger)
|
||||
return deger
|
||||
|
||||
|
||||
def _metin(oge):
|
||||
icerik = oge.get("content")
|
||||
if isinstance(icerik, str):
|
||||
return icerik
|
||||
return "".join(str(p.get("text") or "") for p in icerik or [] if isinstance(p, dict))
|
||||
|
||||
|
||||
def son_istek(req):
|
||||
"""Kullanicinin bu turdaki istegi: son kullanici mesaji. Sesli aktarimda yalniz <input> icindeki soz;
|
||||
baska sarmalli sistem mesajlari (kanca baglami) atlanir."""
|
||||
for oge in reversed(req.get("input") or []):
|
||||
if not (isinstance(oge, dict) and oge.get("type", "message") == "message" and oge.get("role") == "user"):
|
||||
continue
|
||||
metin = _metin(oge).strip()
|
||||
m = re.search(r"<realtime_delegation>.*?<input>(.*?)</input>", metin, re.S)
|
||||
if m:
|
||||
return m.group(1).strip()[:EN_COK_ISTEK]
|
||||
if metin and not metin.startswith("<"):
|
||||
return metin[:EN_COK_ISTEK]
|
||||
return ""
|
||||
|
||||
|
||||
def _kisalt(metin, sinir):
|
||||
if len(metin) <= sinir:
|
||||
return metin
|
||||
bas = sinir * 2 // 3
|
||||
return metin[:bas] + "\n[...]\n" + metin[-(sinir - bas):]
|
||||
|
||||
|
||||
def _gonder(govde, key, sure):
|
||||
istek = urllib.request.Request(ADRES, data=json.dumps(govde).encode("utf-8"), method="POST",
|
||||
headers={"Authorization": "Bearer " + key, "Content-Type": "application/json"})
|
||||
with urllib.request.urlopen(istek, timeout=sure) as yanit:
|
||||
return json.load(yanit)
|
||||
|
||||
|
||||
def sor(istek, cevap, key, sure=SURE, gonder=_gonder, simdi=None):
|
||||
"""Jev'e dort soruyu sorar. Donus: {"ret","sart","teknik","soru"} 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)},
|
||||
"questions": {k: {"type": "noul", "instructions": v} for k, v in SORU.items()}}
|
||||
try:
|
||||
yanitlar = (gonder(govde, key, sure) or {}).get("answers") or {}
|
||||
sonuc = {k: float(yanitlar[k]["noul"]) for k in SORU}
|
||||
except Exception:
|
||||
with _KILIT:
|
||||
_DEVRE["hata"] += 1
|
||||
if _DEVRE["hata"] >= DEVRE_HATA:
|
||||
_DEVRE.update(hata=0, kadar=simdi + DEVRE_SN)
|
||||
return None
|
||||
with _KILIT:
|
||||
_DEVRE["hata"] = 0
|
||||
return sonuc
|
||||
|
||||
|
||||
def karar(puan, ayar=None):
|
||||
"""True: adim gecmez (yedek model yapar). Esikler ayardan degistirilebilir."""
|
||||
e = dict(ESIK)
|
||||
e.update({k: float(v) for k, v in (ayar or {}).items() if k in ESIK})
|
||||
if puan["soru"] >= e["soru"]:
|
||||
return False # kullaniciya soru/onay soruyor: kullanici cevaplar
|
||||
if puan["ret"] >= e["ret"] and puan["teknik"] < e["teknik"]:
|
||||
return True # yapmiyor / soylemiyor (teknik engel degil)
|
||||
return puan["sart"] >= e["sart"] # sormadan kendi sartlariyla degistirdi
|
||||
|
||||
|
||||
def ayar_oku(cfg):
|
||||
"""(acik, hedef slug, ayar sozlugu)."""
|
||||
ayar = cfg if isinstance(cfg, dict) else {}
|
||||
return ayar.get("enabled", True) is not False, str(ayar.get("hedef") or HEDEF), ayar
|
||||
Reference in new issue
Block a user