Skip to main content

Architecture Overview

Evatar uses a three-tier architecture with frontend-backend separation, consisting of Android Client, Python Backend, and React Web Frontend, communicating via REST API.


System Architecture​


Core Components​

Backend Service Layer​

The backend is based on the FastAPI framework, using SQLAlchemy ORM with SQLite database. Core modules:

ModuleFileResponsibility
App Entrymain.pyFastAPI app initialization, CORS, auth middleware, rate limiting
Configconfig.pyPydantic Settings, env var prefix EVATAR_
Data Modelsmodels.pySQLAlchemy declarative models, all table definitions
Screenshot Pipelineservices/pipeline.pyReceives photo_id, calls LLM Vision API to analyze screenshots
Agent Chat Engineservices/agent.pyMulti-turn dialogue, tool call loop (max 3 rounds), user memory injection
Intent Reasonerservices/reasoner.pyBackground scheduled analysis of recent activity, generates structured notes
Memory Systemservices/memory.pyShort-term (48h expiry) and long-term (permanent) memory, LLM extraction + dedup + decay
RAG Retrievalservices/rag.pyFTS5 full-text search + keyword fuzzy matching
LLM Clientservices/llm.pyShared httpx.AsyncClient, supports Vision multimodal and Tool Calling
Schedulerservices/scheduler.pyHourly reasoning, daily memory decay, daily data cleanup
Push Notificationsservices/push.pyBroadcast push to all registered devices (FCM / Webhook)
Data Encryptionservices/encryption.pyFernet symmetric encryption, auto key management, key rotation
Data Retentionservices/retention.pyCleanup expired data by day count
Web Searchservices/search.pyTavily API preferred, Brave Search as fallback
File Storageservices/storage.pySave original images and thumbnails

API Routes​

Route PrefixFileMain Endpoints
/api/photosapi/photos.pyPOST /upload, POST /upload-batch, GET / (list), GET /{id}, GET /{id}/image, GET /sync-state
/api/chatapi/chat.pyPOST /send, POST /send-with-file, GET /conversations, GET /conversations/{id}
/api/dynamicsapi/dynamics.pyGET / (cursor pagination), GET /{id}, PUT /{id}/read, POST /trigger
/api/memoriesapi/memories.pyGET /, GET /stats
/api/configapi/config.pyGET /llm, PUT /llm, GET /llm/presets
/api/skillsapi/skills.pyGET /, GET /{id}
/api/pushapi/push.pyPOST /register, POST /test
/api/healthmain.pyGET / -- returns {"status": "ok"}

Middleware​

Authentication Middleware​

When EVATAR_API_KEY is set, all requests except / and /api/health require a Bearer <key> in the Authorization header. Uses hmac.compare_digest for secure comparison.

Rate Limiting Middleware​

IP-level rate limiting (10 requests per minute) on the following high-frequency endpoints:

  • /api/chat/send
  • /api/chat/send-with-file
  • /api/dynamics/trigger

Android Client Architecture​

The Android client uses the MVVM pattern, built with Jetpack Compose:

ComponentFileResponsibility
MainActivityMainActivity.ktApp entry, permission requests, theme/language switching, onboarding flow
AppNavigationui/AppNavigation.ktBottom navigation: Dynamics / Chat / Settings tabs
OnboardingScreenui/screens/OnboardingScreen.ktFirst-use guide: server config -> sync range -> sync execution
ChatTabui/screens/ChatTab.ktChat interface, supports Markdown rendering and file attachments
DynamicTabui/screens/DynamicTab.ktDynamic notes list, cursor pagination + infinite scroll
SettingsTabui/screens/SettingsTab.ktSettings page: theme, language, server config
SyncManagersync/SyncManager.ktScreenshot scanning (MediaStore) and concurrent upload (Semaphore(3))
SyncWorkersync/SyncWorker.ktWorkManager CoroutineWorker, background scheduled sync
SyncServicesync/SyncService.ktForeground Service, keeps sync task running continuously
ApiClientnetwork/ApiClient.ktOkHttp singleton, retry logic (max 3 times, exponential backoff)
ChatViewModelviewmodel/ChatViewModel.ktChat state management
DynamicViewModelviewmodel/DynamicViewModel.ktDynamic notes state management

Background Tasks​

The backend includes a scheduler (services/scheduler.py) running via asyncio.create_task:

TaskIntervalDescription
Intent Reasoning1 hourCollects recent screenshots, chats, memories, calls LLM to generate note articles
Memory Decay24 hoursDeletes expired short-term memories, reduces long-term memory importance
Data Cleanup24 hoursCleans expired data per EVATAR_RETENTION_DAYS (default 30 days)

Additionally, every 3 screenshot analyses completed (_REASONING_TRIGGER_EVERY = 3), a reasoning cycle is automatically triggered.