OllaHub icon # OllaHub **A desktop chat for your local Ollama models — it scans your hardware, recommends and downloads a model, and can enrich answers with web search, MCP tools and scheduled tasks, all driven by a Rust (Tauri) backend.** ![Version](https://img.shields.io/badge/version-0.1.0-informational) ![Tauri](https://img.shields.io/badge/Tauri-2-informational) ![Next.js](https://img.shields.io/badge/Next.js-16.0.3-informational) [Features](#features) · [Install](#install) · [How it works](#how-it-works) · [Limitations](#known-limitations) · [Build](#build-and-run-locally) · [CI/CD](#cicd)
> [!NOTE] > **Project status:** early (`0.1.0`, 47 commits from 2025-10-27 to 2025-11-27). The setup flow, chat, session > history, model management, web search, MCP, scheduled tasks and auto-update are implemented. The repository has > no license file and no automated test script (`package.json` only defines `dev`, `build`, `start`, `lint`, > `generate-changelog` and `bump-version`). A few settings are placeholders — see > [Known limitations](#known-limitations). > [!IMPORTANT] > **OllaHub is a client for [Ollama](https://ollama.com), not a model runtime.** It talks to the Ollama API > (default `http://localhost:11434`, configurable in Settings), tries to start it when it is installed but > stopped, and can download the Ollama installer when it is missing. Chats are stored locally in a SQLite > database (`ollahub.db` in the app data directory); web search is the part that reaches the internet. ## Features | Area | What it does | |---|---| | **First-run setup** | Hardware scan (CPU, RAM, GPUs), GPU selector and a model recommendation for your specs, then straight into the chat | | **Chat** | Streaming responses from the Rust backend (`chat_stream`), Markdown with syntax-highlighted code blocks, reasoning/thinking steps, source carousel, message actions, resizable sidebar | | **Sessions** | Local history in SQLite with FTS5 full-text search, paginated loading, automatic title + emoji for new chats (model-generated, with a fallback to the first words), export of sessions or all data, delete/clear | | **Models** | List and delete local models, pull with progress (percent, speed), install a `.gguf` file, hardware-aware recommendation | | **Web search** | Headless Chrome scraping across Google, Bing, Yahoo, DuckDuckGo and Startpage (configurable engine order), categories and custom sites, excluded domains, concurrency/timeout/result limits, semantic query expansion (pt-BR / en / es), engine circuit breaker and failure cache, progressive fallback | | **Relevance and context** | Local embeddings (`all-MiniLM-L6-v2` via ONNX Runtime) rank and prune scraped content, with a BM25-like fallback when the embedding model is unavailable; chunking, condensation and key-facts extraction are configurable | | **Deep research** | Multi-step mode: planning → searching → aggregating → validating → formulating | | **MCP** | Configure servers in a JSON editor (`mcp_config.json`), start/stop/restart them as child processes, list and call their tools from the chat | | **Scheduled tasks** | Cron-based tasks (`tokio-cron-scheduler`) with three actions — search and summarize, plain notification, custom prompt — persisted in `tasks.json` | | **System monitor** | CPU/RAM stats and GPU VRAM, usage and temperature dashboards (GPU detection per OS: `wmic`/`nvidia-smi` on Windows, with Linux and macOS paths) | | **Updates** | Tauri updater with signed releases; the automatic check is on by default | | **Desktop shell** | Custom title bar, light/dark theme, desktop notifications | ## Install Installers are produced by the [release workflow](#cicd) for Windows (`msi`), macOS (`dmg`, Apple Silicon and Intel) and Linux (`AppImage`); see the repository's [Releases](https://git.evandro.dev.br/evandro/OllaHub/releases). You can also [build it locally](#build-and-run-locally). > [!WARNING] > **Two things the app does on its own.** > 1. Opening the chat page pulls the small helper model **`qwen2.5:0.5b`** if it is not installed yet (a > "Baixando modelo de IA" progress appears) — expect an extra download on first use. > 2. **Closing the window only hides it.** The close request is intercepted (`prevent_close`) so scheduled tasks > keep running, but the code has no tray icon to bring the window back — the system-tray step is still listed > as pending in [`IMPLEMENTATION_GUIDE.md`](IMPLEMENTATION_GUIDE.md). ## How it works ```mermaid flowchart LR UI["Next.js 16 UI
static export · chat · setup · settings · tasks"] -- "Tauri invoke / events" --> RS["Tauri 2 backend (Rust)
src-tauri/src/lib.rs"] RS --> OL["Ollama API
chat · pull · tags"] RS --> DB[("SQLite ollahub.db
sessions · messages · FTS5")] RS --> WEB["web_scraper.rs
headless Chrome · search engines"] RS --> EMB["embeddings.rs
MiniLM ONNX · BM25 fallback"] RS --> MCP["MCP servers
child processes · JSON-RPC"] RS --> SCH["scheduler
cron tasks"] SCH --> OL SCH --> WEB ```
Technical details | Piece | Where | Notes | |---|---|---| | Frontend | `app/`, `components/`, `hooks/`, `lib/`, `store/` | Next.js 16 (App Router, `output: 'export'`, built with webpack), React 19, Tailwind 4, Radix UI, Zustand store persisted for settings, `react-markdown` + `remark-gfm`, Framer Motion | | Backend | `src-tauri/src/` | `lib.rs` (commands for chat, models, Ollama lifecycle, sessions, MCP, search, tasks, export, installer), `db.rs`, `ollama_client.rs`, `web_scraper.rs`, `embeddings.rs`, `intent_classifier.rs`, `system_monitor.rs`, `scheduler.rs`, `scheduler_loop.rs`, `task_executor.rs`, `sources_config.rs` | | Web search | `web_scraper.rs`, `services/`, `lib/web-search-fallback.ts` | Orchestrated from the frontend (query preprocessing, expansion, progressive multi-round fallback) with scraping done in Rust; `intent_classifier.rs` classifies a query as factual / conversational / technical / opinion / calculation by keyword heuristics | | Embeddings | `embeddings.rs` | Model and tokenizer downloaded from Hugging Face; the ONNX Runtime library is downloaded automatically on Windows, elsewhere the system library path is tried | | Persistence | app data dir | `ollahub.db` (SQLite, bundled `rusqlite`), `mcp_config.json`, `tasks.json`; browser `localStorage` for the setup-complete flag | | Prompts | `data/prompts/` | Default response format, deep-research and prompt-generator prompts | | Model catalog | `data/models/` | 188 JSON files describing Ollama library models (variants, sizes, context); not referenced by the app code | | Release tooling | `scripts/` | `generate-changelog.js` (builds `data/changelog.json` from `feat`/`fix` commits), `bump-version.js` (updates `package.json`, `tauri.conf.json` and `Cargo.toml`) | Further notes: [`docs/updater-setup.md`](docs/updater-setup.md) (signing keys and updater setup), [`docs/style-guide.md`](docs/style-guide.md) (UI spacing, radii, accessibility) and [`IMPLEMENTATION_GUIDE.md`](IMPLEMENTATION_GUIDE.md) (tray, background mode and task scheduler).
## Known limitations - **No tray icon yet:** closing the window hides it (see the warning above). - **"Start with the system" does nothing yet:** the setting only toggles a stored flag; the code carries a `TODO` until `tauri-plugin-autostart` is configured. - **RAG inside `chat_stream` is not wired:** the `enable_rag` branch is commented out as `TODO`; web context is assembled by the frontend before the request. - **Unused leftovers:** `src-tauri/scripts/scraper.py` (a `curl_cffi`/BeautifulSoup scraper) and the Python bootstrap hook/component are not called by the Rust backend; scraping is done by `headless_chrome`. - **Embeddings outside Windows:** the ONNX Runtime library is only auto-downloaded on Windows; on macOS/Linux provide it in the app data folder or on the system path, otherwise ranking falls back to BM25-like scoring. - **Updater endpoint:** it is configured in `src-tauri/tauri.conf.json` and points to a GitHub Releases `latest.json`; update it if releases are published elsewhere. ## Build and run locally Requirements (from the CI workflow): Node.js 20, pnpm 8, a stable Rust toolchain and the [Tauri 2 prerequisites](https://tauri.app/start/prerequisites/). On Ubuntu the workflow installs `libwebkit2gtk-4.1-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev patchelf`. [Ollama](https://ollama.com) is needed at runtime. ```bash git clone https://git.evandro.dev.br/evandro/OllaHub.git cd OllaHub pnpm install pnpm tauri dev # starts `pnpm dev` (Next.js on http://localhost:3000) inside the Tauri window pnpm tauri build # runs `pnpm generate-changelog && pnpm build`, then bundles the installer pnpm lint # ESLint pnpm bump-version # patch | minor | major, optional --commit ``` ## CI/CD The workflow [`.github/workflows/release.yml`](.github/workflows/release.yml) (**Build and Release**, read by Gitea Actions) runs on **pushes to `main`, `master` and `develop`** and on manual dispatch: - **`build`** — matrix on Windows (`msi`), macOS aarch64 and x86_64 (`dmg`) and Ubuntu (`appimage`): installs pnpm 8, Node 20 and Rust, runs `pnpm install --frozen-lockfile`, generates the changelog, builds the Tauri app and bundle (signing with the `TAURI_UPDATER_PRIVATE_KEY` secret when it is set) and uploads the installers as artifacts (7 days). - **`create-release`** — only on pushes to `main`/`master`: reads the version from `package.json`, builds release notes from `data/changelog.json` and publishes release `v` with the downloaded artifacts. ## Notices Built with [Tauri](https://tauri.app), [Next.js](https://nextjs.org), [Radix UI](https://www.radix-ui.com), [Tailwind CSS](https://tailwindcss.com), [Zustand](https://zustand-demo.pmnd.rs), [Lucide](https://lucide.dev), [headless_chrome](https://github.com/rust-headless-chrome/rust-headless-chrome), [ONNX Runtime](https://onnxruntime.ai) and the [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2) model.