Multi-phase research orchestration system with provider abstraction and bridge architecture.
Android Client (Compose + Room)
│
▼
Bridge Server (FastAPI, anti-corruption layer)
├──► Multi-provider search routing (OpenAI/Gemini/Anthropic/Groq/OpenRouter)
└──► NotebookLM CLI orchestration (create notebook, add sources, generate artifacts)
Core technical value:
- orchestrating multi-step research workflows on mobile
- keeping provider differences behind one app contract
- isolating NotebookLM CLI/browser automation behind a stable bridge boundary
The Android app does not call NotebookLM CLI directly. A local bridge server provides a stable HTTP contract and hides:
- CLI process execution
- auth/session checks
- output normalization
- provider-specific integration details
This is intentionally an anti-corruption layer: unstable or heterogeneous external behavior is adapted before it reaches app code.
The app uses one search contract (SearchApi.search) regardless of provider. The bridge routes requests by provider and normalizes response shape to:
titleurlreasontype
Current provider adapters:
- OpenAI
- Gemini
- Anthropic
- Groq (OpenAI-compatible)
- OpenRouter (OpenAI-compatible)
NotebookLM integration is treated as a workflow problem, not a direct API call:
- Create notebook when needed
- Add deduplicated sources
- Trigger artifact generation and persist task identifiers
The app persists workflow state locally:
- Room: threads, messages, sources, artifacts
- DataStore: settings (bridge URL, source limit, provider/model)
- EncryptedSharedPreferences: provider API keys (BYOK)
- Multi-step orchestration flow from query to persisted research state
- Unified SearchApi contract across five provider routes
- Bridge anti-corruption layer for NotebookLM CLI and provider differences
- Explicit thread lifecycle with status transitions (
ACTIVE,RESEARCHING,COMPLETED,FAILED) - Source deduplication and bounded source-limit enforcement before insert
- Build-time environment segregation (debug local-network allowances, release hardening)
- Android: Kotlin, Jetpack Compose, Navigation Compose, Hilt
- Persistence: Room, DataStore, EncryptedSharedPreferences
- Networking: Retrofit, OkHttp, Moshi
- Background: WorkManager (present; partial orchestration role)
- Bridge: FastAPI + Uvicorn (Python)
ChatViewModel: query orchestration, thread transitions, search execution, notebook handoff trigger, artifact request triggerResearchRepository: persistence boundary + bridge API accessSearchApi: app-level unified search request contractBridgeApi: notebook/auth/artifact bridge contractbridge-server/server.py: provider routing + NotebookLM CLI adaptation
- Debug:
- local cleartext config for emulator/host development (
10.0.2.2)
- local cleartext config for emulator/host development (
- Release:
- no debug network security config inheritance
- backup/data extraction hardened in manifest
This repository intentionally documents constraints rather than hiding them.
- Artifact status lifecycle is only partially implemented (task start + persistence exist; full polling/reconciliation remains).
- Orchestration is currently centered in
ChatViewModel; worker-based end-to-end orchestration is not fully realized yet. - Bridge runtime is a local dependency; operational reliability depends on local environment and auth state.
- Provider outputs may vary; bridge currently relies on JSON extraction patterns that can require maintenance.
- Local-first architecture avoids mandatory cloud backend but introduces setup friction for some users.
For a structured status matrix, see docs/IMPLEMENTATION_STATUS.md.
- Architecture:
docs/ARCHITECTURE.md - Orchestration workflow:
docs/ORCHESTRATION_FLOW.md - Technical rationale:
docs/ENGINEERING_DECISIONS.md - Implementation status:
docs/IMPLEMENTATION_STATUS.md - Bridge details:
bridge-server/README.md
- Android Studio + JDK 17
- Android SDK 35
- Python 3.10+
- Local NotebookLM CLI environment configured on bridge host
- At least one provider API key
cd bridge-server
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# Set path to your local codex-notebooklm environment if needed
export CODEX_NOTEBOOKLM_DIR="/path/to/codex-notebooklm"
python server.pyBridge defaults to http://localhost:8080.
- Open project in Android Studio.
- Build and run
appmodule. - Set bridge URL in Settings.
- Emulator default:
http://10.0.2.2:8080
- Emulator default:
- Add provider API key(s) in Settings.
- Start a query from Chat screen.
./gradlew testDebugUnitTest lintDebug assembleDebug
python -m py_compile bridge-server/server.py- Do not hardcode provider keys.
- Keep bridge on trusted network/local machine.
- Debug network exceptions are intentionally scoped away from release builds.