diff --git a/.gitignore b/.gitignore index 4cc9e6bb..dbe88d35 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ caveman-compress.md .claude/worktrees/ evals/snapshots/*.html evals/snapshots/*.png +.eval-home/ diff --git a/README.md b/README.md index c7cc226c..2b404155 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,28 @@ Stop with: "stop caveman" or "normal mode" | **Full** | `/caveman full` | Default caveman. Drop articles, fragments, full grunt | | **Ultra** | `/caveman ultra` | Maximum compression. Telegraphic. Abbreviate everything | +### Türkçe (Turkish) Mode + +Turkish is an agglutinative language, so we can't just drop articles (they don't exist). Instead, we drop pleasantries, shorten verbs (bulunmaktadır → var), and use abbreviations to cut tokens while keeping grammar mostly intact. + +| Level | Trigger | What it do | +|-------|---------|------------| +| **Turkce-Lite** | `/caveman turkce-lite` | Semi-terse Turkish. Active voice, drop pleasantries/filler, keep grammar | +| **Turkce-Full** | `/caveman turkce` | Default Turkish caveman. Drop subjects (pro-drop) and long suffixes, use abbreviations (VT/ayar/komp) | +| **Turkce-Ultra** | `/caveman turkce-ultra` | Maximum Turkish compression. Bare verbs only, mandatory arrows (→), max 1 line per point | + +_Example — "React bileşenim neden yeniden çiziliyor?"_ +- **Normal:** "React bileşeninizin yeniden çizilmesinin nedeni muhtemelen her render döngüsünde yeni bir nesne referansı oluşturmanızdır. Satıriçi bir nesneyi prop olarak geçirdiğinizde, React'in yüzeysel karşılaştırması bunu her seferinde farklı bir nesne olarak görür ve bu da yeniden çizimi tetikler. Nesneyi önbelleğe almak için useMemo kullanmanızı öneririm." +- **Turkce-Lite:** "Bileşen her render'da yeni nesne referansı oluşturuyor, bu yüzden yeniden çiziliyor. useMemo ile sarın." +- **Turkce-Full:** "Her render yeni ref. Satıriçi obj prop = yeni ref = yeniden çizim. useMemo sar." +- **Turkce-Ultra:** "Satıriçi obj → yeni ref → tekrar çizim. useMemo." + +**Turkish Benchmark Results:** +- Average savings: **66%** +- Savings range: **24% - 87%** +- Normal avg output: **1272 tokens** +- Caveman avg output: **339 tokens** + ### 文言文 (Wenyan) Mode Classical Chinese literary compression — same technical accuracy, but in the most token-efficient written language humans ever invented. diff --git a/evals/llm_run.py b/evals/llm_run.py index 795ef07d..308bca6e 100644 --- a/evals/llm_run.py +++ b/evals/llm_run.py @@ -36,18 +36,33 @@ SKILLS = EVALS.parent / "skills" PROMPTS = EVALS / "prompts" / "en.txt" SNAPSHOT = EVALS / "snapshots" / "results.json" +ENV_FILE = EVALS.parent / ".env.local" +EVAL_HOME = EVALS.parent / ".eval-home" TERSE_PREFIX = "Answer concisely." +if ENV_FILE.exists(): + for line in ENV_FILE.read_text().splitlines(): + line = line.strip() + if line and not line.startswith("#") and "=" in line: + key, _, value = line.partition("=") + os.environ.setdefault(key.strip(), value.strip()) + + def run_claude(prompt: str, system: str | None = None) -> str: - cmd = ["claude", "-p"] + # Keep Claude state inside the workspace so sandboxed runs can persist safely. + EVAL_HOME.mkdir(parents=True, exist_ok=True) + env = os.environ.copy() + env["HOME"] = str(EVAL_HOME) + + cmd = ["claude", "-p", "--no-session-persistence"] if system: cmd += ["--system-prompt", system] if model := os.environ.get("CAVEMAN_EVAL_MODEL"): cmd += ["--model", model] cmd.append(prompt) - out = subprocess.run(cmd, capture_output=True, text=True, check=True) + out = subprocess.run(cmd, capture_output=True, text=True, check=True, env=env) return out.stdout.strip() diff --git a/evals/prompts/en.txt b/evals/prompts/en.txt index e05a4dfc..1336d113 100644 --- a/evals/prompts/en.txt +++ b/evals/prompts/en.txt @@ -8,3 +8,15 @@ Why am I getting CORS errors in my browser console? What's the point of using a debouncer on a search input? How does git rebase differ from git merge? When should I use a queue vs a topic in messaging systems? +React bileşenim ebeveyni güncellendiğinde neden her seferinde yeniden çiziliyor? +Vue component parent'i prop'lari eksiksiz mi? Prop drilling yok mu? +Veritabanı bağlantı havuzunu (connection pooling) açıklar mısın? +TCP ve UDP arasındaki fark nedir? +Uzun süre çalışan bir Node.js sürecindeki bellek sızıntısını nasıl çözerim? +SQL EXPLAIN komutu bana ne anlatır? +Hash tabloları çarpışmaları (collision) nasıl yönetir? +Tarayıcı konsolunda neden CORS hataları alıyorum? +Arama input'unda debouncer kullanmanın amacı nedir? +Git rebase ile git merge arasındaki fark nedir? +Mesajlaşma sistemlerinde ne zaman queue, ne zaman topic kullanmalıyım? +Laravel controller'da problem olursa ilk nasıl ele alınmalı? diff --git a/hooks/caveman-mode-tracker.js b/hooks/caveman-mode-tracker.js index 1871b5e5..a04ece63 100644 --- a/hooks/caveman-mode-tracker.js +++ b/hooks/caveman-mode-tracker.js @@ -36,6 +36,9 @@ process.stdin.on('end', () => { else if (arg === 'wenyan-lite') mode = 'wenyan-lite'; else if (arg === 'wenyan' || arg === 'wenyan-full') mode = 'wenyan'; else if (arg === 'wenyan-ultra') mode = 'wenyan-ultra'; + else if (arg === 'turkce-lite' || arg === 'türkçe-lite') mode = 'turkce-lite'; + else if (arg === 'turkce' || arg === 'turkce-full' || arg === 'türkçe' || arg === 'türkçe-full') mode = 'turkce'; + else if (arg === 'turkce-ultra' || arg === 'türkçe-ultra') mode = 'turkce-ultra'; else mode = getDefaultMode(); } diff --git a/skills/caveman/SKILL.md b/skills/caveman/SKILL.md index 2ab498bd..eee4a8a6 100644 --- a/skills/caveman/SKILL.md +++ b/skills/caveman/SKILL.md @@ -3,9 +3,10 @@ name: caveman description: > Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, - wenyan-lite, wenyan-full, wenyan-ultra. + wenyan-lite, wenyan-full, wenyan-ultra, turkce-lite, turkce-full, turkce-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", - "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested. + "be brief", "mağara adam modu", "az token lütfen", "kısa konuş", "/caveman turkce", "/caveman türkçe", + or invokes /caveman. Also auto-triggers when token efficiency is requested. --- Respond terse like smart caveman. All technical substance stay. Only fluff die. @@ -14,7 +15,7 @@ Respond terse like smart caveman. All technical substance stay. Only fluff die. ACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. Off only: "stop caveman" / "normal mode". -Default: **full**. Switch: `/caveman lite|full|ultra`. +Default: **full**. Switch: `/caveman lite|full|ultra|turkce|turkce-lite|turkce-ultra|wenyan|wenyan-lite|wenyan-ultra`. ## Rules @@ -35,6 +36,9 @@ Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:" | **wenyan-lite** | Semi-classical. Drop filler/hedging but keep grammar structure, classical register | | **wenyan-full** | Maximum classical terseness. Fully 文言文. 80-90% character reduction. Classical sentence patterns, verbs precede objects, subjects often omitted, classical particles (之/乃/為/其) | | **wenyan-ultra** | Extreme abbreviation while keeping classical Chinese feel. Maximum compression, ultra terse | +| **turkce-lite** | Drop filler/pleasantries ("Tabii ki", "Memnuniyetle"). Active voice ("yap" not "gerçekleştirilmektedir"). Drop "-mektedir"/"-bulunmaktadır". Keep grammar intact. | +| **turkce-full** | Drop subjects (pro-drop). Drop "-maktadır"/"-ması gerekmektedir" → "-malı". Abbreviations (VT/yetk/ayar/komp/bağ/istek/yanıt/değ/sil/ekle/güncelle). Pattern: `[şey] [durum] [neden]. [çözüm].` | +| **turkce-ultra** | Max compression. Mandatory arrows (→). Bare verbs only ("sar", "kaldır", "ekle"). Max 1 line per point. Mandatory abbreviations. | Example — "Why React component re-render?" - lite: "Your component re-renders because you create a new object reference each render. Wrap it in `useMemo`." @@ -43,6 +47,9 @@ Example — "Why React component re-render?" - wenyan-lite: "組件頻重繪,以每繪新生對象參照故。以 useMemo 包之。" - wenyan-full: "物出新參照,致重繪。useMemo .Wrap之。" - wenyan-ultra: "新參照→重繪。useMemo Wrap。" +- turkce-lite: "Bileşen her render'da yeni nesne referansı oluşturuyor, bu yüzden yeniden çiziliyor. useMemo ile sarın." +- turkce-full: "Her render yeni ref. Satıriçi obj prop = yeni ref = yeniden çizim. useMemo sar." +- turkce-ultra: "Satıriçi obj → yeni ref → tekrar çizim. useMemo." Example — "Explain database connection pooling." - lite: "Connection pooling reuses open connections instead of creating new ones per request. Avoids repeated handshake overhead." @@ -50,6 +57,9 @@ Example — "Explain database connection pooling." - ultra: "Pool = reuse DB conn. Skip handshake → fast under load." - wenyan-full: "池reuse open connection。不每req新開。skip handshake overhead。" - wenyan-ultra: "池reuse conn。skip handshake → fast。" +- turkce-lite: "Bağlantı havuzu, her istekte yeni bağlantı açmak yerine açık bağlantıları yeniden kullanır. Tekrarlanan el sıkışma yükünü önler." +- turkce-full: "Havuz açık VT bağlantılarını tekrar kullanır. Her istekte yeni bağlantı yok. El sıkışma yükü atlanır." +- turkce-ultra: "Havuz = VT bağ. tekrar kullanım. El sıkışma atla → yükte hızlı." ## Auto-Clarity @@ -64,4 +74,4 @@ Example — destructive op: ## Boundaries -Code/commits/PRs: write normal. "stop caveman" or "normal mode": revert. Level persist until changed or session end. \ No newline at end of file +Code/commits/PRs: write normal. "stop caveman" or "normal mode": revert. Level persist until changed or session end.