# superintelligence-android Fork of [superintelligence (JG2HQZWB/superintelligence)](https://notdouble.com/p/JG2HQZWB/superintelligence) — the same hands-on LLM agent, ported from a Rust terminal CLI to an **Android app**: Kotlin + Jetpack Compose, a streaming OpenAI-compatible client, and dialogs instead of `[Y/n]` prompts. ## What it does Point the app at any OpenAI-compatible server (llama-server, LiteLLM, vLLM — anything exposing `/v1/chat/completions` and streaming SSE) and it behaves like the CLI original: - **Streams replies** (SSE) with tool-call deltas assembled as they arrive. - **Tools** the model can call, scoped to the app's private working directory (`Android/data/net.kentonc.si/files`): - `read_file(path)` - `list_dir(path?)` - `search(pattern, path?, include?)` — regex walk, skips binaries/`.git`/`target`/… - `write_file(path, content)` — **approval dialog** - `run_shell(command)` — runs `sh -c` in the working root, 60s timeout — **approval dialog** - **Image attachments** via the system photo picker (png/jpeg/gif/webp, 20 MB cap). - **Markdown replies** rendered with a small built-in renderer (headings, lists, code fences, blockquotes, inline formatting). - Approvals: `write_file` / `run_shell` pop a dialog; the tool stays parked (a `CompletableDeferred`) until you tap **Run it** / **Decline**. Declines are reported back to the model exactly as the CLI does. Settings has an auto-approve switch, equivalent to the CLI's `--yes`. The same guardrails from the Rust port carried over: paths can't escape the working root, tool output is truncated (16 KB), shell commands time out at 60s, a tool-budget of 50 rounds per turn, and on any error the turn's messages are rolled back out of the history. ## Config Everything else you'd find in `src/config.rs` in the CLI owner is editable in the app's **Settings** screen (persisted in SharedPreferences): base URL, API key, model, temperature, max tokens, auto-approve. Settings default mirrors the CLI (`http://127.0.0.1:8085`, model `Qwen3.8-27B-GSQ-RCO-IQ3_XXS-mtp.gguf`) — point it at a server on your LAN instead (Ollama is `http://:11434`, llama-server is `http://:8085`). Cleartext http is allowed on purpose for exactly that. Opening Settings auto-lists the models the selected server serves — from Ollama's `/api/tags` (with on-disk sizes) or any OpenAI-compatible `/v1/models` — as a dropdown, so you never have to type a model name; typing a custom one still works. ## Build Requires Android SDK (platform 35, build-tools 35) and a JDK 17+: ```sh cd android && ./gradlew :app:assembleDebug # -> android/app/build/outputs/apk/debug/app-debug.apk ``` Gradle 8.10.2 + AGP 8.7.3 + Kotlin 2.0.21 + Compose BOM 2024.12.01. A wrapper is included, so no local Gradle install is needed. Install on a device: ```sh adb install android/app/build/outputs/apk/debug/app-debug.apk adb shell am start -n net.kentonc.si/.MainActivity ``` ## Install the APK A ready-to-install debug APK ships **inside this project's bundle** (releases tab → "artifacts in the bundle"), extracted under `bin/`. The name embeds the release version, e.g.: ```sh tar -xf superintelligence-android.tar.gz bin/superintelligence-android-0.2.3.apk adb install bin/superintelligence-android-0.2.3.apk adb shell am start -n net.kentonc.si/.MainActivity ``` It's the standard debug signature (installable directly); versionName matches the project version on the hub. ## In-app self-update From **0.2.3 on**, the app checks the hub on launch and shows a deep-update icon in the top bar whenever `notdouble.com` has a newer release than the installed build. Tap it: it downloads the new APK into app cache (with an in-bar progress ring) and launches the system installer. The first update needs the "allow installs from this app" toggle (Android requires it for anything sideloaded); the app walks you to it, remember to come back and tap the button again. After that first grant, updates are one tap with no re-download of anything. ## Build the Rust original is still here This fork deliberately kept the original CLI sources untouched — `src/`, `Cargo.toml`, and `make build` still produce the `si` terminal binary on any machine. The Android port is a sibling of the CLI, not a replacement of it; both share the same mental model of tools and approvals. ## Layout ``` android/ the new thing: the Android app app/src/main/java/net/kentonc/si/ agent/ Agent.kt LlmClient.kt Tools.kt Models.kt Settings.kt (the port of src/llm.rs + src/tools.rs + src/config.rs) ui/ ChatScreen.kt SettingsScreen.kt MarkdownText.kt Theme.kt AgentViewModel.kt MainActivity.kt src/ the original Rust CLI (unchanged) ``` ## Publish to the hub ```sh make upload # nd validate && nd upload ``` This directory ships to the hub as `JG2HQZWB/superintelligence-android` (fork lineage points at `JG2HQZWB/superintelligence`). Build artifacts (`target/`, Gradle `build/` dirs, APKs) are excluded via `.ndignore`.