feat(codex-bridge): the AITURK work line is part of Codex Baglama

The instruction is added for Codex Desktop whenever this computer has an AITURK
command that can send work (aiturk is); no separate switch, no bridge.json entry.
The bridge fills in the chat id; the command runs in Codex's own folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-11 03:31:49 +03:00
1 parent 615fedde01
commit 48103b9ad3
3 files changed
+122 -17

No files matched your search

+21 -2
View File
@@ -246,6 +246,23 @@ def catalog_refresh_loop():
threading.Thread(target=catalog_refresh_loop, daemon=True).start()
# ---- AITURK is hatti: isi gonderebilen AITURK komutu (is_hatti.py). Kurulum sonradan gelebilir: yoksa 2 dk'da bir bakilir.
HAT_KOMUT = [None]
def hat_komut_loop():
while True:
try:
if (CFG.get("aiturk_hat") or {}).get("enabled") is not False:
bulunan = is_hatti.komut_bul()
if bulunan != HAT_KOMUT[0]:
HAT_KOMUT[0] = bulunan
log(f"AITURK is hatti: {'acik, komut ' + bulunan if bulunan else 'kapali (aiturk is komutu yok)'}")
except Exception as e:
log(f"AITURK is hatti komutu aranamadi: {type(e).__name__}: {e}")
time.sleep(600 if HAT_KOMUT[0] else 120)
threading.Thread(target=hat_komut_loop, daemon=True).start()
LAST_MODELS = {} # hesap kimligi -> son basarili model listesi (chatgpt.com hata verirse bu verilir)
CACHE_DIR = os.path.join(LOGDIR, "son-liste")
@@ -913,7 +930,8 @@ class H(http.server.BaseHTTPRequestHandler):
durum, _, sayi = (IDE_DURUM[0] or "kapali, 0 model").partition(", ")
return self._send_json(200, {"ok": ZSTD_OK, "surum": SURUM, "kod": KOD, "zstd": ZSTD_OK, "ide_durum": durum,
"ide_model": int((sayi.split() or ["0"])[0]),
"ozet": bool((CFG.get("ozet_kopru") or {}).get("enabled", False))})
"ozet": bool((CFG.get("ozet_kopru") or {}).get("enabled", False)),
"is_hatti": bool(HAT_KOMUT[0])})
if self.command == "POST" and path.rstrip("/").endswith("/stop"):
self._send_json(200, {"ok": True})
log("AITURK IDE istegiyle kapatiliyor")
@@ -1272,7 +1290,8 @@ class H(http.server.BaseHTTPRequestHandler):
# Model, sohbetin modelinin soylenerek degistirilebildigini bilsin; yoksa "degistiremem" diyor.
if CFG.get("sesle_model", True) and CFG.get("model_bilgi", True) and sohbet and model_gecis.bilgi_ekle(req):
govde_degisti = True
if is_hatti.masaustu_mu(kaynak) and is_hatti.ekle(req, is_hatti.talimat(CFG.get("aiturk_hat"))):
if is_hatti.masaustu_mu(kaynak) and is_hatti.ekle(
req, is_hatti.talimat(CFG.get("aiturk_hat"), HAT_KOMUT[0], sohbet)):
govde_degisti = True
except Exception as e:
log(f"[{n} {slug}] is hatti talimati atlandi: {type(e).__name__}: {e}")
+62 -12
View File
@@ -1,16 +1,21 @@
"""Codex IDE'ye "is kucuk degilse AITURK yapacak" talimati (11 Ekim 2026).
Kullanici karari: talimat yalniz Codex IDE'nin (masaustu uygulamasi) gordugu sistem talimatinda durur; Codex CLI
talimati hic gormez, varligindan haberi olmaz. Karari secili model verir; kucuk modellerin yanilmasi kabul edilir,
ayri bir yazilimla onune gecilmez.
Kullanici karari: Codex Baglama acikken talimat Codex IDE'nin (masaustu uygulamasi) gordugu sistem talimatinda durur;
Codex CLI talimati hic gormez, varligindan haberi olmaz. Karari secili model verir; kucuk modellerin yanilmasi kabul
edilir, ayri bir yazilimla onune gecilmez.
Bu yuzden talimat hicbir dosyaya yazilmaz (AGENTS.md'yi CLI da okur): kopru, yalniz masaustu uygulamasindan gelen
isteklere, istek gecerken ekler. Istemci `originator` basligindan ayirt edilir (olcum 11 Ekim 2026: masaustu
"Codex Desktop", etkilesimli CLI "codex-tui", `codex exec` "codex_exec").
Ayar (bridge.json): "aiturk_hat": {"enabled": true, "komut": "<isi AITURK'e gonderen komut>", "talimat": "<istege bagli>"}.
Komut tanimli degilse talimat eklenmez: gonderme yolu olmayan bir "AITURK'e gonder" talimati modeli yaniltir.
Hat, Codex Baglama'nin parcasidir: ayri bir dugmesi yoktur, bu bilgisayarda isi gonderebilen bir AITURK komutu
(`aiturk is`) bulundugu surece aciktir. Komut yoksa talimat eklenmez: gonderme yolu olmayan bir "AITURK'e gonder"
talimati modeli yaniltir. Ayar (bridge.json, istege bagli): "aiturk_hat": {"enabled": false} kapatir;
{"komut": "..."} komutu elle verir; {"talimat": "..."} metni degistirir.
"""
import os
import shutil
import subprocess
MASAUSTU = {"codex desktop"}
ISARET = "[AITURK iş hattı]"
@@ -18,9 +23,10 @@ VARSAYILAN = (
ISARET + " Bu Codex, AITURK'e bağlı. Şu kurala göre çalış:\n"
"1. Basit soruyu, bilgi isteğini ya da tek küçük düzeltmeyi kendin yap.\n"
"2. Kullanıcı \"sen yap\" derse işi kendin yap.\n"
"3. İş küçük değilse (birden çok dosya, birkaç adım, yeni özellik, araştırma gerektiren iş) kendin yapma; "
"işi şu komutla AITURK'e gönder, bitmesini bekle ve sonucu kullanıcıya kısaca aktar:\n{komut}\n"
"Emin değilsen işi küçük say ve kendin yap."
"3. İş küçük değilse (birden çok dosya, birkaç adım, yeni özellik, araştırma gerektiren iş) kendin yapma. "
"İşin tam metnini (kullanıcının isteği ve gereken bağlam) UTF-8 bir dosyaya yaz, işi şu komutla AITURK'e gönder, "
"bitmesini bekle ve sonucu kullanıcıya kısaca aktar:\n{komut}\n"
"Komut \"işi sen yap\" derse ya da hata verirse işi kendin yap. Emin değilsen işi küçük say ve kendin yap."
)
@@ -28,11 +34,55 @@ def masaustu_mu(originator):
return str(originator or "").strip().lower() in MASAUSTU
def talimat(ayar):
"""Eklenecek metin; hat kapaliysa ya da komut yoksa None."""
if not isinstance(ayar, dict) or not ayar.get("enabled"):
def adaylar(ortam=None):
"""Isi gonderebilecek AITURK komutu adaylari, oncelik sirasiyla (kurulu AITURK, PATH, hat deneme kurulumu)."""
ortam = os.environ if ortam is None else ortam
yerel = ortam.get("LOCALAPPDATA") or ""
liste = []
if yerel:
liste.append(os.path.join(yerel, "TurkServis", "AITURK", "program", "bin", "aiturk.cmd"))
bulunan = shutil.which("aiturk")
if bulunan:
liste.append(bulunan)
if yerel:
liste.append(os.path.join(yerel, "TurkServis", "AITURK-is-hatti", "Scripts", "aiturk.exe"))
return [y for i, y in enumerate(liste) if y and y not in liste[:i]]
def destekliyor(yol, calistir=subprocess.run):
"""Bu AITURK `is` komutunu taniyor mu? (Eski surumler tanimaz: "No such command 'is'.")"""
if not os.path.isfile(yol):
return False
try:
sonuc = calistir([yol, "is", "--help"], capture_output=True, timeout=40, cwd=os.path.dirname(yol),
creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0))
return sonuc.returncode == 0
except Exception:
return False
def komut_bul(ortam=None, destek=destekliyor):
"""Isi gonderebilen ilk AITURK komutunun yolu; yoksa None."""
for yol in adaylar(ortam):
if destek(yol):
return yol
return None
def komut_satiri(yol, sohbet=""):
"""Modelin calistiracagi hazir satir. Sohbet kimligi kopruden gelir (sohbetler karismasin); klasor verilmez:
komut Codex'in o anki klasorunde calisir, AITURK de isi ayni klasorde yapar."""
sohbet = "".join(c for c in str(sohbet or "") if c.isalnum() or c in "-_")
return f'"{yol}" is' + (f" --sohbet {sohbet}" if sohbet else "") + ' --dosya "<iş metnini yazdığın dosya>"'
def talimat(ayar, bulunan=None, sohbet=""):
"""Eklenecek metin; hat kapaliysa ya da gonderme komutu yoksa None.
bulunan: bu bilgisayarda bulunan AITURK komutunun yolu (komut_bul); ayardaki "komut" onun onune gecer."""
ayar = ayar if isinstance(ayar, dict) else {}
if ayar.get("enabled") is False:
return None
komut = str(ayar.get("komut") or "").strip()
komut = str(ayar.get("komut") or "").strip() or (komut_satiri(bulunan, sohbet) if bulunan else "")
if not komut:
return None
return str(ayar.get("talimat") or VARSAYILAN).replace("{komut}", komut)
@@ -10,16 +10,52 @@ class Hat(unittest.TestCase):
for other in ("codex-tui", "codex_exec", "codex_cli_rs", "", None, "Codex Desktop Helper"):
self.assertFalse(h.masaustu_mu(other), other)
def test_no_instruction_without_the_switch_or_without_a_send_command(self):
def test_no_instruction_when_switched_off_or_without_a_send_command(self):
self.assertIsNone(h.talimat(None))
self.assertIsNone(h.talimat({"enabled": False, "komut": "aiturk gonder"}))
self.assertIsNone(h.talimat({"enabled": True}))
self.assertIsNone(h.talimat({}))
self.assertIsNone(h.talimat({"enabled": True, "komut": " "}))
self.assertIsNone(h.talimat({"enabled": False, "komut": "aiturk gonder"}))
self.assertIsNone(h.talimat({"enabled": False}, "C:/a/aiturk.exe", "s1"))
text = h.talimat({"enabled": True, "komut": "aiturk gonder --dosya is.md"})
self.assertIn("aiturk gonder --dosya is.md", text)
self.assertIn("sen yap", text)
self.assertEqual(h.talimat({"enabled": True, "komut": "x", "talimat": "ozel {komut}"}), "ozel x")
def test_on_by_default_once_a_send_command_exists_on_this_computer(self):
text = h.talimat(None, "C:/Program/aiturk.exe", "019a-bc_d")
self.assertIn('"C:/Program/aiturk.exe" is --sohbet 019a-bc_d --dosya', text)
self.assertIn('"C:/Program/aiturk.exe" is --dosya', h.talimat({}, "C:/Program/aiturk.exe", ""))
# Sohbet kimligi komut satirina yazilir: kabuk karakteri tasiyamaz.
self.assertIn("--sohbet abrm-rf ", h.komut_satiri("x", 'a"b; rm -rf /'))
# Ayardaki komut bulunanin onune gecer.
self.assertIn("elle", h.talimat({"komut": "elle"}, "C:/Program/aiturk.exe"))
def test_the_first_candidate_that_knows_the_command_is_used(self):
import os
import tempfile
with tempfile.TemporaryDirectory() as d:
eski = os.path.join(d, "TurkServis", "AITURK", "program", "bin", "aiturk.cmd")
yeni = os.path.join(d, "TurkServis", "AITURK-is-hatti", "Scripts", "aiturk.exe")
for yol in (eski, yeni):
os.makedirs(os.path.dirname(yol))
open(yol, "w").close()
ortam = {"LOCALAPPDATA": d}
self.assertEqual(h.adaylar(ortam)[0], eski)
self.assertEqual(h.komut_bul(ortam, destek=lambda y: y == yeni), yeni)
self.assertEqual(h.komut_bul(ortam, destek=lambda y: True), eski)
self.assertIsNone(h.komut_bul(ortam, destek=lambda y: False))
class Sonuc:
returncode = 2
self.assertFalse(h.destekliyor(eski, calistir=lambda *a, **k: Sonuc()))
Sonuc.returncode = 0
self.assertTrue(h.destekliyor(eski, calistir=lambda *a, **k: Sonuc()))
self.assertFalse(h.destekliyor(os.path.join(d, "yok.exe"), calistir=lambda *a, **k: Sonuc()))
def patlar(*a, **k):
raise OSError("x")
self.assertFalse(h.destekliyor(eski, calistir=patlar))
def test_instruction_is_put_first_once_and_never_repeated(self):
req = {"input": [{"type": "message", "role": "user", "content": "selam"}]}
text = h.talimat({"enabled": True, "komut": "aiturk gonder"})