# FIKO-AI

Yerel bilgisayarda çalışan, sesli ve yazılı konuşabilen kişisel yapay zekâ asistanı platformu.

**Phase 1 tamamlandı:** Go (Fiber) backend + Angular 22 frontend + MongoDB (bellek içi depo) +
WebSocket streaming sohbet + Ollama ile gerçek LLM üretimi.

**Tool sonuçları türüne göre görünür:** her tool bir `ui` alanı taşır (`table` / `file` / `list` /
`code` / `metrics` / `form` / `json`). Kararı **sunucu** verir: `ui` boşsa `auto` sayılır ve ad ön
ekinden türetilir (`biz`/`memory`/`knowledge` → tablo, `fs` → dosya, `web` → liste, `sys` → terminal).
Arayüzde tool rozetine tıklayınca sonuç o görünümde **interaktif** açılır: tablo aranıp sıralanır,
liste bağlantılıdır, `stdout`/`stderr` ayrı görünür, metrikler kart hâlinde sıralanır.

**Sistem panoları (sadece sohbet değil):** şu an dört ayrı iş paneli var ve hepsi aynı tool'ları
doğrudan, kendi arayüzüyle kullanır —
- **Şirket** (`biz.*`): 14 koleksiyon (müşteri, görev, fatura, gider, ürün, personel, proje…);
  aranabilir/sıralanabilir tablo, şemadan üretilen ekleme–düzenleme formu, iki tıklamalı silme,
  `biz.summary` metrikleri.
- **Bilgi Tabanı** (RAG): belge yükleme, hibrit/anlamsal/kelime arama, skor yüzdesi, indeks durumu.
- **Sistem**: hangi motorların açık, hangi ayarların eksik olduğunu tek ekranda gösterir
  (STT/TTS/iş araçları/bilgi tabanı/hafıza/izinler). Salt okunurdur: ayarlar `backend/.env`dedir.
- Şirket panelinde **CSV dışa/içe aktarma**: görüntülenen kayıtlar indirilir,
  yüklenen CSV satır satır eklenir (tek hatalı satır dosyanın tamamını bozmaz).
- **Hafıza / Akışlar / Skill'ler / Tool'lar**: mevcut paneller.

> Ürünün tamamı ve faz planı için [`PROJE.MD`](PROJE.MD).
> Gelişim günlüğü ve sonraki adımlar için [`docs/ILERLEME.md`](docs/ILERLEME.md).

---

## Hızlı başlangıç

### Gereksinimler
| Araç | Sürüm | Not |
|---|---|---|
| Go | 1.23+ | `go version` |
| Node.js | 20+ | `node -v` |
| Ollama | herhangi | [ollama.com](https://ollama.com) — bir model indirilmiş olmalı |
| MongoDB | 4.4+ | **isteğe bağlı ama önerilir** — konuşma geçmişi kalıcı olsun istersen |

### 1) Ollama'yı hazırla
```bash
ollama serve                 # ayrı bir terminalde çalışır
ollama pull qwen2.5:7b       # ya da listelenen herhangi bir model
ollama list
```

### 2) Backend
```bash
cd backend
cp .env.example .env         # MONGO_URI ve OLLAMA_MODEL ayarlanmalı
go run ./cmd/server
```

**Semantik arama (skill) kalite ölçümü:**
```bash
cd frontend && node tools/embed-bench.mjs
```
8 skill'lik geçici korpus kurar, her sorguyu `keyword` / `semantic` / `hybrid`
modlarında sorar, **hit@1** ve **hit@3** puanlar ve sonra **korporusu siler**
(`FIKO_KEEP=1` ile panelde incelenebilir). Sonuç (`qwen3-embedding`, 24 sorgu,
anahtar kelime örtüşmesi olmayan sorgular):

| mod | hit@1 | hit@3 |
| --- | --- | --- |
| `keyword` | %29 | %33 |
| `semantic` | %67 | %96 |
| `hybrid` | %67 | %96 |

Anahtar kelime tek başına yetersiz; **embedding belirleyici**. Sunucu açılışta
embedding modelini ısıtır (pre-warm), yoksa ilk arama model yüklemesi yüzünden
zaman aşımına uğrar.
Sunucu `:8080` üzerinde açılır:
```
http://localhost:8080/api/health
```

**Depo seçimi otomatiktir:** MongoDB'ye bağlanabilirse konuşmalar kalıcıdır.
Bağlanamazsa sunucu **Uyarı vererek** bellek içi depoya düşer (sohbetler yine çalışır ama
sunucu kapanınca kaybolur). Yalnızca bellekte çalıştırmak için `MONGO_ENABLED=false`.

### 3) Frontend
```bash
cd frontend
npm install
npm start                    # http://localhost:4200
```
`/api` ve `/ws` istekleri `proxy.conf.json` ile backend'e yönlendirilir; tarayıcı
doğrudan `http://localhost:8080` adresine bağlanmaz (CORS'a gerek kalmaz).

---

## 🌐 İnternete yayınlama (HTTPS)

```bash
start-yayin.bat              # yayını başlatır
start-yayin.bat stop         # durdurur
```

**`https://fikoyt.com:4200`** adresinden yayınlanır. Tek süreç, tek origin:

```
https://fikoyt.com:4200
   ├─ /        → Angular arayüzü (statik + SPA fallback)
   ├─ /api/*   → REST API
   └─ /ws      → WebSocket (wss://)
```

**Proxy/nginx yoktur.** Go backend (Fiber) arayüzü, API'yi ve WebSocket'i aynı
adresin üzerinden TLS ile sunar. Arayüz ve API aynı origin'de olduğu için karma
içerik (https sayfa → http istek) ve CORS sorunu yapısal olarak oluşmaz.

### Nasıl çalışır

1. `start-yayin.bat` arayüzü `npm run build` ile derler (yoksa)
2. Backend `HTTP_TLS_CERT` / `HTTP_TLS_KEY` ile HTTPS konuşur
3. `HTTP_STATIC_DIR` içindeki derlenmiş arayüzü sunar
4. SPA rotası (`/ayarlar`, `/tools` …) `index.html`'e düşer — Angular yönlendirme çalışır

### Sertifika

`cert/server.crt` + `cert/server.key` — Let's Encrypt, `CN=fikoyt.com`,
kapsam `*.fikoyt.com` + `fikoyt.com`, geçerlilik **27.12.2026**.

> ⚠️ **IP ile girilmez.** Sertifika alan adı içindir; `https://1.2.3.4:4200`
> girildiğinde tarayıcı "sertifika geçersiz" uyarısı verir.
> ⚠️ **Sertifika 27.12.2026'da doluyor** — o tarihten sonra yenilenmelidir.

### Sunucu tarafı ön koşullar

- DNS kaydı: `fikoyt.com` → sunucunuzun IP'si
- Firewall: **4200** portu dışarı açık

### Güvenlik notu (okumadan açmayın)

Bu ayarlarla sistem **internete açıktır**. Varsayılan durumda:

- **Üyelik sistemi açık** (`FIKO_USERS_ENABLED=true`) — giriş olmadan veri okunamaz
- `sys.exec` **kapalı** (`TOOL_ALLOW_CRITICAL=false`) — süreç çalıştırma yok
- HIGH risk araçlar **kapalı** (`TOOL_ALLOW_HIGH_RISK=false`) — dosya silme dahil

Başkalarına açacaksanız mutlaka `admin` parolasını değiştirin ve
`TOOL_DEFAULT_PERMISSIONS` değerini daraltın (varsayılan `read,write,execute,delete`
olduğu için giriş yapan biri dosya sistemine yazabilir).

### Geliştirme vs yayın

| | Geliştirme | Yayın |
|---|---|---|
| Betik | `start-all.bat` | `start-yayin.bat` |
| Arayüz | `http://localhost:4200` (ng serve) | `https://fikoyt.com:4200` |
| Backend | `:8080` (yalnız API) | `:4200` (TLS + hepsi) |
| Erişim | yalnız bu makine | internet |

**İkisi aynı anda çalışmaz** (ikisi de 4200'i kullanır).

---

## Testler

```bash
# Backend — tüm paketler
cd backend && go test ./...
cd backend && go vet ./... && gofmt -l .

# Backend — Mongo testleri (MONGO_TEST_URI verilmezse otomatik atlanır)
cd backend
$env:MONGO_TEST_URI = "mongodb://kullanici:sifre@localhost:27017/?authSource=admin"
go test ./internal/storage/...

# Frontend — vitest
cd frontend && npm test
```

**Uçtan uca doğrulama** (backend çalışıyor olmalı; gerçek LLM çağrısı yapar):
```bash
cd frontend && node tools/ws-e2e.mjs
```
Akışı uçtan uca dener: sağlık → konuşma aç → WebSocket → mesaj gönder →
delta/final dinle → kalıcılığı doğrula → konuşmayı sil.

Tool çağırmayı sınamak için (Faz 5) `FIKO_PROMPT` ver:
```bash
# macOS/Linux
FIKO_PROMPT="Echo aracini 'merhaba' ile cagir ve sonucu yaz" node tools/ws-e2e.mjs
# PowerShell
$env:FIKO_PROMPT="Echo aracini 'merhaba' ile cagir ve sonucu yaz"; node tools/ws-e2e.mjs
```
Beklenen: `tool.start` → `tool.progress` → `tool.result` → asistan metni.
Model tool desteklemiyorsa yalnızca metin gelir (bu bir hata değildir).

---

## Proje yapısı

```
fiko-ai/
├── PROJE.MD              # ürün spesifikasyonu (prompt)
├── docs/
│   ├── ILERLEME.md       # "kaldığım yer" + oturum günlüğü  ← buraya bak
│   ├── API.md            # REST sözleşmesi + WS akış örneği
│   └── MIMARI.md         # katmanlar, veri akışı, kararlar
├── backend/
│   ├── cmd/server/       # giriş noktası (DI, graceful shutdown)
│   ├── config/           # ortam değişkeni → yapılandırma
│   ├── internal/
│   │   ├── agent/        # mesaj → LLM → akış (orchestrator)
│   │   ├── api/          # Fiber REST uçları + /ws bağlantısı
│   │   │   └── ws/       # oturum yönetimi, heartbeat, backpressure
│   │   ├── conversation/ # konuşma alan modeli + depo arayüzü
│   │   ├── ctxmgr/       # kayan bağlam penceresi (token bütçesi)
│   │   ├── skill/        # Skill Registry, arama/embedding, tool arayüzleri
│   │   ├── schema/       # JSON Schema alt kümesi doğrulaması (bağımlılıksız)
│   │   ├── tool/         # Tool Registry + Executor + izin/risk
│   │   │   └── builtin/  # hazır tool'lar (fs.*, fiko.*, sys.exec)
│   │   ├── event/        # process içi olay yolu (bus)
│   │   ├── llm/          # sağlayıcı arayüzü + Ollama
│   │   ├── prompt/       # sistem istemi üretici
│   │   └── protocol/     # WS olay şemaları (frontend ile paylaşılan)
│   └── pkg/id/           # ön ekli rastgele kimlik
└── frontend/src/app/
    ├── core/             # api + ws servisi, chat/skill/tool store, config
    ├── models/           # protokol + skill/tool REST tipleri
    ├── layout/           # sidebar
    └── features/
        ├── chat/         # mesaj listesi, giriş kutusu, orb
        ├── skills/       # Skill yönetim paneli
        ├── tools/        # Tool yönetim paneli + izin kutusu
        └── settings/     # ayarlar paneli
```

---

## Ortam değişkenleri

Tam liste ve açıklamalar: [`backend/.env.example`](backend/.env.example).

| Değişken | Varsayılan | Açıklama |
|---|---|---|
| `HTTP_ADDR` | `:8080` | Dinlenen adres (yayında `:4200`) |
| `HTTP_ALLOWED_ORIGINS` | `http://localhost:4200,...` | CORS izin listesi; **boşsa tüm origin'lere izin verir** |
| `HTTP_TLS_CERT` | *(boş)* | TLS sertifikası; **yoksa HTTP**, varsa HTTPS |
| `HTTP_TLS_KEY` | *(boş)* | TLS anahtarı; `HTTP_TLS_CERT` ile **birlikte** verilmelidir |
| `HTTP_STATIC_DIR` | *(boş)* | Sunulacak arayüz dizini; boşsa yalnız API |
| `MONGO_URI` | `mongodb://localhost:27017` | Mongo adresi; erişilemezse bellek içi düşüş |
| `MONGO_DATABASE` | `fiko_ai` | Veritabanı adı |
| `MONGO_ENABLED` | (açık) | `false` ise bellek içi depoya zorla düş |
| `OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama adresi |
| `OLLAMA_MODEL` | *(boş)* | Varsayılan model; **sohbet için zorunlu** (arayüzden de seçilebilir) |
| `OLLAMA_EMBED_MODEL` | *(boş)* | Skill araması için embedding modeli; boşsa arama anahtar kelimeye düşer |
| `OLLAMA_REQUEST_TIMEOUT` | `90s` | Ollama istek üst süresi (soğuk model yüklemesi uzun sürer) |
| `OLLAMA_KEEP_ALIVE` | `30m` | **Modeli VRAM'de tutar.** Boş bırakılırsa Ollama birkaç dakikada boşaltır ve her sohbette model yeniden yüklenir (20-60 sn bekleme) |
| `OLLAMA_MAX_CONTEXT` | `8192` | `num_ctx` tavanı (yalnızca istemci belirtmediğinde). Ollama aksi hâlde model kartından devasa bağlam alır ve KV cache VRAM'i tüketir |
| `OLLAMA_NUM_GPU` / `_NUM_BATCH` / `_NUM_THREAD` | `0` | Ollama ayarları; 0 = Ollama varsayılanı (gönderilmez) |
| `TOOL_DEFAULT_PERMISSIONS` | `read,write,execute,delete` | Tool izinlerinin varsayılan kümesi. Silme araçları kullanıcı onay formu olmadan çalışmaz; `system` **yok** (süreç çalıştırma ayrıca `TOOL_EXEC_ENABLED=false`) |
| `TOOL_ALLOW_HIGH_RISK` / `TOOL_ALLOW_CRITICAL` | `false` | HIGH / CRITICAL risk tool'lara izin |
| `TOOL_FS_ROOT` | `data/tools` | Dosya tool'larının kökü (bu klasörün dışına çıkış reddedilir) |
| `TOOL_EXEC_ENABLED` / `TOOL_EXEC_ALLOW` | `false` / *(boş)* | `sys.exec` için iki kapı; izin listesi tam program yolları |
| `TOOL_HTTP_ENABLED` | `true` | Uzak (`kind=http`) tool'ların genel kapısı |
| `TOOL_HTTP_ALLOW_PRIVATE` | `false` | `true` ise SSRF koruması kapanır. **Üretimde kapalı tut** |
| `CHAT_GENERATION_TIMEOUT` | `5m` | Tek üretim üst süresi |
| `CHAT_MAX_AGENT_ITERATIONS` | `4` | Tool çağırma döngüsü üst sınırı (tavan 8; 0 = varsayılan) |
| `WS_PONG_WAIT` | `50s` | Ping cevabı bekleme süresi |
| `STT_*` / `TTS_*` | — | Ses motorları (aşaıdaki ses bölümü) |
| `LOG_LEVEL` / `LOG_FORMAT` | `info` / `text` | `debug\|info\|warn\|error` · `text`\|`json` |

Frontend adresi: `src/index.html` içindeki `window.__FIKO_CONFIG__` (bkz. `core/config.ts`).

---

**Kapsanan:** yazılı sohbet (streaming, iptal, yeniden bağlanma + heartbeat), **kalıcı konuşma geçmişi (MongoDB)**, bağlam yönetimi (kayan pencere), **Skill Registry** (CRUD + embedding araması + arayüz), **Tool Registry** (CRUD + Executor + izin/risk) ve skill→tool çalıştırma, **STT** (konuşma tanıma), **TTS** (sesli okuma + barge-in).

Tool güvenliği: varsayılan izin **yalnızca `execute`**; `read/write/delete/system` ve `high/critical` risk kullanıcıdan açıkça açılır (`GET/PUT /api/permissions`). Dosya tool'ları `TOOL_FS_ROOT` içinde sandozlanır, `sys.exec` varsayılan **kapalıdır**.

## Performans (gerçek zaman)

Gecikme ölçümü:

```bash
cd frontend
node tools/bench-rt.mjs --runs 3   # TTFT, token/sn, ilk ses gecikmesi
node tools/dbg-ws.mjs "metin"      # WS olaylarını canlı izle
```

**Zaten ayarlı gelenler** (`.env`'e dokunmana gerek): `OLLAMA_KEEP_ALIVE=30m` modeli VRAM'de tutar (sohbet arası yeniden yükleme beklemesini siler), `OLLAMA_MAX_CONTEXT=8192` KV cache'in devasa boyutunu engeller, embedding istekleri `num_ctx=512` ile sınırlanır, skill embedding'leri önbelleklenir, TTS sunucusu TF32 kullanır ve **ses cümle metin akışı sırasında üretilir** (`text.final`'ı beklemez).

> ⚠️ **VRAM çakışması:** Ollama + TTS + STT aynı GPU'yu kullanırsa motorlar birbirini kovar (ölçümde tek cümle TTS 1,6 sn yerine 131 sn sürdü). `start-voice.bat` bu yüzden STT'yi **CPU'da** başlatır. Daha fazla GPU istersen `set FIKO_STT_DEVICE=cuda` + `set FIKO_STT_COMPUTE=float16`.
> Büyük modeller (30B) 1,1 token/sn ile gerçek zamanlı **kullanılamaz**; 7-9B sınıfı ~140 token/sn verir. Modeli arayüzden değiştirebilirsin.

**Ses** motor bağımsızdır: backend yalnızca arayüzü tanır (`internal/stt`, `internal/tts`), motoru `.env` ile seçersin.
backend yalnızca arayüzü tanır, motoru sen seçersin ve `.env` ile bağlarsın.

| İşlev | Protokol | Seçenekler |
|---|---|---|
| Konuşma → metin (STT) | `voice.start` / `voice.audio` / `voice.stop` | `whispercpp` (yerel) · `openai` (bulut/uyumlu) |
| Metin → konuşma (TTS) | `tts.mode` / `tts.stop` | `openai` (OpenAI-uyumlu) · `piper` (yerel) |

Örnekler ve ayarlar için `backend/.env.example` dosyasına bak. Sesli okuma hoparlör düğmesiyle açılır (her mesajda otomatik konuşmaz); mikrofonu açtığında asistan susar (**barge-in**).
açılır (her mesajda otomatik konuşmaz); mikrofonu açtığında asistan susar (**barge-in**).

## Sesli asistan (AKTIF)

Ses motorlari **kuruludur ve dogrulanmistir**:

| Bilesen | Adres | Ne yapar | Durum |
|---|---|---|---|
| Konusma tanima | `127.0.0.1:9000` | Mikrofon sesini metne cevirir (faster-whisper small, Turkce) | dogrulandi |
| Sesli okuma | `127.0.0.1:5000` | Asistan yanitini seslendirir (Chatterbox Multilingual) | dogrulandi |

**Baslatma:** proje kokunde `start-all.bat` yeterlidir; motorlari da o baslatir.
Yalnizca ses istemiyorsan `start-all.bat --no-voice`.

Arayuzde mikrofon (konus) ve hoparlor (sesli okuma) dugmeleri otomatik belirir;
motorlar hazir degilse gizlenir. Durumu **Sistem** ekraninda izleyebilirsin.

> **Neden STT CPU'da?** Ollama + TTS + STT ayni GPU'yi kullanirsa VRAM dolar ve
> motorlar birbirini kovar (olcumde tek cumle TTS 1,6 sn yerine 131 sn surdu).
> Varsayilan: STT CPU/int8, TTS + LLM GPU'da. Daha fazla GPU icin
> `FIKO_STT_DEVICE=cuda` + `FIKO_STT_COMPUTE=float16`.

> Kadin sesi icin `models\voices\referans.wav` dosyasina 10-20 sn temiz bir ses klibi
> koy; yoksa modelin yerlesik sesi kullanilir.
## Kapsam dışı

Bilinerek **kapsam dışı** (sonraki fazlar): kimlik doğrulama, MCP, çoklu ajan koordinasyonu.
Ajan döngüsü (tool calling), RAG/bilgi tabanı, hafıza ve akışlar (Agent Builder) **tamamlandı**
ve arayüzde çalışır durumda. Ayrıntı için [`docs/ILERLEME.md`](docs/ILERLEME.md).