- Dart 99.1%
- Kotlin 0.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
Build Mind-Forge Pro APK / Build release APK (arm64) (push) Has been cancelled
Add a persistent Settings tab so users can point Mind-Forge at any OpenAI-compatible API or Ollama host instead of (or alongside) the local llama.cpp engine. - app_settings.dart: shared_preferences-backed singleton storing the chat backend (local/openai/ollama), OpenAI base URL + API key + model, and Ollama host + model. Blank fields gracefully fall back to https://api.openai.com/v1 and http://localhost:11434. - api_client.dart: RemoteApiClient abstraction with OpenAI-compatible /chat/completions and Ollama /api/chat clients. Clients read configuration from AppSettings at every call, so edits apply immediately without restarting. OpenAI key is optional (no auth header for local servers). - chat_logic.dart: send() picks the active RemoteApiClient from settings and routes turns through it; the agentic retry loop works for both remote and local backends. - main.dart: new Settings tab (backend selector + endpoint fields), async settings load before runApp, and a chat banner showing the active backend / prompting to load a model for local mode. - pubspec.yaml: add shared_preferences and http dependencies. |
||
| .github/workflows | ||
| android | ||
| lib | ||
| .gitignore | ||
| LICENSE | ||
| pubspec.yaml | ||
| README.md | ||
Mind-Forge Pro
An offline, on-device "second brain" AI agent for Android. No Termux, no external Ollama server — the app embeds llama.cpp natively via Dart FFI and serves itself over a local HTTP API.
How it works
- Chat — talk to a locally-loaded
.ggufmodel. Every turn is grounded with a lightweight TF-IDF retrieval pass over your own stored notes (lib/memory_agent.dart) before it reaches the model. - Memory DB — browse, inspect, and delete anything the app has remembered (SQLite, on-device only).
- Server Config — pick a
.gguffile from local storage and start a local API server (http://127.0.0.1:<port>/api/generate) that any other app or script on the device can call.
Architecture
| Layer | Tech |
|---|---|
| UI | Flutter (Material 3) |
| Inference | llama_cpp_dart 0.9.x, off the UI thread via LlamaEngine/EngineSession |
| Local server | shelf + shelf_router |
| Memory / RAG | sqflite + a pure-Dart TF-IDF keyword ranker |
| Native actions | a MethodChannel the model can trigger via <ACTION: X> tags |
Building
CI (.github/workflows/build-apk.yml) does everything needed for a
sideloadable release APK — no production keystore required:
- Downloads
llama_cpp_dart's prebuilt Android AAR (CPU + mtmd, arm64-v8a) from its GitHub Releases, matching the exact version pinned inpubspec.yaml, intoandroid/app/libs/llama-cpp-dart.aar. No native compilation happens in this project at all — 0.9.x ships binaries built against its own pinned llama.cpp commit, which is also why the earlier from-source NDK build (against an unpinned llama.cpp clone) kept hitting ABI mismatches. - Runs
flutter build apk --release --target-platform android-arm64with R8/ProGuard shrinking and native debug-symbol stripping enabled (android/app/build.gradle). - Signs the release build with the standard Android debug keystore, cached across runs so every build shares the same signing key — that's what lets you install an updated APK over a previous one without uninstalling first. (This is fine for sideloading; it is not a Play Store–ready signature.)
- Uploads the finished APK as a workflow artifact.
To build locally instead, download llama-cpp-dart.aar yourself (see
the package's install instructions)
into android/app/libs/ before running flutter build apk.
Status
Early scaffold — chat, memory, and server-management UI are wired up;
model loading and generation go through llama_cpp_dart's LlamaEngine/
EngineSession API (0.9.x line — a prerelease, still pre-1.0 with
occasional breaking changes). Verify current API shape against whatever
llama_cpp_dart version is pinned in pubspec.yaml before assuming any
snippet here still matches.