Rodosgrup test projesi. Üretim ürünü değildir; sesli asistan, konuşmacı tanıma ve Claude Code oturumlarıyla etkileşim denemeleri için geliştirilmektedir.
Jarvis, Mac'inizin menü çubuğunda yaşayan sesli asistandır. Adını söylersiniz, uyanır; açık Claude Code oturumlarınıza görev verir, WhatsApp ve Mail'i sizin adınıza kullanır, işi bitince gelip sonucu okur. Yalnızca sizin sesinize tepki verir.
Siz: "Jarvis, web projesine söyle testleri çalıştırsın."
Jarvis: "İlettim." … 40 sn sonra …
Jarvis: "Web projesi bitirdi: 42 test geçti, iki uyarı var."
| 🌙 Bekleme modu | Mikrofon açık ama dışarı tek bayt ses gitmez. Uyandırma kelimesi ("Jarvis", değiştirilebilir) cihaz içi tanımayla yakalanır. |
| 🗣️ Sesli sohbet | Uyanınca OpenAI Realtime'a bağlanır, "Sizi dinliyorum." der, Türkçe konuşur. Cevaptan sonra 5 saniye sessizlikte uyur. Üç ses hattı: Tam, Ekonomik, Yerel (neredeyse ücretsiz). |
| 🧑💻 Claude oturumları | Açık oturumları listeler, durum sorar, görev verir; oturum bitirince özetini okur. Uyuyorsa uyanıp haber verir. |
| 💬 Mac görevleri | WhatsApp, iMessage, Mail, Kişiler, Takvim, uygulama açma, dosya bulma. Gönderme gibi geri alınamaz adımlarda önce "göndereyim mi?" diye sorar. |
| 🔐 Sadece sizin sesiniz | Sesinizin parmak izini yerelde çıkarır, her cümleyi yabancı referans seslerle karşılaştırır. Yabancı ses uyandıramaz, uyandırsa da ilk cümlede elenir. |
| ⚪ Küre | Siyah zeminde parçacık küresi: beklerken mavi, dinlerken beyaz, konuşurken kırmızı; sesinizle dalgalanır. |
brew install xcodegen
sh scripts/fetch-vendor.sh # sherpa-onnx + konuşmacı modeli (vendor/, git'e girmez)
xcodegen generate
xcodebuild -project Jarvis.xcodeproj -scheme Jarvis -configuration Debug -derivedDataPath build build
open build/Build/Products/Debug/Jarvis.app- Menü çubuğundaki simge → Ayarlar… → OpenAI API anahtarı (Keychain'de saklanır).
- Sistem Ayarları › Klavye › Dikte'yi açın. Uyandırma kelimesi Apple'ın konuşma tanımasına bağlıdır; Dikte veya Siri kapalıysa çalışmaz (hata 201).
- Dinle deyin, mikrofon ve konuşma tanıma izinlerini verin. Jarvis beklemeye geçer.
- Ayarlar › Sesimi kaydet… ile sekiz cümle okuyun. Yabancı referans sesler bir kez üretilir, profil çıkar, "sadece benim sesim" açılır.
- "Jarvis" deyin.
mikrofon ──► AudioEngine ──┬──► WakeWord cihaz içi, "Jarvis" ← beklemede yalnız bu
├──► SpeakerVerifier yerel parmak izi + kohort ← uyanışta ve her cümlede
└──► RealtimeClient ──► OpenAI Realtime ──► hoparlör
│ araç çağrıları
┌────────────────────────────────────────────┼──────────────────────────────┐
list_sessions · get_session_status send_task mac_task · mac_confirm
SessionStore (~/.claude kayıtları) Orchestrator (headless claude, Mac işçisi (headless claude,
yalnız SendMessage) yalnız osascript/open/shortcuts/mdfind)
Watcher: oturum boşa düşünce
son mesajını okur
- SessionStore Claude'un kendi kayıt dosyalarını salt okunur kullanır; ayar değiştirmez, hook kurmaz.
- Orchestrator kod çalıştıramayan bir headless Claude; görevi hedef oturuma SendMessage ile iletir.
- Mac işçisi yalnız
osascript,open,shortcuts,mdfindçalıştırabilir. Geri alınamaz işten önceONAY:ile durur; Jarvis sorar, "evet" deyince devam eder. Etiketsiz cevap "yapılmadı" sayılır. - Watcher görev verilen oturumu izler; çalışıp boşa düşünce son mesajını "[BİLDİRİM]" olarak sese sokar.
Shazam'ın yaptığı gibi aynı kaydı aramıyor; her seferinde farklı kelimeler söylüyorsunuz. Bunun yerine ses renginizin parmak izini (embedding) çıkarır ve karşılaştırır:
- Profil: kayıttaki sekiz cümlenin ayrı ayrı parmak izleri. Jarvis'in güvenle kabul ettiği her uzun cümle profile eklenir; sizi dinledikçe daha iyi tanır (en fazla 40 örnek).
- Kohort: OpenAI'nin on sesine üçer cümle okutularak üretilen 30 yabancı referans. Dışarıya yalnız metin gider.
- Karar: cümle size mi, en yakın yabancıya mı daha çok benziyor? Belirgin fark varsa sahibi, yabancı kadar benziyorsa yabancı, arası belirsiz. Uyanışta tek kelime ölçüldüğü için yalnız açıkça yabancı sesler elenir; asıl karar ilk cümlede verilir. Güvenilir oturumda kısa sesler ("evet", "hı") sorgulanmaz.
Model: WeSpeaker ResNet34-LM (sherpa-onnx, 16 kHz, 256 boyut). Güvenlik kilidi değil, filtredir.
| Ayar | Varsayılan | Not |
|---|---|---|
| Ses hattı | Tam (gpt-realtime) |
Ekonomik: gpt-realtime-mini, üçte bir fiyat, Türkçesi zayıf. Yerel: Apple Türkçe tanıma + gpt-4o-mini + Apple sesi; gecikme 1–3 sn, lafı kesmek yok, ses robotik |
| Ses | marin |
OpenAI'nin 10 sesi |
| Uyandırma kelimesi | Jarvis |
Tanıyıcı İngilizce; yakın yazımlar kabul edilir ("Mikail" → "mikhail") |
| Mikrofon | Dahili | AirPods mikrofonu kulaklığı telefon kalitesine düşürür; ses yine kulaklıktan çalar |
| Sadece benim sesim | açık | Kayıt sonunda kendiliğinden açılır |
| claude argümanları | --permission-mode auto |
Hedef oturumlarla aynı izin sınıfı olmalı, yoksa mesaj onay bekler |
| Dakika başına | Günde 30 dk | |
|---|---|---|
| gpt-realtime | ~0,05–0,10 $ | ~2–3 $ |
| gpt-realtime-mini | ~0,02 $ | ~0,5–1 $ |
| Yerel hat | tur başına < 0,001 $ | birkaç sent |
Beklemede ve sessizlikte ücret işlemez. Uyandırma kelimesi ve konuşmacı tanıma tamamen yereldir. Kohort üretimi tek seferlik, birkaç sent.
Ölçülmüş tuzaklar (geliştiriciler için)
- Headless orkestratör mesaj alamıyor:
/tmp/cc-socksaltında soket açmıyor, ListAgents'ta görünmüyor. Cevaplar dökümden (Watcher) okunur. - macOS 27'de SwiftUI fare takibi çöküyor: MenuBarExtra'nın
.windowstili ve çerçevesiz paneldeki NSHostingView, fare üstünden geçincePointerBridge.mouseMovediçinde SIGSEGV. Menü düz NSMenu, küre saf AppKit (NSView + Core Graphics), fare olaylarını yok sayar. - Küre çizimi ana iş parçacığını kilitliyordu: 60 Hz çizim 16 ms'yi aşınca runloop hiç uyumuyor, ana kuyruk sıra alamıyor. Çizim arka planda, ekrana hazır resim konur.
- Yankı önleme + oynatıcı aynı motorda açılmıyor (-10875). İki ayrı AVAudioEngine. Yankı önleme ayrı motordan çalan sesi silmez; bu yüzden Jarvis konuşurken ve bitiminden 400 ms sonrasına kadar mikrofon modele gönderilmez.
- AirPods mikrofonu: kulaklığı 24 kHz telefon profiline düşürür, her profil geçişinde motor yeniden kurulur (23 kez üst üste ölçüldü). Dinle açıkken sistem mikrofonu dahiliye çevrilir, kapanınca geri yüklenir. Motorun giriş birimine aygıt atamak (kAudioOutputUnitProperty_CurrentDevice) -10875 veriyor; sistem varsayılanını değiştirmek sorunsuz.
- Yankı önlemeli mikrofon dizisi 3–5 kanal verir, hepsi aynı işlenmiş sinyal; ilk kanal alınır. Ses kısıktır, sessizlik filtresinin mutlak tabanı düşük tutulur.
- Aynı motora ikinci tap istisna fırlatıp uygulamayı kapatıyor; her denemede taze motor.
- Tek kelimelik "Jarvis" konuşmacı için yetersiz: cümleler 0,8+ alırken tek kelime 0,4–0,7 arasında savruluyor. Uyanışta yalnız açıkça yabancılar elenir.
- Model sesi gerçek zamandan hızlı gönderir: "cevap bitti" olayı ses çalarken gelir. Konuşuyor durumu gerçek çalma sayacına bağlı.
- Araç çalışırken uyunmaz: Mac görevi 30 sn sürebilir; uyku sayacı araç bitene kadar ertelenir.
AVCaptureDevice.requestAccessgeri çağrısındanTask { @MainActor }çalışmadı;DispatchQueue.main.asynckullanılıyor.- Oturum status alanı
idle/busy; ölü pid kayıtlarıkill(pid, 0)ile ayıklanır. - Debug'da
-jarvisOrb YESküreyi açılışta gösterir. Her satır~/Library/Logs/Jarvis.logdosyasına yazılır; son ölçülen ses kesitlerijarvis-uyanis.wav/jarvis-cumle.wavolarak yanına düşer.
- Ucuz ses hattı: Apple konuşma tanıma + küçük metin modeli + Türkçe sistem sesi
- Tamamen çevrimdışı hat: yerel metin modeli ile sıfır maliyet
- Global kısayol ile uyandırma
- İkon, logo ve kapak:
python3 scripts/make_icon.py(Pillow). Logo, uygulamadaki kürenin aynısıdır. - Proje dosyası xcodegen ile üretilir;
Jarvis.xcodeprojgit'e girmez. - Kod yorumları Türkçe, tanımlayıcılar İngilizce.
MIT · © 2026 Rodosgrup Yazılım Ekibi. Ayrıntı için LICENSE.
