|
| 1 | +# OpenKB Desktop (Tauri) |
| 2 | + |
| 3 | +A desktop app that wraps OpenKB for non-technical users: no `pip`, no terminal. |
| 4 | +It is a thin [Tauri](https://tauri.app) (Rust) shell around two things OpenKB |
| 5 | +already produces: |
| 6 | + |
| 7 | +1. **The API sidecar** — `openkb-api` (the FastAPI server from the Knowledge |
| 8 | + Workbench, `openkb.api:main`) frozen into a self-contained binary with |
| 9 | + PyInstaller. It serves both the JSON/SSE API and the built web UI. |
| 10 | +2. **The web UI** — the `frontend/` Vite SPA, served by the sidecar at `/`. |
| 11 | + |
| 12 | +``` |
| 13 | +┌─────────────────────────────────────────────┐ |
| 14 | +│ Tauri shell (Rust + system WebView) │ |
| 15 | +│ │ |
| 16 | +│ spawns ──▶ openkb-api-sidecar (frozen) │ |
| 17 | +│ ├─ FastAPI /api/v1/* │ |
| 18 | +│ └─ web UI / │ |
| 19 | +│ WebView ──▶ http://127.0.0.1:<port>/ │ |
| 20 | +└─────────────────────────────────────────────┘ |
| 21 | +``` |
| 22 | + |
| 23 | +The user double-clicks the app; the Rust shell starts the sidecar on a |
| 24 | +localhost port, waits until it answers, then points the WebView at it. No |
| 25 | +browser, no port, no "server" ever surfaces to the user. |
| 26 | + |
| 27 | +## Why this shape |
| 28 | + |
| 29 | +- OpenKB's capability lives in a heavy Python stack (litellm, pageindex, |
| 30 | + markitdown, pymupdf). Rust can't replace that, so the Python runs as a frozen |
| 31 | + sidecar. The Rust shell is glue: window, WebView, process lifecycle, updater. |
| 32 | +- Tauri (vs Electron) ships no Chromium — smaller download, less memory — at the |
| 33 | + cost of using each platform's system WebView. |
| 34 | + |
| 35 | +## Layout |
| 36 | + |
| 37 | +``` |
| 38 | +desktop/ |
| 39 | + packaging/ # freeze the Python API into a slim sidecar binary |
| 40 | + build_sidecar.sh # PyInstaller recipe (slim: no magika/onnxruntime) |
| 41 | + sidecar_entry.py # frozen entry -> openkb.api:main |
| 42 | + pyi_rthook_magika.py# runtime hook: stub magika (drops onnxruntime) |
| 43 | + prune_litellm_proxy.py # post-build: delete the unused LiteLLM proxy server |
| 44 | + src-tauri/ # Tauri (Rust) shell — spawns the sidecar, opens the window |
| 45 | +``` |
| 46 | + |
| 47 | +## Build pipeline |
| 48 | + |
| 49 | +```bash |
| 50 | +# 1. Python env with API + PyInstaller |
| 51 | +python -m venv .venv && . .venv/bin/activate |
| 52 | +pip install -e ".[api]" pyinstaller |
| 53 | + |
| 54 | +# 2. Build the web UI (its output is what the sidecar serves) |
| 55 | +cd frontend && npm install && npm run build && cd .. |
| 56 | + |
| 57 | +# 3. Freeze the slim API sidecar -> desktop/packaging/dist/openkb-api-sidecar/ |
| 58 | +PYTHON=.venv/bin/python desktop/packaging/build_sidecar.sh |
| 59 | + |
| 60 | +# 4. Build the Tauri app (bundles the sidecar + opens the WebView) |
| 61 | +cd desktop/src-tauri && cargo tauri build |
| 62 | +``` |
| 63 | + |
| 64 | +## Slimming (measured, x86_64 Linux) |
| 65 | + |
| 66 | +The sidecar reuses the packaging work from the CLI slimming (see PR #186 for the |
| 67 | +lazy-markitdown source change that makes it possible): |
| 68 | + |
| 69 | +| stage | compressed | |
| 70 | +|---|---| |
| 71 | +| full PyInstaller freeze | 147 MB | |
| 72 | +| − magika / onnxruntime (stub hook) | 140 MB | |
| 73 | +| − LiteLLM proxy server | 133 MB | |
| 74 | + |
| 75 | +The frozen **API sidecar** (adds FastAPI + uvicorn over the CLI baseline) |
| 76 | +measures **≈134 MB compressed / 338 MB on disk**, verified booting uvicorn and |
| 77 | +serving `GET /api/v1/kbs` → 200. |
| 78 | + |
| 79 | +`pymupdf` (PDF engine) and `pandas`/`numpy` (Excel support) are kept |
| 80 | +deliberately — they are load-bearing for OpenKB's document formats. |
| 81 | + |
| 82 | +## Toolchain / status |
| 83 | + |
| 84 | +Full builds need, per platform: Rust + Cargo, Node + npm, a Python 3.10+ env, |
| 85 | +and on **Linux `webkit2gtk`** (`libwebkit2gtk-4.1-dev`) for the WebView. |
| 86 | + |
| 87 | +**Status:** the API sidecar freeze (`packaging/`) is implemented and verified. |
| 88 | +The `src-tauri/` shell is a reference skeleton — it is *not* compiled in the |
| 89 | +CI/dev container used so far because `webkit2gtk` is absent there; build it on a |
| 90 | +machine (or CI runner) that has the WebView libraries installed. |
0 commit comments