Architecture
Two-component architecture: a Go WhatsApp bridge communicating with a Tauri desktop app written entirely in Rust.
High-Level Diagram
Go Bridge (WhatsApp Layer)
The Go bridge uses whatsmeow, a Go library for WhatsApp Web multidevice API.
- • Maintains WebSocket connection to WhatsApp
- • Handles QR code authentication
- • Stores messages in SQLite database (messages.db)
- • Stores session/auth data in whatsapp.db
- New: Stores contacts in a
contactstable viaStoreContact(), populated onhandleMessage()andhandleHistorySync() - New: API key authentication via
checkAPIKey()middleware — validatesAuthorization: Bearer <key>on/api/sendand/api/download - Exposes REST API on port 8080
Tauri Desktop App (Rust)
The desktop app is built with Tauri v2 and contains all core logic in Rust:
Mesh API Provider (meshapi.ai)
Single MeshApiProvider implements the LLMProvider trait. Routes to 1000+ models via one API key. Supports GET /v1/models for live model listing, GET /v1/models/:id for per-model details (pricing, capabilities, context).
Policy Engine
Propose → Evaluate → Execute. Per-tool permissions, allowlist, contact modes, risk-level classification.
Action Engine
Structured action types with platform-specific executors. Shell disabled by default.
Undo Journal
Every action logged with reverse action. Undo with a single command.
Pending Actions
Medium/high-risk tool calls enter a PendingAction queue. ActionStep structs parsed via parse_ai_response() (returns Vec<ActionStep>). Supports thinking blocks, delays, and batch approval.
Config Persistence
Policy state (allowlist, permissions, contact modes) auto-saved to credential store. Restored on startup via save_config/load_config/clear_config.
Credential Storage (Cross-Platform)
Whatszara uses the keyring crate which transparently maps to the platform-native credential store:
macOS
iCloud Keychain (via Security framework)
Windows
Credential Manager (via wincred)
Linux
Secret Service / keyutils
Two entries are stored, each with service name and username whatszara:
WhatsApp Session Auth
Service: whatszara-wa-session. On bridge connect, whatsapp.db is base64-encoded and stored. On startup, it's decoded and restored — no QR scan needed.
Policy Config
Service: whatszara-config. Stores allowlist, tool permissions, contact modes. Auto-saved on every change. Auto-loaded on startup.
Mesh API Config
Service: whatszara-model-active and whatszara-model-model. Persists active provider and selected model across restarts via save_model_config() / load_model_config().
Keychain Utilities
save_keychain(), load_keychain(), delete_keychain() wrap the keyring crate's Entry::set_password/get_password/delete_credential.
Logout
Kills the bridge, deletes both credential store entries, removes the session file, and clears QR state — requiring a fresh scan.
BYOK (Bring Your Own Key)
Mesh API supports passing upstream provider keys via custom HTTP headers. This lets users use their own OpenAI, Anthropic, or Groq accounts through the Mesh API router, getting unified billing and model management while keeping their existing subscriptions.
// Mesh API sends these headers to upstream providers:
x-mesh-openai-key → OpenAI
x-mesh-anthropic-key → Anthropic
x-mesh-groq-key → Groq
// The Rust backend passes them automatically:
headers.insert("x-mesh-openai-key", openai_key);
headers.insert("x-mesh-anthropic-key", anthropic_key);
headers.insert("x-mesh-groq-key", groq_key);Risk / Approval Flow
In Assistant mode, when the LLM proposes actions, the orchestrator evaluates their risk level:
Low Risk
Auto-executed immediately. Read-only operations like get_volume, list_files.
Medium Risk
Creates a PendingAction in the queue. Requires GUI approval. Operations like open_app, set_volume.
High Risk
Creates a PendingAction. Always requires explicit approval — trust sessions cannot bypass. Shell commands and destructive operations. May also require CaptchaChallenge — an image-based reCAPTCHA (beta/experimental) rendered as a local PNG with random characters for the user to solve in the GUI.
Implementation
- •
parse_ai_response()returnsVec<ActionStep>— each step is a tool call, thinking block, or delay - •
ActionStepenum:ToolCall,Thinking,Delay - •
PendingActionstruct: id, tool, params, risk, timestamp, sender, thinking, delay_ms - •
approve_pending_action()executes the action and logs it - •
reject_pending_action()discards with a notification - •
approve_all_actions()/reject_all_actions()for batch approval - • Frontend polls
get_pending_actionsevery 3 seconds
Data Flow
parse_ai_response() extracts Vec<ActionStep> (tool calls, thinking blocks, delays) → Policy engine evaluates each action's risk