User decision (15 Oct 2026): repeating or scheduled work goes to AITURK; all other work, coding included, goes to one subagent (easy) or a subagent team or dynamic workflow (hard). The main model talks, dispatches and verifies.
138 lines
7.1 KiB
Python
138 lines
7.1 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 ver. İşin tam metnini UTF-8 bir dosyaya yaz ve şu komutla "
|
||
"gönder, sonucu kullanıcıya kısaca aktar:\n{komut}\n"
|
||
"2. Kodlama ve diğer işleri AITURK'e verme. Ana model işi kendisi yapmaz: kolay ya da tek parça işi tek bir alt "
|
||
"ajana, zor ya da çok parçalı işi alt ajan ekibine veya dinamik workflow'a ver. Ana model kullanıcıyla konuşur, "
|
||
"işi dağıtır, sonucu doğrulayıp aktarır.\n"
|
||
"3. Kullanıcı 'Codex' derse işi devretme. Komut hata verirse işi alt ajanla 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
|