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>
136 lines
5.4 KiB
Python
136 lines
5.4 KiB
Python
"""Katman denetimi: Jev, katman combosunun her adimdaki cevabini gecirir ya da gecirmez (11 Ekim 2026).
|
|
|
|
Kullanici karari (11 Ekim 2026): "Jev kati olsun. Af yok istisna yok. 1.Katman combosu Jev'e gelirse Jev bunu
|
|
gecirmezse 2.Katmana yonlendirecek. 2.Katman gecmezse 3.Katmana, 3.Katman gecmezse 4.Katmana. 4.Katman combosu
|
|
gelirse Jev bunu sorgulamadan gecirecek."
|
|
|
|
Katmanlar OmniRoute combolaridir (KATMAN); kopru onlari yalniz adiyla cagirir. Jev (TypeSafe System One) metin
|
|
uretmez, sorulan evet/hayir sorularina olasilik verir. Kural tektir ve istisnasi yoktur: cevap istegi yapmiyorsa
|
|
(ret) ya da sormadan kendi sartlariyla degistiriyorsa (sart) adim gecmez ve ayni adimi bir sonraki katman yapar.
|
|
Metni olmayan (yalniz arac cagiran) adimda sorulacak cevap yoktur. Jev'e ulasilamazsa cevap oldugu gibi verilir.
|
|
"""
|
|
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"
|
|
KATMAN = ("Katman-1", "Katman-2", "Katman-3", "Katman-4")
|
|
ESIK = {"ret": 0.5, "sart": 0.7}
|
|
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."),
|
|
}
|
|
_KILIT = threading.Lock()
|
|
_DEVRE = {"hata": 0, "kadar": 0.0}
|
|
_ANAHTAR = {"okundu": False, "deger": ""}
|
|
|
|
|
|
def sonrakiler(hedef):
|
|
"""Bu katmandan sonra sirayla denenecek katmanlar. Son katman ve katman olmayan model icin bos: Jev'e sorulmaz."""
|
|
ad = str(hedef or "")
|
|
return list(KATMAN[KATMAN.index(ad) + 1:]) if ad in KATMAN else []
|
|
|
|
|
|
def anahtar(ortam=None, dosyalar=None):
|
|
"""TypeSafe anahtari: ortam degiskeni, sonra ~/.typesafe/typesafe.env. Yoksa ""."""
|
|
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 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)},
|
|
"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):
|
|
"""True: adim gecmez, sonraki katman yapar. Istisna yok."""
|
|
return puan["ret"] >= ESIK["ret"] or puan["sart"] >= ESIK["sart"]
|