Kopru: her adim Jev'e gider, sure ve boyut siniri yok
Yazisiz adimda cagrilan komut sorulur; kullanici mesaji bulunamasa da sorulur; Jev'e giden istek ve cevap kesilmez, bekleme suresi siniri yok. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ff53cafb5c
commit
7547de1852
3 files changed
+46
-25
No files matched your search
@@ -21,9 +21,6 @@ ADRES = "https://api.typesafe.ai/v1/systemone"
|
|||||||
MODEL = "jev-1.13.0"
|
MODEL = "jev-1.13.0"
|
||||||
KATMAN = ("Katman-1", "Katman-2", "Katman-3", "Katman-4")
|
KATMAN = ("Katman-1", "Katman-2", "Katman-3", "Katman-4")
|
||||||
ESIK = {"ret": 0.5, "sart": 0.7}
|
ESIK = {"ret": 0.5, "sart": 0.7}
|
||||||
SURE = 6.0
|
|
||||||
EN_COK_ISTEK = 3000
|
|
||||||
EN_COK_CEVAP = 6000
|
|
||||||
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."),
|
||||||
@@ -90,32 +87,44 @@ def son_istek(req):
|
|||||||
metin = _metin(oge).strip()
|
metin = _metin(oge).strip()
|
||||||
m = re.search(r"<realtime_delegation>.*?<input>(.*?)</input>", metin, re.S)
|
m = re.search(r"<realtime_delegation>.*?<input>(.*?)</input>", metin, re.S)
|
||||||
if m:
|
if m:
|
||||||
return m.group(1).strip()[:EN_COK_ISTEK]
|
return m.group(1).strip()
|
||||||
if metin and not metin.startswith("<"):
|
if metin and not metin.startswith("<"):
|
||||||
return metin[:EN_COK_ISTEK]
|
return metin
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def _kisalt(metin, sinir):
|
def komutlar(govde):
|
||||||
if len(metin) <= sinir:
|
"""Yazisi olmayan adimda Jev'e giden metin: modelin bu adimda cagirdigi araclar (ad ve arguman).
|
||||||
return metin
|
govde: ust kaynagin SSE yaniti (bayt). Arac cagrisi yoksa ""."""
|
||||||
bas = sinir * 2 // 3
|
satirlar = []
|
||||||
return metin[:bas] + "\n[...]\n" + metin[-(sinir - bas):]
|
for satir in govde.splitlines():
|
||||||
|
if not satir.startswith(b"data:") or b"response.output_item.done" not in satir:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
oge = json.loads(satir[5:]).get("item") or {}
|
||||||
|
except (ValueError, AttributeError):
|
||||||
|
continue
|
||||||
|
if isinstance(oge, dict) and str(oge.get("type") or "").endswith("_call"):
|
||||||
|
arguman = oge.get("arguments") or oge.get("input") or oge.get("action") or ""
|
||||||
|
if not isinstance(arguman, str):
|
||||||
|
arguman = json.dumps(arguman, ensure_ascii=False)
|
||||||
|
satirlar.append(f"[komut] {oge.get('name') or oge.get('type')}: {arguman}")
|
||||||
|
return "\n".join(satirlar)
|
||||||
|
|
||||||
|
|
||||||
def _gonder(govde, key, sure):
|
def _gonder(govde, key):
|
||||||
istek = urllib.request.Request(ADRES, data=json.dumps(govde).encode("utf-8"), method="POST",
|
istek = urllib.request.Request(ADRES, data=json.dumps(govde).encode("utf-8"), method="POST",
|
||||||
headers={"Authorization": "Bearer " + key, "Content-Type": "application/json"})
|
headers={"Authorization": "Bearer " + key, "Content-Type": "application/json"})
|
||||||
with urllib.request.urlopen(istek, timeout=sure) as yanit:
|
with urllib.request.urlopen(istek) as yanit:
|
||||||
return json.load(yanit)
|
return json.load(yanit)
|
||||||
|
|
||||||
|
|
||||||
def sor(istek, cevap, key, sure=SURE, gonder=_gonder):
|
def sor(istek, cevap, key, gonder=_gonder):
|
||||||
"""Jev'e sorar. Donus: {"ret", "sart"} olasiliklari | None (sorulamadi)."""
|
"""Jev'e sorar. Donus: {"ret", "sart"} olasiliklari | None (sorulamadi)."""
|
||||||
govde = {"model": MODEL, "state": {"user_request": istek, "assistant_reply": _kisalt(cevap, EN_COK_CEVAP)},
|
govde = {"model": MODEL, "state": {"user_request": istek, "assistant_reply": 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) or {}).get("answers") or {}
|
||||||
return {k: float(yanitlar[k]["noul"]) for k in SORU}
|
return {k: float(yanitlar[k]["noul"]) for k in SORU}
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -897,7 +897,9 @@ class H(http.server.BaseHTTPRequestHandler):
|
|||||||
okuyan.feed(chunk)
|
okuyan.feed(chunk)
|
||||||
if time.time() - son_yazi >= 10:
|
if time.time() - son_yazi >= 10:
|
||||||
w(b": denetim\n\n"); son_yazi = time.time()
|
w(b": denetim\n\n"); son_yazi = time.time()
|
||||||
metin = okuyan.metin.strip()
|
yazi = okuyan.metin.strip()
|
||||||
|
# Her adim Jev'e gider: yazi yoksa modelin bu adimda cagirdigi araclar sorulur.
|
||||||
|
metin = yazi or jev_denetim.komutlar(b"".join(parcalar))
|
||||||
gecmedi = False
|
gecmedi = False
|
||||||
if metin:
|
if metin:
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
@@ -907,8 +909,8 @@ class H(http.server.BaseHTTPRequestHandler):
|
|||||||
else:
|
else:
|
||||||
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{'' if yazi else ', yalniz komut'})")
|
||||||
elif b'_call"' not in b"".join(parcalar):
|
else:
|
||||||
# Bos adim: ne yazi var ne arac cagrisi (hata olayi da boyledir, or. "upstream 400"). Kabul
|
# Bos adim: ne yazi var ne arac cagrisi (hata olayi da boyledir, or. "upstream 400"). Kabul
|
||||||
# edilmez, siradaki katman yapar; bos yanit cevap diye verilirse Codex adimi bastan dener.
|
# edilmez, siradaki katman yapar; bos yanit cevap diye verilirse Codex adimi bastan dener.
|
||||||
gecmedi = True
|
gecmedi = True
|
||||||
@@ -1646,7 +1648,7 @@ class H(http.server.BaseHTTPRequestHandler):
|
|||||||
sonuc = self._stream(resp, resp.status, tag, akis)
|
sonuc = self._stream(resp, resp.status, tag, akis)
|
||||||
log(f"{tag} ozet kopru: {akis.sonuc_notu()}")
|
log(f"{tag} ozet kopru: {akis.sonuc_notu()}")
|
||||||
return sonuc
|
return sonuc
|
||||||
if jev_sira and jev_istek and resp.status == 200:
|
if jev_sira and resp.status == 200:
|
||||||
return self._denetimli_akis(resp, tag, rewriter, izle, jev_istek, jev_sira, jev_ac)
|
return self._denetimli_akis(resp, tag, rewriter, izle, jev_istek, jev_sira, jev_ac)
|
||||||
return self._stream(resp, resp.status, tag, rewriter, izle)
|
return self._stream(resp, resp.status, tag, rewriter, izle)
|
||||||
self._send_json(503, {"error": {"message": f"bridge: hedef ulasilamadi {last}"}})
|
self._send_json(503, {"error": {"message": f"bridge: hedef ulasilamadi {last}"}})
|
||||||
|
|||||||
@@ -89,18 +89,18 @@ class Sor(unittest.TestCase):
|
|||||||
def test_request_shape_and_scores(self):
|
def test_request_shape_and_scores(self):
|
||||||
seen = {}
|
seen = {}
|
||||||
|
|
||||||
def gonder(govde, key, sure):
|
def gonder(govde, key):
|
||||||
seen.update(govde=govde, key=key)
|
seen.update(govde=govde, key=key)
|
||||||
return {"answers": {k: {"type": "noul", "noul": 0.25} for k in jev_denetim.SORU}}
|
return {"answers": {k: {"type": "noul", "noul": 0.25} for k in jev_denetim.SORU}}
|
||||||
self.assertEqual(jev_denetim.sor("istek", "c" * 9000, "anahtar", gonder=gonder), {"ret": 0.25, "sart": 0.25})
|
self.assertEqual(jev_denetim.sor("istek", "c" * 9000, "anahtar", gonder=gonder), {"ret": 0.25, "sart": 0.25})
|
||||||
self.assertEqual(seen["key"], "anahtar")
|
self.assertEqual(seen["key"], "anahtar")
|
||||||
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.assertEqual(seen["govde"]["state"]["assistant_reply"], "c" * 9000)
|
||||||
|
|
||||||
def test_failures_return_none_every_time(self):
|
def test_failures_return_none_every_time(self):
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
def bozuk(govde, key, sure):
|
def bozuk(govde, key):
|
||||||
calls.append(1)
|
calls.append(1)
|
||||||
raise OSError("ulasilamadi")
|
raise OSError("ulasilamadi")
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
@@ -126,6 +126,7 @@ class Akis(unittest.TestCase):
|
|||||||
sahte.anahtar = lambda: "k"
|
sahte.anahtar = lambda: "k"
|
||||||
sahte.sor = self.sor
|
sahte.sor = self.sor
|
||||||
sahte.karar = jev_denetim.karar
|
sahte.karar = jev_denetim.karar
|
||||||
|
sahte.komutlar = jev_denetim.komutlar
|
||||||
env = {"jev_denetim": sahte, "yarim": yarim, "time": time, "http": __import__("http.client"),
|
env = {"jev_denetim": sahte, "yarim": yarim, "time": time, "http": __import__("http.client"),
|
||||||
"log": self.logs.append, "RESP_HOP": set(), "json": json}
|
"log": self.logs.append, "RESP_HOP": set(), "json": json}
|
||||||
adlar = ("_akis_basligi", "_denetimli_akis", "_stream")
|
adlar = ("_akis_basligi", "_denetimli_akis", "_stream")
|
||||||
@@ -212,11 +213,20 @@ class Akis(unittest.TestCase):
|
|||||||
self.assertEqual(self.sent(), self.cevap["Katman-3"])
|
self.assertEqual(self.sent(), self.cevap["Katman-3"])
|
||||||
self.assertNotIn(b"upstream 400", self.h.wfile.getvalue())
|
self.assertNotIn(b"upstream 400", self.h.wfile.getvalue())
|
||||||
|
|
||||||
def test_a_step_without_text_is_not_sent_to_jev(self):
|
KOMUT = (b'event: response.output_item.done\ndata: {"type": "response.output_item.done", "item": '
|
||||||
body = b'event: response.output_item.done\ndata: {"type": "response.output_item.done", "item": {"type": "function_call"}}\n\n' + sse()
|
b'{"type": "function_call", "name": "shell", "arguments": "{\\"cmd\\": \\"dir\\"}"}}\n\n')
|
||||||
|
|
||||||
|
def test_a_step_without_text_is_asked_with_its_tool_calls(self):
|
||||||
|
body = self.KOMUT + sse()
|
||||||
self.calistir(body)
|
self.calistir(body)
|
||||||
self.assertEqual(self.sent(), body)
|
self.assertEqual(self.sent(), body)
|
||||||
self.assertEqual(self.asked, [])
|
self.assertEqual(self.asked, ['[komut] shell: {"cmd": "dir"}'])
|
||||||
|
|
||||||
|
def test_a_blocked_step_without_text_goes_to_the_next_layer(self):
|
||||||
|
self.puanlar = [{"ret": 0.9, "sart": 0.0}]
|
||||||
|
self.calistir(self.KOMUT + sse())
|
||||||
|
self.assertEqual(self.opened, ["Katman-2"])
|
||||||
|
self.assertEqual(self.sent(), self.cevap["Katman-2"])
|
||||||
|
|
||||||
def test_an_empty_step_of_the_selected_model_goes_to_the_next_layer(self):
|
def test_an_empty_step_of_the_selected_model_goes_to_the_next_layer(self):
|
||||||
self.calistir(sse()) # no text, no tool call
|
self.calistir(sse()) # no text, no tool call
|
||||||
|
|||||||
Reference in new issue
Block a user