Skip to content

Repository files navigation

VagueMemory — AI Memory Engine

You remember the moment. VagueMemory remembers the evidence.

An Android app that searches your gallery by what you remember, not by filename. Type "find that screenshot where my friend sent me Python code" and it finds it.


Quick start (read this first)

This zip contains the Flutter source only. The android/ folder is generated on your machine so it matches your exact Flutter version.

cd find_it
flutter create .                    # generates android/ (keeps all existing files)
dart run tool/patch_android.dart    # adds permissions, sets minSdk 24
flutter pub get
flutter run                         # phone plugged in, USB debugging on

Full step-by-step guide: see SETUP.md.


Architecture

USER MEMORY QUERY
      ↓
AI QUERY INTERPRETER      (OpenRouter, structured JSON)
      ↓
STRUCTURED SEARCH INTENT  (SearchQuery)
      ↓
LOCAL SEARCH ENGINE       (OCR + metadata + deterministic scoring)
      ↓
TOP 3–5 CANDIDATES
      ↓
AI VISION RERANKING       (only the candidates, never the gallery)
      ↓
FINAL RESULTS + EXPLANATION

The differentiator: the LLM never touches the whole gallery. It converts a vague memory into a search plan. The phone does retrieval locally. Only the strongest 4 candidates are ever sent to a vision model.

Files

File Role
lib/models.dart IndexedImage, SearchQuery, SearchResult, AiRankingResult
lib/store.dart AIConfig, persistence, AI event log
lib/indexing.dart MediaStore access, ML Kit OCR, screenshot heuristics, demo data
lib/local_search.dart Local query parser + deterministic scoring engine
lib/ai.dart Prompt templates, OpenRouter client, interpreter, vision reranker, Memory Lens, pipeline
lib/screens.dart Onboarding, Home, Indexing, Results, Detail, AI Console, Settings
lib/main.dart Entry point + Material 3 dark theme

Local fallback

Every AI path has a real local equivalent. If OpenRouter times out, returns invalid JSON, is rate-limited, or there is no network, the app logs the failure, shows AI unavailable — using local search instead, and keeps working.

Local scoring:

Signal Points
Exact OCR keyword +5
Partial OCR keyword +3
Exact phrase +5
Filename match +2
Screenshot match +3
Date match +3
Time match +3
Concept / synonym +2

Scores are normalised to 0–1 and sorted descending.


OpenRouter configuration

  1. Get a key at https://openrouter.ai/keys.
  2. Open the app → Settings → paste the key → SaveTest connection. The key is stored on-device; you can use your own OpenRouter key (or any OpenAI-compatible endpoint + key) and it is never shared.

Or bake it in at build time:

flutter build apk --release --dart-define=OPENROUTER_API_KEY=sk-or-v1-xxxx

Default model: google/gemma-4-31b-it:free (free tier, vision-capable). Model IDs on OpenRouter change often — if you get an error, pick a current vision model from https://openrouter.ai/models and paste the ID into Settings. Free models are rate-limited (roughly 20 requests/minute).

Never commit a real key. .env is gitignored; .env.example is the template.


Prompt engineering

All prompts live in lib/ai.dartPromptTemplates. Nothing is scattered through the UI. The interpreter prompt establishes role, goal, hard rules (never invent, use null when unknown, preserve explicit terms, separate literal OCR terms from semantic concepts), and a strict JSON schema. The model is asked to produce a search plan, never an answer. Every field is validated before it becomes a Dart object; any parse failure drops to the local parser.


Build

flutter analyze
flutter test
flutter build apk --debug
flutter build apk --release

Release output: build/app/outputs/flutter-apk/app-release.apk

Install on a physical device:

flutter devices
flutter install
# or
adb install -r build/app/outputs/flutter-apk/app-release.apk

Competition device: iQOO Android phone. No emulator-only APIs are used.


Demo script

  1. Open VagueMemory, show the home screen and the AI status badge.
  2. Type: Find that screenshot where my friend sent me Python code.
  3. Watch the live pipeline: understanding → searching → candidates → vision.
  4. Show the hero result and the % MEMORY MATCH badge.
  5. Open Why this matched.
  6. Tap Ask AI about thisSummarize this image.
  7. Open the AI Console and explain:

    "The LLM doesn't search my gallery. It converts my vague memory into a structured search plan. The phone performs local retrieval, then vision AI verifies only the strongest candidates."

  8. Turn off AI mode in Settings (or airplane mode), search again — results still work, with the local-fallback notice.

Demo mode

Tap Demo mode on Home to load five bundled scenarios (Python screenshot, 10 AM timetable, restaurant menu, linked list notes, OS notes). Drop matching images into assets/demo/ — see assets/demo/README.txt. Real device indexing remains the primary flow.


Privacy

Your image index stays on your device. VagueMemory only sends selected information to the AI service when AI features are enabled: your typed memory, and up to 4 candidate thumbnails with their extracted text.


Known limitations

  • OCR is Latin-script only.
  • Indexing the full gallery can take a few minutes on large libraries. You can cap it in Settings (full gallery, 300, or 1000 images) — it defaults to all.
  • Vision reranking depends on the chosen model actually supporting images.
  • Free OpenRouter models are rate-limited; a fresh search may fall back to local.
  • No splash screen or transition animations — reliability was prioritised.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages