feat(codex-bridge): ship the local Codex bridge with the IDE
Adds the IDE's models and combos to Codex's model list and keeps conversation summaries readable across providers, so switching models in Codex no longer drops the conversation. Standard-library Python, run on the agent venv. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HRDGW1LiKcDUZYUdKBoWYW
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""9Router'a giden isteklerde resim, video, ses, PDF ve dev içerikleri sadeleştirir (24 Eylül 2026, kullanıcı onayı).
|
||||
|
||||
Sorun: Codex, image_gen aracının ürettiği resmi (≈3 MB base64 PNG) araç çıktısı olarak sohbete geri koyuyor.
|
||||
9Router'ın Claude çevirisi bunu düz yazı sayıyor: istek 3 milyon token'a çıktı ("prompt is too long:
|
||||
3040251 tokens > 1000000 maximum") ve sohbetteki sonraki HER tur 400 ile düştü; sohbet kurtarılamadı.
|
||||
Aynısı video, ses, PDF/dosya ve çok büyük araç çıktılarıyla da olabilir (kullanıcı isteği: "tekrar böyle sorun olmasın").
|
||||
|
||||
Kural:
|
||||
- Medya parçaları (resim, dosya/PDF, ses, video): araç çıktılarında ve eski mesajlarda kısa notla değiştirilir.
|
||||
Kullanıcının SON mesajındaki medya toplamı TUT_BAYT'ı aşmıyorsa korunur (yeni eklenen dosyayı model görebilsin).
|
||||
- Tür ne olursa olsun tek başına DEV_BAYT'tan büyük her parça (son mesajdaki korunanlar hariç) notla değiştirilir.
|
||||
- Düz yazı araç çıktısı DEV_BAYT'tan büyükse başı ve sonu kalır, ortası notla kısaltılır.
|
||||
Codex'in kendi kaydına dokunulmaz; yalnız 9Router'a giden kopya değişir.
|
||||
"""
|
||||
import json
|
||||
|
||||
TUT_BAYT = 1_000_000
|
||||
DEV_BAYT = 1_000_000
|
||||
RESIM_TUT_BAYT = TUT_BAYT # eski ad
|
||||
MEDYA_TURLERI = {'input_image': 'resim', 'image': 'resim', 'image_url': 'resim',
|
||||
'input_file': 'dosya/PDF', 'file': 'dosya/PDF',
|
||||
'input_audio': 'ses', 'audio': 'ses',
|
||||
'input_video': 'video', 'video': 'video'}
|
||||
|
||||
|
||||
def _boyut(p):
|
||||
try:
|
||||
return len(json.dumps(p, ensure_ascii=False))
|
||||
except (TypeError, ValueError):
|
||||
return len(str(p))
|
||||
|
||||
|
||||
def _medya_mi(p):
|
||||
return isinstance(p, dict) and p.get('type') in MEDYA_TURLERI
|
||||
|
||||
|
||||
def _not(p):
|
||||
tur = MEDYA_TURLERI.get(p.get('type'), p.get('type') or 'içerik') if isinstance(p, dict) else 'içerik'
|
||||
ad = p.get('filename') or p.get('file_path') or p.get('path') or '' if isinstance(p, dict) else ''
|
||||
ek = f' ({ad})' if ad else ''
|
||||
return {'type': 'input_text',
|
||||
'text': f'[{tur}{ek} çıkarıldı (AstraBridge): bu yoldan gönderilemiyor, ~{_boyut(p) // 1024} KB; '
|
||||
'gerekirse dosyayı yolundan aç]'}
|
||||
|
||||
|
||||
def _kisalt(metin):
|
||||
yarim = DEV_BAYT // 4
|
||||
return (metin[:yarim] + f'\n[... {len(metin) - 2 * yarim} karakter çıkarıldı (AstraBridge): çıktı çok büyüktü ...]\n'
|
||||
+ metin[-yarim:])
|
||||
|
||||
|
||||
def resimleri_sadelestir(req, tut_bayt=TUT_BAYT):
|
||||
"""(değiştirilen parça sayısı, kazanılan bayt). req['input'] yerinde değişir."""
|
||||
inp = req.get('input')
|
||||
if not isinstance(inp, list):
|
||||
return 0, 0
|
||||
son_kullanici = None
|
||||
for i, it in enumerate(inp):
|
||||
if isinstance(it, dict) and it.get('type') == 'message' and it.get('role') == 'user':
|
||||
son_kullanici = i
|
||||
koru = set()
|
||||
if son_kullanici is not None:
|
||||
icerik = inp[son_kullanici].get('content')
|
||||
if isinstance(icerik, list):
|
||||
medya = [p for p in icerik if _medya_mi(p)]
|
||||
if medya and sum(_boyut(p) for p in medya) <= tut_bayt:
|
||||
koru.add(son_kullanici)
|
||||
sayi = kazanc = 0
|
||||
for i, it in enumerate(inp):
|
||||
if not isinstance(it, dict) or i in koru:
|
||||
continue
|
||||
for alan in ('content', 'output'):
|
||||
deger = it.get(alan)
|
||||
if isinstance(deger, str) and len(deger) > DEV_BAYT:
|
||||
yeni = _kisalt(deger)
|
||||
kazanc += len(deger) - len(yeni)
|
||||
sayi += 1
|
||||
it[alan] = yeni
|
||||
continue
|
||||
if not isinstance(deger, list):
|
||||
continue
|
||||
degisti = False
|
||||
yeni_liste = []
|
||||
for p in deger:
|
||||
if _medya_mi(p) or _boyut(p) > DEV_BAYT:
|
||||
kazanc += _boyut(p)
|
||||
sayi += 1
|
||||
degisti = True
|
||||
yeni_liste.append(_not(p))
|
||||
else:
|
||||
yeni_liste.append(p)
|
||||
if degisti:
|
||||
it[alan] = yeni_liste
|
||||
return sayi, kazanc
|
||||
Reference in New Issue
Block a user