AI ile güçlendirilmiş, hafızası olan bir Gmail yönetim asistanı. Gelen mailleri senin kurallarına göre sınıflandırır, görev çıkarır, taslak üretir — Gmail'i asla kendi başına göndermez.
Genel vizyon ve yol haritası: docs/PLAN.md
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # ANTHROPIC_API_KEY ekle
# credentials.json → proje kökü (Google Cloud OAuth Desktop app)
python -m app.main auth
python -m app.main sync --dry-run
python -m app.main serve # http://127.0.0.1:8765Gmail'e yazma varsayılan kapalı (
GMAIL_WRITE=off): sınıflandırma yalnızca yerel DB'de tutulur, Gmail etiketleri değişmez. Etiketlemeyi açmak için.env→GMAIL_WRITE=on.
Faz 1 — Gelen mailleri güvenli biçimde çekip senin tanımladığın kurallara göre (
rules.yaml) sınıflandırır, etiketler ve istersen gelen kutusundan arşivler. Sınıflandırma koda gömülü değil — tamamen senin elinde.Faz 2 — Beklentiler ("şu gelince haber ver" + son tarih hatırlatması) ve süregelen işler (durum takibi, otomatik mail bağlama, zaman çizelgesi).
Faz 3 — Üslup öğrenme (Sent klasöründen kime nasıl yazdığını öğrenir) ve taslak üretimi (senin tarzında yanıt taslağı; asla göndermez, Gmail Taslaklar'a koyar — sen düzeltip gönderirsin).
Faz 4 — Knowledge Base (agent'a kişi/proje/kurum bilgisi öğretirsin) ve süreç tartışma (
ask) — ilgili bilgileri + işleri toplayıp durumu konuşur. KB, taslak üretimine de beslenir.Faz 5 — Günlük briefing (
brief) ve davranış öğrenme (suggest-rules): agent kendi geçmişine bakıp tekrarlayan LLM sınıflandırmaları için deterministik kural önerir (token tasarrufu + tutarlılık).
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtcp .env.example .env| Değişken | Varsayılan | Açıklama |
|---|---|---|
ANTHROPIC_API_KEY |
— | Zorunlu. Claude API anahtarı |
GMAIL_WRITE |
off |
on → sınıflandırmayı Gmail'e de yansıt (etiket/arşiv/yıldız) |
CLASSIFIER_MODEL |
claude-haiku-4-5-20251001 |
Sınıflandırma modeli |
DRAFTER_MODEL |
claude-sonnet-4-6 |
Taslak üretimi modeli |
LABEL_PREFIX |
AI |
Öncelik/durum etiketleri için önek (AI/Öncelik/...) |
FIRST_SYNC_QUERY |
newer_than:7d |
İlk sync'te hangi mailler taranır |
FIRST_SYNC_MAX |
50 |
İlk sync'te en fazla kaç mail |
- Google Cloud Console → yeni proje.
- Gmail API'yi etkinleştirin.
- APIs & Services → OAuth consent screen → External, kendinizi "Test user" ekleyin.
- Credentials → Create Credentials → OAuth client ID → Desktop app.
- İndirdiğiniz JSON'u proje köküne
credentials.jsonadıyla koyun.
python -m app.main auth # İlk bağlantı (tarayıcıda izin verirsiniz)
python -m app.main sync --dry-run # ÖNİZLEME: ne yapılacağını gösterir, dokunmaz
python -m app.main sync # Yeni mailleri sınıflandır + etiketle/arşivle
python -m app.main status # Son sınıflandırmaları listeleİlk kez çalıştırmadan önce
sync --dry-runile kurallarının ne yapacağını gör; emin olduğunda--dry-runolmadan çalıştır.
# Beklentiler — "şu gelince haber ver"
python -m app.main watch "Ali'den sunum dosyasını bekliyorum" --due 2026-07-05
python -m app.main watchers # listele
python -m app.main watch-cancel 3 # iptal
# Süregelen işler — durum takibi + otomatik bağlama
python -m app.main matter "X firması bütçe onayı" --from x-firma.com --keyword bütçe
python -m app.main matters # listele
python -m app.main matter-show 1 # zaman çizelgesi
python -m app.main matter-status 1 done # open | waiting | donesync sırasında: gelen mailler eşleşen işlere otomatik bağlanır (thread
devamlılığı + kriter), beklentiler önce deterministik ön-filtreden geçer, yalnızca
aday çıkanlar için tek LLM çağrısıyla doğrulanır. Tetiklenen mail yıldızlanır ve
gelen kutusunda tutulur. Son tarihi geçen beklentiler sync sonunda hatırlatılır.
python -m app.main learn-style # Sent klasörünü analiz et, üslubu öğren
python -m app.main styles # öğrenilen profilleri listele
python -m app.main draft <message_id> --instruction "kabul et, salıyı öner"
python -m app.main draft <message_id> --dry-run # taslağı sadece göster, oluşturmalearn-style gönderdiğin maillerden global ve kişiye özel üslup profilleri
çıkarır (dil, resmiyet, selamlama/kapanış, imza, uzunluk, emoji). draft bir maile
yanıt taslağını senin üslubunda üretir ve Gmail Taslaklar'a koyar — draft
asla göndermez; gözden geçirip kendin gönderirsin (human-in-the-loop).
# Agent'a bilgi öğret (doğal dille ya da yapılandırılmış)
python -m app.main remember "Ayşe Yılmaz mentor programının sorumlusu, ayse@vakif.org"
python -m app.main kb-add project "Bütçe 2026" "Yıllık onay süreci" --keyword bütçe
python -m app.main kb # listele · kb-show / kb-remove
# Bir süreci/durumu ajanla tartış
python -m app.main ask "Bütçe onay sürecinde ne durumda olmalıyım?"remember doğal dil notu yapılandırılmış bir kayda çevirir (kişi/proje/kurum/tercih).
ask soruyla ilgili KB kayıtlarını + süregelen işleri (zaman çizelgesiyle) toplar,
durumu özetler ve sonraki adımları önerir. KB ayrıca draft üretimine de beslenir —
alıcıya/projeye dair bildiklerin taslağa yansır.
python -m app.main brief --days 1 # bugün neye bakmalısın (deterministik, LLM'siz)
python -m app.main suggest-rules # geçmişe bakıp deterministik kural önerbrief yanıt bekleyenleri, aktif/süresi geçmiş beklentileri ve açık işleri tek
ekranda toplar. suggest-rules agent'ın kendi geçmişini analiz eder: bir domain
sürekli aynı kategoriye (çoğunlukla LLM ile) atanıyorsa, yapıştırmaya hazır bir
rules.yaml kuralı önerir — gelecekte o domain LLM harcamadan sınıflanır. Kuralı
otomatik eklemez; onaylayıp eklemek sende.
python -m app.main onboard # son 3 ayı tara → kişi/iş önerileri (dosyaya)
# → onboarding/people.yaml + matters.yaml'ı düzenle (ilişki doldur, gereksizi sil)
python -m app.main onboard --apply # KB + işlere işle, başlangıç çizgisini çekpython -m app.main tasks # gelen kutusundan çıkarılan görevler (to-do)
python -m app.main tasks --check # thread'lere bakıp yanıtlanmışları kapat
python -m app.main task-done 4 # görevi elle kapat
python -m app.main notes # çıkarılan toplantı notları (karar + aksiyon)
python -m app.main sync --lite # ucuz mod: görev/not çıkarımını atlasync sırasında yanıt-bekleyen maillerden görev (tür/ne/kim/son tarih), karar
içeren maillerden toplantı notu (kararlar + aksiyonlar) çıkarılır. tasks --check
bir görevin thread'inde senden sonraki yanıtın varsa onu "halledildi" sayıp kapatır
("zaten yapıldı mı"). Hepsi brief'te toplanır.
python -m app.main notify-test # bildirim çalışıyor mu?
python -m app.main sync --notify # önemli bir şey varsa masaüstü bildirimi
python -m app.main brief --notify # günlük özeti bildirim olarak da gönder
python -m app.main schedule --times 08:00,13:00,18:00 # otomatik çalıştırma (macOS launchd)
# → etkinleştir: launchctl load ~/Library/LaunchAgents/com.gmailagent.sync.plist
python -m app.main schedule --remove # zamanlamayı kaldırschedule macOS launchd ile sync --notify --quiet'i seçtiğin saatlerde otomatik
çalıştırır. Akıllı bildirim: sadece acil mail, tetiklenen beklenti, yeni görev ya
da süresi geçen beklenti varsa rahatsız eder — gerisi sessiz. Bildirimler ayrıca
data/notifications.log'a, sync logları data/agent.log'a yazılır.
python -m app.main auth # ⚠️ Calendar scope eklendi → bir kez yeniden auth
python -m app.main agenda --days 7 # yaklaşan toplantılar
python -m app.main meeting-brief --days 2 # yaklaşan toplantı(lar) için hazırlık brief'imeeting-brief her yaklaşan toplantıyı geçmiş kararlar + aksiyon maddeleri + açık
görevler ile eşleştirir ve "geçen sefer şunu kararlaştırdın, bu toplantıya kadar şunlar
bekliyor" özeti üretir. Calendar erişimi calendar.readonly (salt-okunur).
Arama (KB, ask) artık Türkçe eklere toleranslı: "bütçeyi" sorgusu "Bütçe" kaydını
bulur (ASCII-fold + kök-önek eşleşmesi, yeni bağımlılık/anahtar yok).
python -m app.main matters --dups # yakın-tekrar işleri bul
python -m app.main matter-merge 5 11 # #11'i #5'e birleştir (bağ/görev/not taşınır)Not: Gerçek vektör arama (Voyage + pgvector) bilinçli olarak ertelendi — bu ölçekte kök-eşleşmesi aynı değeri sıfır altyapıyla veriyor. Veri büyürse yükseltilebilir.
İlk sync son 7 günün maillerini işler (.env → FIRST_SYNC_QUERY / FIRST_SYNC_MAX).
Sonraki çalıştırmalar yalnızca yeni gelenleri işler (incremental, history.list).
Kategoriler, kurallar ve gelen-kutusu görünürlüğü koda gömülü değil; hepsi
proje kökündeki rules.yaml dosyasında (panel Kurallar sayfasından da
düzenlenebilir — kaydet deyince dosyaya yazılır). Kurallar yukarıdan aşağıya
değerlendirilir, ilk eşleşen kazanır.
Kategoriler vs kurallar: Kategori = mail türü ve gelen kutusunda mı kalacağı
(inbox: keep|archive). Kural = hangi mail hangi kategoriye gider (when koşulu
setaksiyonu). Önce kategori tanımla, sonra ona yönlendiren kurallar yaz.
Koşullar (when) üç tipte olabilir, karıştırabilirsin:
- Deterministik (ücretsiz):
from,from_domain,from_contains,to,subject_contains,body_contains,has_attachment,is_calendar_invite,list_unsubscribe,precedence_bulk,has_header - Anlamsal (LLM):
prompt: "doğal dille evet/hayır sorusu" - Birleştirici:
all: [..](VE) ·any: [..](VEYA) ·not: {..}
Aksiyon (set): category, priority (Acil|Normal|Düşük),
inbox (keep|archive), requires_reply, notify (yıldızla + bildir).
stop: true → eşleşince dur.
Kategorileri elle eklemek zorunda değilsin. Hiçbir kategoriye tam oturmayan bir
mail gelince agent otomatik yeni kategori açar (varsayılan inbox: keep) ve
sana bildirir. İki kaynak vardır:
rules.yaml→ senin sabit/öncelikli kategorilerin ve kuralların.- Öğrenilen kategoriler (DB) → agent'ın gözlemleyip açtıkları.
Guardrail (drift önleme): yeni ad önerilince mevcut kategorilerle harf-duyarsız karşılaştırılır; "Fatura" varken "fatura"/"Faturalar" açılmaz, var olan kullanılır. LLM fallback'i her zaman tüm bilinen kategorilerin listesini görür, böylece parçalanma olmaz.
python -m app.main categories # tüm kategoriler (dosya + öğrenilen)
python -m app.main category-inbox "Bağış" archive # öğrenilen birinin görünürlüğüİstediğinde öğrenilen bir kategoriyi rules.yaml'a taşıyıp kurala bağlayabilirsin.
- Deterministik geçiş (0 token): tamamen kural tabanlı bir eşleşme bulunursa LLM hiç çalışmaz.
- Anlamsal geçiş (gerekirse tek çağrı): kalan tüm
promptsoruları + (gerekiyorsa) fallback sınıflandırması tek Claude Haiku çağrısında çözülür. N anlamsal kural = N çağrı değil.
Nihai seçim her zaman senin yazdığın öncelik sırasına göre yapılır.
sync sonunda kaç mailin kural-tabanlı, kaçının LLM ile sınıflandığını raporlar.
<KategoriAdı> # rules.yaml kategorisi — doğrudan etiket adı (Toplantı, Fatura…)
AI/Öncelik/{Acil, Normal, Düşük}
AI/Durum/Yanıt Bekliyor # requires_reply olanlar
⭐ yıldız # notify:true olan kurallar
📥 arşivle # inbox:archive → INBOX etiketi kaldırılır (geri alınabilir)
python -m app.main serve # FastAPI servisi (http://127.0.0.1:8765 · /docs)
python -m app.main menubar # macOS menü çubuğu (servisi de başlatır)menubar menü çubuğunda 📬 açık-görev sayısı + 🔴 acil rozetini gösterir; tıkla →
Bugün / Hatırlatmalar / Şimdi sync / Önerileri gözden geçir / Paneli aç. Servis ayakta
değilse menü çubuğu onu arka planda başlatır (tek komutla her şey).
Panel (http://127.0.0.1:8765/) — Notion tarzı, beyaz/minimal web arayüzü:
| Sayfa | Ne yapar |
|---|---|
| Bugün | Günün özeti — sayılar, hatırlatmalar (açık görev listesi burada tekrarlanmaz) |
| Gelen öneriler | E-postalardan çıkarılan görev önerileri (Onayla / Yoksay) |
| Görevler | Açık işler — Tamamla / Tamamla ve taslak |
| Projeler | Süregelen işler (matters) |
| Kurallar | Görsel kural editörü — kategori + kural ekle/düzenle, arka planda rules.yaml'a yazar |
Sidebar:
- Şimdi eşitle — anlık sync
- 15 dk otomatik eşitle — checkbox (tercih
localStorage'da saklanır, sessiz sync)
Ham API: /docs · Kurallar API: GET /rules → {document}, PUT /rules/document
python -m app.main build-app # dist/GmailAgent.app üretir
open dist/GmailAgent.app # menü çubuğunda başlar (Dock'ta görünmez)Üretilen .app mevcut .venv'i sarar (hafif, anında çalışır). Uygulamalar'a taşıyıp
Sistem Ayarları → Giriş Öğeleri'ne ekleyerek girişte otomatik başlatabilirsin.
Tamamen bağımsız bir bundle istersen py2app/Briefcase kullanılabilir (daha ağır).
pip install -r requirements-dev.txt
python -m pytest # tests/ — izole geçici DB, Gmail/LLM gerektirmezSuite çekirdeği uçtan uca kapsar: sınıflandırma motoru, görev döngüsü, watcher/matter, DB-only sınıflandırma, FastAPI servis (TestClient), onboarding, hatırlatmalar.
credentials.json,token.json,.envasla commit edilmez —.gitignore'da.data/(SQLite DB, loglar) veonboarding/(kişisel öneriler) yerel kalır.- Mail içeriği güvenilmez girdi sayılır; prompt-injection'a karşı sınırlayıcıyla sarılır.
- Agent asla mail göndermez/silmez — en fazla etiketler, arşivler, Gmail Taslaklar'a yazar.
rules.yaml # kategoriler + kurallar (panelden de düzenlenir)
.env.example # ortam değişkeni şablonu
app/
├── main.py # CLI giriş noktası
├── config.py # ayarlar (.env)
├── labels.py # karar → Gmail etiketi / arşiv / yıldız
├── gmail/ # OAuth, API, incremental sync
├── classification/
│ ├── config_rules.py # rules.yaml yükleme + doğrulama
│ ├── rules_document.py # görsel editör ↔ YAML dönüşümü
│ ├── engine.py # iki geçişli karar motoru
│ └── classifier.py # Claude (Haiku) batched anlamsal değerlendirme
├── tracking/ # beklentiler (watchers) + süregelen işler (matters)
├── drafting/ # üslup öğrenme + taslak üretimi
├── knowledge/ # Knowledge Base + ask
├── learning/ # briefing + kural önerisi
├── work/ # görev çıkarımı, yanıt takibi
├── service/
│ ├── api.py # FastAPI (panel + REST)
│ └── static/panel.html # web arayüzü
├── menubar/ # macOS menü çubuğu uygulaması
└── storage/db.py # SQLite
data/ # agent.db, loglar (gitignore)
tests/ # pytest — Gmail/LLM gerektirmez
docs/ # PLAN, mimari notlar
Kişisel / dahili kullanım. Dağıtım veya lisans belirtilmemişse repo sahibine aittir.