{"id":45692882,"url":"https://github.com/lettuceai/app","last_synced_at":"2026-05-30T18:00:42.492Z","repository":{"id":312330400,"uuid":"1046859543","full_name":"LettuceAI/app","owner":"LettuceAI","description":" Privacy-first AI roleplay \u0026 BYOK (Bring Your Own Key) \u0026 roleplaying, companion and storytelling app with long-term memory, custom characters, and 20+ providers. Android, Windows, macOS, Linux. Supports 20+ LLM Providers.","archived":false,"fork":false,"pushed_at":"2026-05-25T22:13:31.000Z","size":98711,"stargazers_count":62,"open_issues_count":5,"forks_count":15,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-05-26T00:25:56.992Z","etag":null,"topics":["ai","airoleplay","llamacpp","local-ai","mobile","ollama","privacy","react","roleplay","roleplaying","rp","sillytavern","tauri"],"latest_commit_sha":null,"homepage":"https://lettuceai.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LettuceAI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-29T10:43:44.000Z","updated_at":"2026-05-25T22:13:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"ac344c79-1103-416f-aef4-9e6e41aaf5fa","html_url":"https://github.com/LettuceAI/app","commit_stats":null,"previous_names":["lettuceai/mobile-app","lettuceai/app"],"tags_count":133,"template":false,"template_full_name":null,"purl":"pkg:github/LettuceAI/app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LettuceAI%2Fapp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LettuceAI%2Fapp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LettuceAI%2Fapp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LettuceAI%2Fapp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LettuceAI","download_url":"https://codeload.github.com/LettuceAI/app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LettuceAI%2Fapp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33703065,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","airoleplay","llamacpp","local-ai","mobile","ollama","privacy","react","roleplay","roleplaying","rp","sillytavern","tauri"],"created_at":"2026-02-24T18:41:36.925Z","updated_at":"2026-05-30T18:00:42.464Z","avatar_url":"https://github.com/LettuceAI.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/LettuceAI/.github/blob/main/profile/LettuceAI-banner.png\" alt=\"LettuceAI Banner\" /\u003e\n\n\n   \n  # LettuceAI\n  \n  Privacy-first AI roleplay \u0026 storytelling app with long-term memory, custom characters, and 20+ providers. Runs on Android, Windows, macOS, and Linux.\n  \n  [Overview](#overview) • [Install](#install) • [Development](#development) • [Android](#android) • [iOS](#ios) • [Contributing](#contributing)\n\u003c/div\u003e\n\n## Overview\n\nLettuceAI is a privacy-focused, free and open-source AI character chat app for immersive roleplay, storytelling, and realistic AI companions with long-term memory that actually lasts.\n\nIt is client-side first and supports 20+ AI providers with a bring-your-own-key setup, including OpenAI, Anthropic, Google Gemini, DeepSeek, Mistral, and Groq, plus local models through Ollama and `llama.cpp`.\n\nLettuceAI is fully free and open source with no paywalls or locked features. Your chats, characters, memories, and API keys stay on your device, so you control your data.\n\n## Screenshots\n\n### Core Experience\n\n| Chat | Character Editor |\n| --- | --- |\n| ![Chat screen](docs/readme/chat.png) | ![Character editor](docs/readme/character_editor.png) |\n| Live roleplay chat with character-aware UI. | Build and refine character identity, definition, and avatar. |\n\n| Memory | Image Generation |\n| --- | --- |\n| ![Memory screen](docs/readme/memory.png) | ![Image prompt and result](docs/readme/image_prompt.png) |\n| Review context summaries and manage saved memories. | Generate character visuals directly from prompts. |\n\n### Advanced Controls\n\n| Models | System Prompt Editor |\n| --- | --- |\n| ![Models screen](docs/readme/models.png) | ![System prompt editor](docs/readme/system_prompt_editor.png) |\n| Configure local or remote model backends. | Edit structured prompt templates and variables. |\n\nScreenshots feature “King Cassian” by [jawawgf](https://character-tavern.com/character/jawawgf/king_cassian), used for demonstration.\n\n## Install\n\n### Prerequisites\n\n- Bun 1.1+ (includes Node.js compatibility): https://bun.sh/\n- Rust 1.70+ and Cargo\n- Android SDK (optional, for Android builds)\n- Xcode + iOS SDK (optional, for iOS builds, macOS only)\n\n### Quick Start\n\n```bash\n# Clone the repository\ngit clone https://github.com/LettuceAI/mobile-app.git\ncd mobile-app\n\n# Install dependencies\nbun install\n```\n\n## Development\n\n### Common Commands\n\n```bash\n# Frontend only\nbun run dev\nbun run build\n\n# Desktop (default Tauri flow)\nbun run tauri dev\nbun run tauri build\n\n# Linux / Wayland fallback if the normal Tauri run has WebKit issues\nbun run tauri:dev:webkit-safe\nbun run tauri:build:webkit-safe\n\n# Desktop with NVIDIA CUDA llama.cpp acceleration (auto-detect local GPU arch)\nbun run tauri:dev:cuda:auto\nbun run tauri:build:cuda:auto\n\n# Desktop with Vulkan llama.cpp acceleration (AMD/Intel/NVIDIA, driver-dependent)\nbun run tauri dev --features llama-gpu-vulkan\nbun run tauri build --features llama-gpu-vulkan\n\n# Desktop with Metal llama.cpp acceleration (Apple Silicon/Intel Macs, macOS only)\nbun run tauri:dev:metal\nbun run tauri:build:metal\nbun run tauri:build:macos\n\n# Android\nbun run tauri:android:init\nbun run tauri:android:dev\nbun run tauri:android:build\n\n# iOS (macOS only)\nbun run tauri:ios:init\nbun run tauri:ios:dev:ready\nbun run tauri:ios:build:ready\n\n# Quality\nbunx tsc --noEmit\nbun run check\ncd src-tauri \u0026\u0026 cargo fmt \u0026\u0026 cargo check\n```\n\n### Which Command Should I Use?\n\n- Use `bun run tauri dev` / `bun run tauri build` for normal desktop work.\n- If you are on Linux and experiencing Wayland / WebKit issues, try\n  `bun run tauri:dev:webkit-safe` or `bun run tauri:build:webkit-safe`.\n- Use `bun run tauri:dev:cuda:auto` or `...build:cuda:auto` on NVIDIA systems.\n  These wrappers auto-detect `CMAKE_CUDA_ARCHITECTURES` and apply Linux PIC flags.\n- Use `bun run tauri:android:dev` / `...build` for Android instead of raw\n  `tauri android ...`.\n  The wrapper:\n  - forces a repo-local temp dir under `.tmp/android-build`\n  - reapplies the Android override templates before each run\n- Use `bun run tauri:ios:dev:ready` / `...build:ready` for iOS unless you are\n  managing ONNX Runtime slices manually.\n\n### Windows Shortcuts\n\nIf some contributors are more comfortable with `.cmd` or PowerShell entry points,\nthe repo also includes wrappers under `scripts/windows/`:\n\n```powershell\n.\\scripts\\windows\\desktop-dev.ps1\n.\\scripts\\windows\\desktop-build.ps1\n.\\scripts\\windows\\android-init.ps1\n.\\scripts\\windows\\android-dev.ps1\n.\\scripts\\windows\\android-build.ps1\n.\\scripts\\windows\\check.ps1\n```\n\n```bat\nscripts\\windows\\desktop-dev.cmd\nscripts\\windows\\desktop-build.cmd\nscripts\\windows\\android-init.cmd\nscripts\\windows\\android-dev.cmd\nscripts\\windows\\android-build.cmd\nscripts\\windows\\check.cmd\n```\n\n## Kokoro TTS / eSpeak NG\n\nKokoro TTS phonemization is powered by eSpeak NG. Desktop builds shell out to a\nsystem-installed `espeak-ng`; Android builds link against a bundled native\n`libttsespeak.so` (see the [Android](#android) section for the bundle flow).\n\n### Desktop install (Windows / macOS / Linux)\n\nIf `espeak-ng` is not on `PATH`, the app surfaces this same guidance at runtime.\nInstall it once and restart the app:\n\n- **Windows**\n\n  ```powershell\n  winget install eSpeak-NG.eSpeak-NG\n  ```\n\n  Or download an installer from the [eSpeak NG releases](https://github.com/espeak-ng/espeak-ng/releases).\n  Make sure the install directory is on `PATH` so the `espeak-ng` command resolves\n  in a fresh shell.\n\n- **macOS**\n\n  ```bash\n  brew install espeak-ng\n  ```\n\n- **Linux**\n\n  ```bash\n  # Ubuntu / Debian\n  sudo apt install espeak-ng\n\n  # Fedora\n  sudo dnf install espeak-ng\n\n  # Arch / Manjaro\n  sudo pacman -S espeak-ng\n  ```\n\nYou can also point the app at a custom binary or data dir from the TTS settings\npanel, which maps to `EspeakConfig { bin_path, data_path }` and overrides the\nPATH lookup.\n\n## Android\n\n### Setup\n\n- Install Android Studio and let it install:\n  - Android SDK\n  - Android SDK Platform-Tools\n  - Android command-line tools\n  - Android NDK\n- Use JDK 17 or newer\n- Set these env vars in your shell startup files so both interactive shells and\n  non-interactive `bash -lc` builds see the same Android toolchain:\n\n  ```bash\n  export ANDROID_SDK_ROOT=\"$HOME/Android/Sdk\"\n  export ANDROID_HOME=\"$ANDROID_SDK_ROOT\"\n  export ANDROID_NDK_HOME=\"$ANDROID_SDK_ROOT/ndk/\u003cyour-installed-ndk\u003e\"\n  export NDK_HOME=\"$ANDROID_NDK_HOME\"\n  export PATH=\"$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$PATH\"\n  ```\n\n  PowerShell equivalent for the current session:\n\n  ```powershell\n  $env:ANDROID_SDK_ROOT = \"$HOME\\Android\\Sdk\"\n  $env:ANDROID_HOME = $env:ANDROID_SDK_ROOT\n  $env:ANDROID_NDK_HOME = \"$env:ANDROID_SDK_ROOT\\ndk\\\u003cyour-installed-ndk\u003e\"\n  $env:NDK_HOME = $env:ANDROID_NDK_HOME\n  $env:PATH = \"$env:ANDROID_SDK_ROOT\\platform-tools;$env:ANDROID_SDK_ROOT\\emulator;$env:ANDROID_SDK_ROOT\\cmdline-tools\\latest\\bin;$env:PATH\"\n  ```\n\n- If you use `fish`, set the same values there too. The most common failure mode\n  is having `fish` point at one SDK and `bash -lc` point at another.\n- Verify your environment before building:\n\n  ```bash\n  bash -lc 'echo ANDROID_HOME=$ANDROID_HOME; echo ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT; echo ANDROID_NDK_HOME=$ANDROID_NDK_HOME; echo NDK_HOME=$NDK_HOME'\n  ```\n\n- Initialize the Android project once:\n\n  ```bash\n  bun run tauri:android:init\n  ```\n\n### Kokoro TTS / eSpeak NG bundle\n\nAndroid builds use the on-device Kokoro TTS pipeline, which calls eSpeak NG natively\nthrough `libttsespeak.so` plus the `espeak-ng-data` voice tables. These artifacts are\n**not** committed (`jniLibs/**/*.so` is gitignored), so every Android build must\nprovision them before `tauri android build` runs. `src-tauri/build.rs` enforces this\nand refuses to build without them.\n\nThe Rust JNI side resolves the Kotlin bridge class from `tauri.conf.json::identifier`\nat compile time (or from `KOKORO_ANDROID_BRIDGE_CLASS` if set), so flavors with\ndifferent package identifiers work out of the box.\n\nThere are four supported ways to provide the bundle:\n\n1. **Default project bundle URL**\n\n   If neither `KOKORO_ESPEAK_ANDROID_BUNDLE_PATH` nor\n   `KOKORO_ESPEAK_ANDROID_BUNDLE_URL` is set, `src-tauri/build.rs` automatically\n   downloads the current default bundle from the project release:\n\n   ```text\n   https://github.com/LettuceAI/app/releases/download/espeak-android-bundle-v2/kokoro-espeak-android-bundle.tar.gz\n   ```\n\n   This is the easiest path for most contributors and for CI.\n\n2. **Local bundle build**\n\n   ```bash\n   ANDROID_SDK_ROOT=$ANDROID_HOME bash scripts/build-espeak-android-bundle.sh\n   export KOKORO_ESPEAK_ANDROID_BUNDLE_PATH=/tmp/kokoro-espeak-android-bundle.tar.gz\n   bun run tauri:android:dev   # or `bun run tauri:android:build`\n   ```\n\n   The script clones eSpeak NG into `/tmp/espeak-ng-android-build`, runs\n   `./gradlew :app:assembleRelease` (Gradle pulls the matching NDK + CMake on demand),\n   and produces a tarball with the layout `build.rs` expects:\n\n   ```text\n   jniLibs/arm64-v8a/libttsespeak.so\n   jniLibs/armeabi-v7a/libttsespeak.so\n   jniLibs/x86/libttsespeak.so\n   jniLibs/x86_64/libttsespeak.so\n   espeak-ng-data/...\n   ```\n\n   Override defaults with `ESPEAK_NG_REPO`, `ESPEAK_NG_REF`, `OUTPUT_BUNDLE`, or\n   `WORK_DIR`.\n\n   This helper is currently a Bash script. On Windows, most contributors should\n   prefer the default release bundle URL or provide `KOKORO_ESPEAK_ANDROID_BUNDLE_URL`\n   / `KOKORO_ESPEAK_ANDROID_BUNDLE_PATH` directly instead of trying to build the\n   bundle locally.\n\n3. **Remote bundle override**\n\n   Point `build.rs` at any HTTP-reachable tarball/zip with the same layout:\n\n   ```bash\n   export KOKORO_ESPEAK_ANDROID_BUNDLE_URL=https://example.com/kokoro-espeak-android-bundle.tar.gz\n   ```\n\n4. **Already-installed artifacts**\n\n   If `gen/android/app/src/main/jniLibs/\u003cabi\u003e/libttsespeak.so` and\n   `gen/android/app/src/main/assets/kokoro/espeak-ng-data/phontab` already exist,\n   `build.rs` reuses them and skips fetching anything.\n\n### Build and Run\n\n```bash\n# Run on Android emulator / attached device\nbun run tauri:android:dev\n\n# Build Android APK\nbun run tauri:android:build\n```\n\n### Notes\n\n- `whisper-rs` Android builds expect a working NDK/CMake toolchain. If Android\n  Rust builds fail in `whisper-rs-sys`, check your `ANDROID_NDK_HOME` / `NDK_HOME`\n  first.\n- If Android builds fail in `tauri-plugin-fs` with a `File exists (os error 17)`\n  error under the Cargo registry, clear the Cargo build outputs and retry:\n\n  ```bash\n  cargo clean --manifest-path src-tauri/Cargo.toml\n  ```\n\n### CI bundle workflow\n\nThe repo ships a dedicated workflow that builds and publishes the bundle as a\nGitHub release asset, and the Android dev/release workflows download and verify it\nbefore each build:\n\n- `.github/workflows/espeak-android-bundle.yml` — `workflow_dispatch` only.\n  Inputs: `tag` (release tag, e.g. `espeak-android-bundle-v1`), `espeak_ref`,\n  `espeak_repo`, `prerelease`. Uploads `kokoro-espeak-android-bundle.tar.gz` plus a\n  `.sha256` sidecar to the chosen release tag.\n- `.github/espeak-android-bundle.env` — pin file consumed by both Android workflows:\n\n  ```bash\n  BUNDLE_TAG=espeak-android-bundle-v1\n  BUNDLE_ASSET=kokoro-espeak-android-bundle.tar.gz\n  BUNDLE_SHA256=\u003csha256 of the published asset\u003e\n  ESPEAK_NG_REF=master\n  ```\n\n- `.github/workflows/android-build.yml` and `.github/workflows/android-release-build.yml`\n  source the pin file, `gh release download` the asset into `RUNNER_TEMP`, verify\n  the sha256, and export `KOKORO_ESPEAK_ANDROID_BUNDLE_PATH` before\n  `tauri android build`.\n\nTo roll out a new bundle: dispatch `Build / eSpeak NG Android Bundle` with a fresh\ntag, copy the printed `BUNDLE_TAG` / `BUNDLE_SHA256` block from the release notes\ninto `.github/espeak-android-bundle.env`, and commit. From then on Android CI\nbuilds pick it up automatically.\n\n## iOS\n\n### Setup (macOS only)\n\n- Install Xcode from the App Store\n- Install Xcode command-line tools: `xcode-select --install`\n- Install CocoaPods: `sudo gem install cocoapods` (or Homebrew)\n- Provide ONNX Runtime for iOS with CoreML support:\n  - Build/download an iOS-compatible ONNX Runtime package that includes CoreML EP\n  - Set `ORT_LIB_LOCATION` to the directory containing the ONNX Runtime libraries before building\n- Initialize iOS project files:\n\n```bash\nexport ORT_LIB_LOCATION=/absolute/path/to/onnxruntime/ios/libs\nbun run tauri:ios:init\n```\n\n### Build and Run\n\n```bash\n# Run on iOS simulator/device (from macOS)\nbun run tauri:ios:dev:ready\n\n# Build iOS app\nbun run tauri:ios:build:ready\n```\n\nFor `llama-gpu-cuda`, install the NVIDIA CUDA toolkit and driver on the build machine.\nFor `llama-gpu-metal`, build on macOS with Xcode command-line tools installed.\n\n## macOS Distribution\n\nBuild a native macOS app bundle and DMG installer on macOS:\n\n```bash\nbun run tauri:build:macos\n```\n\nThe build script auto-downloads a compatible ONNX Runtime dylib for macOS into `src-tauri/onnxruntime` (unless `ORT_LIB_LOCATION` is explicitly set), and bundles it into the app resources.\n\nArtifacts are generated under:\n\n- `src-tauri/target/release/bundle/macos/*.app`\n- `src-tauri/target/release/bundle/dmg/*.dmg`\n\n## Contributing\n\nWe welcome contributions.\n\n1. Fork the repo\n2. Create a feature branch `git checkout -b feature/my-change`\n3. Follow TypeScript and React best practices\n4. Test your changes\n5. Commit with clear, conventional messages\n6. Push and open a PR\n\n## License\n\nGNU Affero General Public License v3.0 — see `LICENSE`\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003ePrivacy-first • Local-first • Open Source\u003c/p\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flettuceai%2Fapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flettuceai%2Fapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flettuceai%2Fapp/lists"}