Metadata-Version: 2.5
Name: cokgine
Version: 0.2.4
Summary: Standalone Ollama-like LLM engine (MLX: Metal, CUDA, CPU) with built-in genetic AI
Author: Kridho Cokro
License-Expression: LicenseRef-Proprietary
Keywords: cuda,genetic-algorithm,llm,metal,mlx,ollama
Requires-Python: <3.13,>=3.12
Requires-Dist: fastapi>=0.115
Requires-Dist: huggingface-hub>=0.33
Requires-Dist: mlx-lm<0.32,>=0.31
Requires-Dist: mlx>=0.31.2
Requires-Dist: rich>=13.9
Requires-Dist: typer>=0.12
Requires-Dist: uvicorn>=0.32
Provides-Extra: cpu
Requires-Dist: mlx[cpu]; extra == 'cpu'
Provides-Extra: cuda
Requires-Dist: mlx[cuda12]; extra == 'cuda'
Provides-Extra: vision
Requires-Dist: mlx-vlm>=0.3; extra == 'vision'
Description-Content-Type: text/markdown

# cokgine

Engine AI mandiri ala Ollama lintas platform (macOS Apple Silicon, Linux CUDA, Linux CPU) — load model LLM dari HuggingFace,
jalankan in-process via [MLX](https://github.com/ml-explore/mlx), dan evolusi prompt
dengan algoritma genetika bawaan. Tanpa Ollama, tanpa llama.cpp server, tanpa perantara.

```
┌─────────────┐   ┌──────────────────────────────────────────┐
│ CLI / REST  │──▶│ EngineService ──▶ MlxBackend (mlx-lm)     │
│ Open WebUI  │   │      │                                    │
│ Genetics    │───┘      └──▶ FakeBackend (--fake, tanpa GPU) │
└─────────────┘   └──────────────────────────────────────────┘
```

- **Lintas Platform** — macOS (Apple Silicon Metal), Linux (NVIDIA CUDA), dan Linux (CPU).
- **Cepat** — MLX memanfaatkan akselerasi GPU secara native (Metal di Mac, CUDA di Linux); Llama-3.2-1B berjalan ~50 tok/dtk di M4 Max.
- **REST kompatibel Ollama** — aplikasi eksternal tinggal ganti base URL ke `http://localhost:11435`.
- **Genetic AI bawaan** — algoritma genetika yang memakai inferensi engine sendiri sebagai mutator dan penilai fitness.

## Platform & Instalasi

Memerlukan [uv](https://docs.astral.sh/uv/) (direkomendasikan) atau Python 3.12.

| Platform | Akselerasi | Perintah Install | Catatan |
|---|---|---|---|
| **macOS (Apple Silicon)** | Metal (GPU) | `uv tool install cokgine` | M1/M2/M3/M4, macOS 13.5+ |
| **Linux (NVIDIA GPU)** | CUDA 12 (GPU) | `uv tool install "cokgine[cuda]"` | Driver ≥ 550.54, SM 7.5+ (T4+), glibc ≥ 2.35 |
| **Linux (VPS / Server)** | CPU | `uv tool install "cokgine[cpu]"` | Model kecil 1–3B, glibc ≥ 2.35 |

> **Catatan Shell:** Tanda kutip pada `"cokgine[cpu]"` dan `"cokgine[cuda]"` **wajib disertakan** agar kurung siku `[...]` tidak diinterpretasikan oleh shell (zsh/bash).

### Syarat Linux CUDA

- **NVIDIA Driver**: ≥ `550.54.14` (`nvidia-smi` untuk cek).
- **Compute Capability**: **SM 7.5+** (Turing/Ampere/Ada/Hopper: T4, RTX 20xx/30xx/40xx, A10, A100, H100; GPU lawas seperti V100/Pascal tidak didukung oleh MLX CUDA).
- **C-library**: glibc ≥ `2.35` (bawaan Ubuntu 22.04 LTS ke atas; periksa dengan `ldd --version`).

### Panduan Cloud GPU (RunPod / Vast.ai)

1. **Pilih Instance On-Demand (Bukan Serverless)**:
   Model LLM (mis. 17 GB untuk 30B) butuh dimuat ke memori. Instance serverless akan memicu reload cold-start yang lama setiap kali jeda request.
2. **Jalankan Server**:
   ```bash
   uv tool install "cokgine[cuda]"
   cokgine pull qwen3-coder-30b
   cokgine serve --host 0.0.0.0
   ```
3. **Keamanan Jaringan**: Server cokgine tidak memakai autentikasi (identik dengan default Ollama). Jangan expose port 11435 ke publik tanpa proteksi; gunakan private overlay network (Tailscale / WireGuard) atau reverse proxy dengan autentikasi.
4. **Batas Memori GPU**: Untuk GPU dengan VRAM 24–36 GB (mis. RTX 3090/4090), set:
   ```bash
   export COKGINE_MAX_LOADED=1
   ```
   agar LRU cache tidak menumpuk lebih dari satu model besar di VRAM.

### Ekspektasi Linux CPU (VPS tanpa GPU)

Pada VPS tanpa GPU, MLX otomatis beroperasi di mode CPU:
- Ditujukan untuk uji coba, integrasi CI/CD, atau model kecil (1B–3B seperti `llama3.2-1b`).
- Inferensi CPU jauh lebih lambat dibanding GPU; menjalankan model 30B di CPU tidak realistis untuk penggunaan interaktif.

### Instalasi dari Source (Pengembang)

Lihat [DEVELOPING.md](DEVELOPING.md):

```bash
uv sync
uv run cokgine --help
```

Model tersimpan di `~/.cokgine/models/` (ubah via `COKGINE_HOME`).

Ketik `cokgine` tanpa perintah untuk melihat backend aktif (`metal`, `cuda`, atau `cpu`), status server, model lokal, dan panduan perintah.

## Quickstart

```bash
# ambil model uji (~0.7 GB)
cokgine pull llama3.2-1b

# tanya langsung dari CLI
cokgine generate llama3.2-1b "What is the capital of France?"

# REPL interaktif
cokgine run llama3.2-1b

# jalankan server REST (port 11435)
cokgine serve
```

Model 7–8B (butuh ~5 GB RAM untuk 4-bit):

```bash
cokgine pull llama3.1-8b        # mlx-community/Meta-Llama-3.1-8B-Instruct-4bit
cokgine pull qwen2.5-7b
cokgine pull qwen3-8b
```

Model coding 30B MoE (17 GB, cocok untuk agentic coding via Cline; set
`COKGINE_MAX_LOADED=1` di RAM 36 GB):

Model Coding & Technical ERP (SuiteScript, SuiteQL, APIs):

```bash
cokgine pull qwen2.5-coder-7b    # mlx-community/Qwen2.5-Coder-7B-Instruct-4bit (~4.5 GB)
cokgine pull qwen2.5-coder-14b   # mlx-community/Qwen2.5-Coder-14B-Instruct-4bit (~9 GB)
cokgine pull qwen3-coder-30b     # mlx-community/Qwen3-Coder-30B-A3B-Instruct-4bit (~17 GB, MoE)
```

Model Functional ERP & Alur Bisnis / Akuntansi:

```bash
cokgine pull qwen2.5-14b         # mlx-community/Qwen2.5-14B-Instruct-4bit (~9 GB)
cokgine pull deepseek-r1-14b     # mlx-community/DeepSeek-R1-Distill-Qwen-14B-4bit (~9 GB)
```

## Model apa pun dari HuggingFace

Tidak ada daftar model yang dikunci di kode. Semua repo `mlx-community/...`
(atau repo MLX apa pun) bisa ditarik langsung dengan repo id-nya:

```bash
cokgine pull mlx-community/Llama-3.1-8B-Instruct-4bit
```

Alias bawaan: `llama3.2-1b`, `llama3.1-8b`, `qwen2.5-7b`, `qwen2.5-14b`,
`qwen3-8b`, `qwen2.5-coder-7b`, `qwen2.5-coder-14b`, `qwen3-coder-30b`,
`deepseek-r1-14b`. Buat alias pribadi sendiri — tersimpan di
`~/.cokgine/aliases.json`, tanpa mengubah kode:

```bash
cokgine alias add deepseek mlx-community/DeepSeek-R1-Distill-Qwen-7B-4bit
cokgine pull deepseek
cokgine alias list          # alias -> repo id, plus status sudah/belum ditarik
cokgine alias rm deepseek   # hapus alias; file model (jika ada) tetap utuh
```

`cokgine pull <nama> --alias <nama-baru>` juga menyimpan alias saat selesai
mengunduh.

## REST API (kompatibel Ollama)

Semua endpoint streaming memakai NDJSON — satu objek JSON per baris
(`Content-Type: application/x-ndjson`), sama seperti Ollama. Set `stream: false`
untuk satu respons buffered.

| Endpoint | Fungsi |
|---|---|
| `GET /` | heartbeat |
| `GET /api/version` | versi server |
| `POST /api/generate` | generate satu prompt |
| `POST /api/chat` | chat multi-turn dengan chat template |
| `GET /api/tags` | daftar model lokal |
| `POST /api/pull` | unduh model dari HuggingFace |
| `POST /api/show` | detail model |
| `DELETE /api/delete` | hapus model lokal |

```bash
curl --json '{"model":"llama3.2-1b","prompt":"Say OK","stream":false}' \
     http://localhost:11435/api/generate

curl -sN --json '{"model":"llama3.2-1b","messages":[{"role":"user","content":"Say OK"}]}' \
     http://localhost:11435/api/chat
```

Open WebUI: tambahkan koneksi OpenAI/Ollama ke `http://localhost:11435` — CORS terbuka.

### Options yang dikenali

`options` map Ollama diterjemahkan ke sampler MLX:

| Ollama | cokgine |
|---|---|
| `temperature`, `top_p`, `top_k` | sampler MLX |
| `repeat_penalty` | logits processor repetition penalty |
| `num_predict` | `max_tokens` (default 512; -1 → 8192) |
| `num_ctx` | `max_kv_size` (default 8192; **per-request** — tidak memicu reload) |
| `stop` | pemotongan stream sisi klien |
| `seed` | `mx.random.seed` |

Opsi lain diabaikan.

### Model thinking (Qwen3, DeepSeek-R1, …)

Field `think` mengikuti semantik Ollama: `true` / `false`, atau level
(`"low"`, `"medium"`, `"high"`, `"max"`) yang diperlakukan sebagai "thinking on".
Soft switch `/think` dan `/no_think` pada pesan user terakhir juga dikenali —
`think` eksplisit selalu menang atas soft switch.

Chain-of-thought tidak pernah bercampur dengan jawaban: reasoning dikirim di
field tersendiri (`message.thinking` untuk `/api/chat`, `thinking` untuk
`/api/generate`) dan field itu dihilangkan bila kosong. Ini juga memperbaiki
tool calling, karena JSON `tool_calls` tidak lagi tercemar blok `<think>`.

```bash
# jawaban langsung, tanpa reasoning
curl --json '{"model":"qwen3-8b","think":false,"stream":false,"messages":[{"role":"user","content":"9.11 vs 9.9, mana yang lebih besar?"}]}' \
     http://localhost:11435/api/chat
```

Di CLI: `cokgine generate qwen3-8b "…" --no-think`. Di dalam REPL ada perintah
`/think` dan `/no_think`; reasoning dicetak redup agar terpisah dari jawaban.

### Perilaku error

Stream yang gagal di tengah jalan tidak lagi diam (HTTP 200 + body kosong).
Chunk terakhir berisi `{"error": "...", "done": true, "done_reason": "error"}`.
Sebelum stream dimulai, error dipetakan ke status HTTP yang benar: `404` model
tidak dikenal, `400` model incomplete atau payload tidak valid, `500` kegagalan
engine. Traceback lengkap tetap masuk log server.

Pull yang terputus juga tidak lagi meninggalkan model yang "terdaftar tapi
tidak bisa dimuat": setiap pull diverifikasi terhadap
`model.safetensors.index.json` (shard hilang, file 0 byte, atau total byte di
bawah yang dideklarasikan), manifest hanya ditulis bila model lengkap, dan
`cokgine list` / `cokgine show` menandai model yang belum selesai beserta
perintah untuk melanjutkannya.

## Genetic AI

`cokgine evolve` menjalankan algoritma genetika di atas inferensi engine sendiri:
setiap individu adalah **prompt-genome** (system prompt + instruction template
dengan placeholder `{input}`), dievolusi lewat seleksi tournament, crossover,
mutasi string deterministik, dan mutasi berbantuan LLM (temperature 0.9).

```bash
cokgine evolve --config examples/evolve_capitals.json
cokgine evolve --task "answer in rhymes" --model llama3.2-1b
cokgine evolve --resume <RUN_ID>          # lanjut dari checkpoint
```

Contoh config:

```json
{
  "task": "answer world capital-city questions accurately and concisely",
  "samples": [
    { "input": "What is the capital of France?", "expected": "Paris" }
  ],
  "target_model": "llama3.2-1b",
  "fitness": { "strategy": "contains" },
  "population": 6,
  "generations": 5,
  "llm_mutation_rate": 0.3
}
```

Strategi fitness:

- `contains` / `exact` / `regex` — deterministik terhadap `expected`.
- `llm_judge` — engine menilai jawaban kandidatnya sendiri (rubrik bisa dikustom via `"rubric"`).

Checkpoint atomik per generasi tersimpan di `~/.cokgine/evolve/<run_id>/state.json`;
run bisa dilanjutkan dengan `--resume`. Seed RNG dikonfigurasi (`"seed": 42`) agar
run reproducible.

Seam arsitektur untuk masa depan: `WeightGenome` (evolusi bobot/LoRA) — parameter
`adapter` sudah mengalir dari options → cache key → `mlx_lm.load(adapter_path=...)`,
jadi evolusi adapter bisa ditambahkan tanpa menyentuh core.

## Mode tanpa GPU / demo

Seluruh stack (CLI, REST, evolve) bisa dijalankan tanpa model dan tanpa jaringan:

```bash
cokgine serve --fake
cokgine evolve --fake --config examples/evolve_capitals.json
# atau: export COKGINE_FAKE=1
```

## Memori (M-series 36 GB)

- LRU cache memuat maksimal 2 model sekaligus (`COKGINE_MAX_LOADED`); evict memanggil `gc.collect()` + `mx.clear_cache()`.
- `num_ctx` besar menaikkan pemakaian KV-cache per request — 8192 aman untuk model 8B-4bit.
- Untuk headroom lebih saat load 2 model 8B: `sudo sysctl iogpu.wired_limit_mb=28000`.

Lisensi: proprietary — semua hak dilindungi. Penggunaan kembali atau redistribusi
source code tidak diizinkan tanpa izin tertulis dari pemilik.
