-
Notifications
You must be signed in to change notification settings - Fork 0
Zelara Core
Status: v0.6.0 Phase 5 complete (2026-04-08) — AI runtime platform, PaddleOCR ONNX pipeline, Qwen3 persistent subprocess, model manager, hardware tier detection, finance_import.rs
Zelara Core is the desktop application that powers every Zelara app. It runs on your computer and exposes local AI capabilities over an encrypted connection to your phone. Every Zelara mobile app can connect to it and offload heavy computation — receipt scanning, language model inference, image recognition, document parsing — without sending data to any cloud.
Tagline: "Your personal AI hub. Install once, power all your Zelara apps."
Most "AI-powered" apps run models in a data center. That means:
- Your photos and documents leave your device
- You pay a subscription for someone else's compute
- The app stops working when the server is down or the company changes pricing
Zelara Core inverts this. Your desktop has significantly more compute than your phone. Models that would be impractical on a phone (PaddleOCR, DistilBERT, local LLMs) run comfortably on a modern laptop. Zelara Core manages those models and serves results back to your phone over a TLS-encrypted local connection — same network, milliseconds of latency, zero cloud.
Zelara Core maintains a catalog of ONNX and GGUF models used by Zelara apps:
| Model | Purpose | Size | Used By |
|---|---|---|---|
| PaddleOCR v5 (det + rec) | Receipt scanning, document OCR | ~20 MB | Zelara Finance |
| distilbert-base-multilingual-cased | Transaction auto-categorization | ~65 MB | Zelara Finance |
| MobileNet v3 (ONNX) | Recycling CV — bag/recyclables detection | ~10 MB | Zelara (main) |
| Mistral 7B GGUF (optional) | Natural language spend coaching, Q&A | ~4 GB | Zelara Finance (enhanced) |
Core downloads models on demand (first time an app requests a capability that needs them), caches them to the app data directory, and reuses them across sessions. Models are never re-downloaded unless explicitly updated by the user.
Any Zelara app on the local network can connect to Core via:
- BLE auto-discovery: Core advertises its IP:port over Bluetooth at launch; apps connect automatically when in range — no user action required
- QR pairing: Core displays a QR code for manual first-time pairing on unfamiliar networks
Once connected, the app gets:
- AI task results (OCR, categorization, CV, LLM inference)
- Progress sync — Core is the authoritative source of truth for skill tree state
- Cross-app data aggregation (e.g., Finance totals surfaced in Core's dashboard)
Core receives ai_task messages over WSS and routes them to the right model:
{
"type": "ai_task",
"task_id": "uuid",
"capability": "ocr_receipt | categorize_transaction | classify_image | llm_query",
"payload": {}
}Response:
{
"type": "ai_task_result",
"task_id": "uuid",
"result": {},
"processing_ms": 340
}This replaces the current hardcoded image_validation task type with a general-purpose
capability dispatch system. Each capability maps to a Rust handler in src-tauri/src/ai/.
If the required model is not yet downloaded, Core responds with:
{
"type": "ai_task_result",
"task_id": "uuid",
"status": "model_required",
"model": "paddleocr-v5",
"size_mb": 20
}The app then surfaces a "Download model on Core" prompt to the user.
When Zelara Finance is connected, Core receives a finance_expense_sync push whenever a new
expense is logged. Core persists this in its own SQLite Finance DB and surfaces it in the
full-screen desktop Finance dashboard. This follows the same broadcast pattern as
progress_sync (already implemented in device_linking.rs).
Core (storage.rs) is the authoritative source for user skill tree state:
- Points earned across all connected Zelara apps accumulate here
- Unlock thresholds checked and enforced server-side
-
progress_syncbroadcast to all connected apps after any state change
- Header: "Zelara Desktop"
- Sections: Device Linking / Testing Panel / Module List
- Developer-tool aesthetic — QR code as hero UI, status badges, debug log in center view
- Not useful to non-developer users
Four-section side navigation. Designed for visibility and control — a power user who wants to know what their AI hub is doing, not just a developer tool.
┌──────────────────────────────────────────────────────┐
│ Zelara Core ● AI Hub active [Settings ⚙] │
├──────────────────────────────────────────────────────┤
│ │
│ Connected Apps │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ 💰 Zelara Finance │ │ 📱 Zelara │ │
│ │ ● Connected │ │ ○ Not linked │ │
│ │ 14 tasks today │ │ │ │
│ └────────────────────┘ └────────────────────┘ │
│ │
│ Today's Activity │
│ ┌──────────────────────────────────────────────┐ │
│ │ 09:42 Receipt OCR (340ms) Zelara Finance │ │
│ │ 09:41 Categorization ×3 Zelara Finance │ │
│ │ 09:38 Recycling validation Zelara (main) │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ Network │
│ ● WSS server running on :8765 │
│ ● BLE advertising 192.168.1.42:8765 │
│ 1 device connected │
│ │
│ [Pair New Device] │
└──────────────────────────────────────────────────────┘
Key changes from current UI:
- "Zelara Desktop" → "Zelara Core"
- App cards replace abstract "device count" — user sees which named apps are connected
- Activity feed shows real AI tasks processed with timing (not just a developer debug log)
- QR pairing is a secondary action (
[Pair New Device]button), not the hero UI
┌──────────────────────────────────────────────────────┐
│ AI Models Storage: 95 MB used │
├──────────────────────────────────────────────────────┤
│ │
│ Installed │
│ ───────────────────────────────────────────────── │
│ ● PaddleOCR v5 20 MB 9× today │
│ Receipt & document OCR (80+ languages) │
│ │
│ ● DistilBERT (multilingual) 65 MB 3× today │
│ Transaction auto-categorization │
│ │
│ ● MobileNet v3 (CV) 10 MB 1× today │
│ Recycling bag detection │
│ │
│ Available to Install │
│ ───────────────────────────────────────────────── │
│ ○ Mistral 7B GGUF 4.1 GB [Download] │
│ Enhanced spend coaching and natural language Q&A │
│ Requires: 8 GB+ RAM, ~15 min first download │
│ │
└──────────────────────────────────────────────────────┘
Models are stored at:
- Windows:
%APPDATA%\Zelara\models\ - macOS/Linux:
~/.zelara/models/
Download progress is shown inline. Models load into memory on first use and stay resident while Core is running.
┌──────────────────────────────────────────────────────┐
│ Finance [Import ▼] [Export ▼] April 2026 │
├──────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ Total Spent │ │ Transactions │ │ Surplus │ │
│ │ $1,247.83 │ │ 47 │ │ $752.17 │ │
│ └──────────────┘ └──────────────┘ └────────────┘ │
│ │
│ Spending Trend (6 months, Recharts animated line) │
│ Nov — Dec — Jan — Feb — Mar — Apr(forecast····) │
│ │
│ By Category Top Merchants │
│ Food ████ $423 Walmart $287 │
│ Transport ███ $187 Shell $124 │
│ Utilities ███ $164 Starbucks $89 │
│ │
│ Recent Transactions │
│ Apr 4 Walmart Food -$45.23 Receipt OCR │
│ Apr 4 Shell Trans -$62.00 Manual │
│ [See all →] │
│ │
│ [📁 Import Bank File] [📤 Export Report] │
└──────────────────────────────────────────────────────┘
When no Finance app has ever connected: show "Install Zelara Finance on your phone to see your financial dashboard here."
Drag-and-drop file import: drop OFX / CSV / XLSX / PDF onto the window → auto-detected
format → Rust backend parses via finance_import.rs → preview parsed rows → confirm.
Network
───────────────────────────────────────────────
WSS Port 8765
BLE Advertising ● On [Toggle]
TLS Certificate Self-signed (generated 2026-02-15)
[Regenerate Certificate]
Storage
───────────────────────────────────────────────
Models directory %APPDATA%\Zelara\models\ [Change]
Finance database %APPDATA%\Zelara\finance.db
Progress file %APPDATA%\Zelara\progress.json
Connected Apps (pairing history)
───────────────────────────────────────────────
Zelara Finance Last seen: today 09:42
Zelara (main) Last seen: today 09:38
[Forget all paired devices]
Debug
───────────────────────────────────────────────
Points: 60 [+10] [+50] [+9999] [Reset to 0]
Debug controls moved here from the old TestingPanel — keeps the hub views clean.
src-tauri/src/
├── lib.rs (command registration — updated)
├── storage.rs (progress/unlock — unchanged)
├── device_linking.rs (WSS server, broadcast — extended for ai_task)
├── ble_advertising.rs (unchanged)
├── cv_processor.rs (recycling CV — now delegates through ai/ dispatcher)
├── finance_import.rs (desktop-side file parsing: calamine, csv-core, ofxy)
└── ai/
├── mod.rs (capability registry + re-exports)
├── dispatcher.rs (routes AiTask to the right handler by capability string)
├── model_manager.rs (download, cache, load ONNX/GGUF models to app_data_dir)
├── ocr_receipt.rs (PaddleOCR v5 — det + rec pipeline, vertical tiling for long receipts)
├── categorization.rs (DistilBERT tokenize + ONNX inference → Category)
└── llm.rs (llama-cpp-rs bindings for Mistral 7B — feature-flagged: "llm")
"ai_task" => {
let task: AiTask = serde_json::from_value(payload)?;
let result = ai::dispatcher::dispatch(task, &app_handle).await;
send_to_client(client_id, result).await;
}
"finance_expense_sync" => {
let expense: ExpenseRecord = serde_json::from_value(payload)?;
finance_import::record_expense(&expense, &app_handle).await?;
app_handle.emit("finance-expense-received", &expense)?;
}#[derive(Deserialize)]
pub struct AiTask {
pub task_id: String,
pub capability: String, // "ocr_receipt" | "categorize_transaction" | "classify_image" | "llm_query"
pub payload: serde_json::Value,
}
#[derive(Serialize)]
pub struct AiTaskResult {
pub task_id: String,
pub result: Option<serde_json::Value>,
pub status: String, // "ok" | "model_required" | "error"
pub model: Option<String>,
pub size_mb: Option<u32>,
pub processing_ms: u64,
}- Models stored at
{app_data_dir}/models/{model_name}/ -
get_model_statusTauri command → returns list of installed models + storage bytes (for Models UI) -
download_model(name)Tauri command → streams download, emitsmodel-download-progressevents to frontend - On
ai_taskwith missing model → immediatemodel_requiredresponse (no hanging) - Loaded models cached in
Arc<Mutex<HashMap<String, OnnxSession>>>in Tauri state
The existing image_validation task type in device_linking.rs stays as-is for backward
compatibility with the current Zelara mobile app. Internally, it will route through
ai::dispatcher::dispatch once the ai/ module exists, but the external WSS message type
remains image_validation so no mobile app update is required to maintain recycling validation.
| Current component | What happens in redesign |
|---|---|
DevicePairing.tsx |
Absorbed into Hub view — "Pair New Device" button triggers QR modal |
ProgressDisplay.tsx |
Removed from header; compact points badge only (e.g., "60 pts") |
ModuleList.tsx |
Removed — "modules" concept replaced by connected app cards |
TestingPanel.tsx |
Retained for dev use; debug point controls move to Settings |
New: HubView.tsx
|
Main landing: app cards, activity feed, network status |
New: ModelsView.tsx
|
AI model catalog, download, storage usage |
New: FinanceDashboard.tsx
|
Full-screen Finance analytics (Finance app must be connected) |
New: SettingsView.tsx
|
Network config, BLE toggle, storage paths, debug controls |
App.tsx router:
type View = 'hub' | 'models' | 'finance' | 'settings';Side nav layout (icon + label, minimal):
💻 Hub
🧠 AI Models
💰 Finance
⚙️ Settings
| Capability | v0.6.0 | v0.7.0 | v1.x |
|---|---|---|---|
| Recycling CV (MobileNet) | ✓ existing | ✓ | ✓ |
| Receipt OCR (PaddleOCR v5) | ✓ | ✓ | ✓ |
| Transaction categorization (DistilBERT) | ✓ | ✓ | ✓ |
| Rule-based spend coaching | ✓ | ✓ | ✓ |
| Finance desktop dashboard | ✓ | ✓ | ✓ |
| Local LLM spend coaching (Mistral 7B) | deferred | ✓ | ✓ |
| Document intelligence (general) | — | ✓ | ✓ |
| Health/fitness CV models | — | — | ✓ |
Zelara Core (Desktop)
├── powers → Zelara Finance (receipt OCR, categorization, finance dashboard)
├── powers → Zelara (main app) (recycling CV, progress sync)
└── powers → [future apps] (any AI capability they need)
Zelara Finance → earns points → syncs to Core → Core broadcasts → all connected apps
Zelara (main) → earns points → syncs to Core → Core broadcasts → all connected apps
Core is never a mobile app. It is always the desktop hub. Mobile apps work in degraded mode (rule-based fallbacks) when Core is not connected, and get full AI capabilities when connected.
- Zelara-Finance.md — Zelara Finance standalone app design
- Device-Linking.md — WSS protocol, TLS, BLE auto-discovery
- Architecture.md — Decision log including this redesign decision