Architecture
Layers
UI (screens / widgets)
│
ModelOrchestrator ←── MemoryService (RAG), MCP, Tasks, Notes
│
flutter_gemma / LiteRT-LM
│
Platform channels → Android (tools, screenshot, assistant key)
Key Dart services
| Service | Role |
|---|---|
ModelOrchestrator |
Model load/unload, chat stream, tool loop, idle release |
ModelManager |
Download, disk register, prefs sync |
MemoryService |
Local RAG / conversation memory |
ToolExecutorService |
MethodChannel + progress EventChannel |
ScreenshotService |
MediaProjection frames via dedicated channel |
McpService / McpClient |
External MCP (HTTP/SSE, stdio) |
ParallelSessionManager |
Multi-chat (capped on Android) |
PlatformAdaptationService |
Platform capability flags + RAM warnings |
Inference pipeline
- User sends message (optional image / attachments)
- RAG context retrieved
- Model selected (
ModelSelector) or override from UI - Engine loaded with
supportImagewhen the model has vision - Stream tokens via
generateChatResponseAsync - Tool calls executed; results fed back (multi-round)
- Idle timer / lifecycle may unload the model only after streaming ends
Native Android
| Component | Purpose |
|---|---|
MainActivity |
Flutter host, channels, MediaProjection result |
AssistantActivity |
System assistant entry + screenshot handoff |
ScreenCaptureHelper |
MediaProjection, on-demand JPEG frames |
MediaProjectionService |
FGS for API 34+ projection |
ToolExecutor |
Alarms, apps, SMS, weather, etc. |
Stability rules (critical)
- Never
close()the LiteRT engine while_isStreamingis true (SIGABRT) - Vision models must load with
supportImage: trueeven for text-only first turns - Screenshot bytes travel via
ScreenshotService, not large MethodChannel maps - Prefer SmolLM / Gemma 3 1B on ≤6 GB RAM devices for long debug sessions