- Default routing rule (user decision, 15 Oct 2026): repeating/scheduled work goes to the AITURK IDE bot as a cron job; coding stays in Codex (itself or its subagents); 'Codex' or 'sen yap' keeps everything in Codex. - Settings > Codex Bağlama: choice (recommended / send large work / never / custom text) with a text box and restore-default; written to bridge.json aiturk_hat. - Bridge re-reads aiturk_hat when bridge.json changes: no restart. IDE apply keeps aiturk_hat instead of wiping it. - Bridge version 20, IDE 1.0.0-beta.40. Jev untouched.
139 lines
7.3 KiB
Python
139 lines
7.3 KiB
Python
"""Codex IDE'ye "is kucuk degilse AITURK yapacak" talimati (11 Ekim 2026).
|
||
|
||
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").
|
||
|
||
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 ({komut}, {zamanla} yer tutuculari);
|
||
{"secim": "onerilen"|"buyuk"|"kapali"|"ozel"} AITURK IDE ayarlar ekranindan yazilir. Kopru ayari her istekte
|
||
dosyadan tazeler (kopru.py hat_ayari), yeniden baslatma gerekmez.
|
||
"""
|
||
import os
|
||
import shutil
|
||
import subprocess
|
||
|
||
MASAUSTU = {"codex desktop"}
|
||
ISARET = "[AITURK iş hattı]"
|
||
ESKI = (
|
||
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. "
|
||
"İş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."
|
||
)
|
||
# Kullanici karari, 15 Ekim 2026: tekrarli/zamanli isler AITURK IDE botuna, kodlama Codex'te kalir.
|
||
VARSAYILAN = (
|
||
ISARET + " Bu Codex, AITURK'e bağlı. İş dağıtımı kuralı:\n"
|
||
"1. Tekrarlı, zamanlanmış ya da sürekli açık kalacak işleri (her gün şu saatte, saat başı, haftada bir, "
|
||
"'7 gün her gün baksın' gibi) AITURK IDE'deki bota zamanlanmış iş olarak ver. PowerShell'de tek satır:\n{zamanla}\n"
|
||
"Belirli süreli işte (ör. 7 gün her gün) --repeat ile tekrar sayısını ver. HERMES_HOME kısmını atlama. "
|
||
"Aynı satırla 'cron list' çalıştırıp işin kaydını doğrula; kullanıcıya işin adını, zamanlamasını ve ilk çalışma "
|
||
"zamanını söyle. İşler AITURK IDE açıkken çalışır.\n"
|
||
"2. Kodlama işlerini AITURK'e verme: kolaysa kendin ya da kendi alt ajanınla yap, zorsa kendi alt ajan ekibine dağıt.\n"
|
||
"3. Basit soru, bilgi isteği ve küçük düzeltmeleri kendin yap.\n"
|
||
"4. Kullanıcı 'Codex' ya da 'sen yap' derse hiçbir işi devretme. Komut hata verirse işi kendin yap."
|
||
)
|
||
# Ayarlar ekranindaki hazir secenekler (bridge.json "aiturk_hat": {"secim": ...}).
|
||
SECIMLER = {"onerilen": VARSAYILAN, "buyuk": ESKI}
|
||
|
||
|
||
def zamanla_satiri(ortam=None):
|
||
"""AITURK IDE botuna zamanlanmis is veren hazir satir; IDE ajan klasoru yoksa ''."""
|
||
ortam = os.environ if ortam is None else ortam
|
||
ev = str(ortam.get("HERMES_HOME") or "").strip()
|
||
if not ev:
|
||
return ""
|
||
exe = os.path.join(ev, "bin", "hermes.exe")
|
||
return (f"$env:HERMES_HOME='{ev}'; & '{exe}' cron create --name '<kısa ad>' --workdir '<işin klasörü>' "
|
||
"'<zamanlama: 30m, every 2h ya da 0 9 * * *>' '<işin tam ve kendi başına anlaşılır talimatı>'")
|
||
|
||
|
||
def masaustu_mu(originator):
|
||
return str(originator or "").strip().lower() in MASAUSTU
|
||
|
||
|
||
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="", zamanla=None):
|
||
"""Eklenecek metin; hat kapaliysa ya da metnin istedigi gonderme yolu yoksa None.
|
||
bulunan: bu bilgisayarda bulunan AITURK komutunun yolu (komut_bul); ayardaki "komut" onun onune gecer.
|
||
zamanla: AITURK IDE botuna zamanlanmis is veren satir (zamanla_satiri); None ise ortamdan bulunur.
|
||
Secim (ayarlar ekrani): "onerilen" (varsayilan), "buyuk" (eski davranis), "kapali", "ozel" ("talimat" metni).
|
||
Secimsiz eski ayarda "talimat" doluysa ozel sayilir."""
|
||
ayar = ayar if isinstance(ayar, dict) else {}
|
||
secim = str(ayar.get("secim") or "").strip()
|
||
if ayar.get("enabled") is False or secim == "kapali":
|
||
return None
|
||
if secim in SECIMLER:
|
||
metin = SECIMLER[secim]
|
||
else:
|
||
metin = str(ayar.get("talimat") or "").strip() or VARSAYILAN
|
||
komut = str(ayar.get("komut") or "").strip() or (komut_satiri(bulunan, sohbet) if bulunan else "")
|
||
zamanla = zamanla_satiri() if zamanla is None else zamanla
|
||
if ("{komut}" in metin and not komut) or ("{zamanla}" in metin and not zamanla):
|
||
return None
|
||
return metin.replace("{komut}", komut).replace("{zamanla}", zamanla)
|
||
|
||
|
||
def ekle(req, metin):
|
||
"""Talimati istegin basina developer mesaji olarak koyar. True: eklendi (zaten varsa eklenmez)."""
|
||
girdi = req.get("input")
|
||
if not metin or not isinstance(girdi, list):
|
||
return False
|
||
for oge in girdi[:3]:
|
||
icerik = oge.get("content") if isinstance(oge, dict) else None
|
||
yazi = icerik if isinstance(icerik, str) else " ".join(str(p.get("text") or "") for p in icerik or [] if isinstance(p, dict))
|
||
if ISARET in yazi:
|
||
return False
|
||
girdi.insert(0, {"type": "message", "role": "developer", "content": [{"type": "input_text", "text": metin}]})
|
||
return True
|