Librechat-Mobile/README.md
Garfie abde86ca4e chore(sync): sync to upstream LibreChat v0.8.5
Targets upstream tag v0.8.5 (commit 9ccc8d9be). Bumps the supported
backend version constant, advances the upstream submodule pin, and
adds wire-protocol parity for new server features.

Wire protocol
- Add ContentType.SUMMARY enum value and flat sibling fields on
  MessageContentPart (content as JsonElement to absorb array/string/
  legacy-text variants per BaseClient.getSummaryText).
- Add Anthropic effort.xhigh dropdown value, ThinkingDisplay (Opus 4.7
  reasoning visibility), and Message.contextMeta pass-through.
- Add allowAccountDeletion to StartupConfig (defaults to true to
  preserve older-server behavior).
- Drop unused instanceProjectId from StartupConfig and from
  ConfigRepositoryImpl.isValidLibreChatConfig.

New endpoints / features
- Favorites: UserFavorite DTO + FavoritesApi + FavoritesRepository,
  Settings -> Favorites sub-screen (list/unpin), pin icons in chat
  model selector. Repository owns the canonical list as a StateFlow
  guarded by Mutex.withLock so chat-side toggles and settings-side
  bulk-unpin can't drift apart and concurrent writes can't lose each
  other.
- Prompt-group usage telemetry (POST /api/prompts/groups/:id/use,
  fire-and-forget on prompt insertion).
- Summarize SSE events (on_summarize_complete -> StreamEvent.ContextSummary)
  and a collapsible "Summarized earlier messages" card rendered from
  the persisted SUMMARY content part. Forward-compat else-arm preserved
  on both LangGraph and legacy SSE mappers.

Backward compatibility
- BackendVersion.isCompatibleOrNewer helper added; documented fail-open
  contract for callers that have already null-checked
  detectedBackendVersion.
- New VERSION_GATES.md catalog at repo root tracks every code path that
  branches on server version. Initial entries:
  - isCollaborative agent toggle (hidden on v0.8.5+; full-ACL UX deferred)
  - xhigh effort dropdown value (filtered out on <v0.8.5 to avoid
    server-side enum rejection)

Defensive hardening
- ChatApi.startChat asserts Content-Type: application/json before
  decoding ChatStartResponse and catches NoTransformationFoundException
  as a backstop, translating both to a friendly ApiException. Observed
  during testing on v0.8.5-rc1 with summarization enabled, where the
  agents chat-start endpoint returned 200 OK with no Content-Type and
  Ktor leaked a NoTransformationFoundException stack trace into the
  chat surface. Belt-and-suspenders against future backend regressions
  or unsupported-server pointing.

Documentation
- DISCOVERY.md updated for the v0.8.5 surface: /api/endpoints now
  requires JWT, /api/config pre-auth/post-auth split, allowAccountDeletion,
  instanceProjectId removal, favorites endpoints (with all three XOR
  variants: agentId | model+endpoint | spec), prompt-usage endpoint,
  /api/admin/** marked out-of-scope. Plus a new MessageContentPart +
  SUMMARY wire-shape section.

iOS
- Swift SharedFrameworkTest.swift updated for the new
  StreamEvent.ContextSummary variant and Message.contextMeta
  constructor argument.

Out of scope (by design)
- /api/admin/** route family - web-only feature.
- Full ACL migration for agent sharing - replaced by version-gating
  the legacy isCollaborative toggle.
- Spec-pinning UI on mobile - UserFavorite.spec round-trips for
  fidelity with web-authored pins, but mobile does not yet surface
  a spec picker.
2026-04-26 23:48:14 -06:00

154 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LibreChat Mobile
[![LibreChat](https://img.shields.io/badge/LibreChat-v0.8.4__v0.8.5-blue)](https://github.com/danny-avila/LibreChat/releases/tag/v0.8.5)
A third-party native mobile client for [LibreChat](https://www.librechat.ai/) (Android & iOS). Not affiliated with the official LibreChat project — this is an independent app that connects to any self-hosted LibreChat server, no backend modifications required.
> **Backend compatibility:** Tested against LibreChat **v0.8.4 v0.8.5**. Older releases may work but are not guaranteed; newer releases are supported on a best-effort basis until the next sync.
## Features
- **Chat** — Real-time streaming (SSE), message branching & sibling navigation, stop/regenerate/continue, markdown with syntax highlighting, LaTeX math rendering, code blocks with copy, image display, file attachments, tool call progress cards
- **Model Selection** — Searchable bottom sheet grouped by endpoint, model comparison mode
- **Agents** — Marketplace with search and categories, MCP server configuration
- **Conversations** — Paginated list with date grouping, tags, search, rename, archive, delete, share, fork, duplicate, export/import
- **Presets & Prompts** — Save/load chat presets, prompts library with @mention insertion
- **Authentication** — Login, registration, forgot password, two-factor (TOTP + backup codes), OAuth (Google, GitHub, Discord, Facebook, Apple, OpenID)
- **Files** — Upload, list, delete, inline image rendering with pinch-to-zoom
- **Voice** — Speech-to-text input, text-to-speech playback (device and server engines)
- **Settings** — Theme (system/light/dark), account management, data controls
- **Tablet** — Adaptive dual-pane layout (600dp+) with persistent sidebar
- **Accessibility** — Semantic headings, content descriptions, 48dp touch targets, live regions
## Screenshots
| Feature | Phone | Tablet / Foldable |
|---|---|---|
| **Server Connect** — Point the app at any self-hosted LibreChat server | <img src="docs/screenshots/server-url-phone.png" width="280"> | <img src="docs/screenshots/server-url-tablet.png" width="380"> |
| **Home Screen** — Clean welcome screen with voice input and quick access | <img src="docs/screenshots/home-phone.png" width="280"> | <img src="docs/screenshots/home-tablet.png" width="380"> |
| **Conversations Sidebar** — Swipe to open your chat history with search, tags, and date grouping | <img src="docs/screenshots/sidebar-phone.gif" width="280"> | <img src="docs/screenshots/sidebar-tablet.gif" width="380"> |
| **Predictive Back** — Native Android back gesture with peek animation | <img src="docs/screenshots/predictive-back-phone.gif" width="280"> | <img src="docs/screenshots/predictive-back-tablet.gif" width="380"> |
| **Mermaid Diagrams** — Interactive flowcharts and diagrams rendered in-chat | <img src="docs/screenshots/mermaid-phone.png" width="280"> | <img src="docs/screenshots/mermaid-tablet.png" width="380"> |
| **LaTeX Math** — Beautifully typeset equations and formulas | <img src="docs/screenshots/latex-phone.png" width="280"> | <img src="docs/screenshots/latex-tablet.png" width="380"> |
| **Code Blocks** — Syntax-highlighted code with language badge and copy button | <img src="docs/screenshots/code-phone.png" width="280"> | <img src="docs/screenshots/code-tablet.png" width="380"> |
| **Tables** — Clean, scrollable data tables | <img src="docs/screenshots/table-phone.png" width="280"> | <img src="docs/screenshots/table-tablet.png" width="380"> |
| **Extended Thinking** — See the model's reasoning process | <img src="docs/screenshots/thinking-phone.png" width="280"> | <img src="docs/screenshots/thinking-tablet.png" width="380"> |
| **Image Generation** — AI-generated images via agents | <img src="docs/screenshots/imagegen-phone.png" width="280"> | <img src="docs/screenshots/imagegen-tablet.png" width="380"> |
| **Chat Options** — Attach files, switch models, toggle tools, and tune parameters | <img src="docs/screenshots/chat-options-phone.png" width="280"> | <img src="docs/screenshots/chat-options-tablet.png" width="380"> |
| **Model Selection** — Searchable bottom sheet with models grouped by provider | <img src="docs/screenshots/model-selection-phone.png" width="280"> | <img src="docs/screenshots/model-selection-tablet.png" width="380"> |
| **Model Parameters** — Fine-tune temperature, top-p, tokens, and custom instructions | <img src="docs/screenshots/model-params-phone.png" width="280"> | <img src="docs/screenshots/model-params-tablet.png" width="380"> |
| **Photo Upload** — Attach images from your gallery or camera | <img src="docs/screenshots/photo-upload-phone.png" width="280"> | <img src="docs/screenshots/photo-upload-tablet.png" width="380"> |
| **Settings** — Theme, language, layout, and personalization options | <img src="docs/screenshots/settings-phone.png" width="280"> | <img src="docs/screenshots/settings-tablet.png" width="380"> |
## Server Setup
The app works with any standard LibreChat server. During onboarding, you'll enter your server URL (e.g., `https://chat.example.com` or `http://192.168.1.100:3080`).
### Required Configuration
Add the following to your LibreChat server's `.env` file:
```env
# Safety net for native app clients.
# The app sends a browser User-Agent to pass the uaParser middleware,
# but if it ever fails to parse, this prevents ban point accumulation.
NON_BROWSER_VIOLATION_SCORE=0
```
Without this setting, the server's violation system may accumulate ban points against the mobile client if the User-Agent check fails, eventually locking the account out.
### Self-Signed Certificates (iOS)
The iOS app can connect to a LibreChat server using a self-signed certificate, but iOS enforces strict requirements on all TLS certificates regardless of whether they are self-signed or CA-issued. The certificate must meet **all** of the following or iOS will reject the connection:
| Requirement | Details |
|---|---|
| **Validity period** | ≤ 398 days (for certificates issued after September 1, 2020) |
| **Subject Alternative Name** | DNS name must be present in the SAN extension — CommonName alone is not accepted |
| **Key algorithm** | RSA ≥ 2048 bits |
| **Signature algorithm** | SHA-256 or better (SHA-1 is not accepted) |
| **Extended Key Usage** | Must include `id-kp-serverAuth` (TLS Web Server Authentication) |
The 398-day validity limit is the most common cause of failures — a certificate that works in every browser but was generated with a multi-year validity will be rejected by iOS.
**Setup steps:**
1. Generate a compliant certificate signed by your own CA (tools like [`mkcert`](https://github.com/FiloSottile/mkcert) handle all requirements automatically)
2. On your iPhone: **Settings → General → VPN & Device Management** — install your CA certificate
3. Go to **Settings → General → About → Certificate Trust Settings** — enable full trust for your CA
Once the CA is trusted on the device, you only need to re-install it if you create a new CA. The server certificate itself (which you replace when it expires) does not need to be installed separately.
> **Android** has no equivalent restrictions — self-signed certificates with any validity period work as long as the CA is trusted on the device.
### Notes
- **Registration** — The app respects your server's registration settings. If registration is disabled server-side, only the login form is shown.
## Requirements
| Tool | Version |
|------|---------|
| JDK | 17+ |
| Android Studio or IntelliJ IDEA | Latest stable (recommended IDE for all code editing) |
| Xcode | 15+ (iOS only, Apple Silicon Mac required — IDE not needed, CLI only) |
| iOS Deployment Target | 16.0+ |
| Gradle | 9.4.1 (via wrapper) |
| Kotlin | 2.3.20 |
## Building from Source
### Android
```bash
./gradlew assembleDebug
```
The debug APK will be at `app/build/outputs/apk/debug/app-debug.apk`.
For a release build:
```bash
./gradlew assembleRelease
```
### iOS
**Simulator:**
```bash
./gradlew :shared:linkDebugFrameworkIosSimulatorArm64
xcodebuild -project iosApp/iosApp.xcodeproj -scheme iosApp \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-derivedDataPath iosApp/build build
```
**Physical device:**
```bash
./gradlew :shared:linkDebugFrameworkIosArm64
open iosApp/iosApp.xcodeproj
```
Then in Xcode: select your device, set your Team under Signing & Capabilities, and press ⌘R.
See [iosApp/README.md](iosApp/README.md) for full build and launch instructions.
### Tech Stack
- Kotlin Multiplatform (KMP) with shared business logic
- Jetpack Compose (Android) + Compose Multiplatform (iOS)
- Koin (dependency injection)
- Ktor Client (OkHttp on Android, Darwin on iOS)
- Kotlinx Serialization
- Room (cache), DataStore (preferences), EncryptedSharedPreferences / Keychain (tokens)
- Kotlin 2.3.20, compileSdk 36, minSdk 26
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, code style, and PR guidelines.
## License
This project is licensed under the [MIT License](LICENSE).