Merge pull request #8 from garfiec/chore/rename-to-mobile

Rename project from LibreChat Android to LibreChat Mobile
This commit is contained in:
Garfie Chiu 2026-04-03 16:57:52 -05:00 committed by GitHub
commit 9be9a57b9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
161 changed files with 406 additions and 403 deletions

View file

@ -1,8 +1,8 @@
--- ---
name: sync-upstream name: sync-upstream
description: > description: >
Sync the LibreChat Android client with a newer official LibreChat server release. Sync the LibreChat Mobile client with a newer official LibreChat server release.
Diffs upstream tags, identifies gaps in the Android app, proposes changes with Diffs upstream tags, identifies gaps in the mobile app, proposes changes with
user approval, then implements them. Use when a new LibreChat version is released. user approval, then implements them. Use when a new LibreChat version is released.
allowed-tools: Bash, Read, Glob, Grep, Write, Edit, Agent, TeamCreate, SendMessage, TaskCreate, TaskUpdate, TaskGet, TaskList allowed-tools: Bash, Read, Glob, Grep, Write, Edit, Agent, TeamCreate, SendMessage, TaskCreate, TaskUpdate, TaskGet, TaskList
argument-hint: "[target-tag] (optional, defaults to latest stable)" argument-hint: "[target-tag] (optional, defaults to latest stable)"
@ -10,7 +10,7 @@ argument-hint: "[target-tag] (optional, defaults to latest stable)"
# Sync Upstream # Sync Upstream
Synchronize the LibreChat Android app with a newer version of the official LibreChat server. Synchronize the LibreChat Mobile app with a newer version of the official LibreChat server.
This is a multi-phase, team-based workflow. This is a multi-phase, team-based workflow.
You are the **team lead**. You orchestrate at a high level. You NEVER read code, write code, You are the **team lead**. You orchestrate at a high level. You NEVER read code, write code,
@ -22,18 +22,20 @@ Create an Agent Team with 4 teammates at the start:
| Teammate | Role | Prompt Summary | | Teammate | Role | Prompt Summary |
|----------|------|----------------| |----------|------|----------------|
| **investigator** | Reads upstream diffs, analyzes API/type/UI changes, cross-references with Android codebase | "You are the investigator for a LibreChat Android upstream sync. Your job is to analyze diffs between upstream tags and identify gaps in the Android client. You have read-only responsibilities — never write code." | | **investigator** | Reads upstream diffs, analyzes API/type/UI changes, cross-references with mobile codebase | "You are the investigator for a LibreChat Mobile upstream sync. Your job is to analyze diffs between upstream tags and identify gaps in the mobile client. You have read-only responsibilities — never write code." |
| **android-expert** | Technical advisor on Android architecture and best practices. Cross-checks all guidance with online research before advising. | "You are the Android tech lead for a LibreChat Android upstream sync. You provide guidance on Android best practices, Jetpack Compose patterns, Kotlin idioms, and architectural decisions. CRITICAL: You MUST cross-check your knowledge by researching online (WebSearch/WebFetch) before giving advice. Never rely solely on training data — always verify current best practices, especially for Compose, Hilt, Ktor, and Material 3. Return researched guidance to teammates who ask." | | **android-expert** | Technical advisor on Android architecture and best practices. Cross-checks all guidance with online research before advising. | "You are the Android tech lead for a LibreChat Mobile upstream sync. You provide guidance on Android best practices, Jetpack Compose patterns, Kotlin idioms, and architectural decisions. CRITICAL: You MUST cross-check your knowledge by researching online (WebSearch/WebFetch) before giving advice. Never rely solely on training data — always verify current best practices, especially for Compose, Ktor, and Material 3. Return researched guidance to teammates who ask." |
| **implementer** | Writes code changes to Android app following existing patterns and conventions | "You are the implementer for a LibreChat Android upstream sync. Your job is to write code changes following existing architecture patterns. Always read the module's CLAUDE.md before touching it. Follow safeApiCall, Hilt DI, UDF, Ktor, @Serializable patterns. Before making significant architectural decisions, consult the android-expert teammate." | | **ios-kmp-expert** | Technical advisor on iOS and Kotlin Multiplatform architecture. Ensures KMP shared code and iOS-specific implementations follow platform conventions. | "You are the iOS/KMP tech lead for a LibreChat Mobile upstream sync. You provide guidance on Compose Multiplatform patterns, KMP expect/actual declarations, iOS platform APIs (UIKit, Foundation, Keychain), SKIE interop, and ensuring shared code compiles correctly for both targets. CRITICAL: You MUST cross-check your knowledge by researching online (WebSearch/WebFetch) before giving advice. Never rely solely on training data — always verify current best practices for CMP, KMP, and iOS platform conventions. Return researched guidance to teammates who ask." |
| **verifier** | Checks implementation correctness, runs builds, validates changes match proposal | "You are the verifier for a LibreChat Android upstream sync. Your job is to independently validate that implementation matches the approved proposal. Run builds, review changes, and flag issues. Message the implementer directly if fixes are needed." | | **implementer** | Writes code changes to mobile app following existing patterns and conventions | "You are the implementer for a LibreChat Mobile upstream sync. Your job is to write code changes following existing architecture patterns. Always read the module's CLAUDE.md before touching it. Follow safeApiCall, Koin DI, UDF, Ktor, @Serializable patterns. Before making significant architectural decisions, consult the android-expert or ios-kmp-expert teammate." |
| **verifier** | Checks implementation correctness, runs builds, validates changes match proposal | "You are the verifier for a LibreChat Mobile upstream sync. Your job is to independently validate that implementation matches the approved proposal. Run builds, review changes, and flag issues. Message the implementer directly if fixes are needed." |
**Teammate interaction pattern:** **Teammate interaction pattern:**
- **investigator** works independently on Phase A and B (diff + gap analysis) - **investigator** works independently on Phase A and B (diff + gap analysis)
- **android-expert** is consulted by the implementer before architectural decisions and by the - **android-expert** is consulted for Android-specific architecture, Compose, and Material 3 decisions.
lead when the proposal involves patterns that may have better modern alternatives. The The android-expert MUST search online to verify recommendations — do not accept advice that
android-expert MUST search online to verify recommendations — do not accept advice that
hasn't been cross-checked against current documentation. hasn't been cross-checked against current documentation.
- **implementer** does all code changes, consulting android-expert for non-trivial patterns - **ios-kmp-expert** is consulted for KMP shared code, expect/actual patterns, iOS platform APIs,
and Compose Multiplatform concerns. Same online-verification requirement as android-expert.
- **implementer** does all code changes, consulting android-expert or ios-kmp-expert for non-trivial patterns
- **verifier** validates after implementer finishes, messages implementer for fixes - **verifier** validates after implementer finishes, messages implementer for fixes
**Important:** Teammates retain context across messages. Reuse them for follow-ups — do NOT **Important:** Teammates retain context across messages. Reuse them for follow-ups — do NOT
@ -45,7 +47,7 @@ Run these checks yourself (lightweight, no codebase reading):
### 1. Submodule check ### 1. Submodule check
```bash ```bash
cd LibreChat-Android && git submodule status cd Librechat-Mobile && git submodule status
``` ```
If `upstream/` is missing: If `upstream/` is missing:
```bash ```bash
@ -61,7 +63,7 @@ If missing, create from current state:
```bash ```bash
VERSION=$(grep 'SUPPORTED_BACKEND_VERSION' core/common/src/main/kotlin/com/garfiec/librechat/core/common/BackendVersion.kt | grep -o '"[^"]*"' | tr -d '"') VERSION=$(grep 'SUPPORTED_BACKEND_VERSION' core/common/src/main/kotlin/com/garfiec/librechat/core/common/BackendVersion.kt | grep -o '"[^"]*"' | tr -d '"')
COMMIT=$(cd upstream && git rev-parse HEAD) COMMIT=$(cd upstream && git rev-parse HEAD)
echo "# Upstream LibreChat version this Android build tracks." > UPSTREAM_VERSION echo "# Upstream LibreChat version this mobile build tracks." > UPSTREAM_VERSION
echo "# Updated by the sync-upstream skill. Do not edit manually." >> UPSTREAM_VERSION echo "# Updated by the sync-upstream skill. Do not edit manually." >> UPSTREAM_VERSION
echo "tag=v${VERSION}" >> UPSTREAM_VERSION echo "tag=v${VERSION}" >> UPSTREAM_VERSION
echo "commit=${COMMIT}" >> UPSTREAM_VERSION echo "commit=${COMMIT}" >> UPSTREAM_VERSION
@ -126,7 +128,7 @@ Create a task for the investigator with this prompt:
> - **API changes**: New/modified/removed routes, controller logic > - **API changes**: New/modified/removed routes, controller logic
> - **Type/schema changes**: New/modified data types, request/response shapes > - **Type/schema changes**: New/modified data types, request/response shapes
> - **UI changes**: New components, modified user flows > - **UI changes**: New components, modified user flows
> - **Bug fixes**: Fixes that may need Android equivalents > - **Bug fixes**: Fixes that may need mobile equivalents
> - **Infrastructure**: Build, config, deps (usually not relevant) > - **Infrastructure**: Build, config, deps (usually not relevant)
> 6. Report back a structured summary table. > 6. Report back a structured summary table.
@ -149,14 +151,14 @@ Once investigator reports back:
### B1. Send follow-up to investigator ### B1. Send follow-up to investigator
> Now cross-reference the upstream changes you found with the Android codebase. > Now cross-reference the upstream changes you found with the mobile codebase.
> >
> 1. Read these mapping files from `${CLAUDE_SKILL_DIR}/reference/`: > 1. Read these mapping files from `${CLAUDE_SKILL_DIR}/reference/`:
> - `api-mapping.md` — official routes to Android *Api.kt files > - `api-mapping.md` — official routes to mobile *Api.kt files
> - `model-mapping.md` — official TS types to Kotlin data classes > - `model-mapping.md` — official TS types to Kotlin data classes
> - `ui-mapping.md` — web components to Android feature modules > - `ui-mapping.md` — web components to mobile feature modules
> 2. For each API change from Phase A: > 2. For each API change from Phase A:
> - Grep the Android codebase (`core/network/src/`) for the corresponding endpoint > - Grep the mobile codebase (`core/network/src/`) for the corresponding endpoint
> - Note if it exists, needs updating, or is missing > - Note if it exists, needs updating, or is missing
> 3. For each type/schema change: > 3. For each type/schema change:
> - Check `core/model/src/` for matching Kotlin data class > - Check `core/model/src/` for matching Kotlin data class
@ -168,11 +170,11 @@ Once investigator reports back:
> - **Breaking** (must fix): Changed request/response shapes, removed/renamed endpoints, auth changes > - **Breaking** (must fix): Changed request/response shapes, removed/renamed endpoints, auth changes
> - **Additive** (new feature): New endpoints, new UI features, new optional fields > - **Additive** (new feature): New endpoints, new UI features, new optional fields
> - **Cosmetic** (polish): UI improvements, a11y, i18n > - **Cosmetic** (polish): UI improvements, a11y, i18n
> 6. Report the categorized gap list with specific file paths for both upstream and Android. > 6. Report the categorized gap list with specific file paths for both upstream and mobile.
### B2. Receive gap report ### B2. Receive gap report
The investigator now has full context of both the upstream diff AND the Android gaps. The investigator now has full context of both the upstream diff AND the mobile gaps.
Keep the investigator alive for follow-up questions during Phase C. Keep the investigator alive for follow-up questions during Phase C.
**Done when:** You have the categorized gap list from the investigator. **Done when:** You have the categorized gap list from the investigator.
@ -191,42 +193,43 @@ Take the investigator's gap report and present it as a structured proposal:
### Breaking Changes ({count}) — must fix before updating version ### Breaking Changes ({count}) — must fix before updating version
For each: For each:
- What changed upstream (with file reference) - What changed upstream (with file reference)
- What Android file(s) need updating - What Mobile file(s) need updating
- Proposed change - Proposed change
### New Features ({count}) — recommended ### New Features ({count}) — recommended
For each: For each:
- What was added upstream - What was added upstream
- Proposed Android implementation approach - Proposed mobile implementation approach
- Which module(s) would be affected - Which module(s) would be affected
### UI Changes Needing User Input ({count}) ### UI Changes Needing User Input ({count})
For each: For each:
- What the web app does (with file reference) - What the web app does (with file reference)
- Why it doesn't translate directly to Android/Compose - Why it doesn't translate directly to mobile/Compose
- 2-3 concrete options for the user to choose from - 2-3 concrete options for the user to choose from
### Deferred Items ({count}) — can wait for a future sync ### Deferred Items ({count}) — can wait for a future sync
Items that are low priority or require significant new infrastructure. Items that are low priority or require significant new infrastructure.
``` ```
### Consult android-expert on non-trivial items ### Consult experts on non-trivial items
Before presenting to the user, for any proposed change that involves: Before presenting to the user, for any proposed change that involves:
- New architectural patterns (e.g., adding a new module, new DI scope) - New architectural patterns (e.g., adding a new module, new DI scope)
- UI patterns that don't have an existing equivalent in the codebase - UI patterns that don't have an existing equivalent in the codebase
- Performance-sensitive changes (e.g., new list rendering, image loading) - Performance-sensitive changes (e.g., new list rendering, image loading)
- Navigation changes - Navigation changes
- KMP shared code or expect/actual patterns
Send these items to the **android-expert** teammate: Send Android-specific items to **android-expert** and KMP/iOS items to **ios-kmp-expert**:
> Review these proposed Android changes for best practices. For each item, > Review these proposed mobile changes for best practices. For each item,
> research online to verify the recommended approach is current (especially > research online to verify the recommended approach is current (especially
> for Compose, Material 3, Hilt, and Ktor). Flag any items where modern > for Compose, Material 3, Koin, and Ktor). Flag any items where modern
> best practices differ from what we're proposing. > best practices differ from what we're proposing.
> {list of non-trivial items} > {list of non-trivial items}
Incorporate the android-expert's feedback into the proposal before showing the user. Incorporate the experts' feedback into the proposal before showing the user.
### Approval gate ### Approval gate
@ -268,8 +271,8 @@ Create a task for the implementer with the approved change list:
> - Ktor client patterns in `core/network/` > - Ktor client patterns in `core/network/`
> >
> **Before making non-trivial architectural decisions** (new patterns, new modules, > **Before making non-trivial architectural decisions** (new patterns, new modules,
> complex UI components), message the **android-expert** teammate for guidance. > complex UI components), message the **android-expert** or **ios-kmp-expert** teammate for guidance.
> The android-expert will research current best practices online and advise. > They will research current best practices online and advise.
> >
> **Approved changes:** > **Approved changes:**
> {paste the approved change list here} > {paste the approved change list here}

View file

@ -1,6 +1,6 @@
# Android Architecture Reference # LibreChat Mobile Architecture Reference
Condensed architecture guide for the LibreChat Android app. Read module-specific `CLAUDE.md` files for full details. Condensed architecture guide for the LibreChat Mobile app. Read module-specific `CLAUDE.md` files for full details.
## Module Dependency Graph ## Module Dependency Graph
@ -143,7 +143,7 @@ Two-phase protocol:
- Room entity: `{Domain}Entity.kt` - Room entity: `{Domain}Entity.kt`
- Room DAO: `{Domain}Dao.kt` - Room DAO: `{Domain}Dao.kt`
- DI module: `{Domain}Module.kt` - DI module: `{Domain}Module.kt`
- Convention plugins: `librechat.android.{type}` (e.g., `librechat.android.feature`) - Convention plugins: `librechat.mobile.{type}` (e.g., `librechat.mobile.feature`)
## Build System ## Build System

View file

@ -1,10 +1,10 @@
# API Route Mapping: Official → Android # API Route Mapping: Official → Mobile
Maps official LibreChat API route files to their Android `*Api.kt` counterparts. Maps official LibreChat API route files to their mobile `*Api.kt` counterparts.
## Implemented ## Implemented
| Official Route | Android API File | Notes | | Official Route | Mobile API File | Notes |
|---------------|-----------------|-------| |---------------|-----------------|-------|
| `routes/auth.js` | `AuthApi.kt` | Login, register, refresh, logout, 2FA | | `routes/auth.js` | `AuthApi.kt` | Login, register, refresh, logout, 2FA |
| `routes/oauth.js` | `AuthApi.kt` | OAuth flows (shared file) | | `routes/oauth.js` | `AuthApi.kt` | OAuth flows (shared file) |
@ -28,15 +28,15 @@ Maps official LibreChat API route files to their Android `*Api.kt` counterparts.
| N/A | `SpeechApi.kt` | Text-to-speech | | N/A | `SpeechApi.kt` | Text-to-speech |
| N/A | `ApiKeysApi.kt` | API key management | | N/A | `ApiKeysApi.kt` | API key management |
## Gaps (no Android counterpart yet) ## Gaps (no mobile counterpart yet)
| Official Route | What It Does | Priority | | Official Route | What It Does | Priority |
|---------------|-------------|----------| |---------------|-------------|----------|
| `routes/categories.js` | Agent categories | Low — categories embedded in agent responses | | `routes/categories.js` | Agent categories | Low — categories embedded in agent responses |
| `routes/endpoints.js` | List available endpoints | Medium — Android uses config response instead | | `routes/endpoints.js` | List available endpoints | Medium — Mobile uses config response instead |
| `routes/models.js` | List available models per endpoint | Medium — Android uses config response instead | | `routes/models.js` | List available models per endpoint | Medium — Mobile uses config response instead |
| `routes/roles.js` | Role-based access control (admin) | Low — admin feature | | `routes/roles.js` | Role-based access control (admin) | Low — admin feature |
| `routes/settings.js` | User settings CRUD | Medium — Android uses local DataStore | | `routes/settings.js` | User settings CRUD | Medium — Mobile uses local DataStore |
| `routes/actions.js` | Custom actions/plugins | Low — plugin system | | `routes/actions.js` | Custom actions/plugins | Low — plugin system |
| `routes/assistants/` (dir) | OpenAI Assistants API | Low — agents supersede assistants | | `routes/assistants/` (dir) | OpenAI Assistants API | Low — agents supersede assistants |
| `routes/accessPermissions.js` | File access permissions | Low — admin feature | | `routes/accessPermissions.js` | File access permissions | Low — admin feature |

View file

@ -1,10 +1,10 @@
# UI Mapping: Official React Components → Android Feature Modules # UI Mapping: Official React Components → Mobile Feature Modules
Maps web client component directories to Android Compose feature modules. Maps web client component directories to mobile Compose feature modules.
## Implemented ## Implemented
| Web Component Dir | Android Module | Coverage | | Web Component Dir | Mobile Module | Coverage |
|-------------------|---------------|----------| |-------------------|---------------|----------|
| `components/Chat/` | `feature/chat/` | Core chat UI, message list, input | | `components/Chat/` | `feature/chat/` | Core chat UI, message list, input |
| `components/Messages/` | `feature/chat/` | Message rendering, branching, siblings | | `components/Messages/` | `feature/chat/` | Message rendering, branching, siblings |
@ -17,11 +17,11 @@ Maps web client component directories to Android Compose feature modules.
| `components/Banners/` | `app/` | System banner display | | `components/Banners/` | `app/` | System banner display |
| `components/Endpoints/` | `feature/chat/` | Model/endpoint selector bottom sheet | | `components/Endpoints/` | `feature/chat/` | Model/endpoint selector bottom sheet |
## Gaps (no Android counterpart) ## Gaps (no mobile counterpart)
| Web Component Dir | What It Does | Priority | Notes | | Web Component Dir | What It Does | Priority | Notes |
|-------------------|-------------|----------|-------| |-------------------|-------------|----------|-------|
| `components/Prompts/` | Prompts library with CRUD, categories, sharing | Medium | Android has PromptsApi but no dedicated UI | | `components/Prompts/` | Prompts library with CRUD, categories, sharing | Medium | Mobile has PromptsApi but no dedicated UI |
| `components/Artifacts/` | Code/document artifact viewer and editor | Medium | New feature in recent versions | | `components/Artifacts/` | Code/document artifact viewer and editor | Medium | New feature in recent versions |
| `components/MCP/` | MCP server configuration UI | Low | Admin-oriented feature | | `components/MCP/` | MCP server configuration UI | Low | Admin-oriented feature |
| `components/MCPUIResource/` | MCP UI resource rendering | Low | Depends on MCP support | | `components/MCPUIResource/` | MCP UI resource rendering | Low | Depends on MCP support |
@ -33,13 +33,13 @@ Maps web client component directories to Android Compose feature modules.
| `components/Audio/` | Voice input/output, TTS | Medium | SpeechApi exists, no UI | | `components/Audio/` | Voice input/output, TTS | Medium | SpeechApi exists, no UI |
| `components/Plugins/` | Legacy plugin system | N/A | Superseded by agents | | `components/Plugins/` | Legacy plugin system | N/A | Superseded by agents |
| `components/Tools/` | Tool configuration and management | Low | Part of agent setup | | `components/Tools/` | Tool configuration and management | Low | Part of agent setup |
| `components/OAuth/` | OAuth provider buttons | Low | Android uses Chrome Custom Tabs | | `components/OAuth/` | OAuth provider buttons | Low | Mobile uses Chrome Custom Tabs |
| `components/Web/` | Web search integration | Low | Agent tool feature | | `components/Web/` | Web search integration | Low | Agent tool feature |
| `components/System/` | System-level UI (error boundaries, etc.) | Low | Android has own error handling | | `components/System/` | System-level UI (error boundaries, etc.) | Low | Mobile has own error handling |
## Key Web Patterns → Android Equivalents ## Key Web Patterns → Mobile Equivalents
| Web Pattern | Android Equivalent | | Web Pattern | Mobile Equivalent |
|------------|-------------------| |------------|-------------------|
| Recoil atoms (`store/`) | ViewModel state (StateFlow) | | Recoil atoms (`store/`) | ViewModel state (StateFlow) |
| React Query hooks (`hooks/`) | Repository + ViewModel | | React Query hooks (`hooks/`) | Repository + ViewModel |

View file

@ -1,13 +1,13 @@
# Upstream Paths to Watch # Upstream Paths to Watch
These are the directories in the `upstream/` submodule that matter for Android parity. These are the directories in the `upstream/` submodule that matter for mobile parity.
Use these paths when generating focused diffs between tags. Use these paths when generating focused diffs between tags.
| Path | What It Contains | Why It Matters | | Path | What It Contains | Why It Matters |
|------|-----------------|----------------| |------|-----------------|----------------|
| `api/server/routes/` | Express route definitions (REST endpoints) | Defines the API contract the Android app calls | | `api/server/routes/` | Express route definitions (REST endpoints) | Defines the API contract the mobile app calls |
| `api/server/controllers/` | Request handlers and business logic | Shows request/response shapes and validation | | `api/server/controllers/` | Request handlers and business logic | Shows request/response shapes and validation |
| `packages/data-provider/src/` | Shared types, schemas, API client, config | Canonical type definitions; Android models must match | | `packages/data-provider/src/` | Shared types, schemas, API client, config | Canonical type definitions; Mobile models must match |
| `packages/data-provider/src/types/` | TypeScript type subdirectory (queries, mutations, agents, etc.) | React Query hook types that define API shapes | | `packages/data-provider/src/types/` | TypeScript type subdirectory (queries, mutations, agents, etc.) | React Query hook types that define API shapes |
| `packages/data-schemas/src/` | Mongoose schemas and DB models | Database schema changes that affect API responses | | `packages/data-schemas/src/` | Mongoose schemas and DB models | Database schema changes that affect API responses |
| `client/src/components/` | React UI components by feature area | Reference for Android UI feature parity | | `client/src/components/` | React UI components by feature area | Reference for Android UI feature parity |

View file

@ -1,6 +1,6 @@
# LibreChat Android # LibreChat Mobile
Native Android client for LibreChat. Connects to existing LibreChat backend servers (no backend changes). Users specify server URL during onboarding. Native mobile client for LibreChat (Android & iOS). Connects to existing LibreChat backend servers (no backend changes). Users specify server URL during onboarding.
## Tech Stack ## Tech Stack
@ -42,7 +42,7 @@ Each module has its own `CLAUDE.md` with specific guidance.
## Adding a New Feature Module ## Adding a New Feature Module
1. Create the module directory under `feature/` 1. Create the module directory under `feature/`
2. Apply the `librechat.android.feature` convention plugin in `build.gradle.kts` — this auto-applies Koin + Compose deps 2. Apply the `librechat.mobile.feature` convention plugin in `build.gradle.kts` — this auto-applies Koin + Compose deps
3. Create `di/<Feature>Module.kt` with a Koin `module { }` containing `viewModelOf(::YourViewModel)` definitions 3. Create `di/<Feature>Module.kt` with a Koin `module { }` containing `viewModelOf(::YourViewModel)` definitions
4. Register the module in `LibreChatApplication.kt`'s `startKoin { modules(...) }` list 4. Register the module in `LibreChatApplication.kt`'s `startKoin { modules(...) }` list
5. Use `koinViewModel()` in screen composables to inject ViewModels 5. Use `koinViewModel()` in screen composables to inject ViewModels
@ -58,6 +58,6 @@ Each module has its own `CLAUDE.md` with specific guidance.
## Upstream Sync ## Upstream Sync
- **`upstream/`** — Git submodule of the [official LibreChat repo](https://github.com/danny-avila/LibreChat). Read-only reference for API and web app parity. Do not modify. - **`upstream/`** — Git submodule of the [official LibreChat repo](https://github.com/danny-avila/LibreChat). Read-only reference for API and web app parity. Do not modify.
- **`UPSTREAM_VERSION`** — Tracks which official tag/commit this Android build is based on. Updated by the `/sync-upstream` skill. - **`UPSTREAM_VERSION`** — Tracks which official tag/commit this mobile build is based on. Updated by the `/sync-upstream` skill.
- **`BackendVersion.kt`** (`core/common/`) — `SUPPORTED_BACKEND_VERSION` constant must match the tag in `UPSTREAM_VERSION` (without `v` prefix). - **`BackendVersion.kt`** (`core/common/`) — `SUPPORTED_BACKEND_VERSION` constant must match the tag in `UPSTREAM_VERSION` (without `v` prefix).
- **`/sync-upstream`** — Claude Code skill to diff upstream releases, identify gaps, propose changes, and implement them with user approval. Uses Agent Teams (investigator, android-expert, implementer, verifier). - **`/sync-upstream`** — Claude Code skill to diff upstream releases, identify gaps, propose changes, and implement them with user approval. Uses Agent Teams (investigator, android-expert, implementer, verifier).

View file

@ -14,8 +14,8 @@
```bash ```bash
# Clone with submodules (upstream LibreChat server reference) # Clone with submodules (upstream LibreChat server reference)
git clone --recursive https://github.com/anthropics/LibreChat-Android.git git clone --recursive https://github.com/garfiec/Librechat-Mobile.git
cd LibreChat-Android cd Librechat-Mobile
``` ```
### Android ### Android

View file

@ -1,7 +1,7 @@
# LibreChat Android - Discovery & Context Document # LibreChat Mobile - Discovery & Context Document
## Project Goal ## Project Goal
Build a native Android app (LibreChat-Android) with full feature parity to the LibreChat web application. The app must connect to an existing LibreChat backend server (no backend changes). Users specify the server URL during onboarding. Build a native mobile app (LibreChat-Mobile) with full feature parity to the LibreChat web application. The app must connect to an existing LibreChat backend server (no backend changes). Users specify the server URL during onboarding.
## Tech Stack (Mandated) ## Tech Stack (Mandated)
- **UI**: Jetpack Compose + Compose Navigation - **UI**: Jetpack Compose + Compose Navigation

View file

@ -1,8 +1,8 @@
# LibreChat Android # LibreChat Mobile
[![LibreChat](https://img.shields.io/badge/LibreChat-v0.8.4-blue)](https://github.com/danny-avila/LibreChat/releases/tag/v0.8.4) [![LibreChat](https://img.shields.io/badge/LibreChat-v0.8.4-blue)](https://github.com/danny-avila/LibreChat/releases/tag/v0.8.4)
A third-party native Android client for [LibreChat](https://www.librechat.ai/). Not affiliated with the official LibreChat project — this is an independent app that connects to any self-hosted LibreChat server, no backend modifications required. 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.
## Features ## Features
@ -53,7 +53,7 @@ Add the following to your LibreChat server's `.env` file:
NON_BROWSER_VIOLATION_SCORE=0 NON_BROWSER_VIOLATION_SCORE=0
``` ```
Without this setting, the server's violation system may accumulate ban points against the Android client if the User-Agent check fails, eventually locking the account out. 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.
### Notes ### Notes

View file

@ -1,4 +1,4 @@
# Upstream LibreChat version this Android build tracks. # Upstream LibreChat version this mobile build tracks.
# Updated by the sync-upstream skill. Do not edit manually. # Updated by the sync-upstream skill. Do not edit manually.
tag=v0.8.4 tag=v0.8.4
commit=0736ff26686e911c9785a237c63a799db1813f0b commit=0736ff26686e911c9785a237c63a799db1813f0b

View file

@ -50,7 +50,7 @@ Conversations are integrated into the drawer body. Agents, Files, and Settings a
## Dependencies ## Dependencies
This module depends on all `:core:*` and all `:feature:*` modules. This module depends on all `:core:*` and all `:feature:*` modules.
It applies convention plugins: `librechat.android.application`, `librechat.android.compose`, `librechat.android.koin`. It applies convention plugins: `librechat.mobile.application`, `librechat.mobile.compose`, `librechat.mobile.koin`.
### Server-Synced Favorites ### Server-Synced Favorites
- `NavHostViewModel` exposes `favorites: StateFlow<Set<String>>` and `toggleFavorite()` - `NavHostViewModel` exposes `favorites: StateFlow<Set<String>>` and `toggleFavorite()`

View file

@ -1,7 +1,7 @@
plugins { plugins {
id("librechat.android.application") id("librechat.mobile.application")
id("librechat.android.compose") id("librechat.mobile.compose")
id("librechat.android.koin") id("librechat.mobile.koin")
} }
android { android {

View file

@ -1,4 +1,4 @@
# LibreChat Android ProGuard Rules # LibreChat Mobile ProGuard Rules
# Keep Kotlin serialization # Keep Kotlin serialization
-keepattributes *Annotation*, InnerClasses -keepattributes *Annotation*, InnerClasses

View file

@ -6,12 +6,12 @@ Convention plugins that apply consistent Gradle configuration across all modules
| Plugin ID | Class | What it does | | Plugin ID | Class | What it does |
|-----------|-------|-------------| |-----------|-------|-------------|
| `librechat.android.application` | `AndroidApplicationConventionPlugin` | AGP application plugin, compileSdk 35, minSdk 26, JDK 17 | | `librechat.mobile.application` | `AndroidApplicationConventionPlugin` | AGP application plugin, compileSdk 35, minSdk 26, JDK 17 |
| `librechat.android.library` | `AndroidLibraryConventionPlugin` | AGP library plugin, same SDK/JDK config | | `librechat.mobile.library` | `AndroidLibraryConventionPlugin` | AGP library plugin, same SDK/JDK config |
| `librechat.android.compose` | `AndroidComposeConventionPlugin` | Compose compiler, Compose BOM, Material 3 | | `librechat.mobile.compose` | `AndroidComposeConventionPlugin` | Compose compiler, Compose BOM, Material 3 |
| `librechat.android.koin` | `AndroidKoinConventionPlugin` | Koin core + Android dependencies | | `librechat.mobile.koin` | `AndroidKoinConventionPlugin` | Koin core + Android dependencies |
| `librechat.android.feature` | `AndroidFeatureConventionPlugin` | Auto-applies: library + compose + koin + serialization | | `librechat.mobile.feature` | `AndroidFeatureConventionPlugin` | Auto-applies: library + compose + koin + serialization |
| `librechat.android.room` | `AndroidRoomConventionPlugin` | Room + KSP, schema export config | | `librechat.mobile.room` | `AndroidRoomConventionPlugin` | Room + KSP, schema export config |
| `librechat.kotlin.serialization` | `KotlinSerializationConventionPlugin` | Kotlinx Serialization plugin + JSON dependency | | `librechat.kotlin.serialization` | `KotlinSerializationConventionPlugin` | Kotlinx Serialization plugin + JSON dependency |
## Critical: apply() Signature ## Critical: apply() Signature
@ -32,6 +32,6 @@ build.gradle.kts files. Use `libs.` accessors (e.g., `libs.koin.android`, `libs.
## Feature Module Convention ## Feature Module Convention
Feature modules use `id("librechat.android.feature")` which auto-applies library, compose, Feature modules use `id("librechat.mobile.feature")` which auto-applies library, compose,
koin, and serialization. They only need to add feature-specific dependencies. koin, and serialization. They only need to add feature-specific dependencies.
Feature modules depend on `:core:*` only, never on other feature modules. Feature modules depend on `:core:*` only, never on other feature modules.

View file

@ -16,27 +16,27 @@ dependencies {
gradlePlugin { gradlePlugin {
plugins { plugins {
register("androidApplication") { register("androidApplication") {
id = "librechat.android.application" id = "librechat.mobile.application"
implementationClass = "AndroidApplicationConventionPlugin" implementationClass = "AndroidApplicationConventionPlugin"
} }
register("androidLibrary") { register("androidLibrary") {
id = "librechat.android.library" id = "librechat.mobile.library"
implementationClass = "AndroidLibraryConventionPlugin" implementationClass = "AndroidLibraryConventionPlugin"
} }
register("androidCompose") { register("androidCompose") {
id = "librechat.android.compose" id = "librechat.mobile.compose"
implementationClass = "AndroidComposeConventionPlugin" implementationClass = "AndroidComposeConventionPlugin"
} }
register("androidFeature") { register("androidFeature") {
id = "librechat.android.feature" id = "librechat.mobile.feature"
implementationClass = "AndroidFeatureConventionPlugin" implementationClass = "AndroidFeatureConventionPlugin"
} }
register("androidRoom") { register("androidRoom") {
id = "librechat.android.room" id = "librechat.mobile.room"
implementationClass = "AndroidRoomConventionPlugin" implementationClass = "AndroidRoomConventionPlugin"
} }
register("androidKoin") { register("androidKoin") {
id = "librechat.android.koin" id = "librechat.mobile.koin"
implementationClass = "AndroidKoinConventionPlugin" implementationClass = "AndroidKoinConventionPlugin"
} }
register("kotlinSerialization") { register("kotlinSerialization") {
@ -44,7 +44,7 @@ gradlePlugin {
implementationClass = "KotlinSerializationConventionPlugin" implementationClass = "KotlinSerializationConventionPlugin"
} }
register("androidDetekt") { register("androidDetekt") {
id = "librechat.android.detekt" id = "librechat.mobile.detekt"
implementationClass = "AndroidDetektConventionPlugin" implementationClass = "AndroidDetektConventionPlugin"
} }
register("kmpLibrary") { register("kmpLibrary") {

View file

@ -10,7 +10,7 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
with(target) { with(target) {
pluginManager.apply("com.android.application") pluginManager.apply("com.android.application")
pluginManager.apply("org.jetbrains.kotlin.android") pluginManager.apply("org.jetbrains.kotlin.android")
pluginManager.apply("librechat.android.detekt") pluginManager.apply("librechat.mobile.detekt")
pluginManager.apply("org.jetbrains.kotlinx.kover") pluginManager.apply("org.jetbrains.kotlinx.kover")
tasks.withType<KotlinCompile>().configureEach { tasks.withType<KotlinCompile>().configureEach {

View file

@ -5,9 +5,9 @@ import org.gradle.kotlin.dsl.dependencies
class AndroidFeatureConventionPlugin : Plugin<Project> { class AndroidFeatureConventionPlugin : Plugin<Project> {
override fun apply(target: Project) { override fun apply(target: Project) {
with(target) { with(target) {
pluginManager.apply("librechat.android.library") pluginManager.apply("librechat.mobile.library")
pluginManager.apply("librechat.android.compose") pluginManager.apply("librechat.mobile.compose")
pluginManager.apply("librechat.android.koin") pluginManager.apply("librechat.mobile.koin")
dependencies { dependencies {
add("implementation", project(":core:ui")) add("implementation", project(":core:ui"))

View file

@ -10,7 +10,7 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
with(target) { with(target) {
pluginManager.apply("com.android.library") pluginManager.apply("com.android.library")
pluginManager.apply("org.jetbrains.kotlin.android") pluginManager.apply("org.jetbrains.kotlin.android")
pluginManager.apply("librechat.android.detekt") pluginManager.apply("librechat.mobile.detekt")
pluginManager.apply("org.jetbrains.kotlinx.kover") pluginManager.apply("org.jetbrains.kotlinx.kover")
tasks.withType<KotlinCompile>().configureEach { tasks.withType<KotlinCompile>().configureEach {

View file

@ -9,7 +9,7 @@ class KmpLibraryConventionPlugin : Plugin<Project> {
with(target) { with(target) {
pluginManager.apply("com.android.library") pluginManager.apply("com.android.library")
pluginManager.apply("org.jetbrains.kotlin.multiplatform") pluginManager.apply("org.jetbrains.kotlin.multiplatform")
pluginManager.apply("librechat.android.detekt") pluginManager.apply("librechat.mobile.detekt")
pluginManager.apply("org.jetbrains.kotlinx.kover") pluginManager.apply("org.jetbrains.kotlinx.kover")
extensions.configure<KotlinMultiplatformExtension> { extensions.configure<KotlinMultiplatformExtension> {

View file

@ -37,4 +37,4 @@ This lives here (not in `:core:network`) because repositories in `:core:data` ca
- **Pure Kotlin preferred.** Minimal Android dependencies (only what ConnectivityObserver and Koin require). - **Pure Kotlin preferred.** Minimal Android dependencies (only what ConnectivityObserver and Koin require).
- **No network or data dependencies.** This module must not depend on `:core:network`, `:core:data`, or `:core:model`. - **No network or data dependencies.** This module must not depend on `:core:network`, `:core:data`, or `:core:model`.
- Dependencies: `coroutines-core`, `coroutines-android`, Koin. - Dependencies: `coroutines-core`, `coroutines-android`, Koin.
- Convention plugin: `librechat.android.library` + `librechat.android.koin`. - Convention plugin: `librechat.mobile.library` + `librechat.mobile.koin`.

View file

@ -55,7 +55,7 @@ Wrap `EncryptedSharedPreferences` in try/catch -- some OEM devices have broken K
## Rules ## Rules
- Dependencies: `:core:network`, `:core:model`, `:core:common`, Room, DataStore, security-crypto, Ktor, kotlinx-serialization, Timber, Koin. - Dependencies: `:core:network`, `:core:model`, `:core:common`, Room, DataStore, security-crypto, Ktor, kotlinx-serialization, Timber, Koin.
- Convention plugins: `librechat.android.library` + `librechat.android.koin` + `librechat.android.room` + `librechat.kotlin.serialization`. - Convention plugins: `librechat.mobile.library` + `librechat.mobile.koin` + `librechat.mobile.room` + `librechat.kotlin.serialization`.
- Repositories must use `safeApiCall` from `:core:common` for all network calls. - Repositories must use `safeApiCall` from `:core:common` for all network calls.
- Entities are internal to this module -- feature modules work with domain models from `:core:model`. - Entities are internal to this module -- feature modules work with domain models from `:core:model`.
- All DAO read methods that the UI observes should return `Flow`, not suspend functions. - All DAO read methods that the UI observes should return `Flow`, not suspend functions.

View file

@ -27,4 +27,4 @@ All `@Serializable` data classes -- domain models, DTOs, request/response wrappe
- Only dependency beyond `:core:common` is `kotlinx-serialization-json`. - Only dependency beyond `:core:common` is `kotlinx-serialization-json`.
- Use `@Serializable` on every data class. Use `@SerialName` for snake_case JSON fields. - Use `@Serializable` on every data class. Use `@SerialName` for snake_case JSON fields.
- Use `JsonObject` / `JsonElement` for truly polymorphic/mixed-type fields (e.g., `Agent.avatar`, `Feedback.tag`). - Use `JsonObject` / `JsonElement` for truly polymorphic/mixed-type fields (e.g., `Agent.avatar`, `Feedback.tag`).
- Convention plugins: `librechat.android.library` + `librechat.kotlin.serialization`. - Convention plugins: `librechat.mobile.library` + `librechat.kotlin.serialization`.

View file

@ -41,6 +41,6 @@ On reconnection, append `?resume=true` to get a `sync` event with `runSteps[]` +
## Rules ## Rules
- Dependencies: `:core:model`, `:core:common`, Ktor bundles, kotlinx-serialization, Timber, Koin. - Dependencies: `:core:model`, `:core:common`, Ktor bundles, kotlinx-serialization, Timber, Koin.
- Convention plugins: `librechat.android.library` + `librechat.android.koin` + `librechat.kotlin.serialization`. - Convention plugins: `librechat.mobile.library` + `librechat.mobile.koin` + `librechat.kotlin.serialization`.
- API services must not contain business logic -- they are thin HTTP wrappers. - API services must not contain business logic -- they are thin HTTP wrappers.
- All `arg`-wrapped endpoints must match the backend pattern: `setBody(mapOf("arg" to mapOf(...)))`. - All `arg`-wrapped endpoints must match the backend pattern: `setBody(mapOf("arg" to mapOf(...)))`.

View file

@ -42,7 +42,7 @@ Material 3 theme and shared Compose components used across all feature modules.
- Components accept domain models from `:core:model` as parameters and render them. - Components accept domain models from `:core:model` as parameters and render them.
- All components must be stateless or hoist state to the caller. - All components must be stateless or hoist state to the caller.
- Dependencies: `:core:model`, `:core:common`, Coil for image loading, Compose libraries. - Dependencies: `:core:model`, `:core:common`, Coil for image loading, Compose libraries.
- Convention plugins: `librechat.android.library` + `librechat.android.compose`. - Convention plugins: `librechat.mobile.library` + `librechat.mobile.compose`.
- No DI in this module (no Koin modules, no injected classes). - No DI in this module (no Koin modules, no injected classes).
- Use `@Preview` annotations on all components for Android Studio preview support. - Use `@Preview` annotations on all components for Android Studio preview support.
- During SSE streaming, buffer markdown re-renders to ~100ms intervals to avoid frame drops. - During SSE streaming, buffer markdown re-renders to ~100ms intervals to avoid frame drops.

View file

@ -3,13 +3,13 @@ package com.garfiec.librechat.core.ui.components
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import com.garfiec.librechat.core.model.EModelEndpoint import com.garfiec.librechat.core.model.EModelEndpoint
import librechat_android.core.ui.generated.resources.Res import librechat_mobile.core.ui.generated.resources.Res
import librechat_android.core.ui.generated.resources.ic_agents import librechat_mobile.core.ui.generated.resources.ic_agents
import librechat_android.core.ui.generated.resources.ic_anthropic import librechat_mobile.core.ui.generated.resources.ic_anthropic
import librechat_android.core.ui.generated.resources.ic_azure import librechat_mobile.core.ui.generated.resources.ic_azure
import librechat_android.core.ui.generated.resources.ic_bedrock import librechat_mobile.core.ui.generated.resources.ic_bedrock
import librechat_android.core.ui.generated.resources.ic_google import librechat_mobile.core.ui.generated.resources.ic_google
import librechat_android.core.ui.generated.resources.ic_openai import librechat_mobile.core.ui.generated.resources.ic_openai
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
/** /**

View file

@ -23,8 +23,8 @@ import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
@Composable @Composable
actual fun AgentAvatarPicker( actual fun AgentAvatarPicker(

View file

@ -57,8 +57,8 @@ import com.garfiec.librechat.core.model.ActionAuth
import com.garfiec.librechat.core.model.ActionMetadata import com.garfiec.librechat.core.model.ActionMetadata
import com.garfiec.librechat.core.model.request.FunctionTool import com.garfiec.librechat.core.model.request.FunctionTool
import com.garfiec.librechat.feature.agents.AgentActionDisplayData import com.garfiec.librechat.feature.agents.AgentActionDisplayData
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.util.OpenApiSpecParser import com.garfiec.librechat.feature.agents.util.OpenApiSpecParser
import com.garfiec.librechat.feature.agents.util.ParsedFunctionInfo import com.garfiec.librechat.feature.agents.util.ParsedFunctionInfo
import kotlinx.coroutines.delay import kotlinx.coroutines.delay

View file

@ -29,8 +29,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
data class AgentAdvancedSettings( data class AgentAdvancedSettings(

View file

@ -18,8 +18,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
data class AgentCapabilities( data class AgentCapabilities(
val artifacts: Boolean = false, val artifacts: Boolean = false,

View file

@ -16,8 +16,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import com.garfiec.librechat.core.model.AgentCategory import com.garfiec.librechat.core.model.AgentCategory
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
/** /**
* Maps category values to human-readable English labels. * Maps category values to human-readable English labels.

View file

@ -15,8 +15,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
@Composable @Composable
fun AgentCodeInterpreterSection( fun AgentCodeInterpreterSection(

View file

@ -15,8 +15,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
@Composable @Composable
fun AgentFileSearchSection( fun AgentFileSearchSection(

View file

@ -38,8 +38,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.agents.AgentHandoffDisplayData import com.garfiec.librechat.feature.agents.AgentHandoffDisplayData
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
@Composable @Composable
fun AgentHandoffConfig( fun AgentHandoffConfig(

View file

@ -24,8 +24,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.mcp.McpTool import com.garfiec.librechat.core.model.mcp.McpTool
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
/** Hierarchical MCP tool picker grouped by server with checkbox selection. */ /** Hierarchical MCP tool picker grouped by server with checkbox selection. */
@Composable @Composable

View file

@ -18,8 +18,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
data class ModelOption( data class ModelOption(
val id: String, val id: String,

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
enum class AgentVisibility(val label: String) { enum class AgentVisibility(val label: String) {
PRIVATE("Private"), PRIVATE("Private"),

View file

@ -11,8 +11,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
@androidx.compose.runtime.Immutable @androidx.compose.runtime.Immutable
data class SupportContactState( data class SupportContactState(

View file

@ -23,8 +23,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
data class AgentVersion( data class AgentVersion(
val version: Int, val version: Int,

View file

@ -49,8 +49,8 @@ import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import com.garfiec.librechat.feature.agents.AgentToolDisplayData import com.garfiec.librechat.feature.agents.AgentToolDisplayData
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
/** /**
* Full-screen dialog for selecting agent tools, matching the web app's ToolSelectDialog. * Full-screen dialog for selecting agent tools, matching the web app's ToolSelectDialog.

View file

@ -51,8 +51,8 @@ import com.garfiec.librechat.core.ui.components.AvatarImage
import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.LoadingIndicator
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailEvent import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailEvent
import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailViewModel import com.garfiec.librechat.feature.agents.viewmodel.AgentDetailViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -53,8 +53,8 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.ErrorBanner import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.LoadingIndicator
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.components.AgentActionsPanel import com.garfiec.librechat.feature.agents.components.AgentActionsPanel
import com.garfiec.librechat.feature.agents.components.AgentAdvancedPanel import com.garfiec.librechat.feature.agents.components.AgentAdvancedPanel
import com.garfiec.librechat.feature.agents.components.AgentAvatarPicker import com.garfiec.librechat.feature.agents.components.AgentAvatarPicker

View file

@ -52,8 +52,8 @@ import com.garfiec.librechat.core.ui.components.ErrorBanner
import com.garfiec.librechat.core.ui.components.LibreChatTopBar import com.garfiec.librechat.core.ui.components.LibreChatTopBar
import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.feature.agents.AgentCardDisplayData import com.garfiec.librechat.feature.agents.AgentCardDisplayData
import librechat_android.feature.agents.generated.resources.Res import librechat_mobile.feature.agents.generated.resources.Res
import librechat_android.feature.agents.generated.resources.* import librechat_mobile.feature.agents.generated.resources.*
import com.garfiec.librechat.feature.agents.viewmodel.AgentMarketplaceViewModel import com.garfiec.librechat.feature.agents.viewmodel.AgentMarketplaceViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -31,8 +31,8 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.ForgotPasswordViewModel import com.garfiec.librechat.feature.auth.viewmodel.ForgotPasswordViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.LoginViewModel import com.garfiec.librechat.feature.auth.viewmodel.LoginViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -28,8 +28,8 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.RegisterViewModel import com.garfiec.librechat.feature.auth.viewmodel.RegisterViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -31,8 +31,8 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.ResetPasswordViewModel import com.garfiec.librechat.feature.auth.viewmodel.ResetPasswordViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -25,8 +25,8 @@ import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.ServerUrlViewModel import com.garfiec.librechat.feature.auth.viewmodel.ServerUrlViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -32,8 +32,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.TermsViewModel import com.garfiec.librechat.feature.auth.viewmodel.TermsViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -38,8 +38,8 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.TwoFactorViewModel import com.garfiec.librechat.feature.auth.viewmodel.TwoFactorViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -30,8 +30,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import librechat_android.feature.auth.generated.resources.Res import librechat_mobile.feature.auth.generated.resources.Res
import librechat_android.feature.auth.generated.resources.* import librechat_mobile.feature.auth.generated.resources.*
import com.garfiec.librechat.feature.auth.viewmodel.VerifyEmailViewModel import com.garfiec.librechat.feature.auth.viewmodel.VerifyEmailViewModel
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel

View file

@ -34,8 +34,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import co.touchlab.kermit.Logger import co.touchlab.kermit.Logger
import java.io.File import java.io.File

View file

@ -53,8 +53,8 @@ import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.garfiec.librechat.feature.chat.McpServerDisplayData import com.garfiec.librechat.feature.chat.McpServerDisplayData
import com.garfiec.librechat.feature.chat.PromptMentionDisplayData import com.garfiec.librechat.feature.chat.PromptMentionDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import java.io.File import java.io.File
@Composable @Composable

View file

@ -51,8 +51,8 @@ import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.core.model.AgentToolCall import com.garfiec.librechat.core.model.AgentToolCall
import com.garfiec.librechat.core.model.ContentType import com.garfiec.librechat.core.model.ContentType
import com.garfiec.librechat.core.model.MessageContentPart import com.garfiec.librechat.core.model.MessageContentPart
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.components.artifact.ArtifactButton import com.garfiec.librechat.feature.chat.components.artifact.ArtifactButton
import com.garfiec.librechat.feature.chat.components.artifact.ArtifactPanel import com.garfiec.librechat.feature.chat.components.artifact.ArtifactPanel
import com.garfiec.librechat.feature.chat.components.artifact.ArtifactSegment import com.garfiec.librechat.feature.chat.components.artifact.ArtifactSegment

View file

@ -53,8 +53,8 @@ import coil3.compose.AsyncImage
import coil3.SingletonImageLoader import coil3.SingletonImageLoader
import coil3.request.ImageRequest import coil3.request.ImageRequest
import coil3.toBitmap import coil3.toBitmap
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext

View file

@ -60,8 +60,8 @@ import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.mikepenz.markdown.m3.Markdown import com.mikepenz.markdown.m3.Markdown
import com.mikepenz.markdown.m3.markdownColor import com.mikepenz.markdown.m3.markdownColor
import com.mikepenz.markdown.m3.markdownTypography import com.mikepenz.markdown.m3.markdownTypography

View file

@ -47,8 +47,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import co.touchlab.kermit.Logger import co.touchlab.kermit.Logger
@Composable @Composable

View file

@ -31,8 +31,8 @@ import com.garfiec.librechat.core.model.Message
import com.garfiec.librechat.core.ui.components.AvatarImage import com.garfiec.librechat.core.ui.components.AvatarImage
import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
private const val ACTION_AUTO_HIDE_MILLIS = 30_000L private const val ACTION_AUTO_HIDE_MILLIS = 30_000L

View file

@ -29,8 +29,8 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
actual fun VideoContent( actual fun VideoContent(

View file

@ -31,8 +31,8 @@ import androidx.media3.common.MediaItem
import androidx.media3.common.Player import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView import androidx.media3.ui.PlayerView
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** Plays video via ExoPlayer (media3) in a 16:9 card. Releases player on dispose via DisposableEffect. */ /** Plays video via ExoPlayer (media3) in a 16:9 card. Releases player on dispose via DisposableEffect. */
@Composable @Composable

View file

@ -63,8 +63,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.components.CodeBlock import com.garfiec.librechat.feature.chat.components.CodeBlock
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import co.touchlab.kermit.Logger import co.touchlab.kermit.Logger

View file

@ -77,8 +77,8 @@ import com.garfiec.librechat.core.model.ContentType
import com.garfiec.librechat.core.model.MessageContentPart import com.garfiec.librechat.core.model.MessageContentPart
import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.LoadingIndicator
import com.garfiec.librechat.core.ui.components.ModelParameterSheet import com.garfiec.librechat.core.ui.components.ModelParameterSheet
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.components.ChatInput import com.garfiec.librechat.feature.chat.components.ChatInput
import com.garfiec.librechat.feature.chat.components.ComparisonDualPane import com.garfiec.librechat.feature.chat.components.ComparisonDualPane
import com.garfiec.librechat.feature.chat.components.ComparisonTabBar import com.garfiec.librechat.feature.chat.components.ComparisonTabBar

View file

@ -27,8 +27,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Data class representing an agent handoff event. * Data class representing an agent handoff event.

View file

@ -53,8 +53,8 @@ import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.feature.chat.McpServerDisplayData import com.garfiec.librechat.feature.chat.McpServerDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Floating row of Material 3 chips above the chat input field. * Floating row of Material 3 chips above the chat input field.

View file

@ -36,8 +36,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.feature.chat.McpServerDisplayData import com.garfiec.librechat.feature.chat.McpServerDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
data class ToolToggle( data class ToolToggle(
val id: String, val id: String,

View file

@ -55,8 +55,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.common.ToolConstants
import com.garfiec.librechat.feature.chat.McpServerDisplayData import com.garfiec.librechat.feature.chat.McpServerDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable

View file

@ -35,8 +35,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Popup import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties import androidx.compose.ui.window.PopupProperties
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Parsed citation found in message text. * Parsed citation found in message text.

View file

@ -44,8 +44,8 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.withStyle import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@Composable @Composable

View file

@ -42,8 +42,8 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Data class representing a code execution result parsed from tool call output. * Data class representing a code execution result parsed from tool call output.

View file

@ -42,13 +42,13 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.chat.McpServerDisplayData import com.garfiec.librechat.feature.chat.McpServerDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.cd_send_message import librechat_mobile.feature.chat.generated.resources.cd_send_message
import librechat_android.feature.chat.generated.resources.cd_start_voice_recording import librechat_mobile.feature.chat.generated.resources.cd_start_voice_recording
import librechat_android.feature.chat.generated.resources.cd_stop_generation import librechat_mobile.feature.chat.generated.resources.cd_stop_generation
import librechat_android.feature.chat.generated.resources.hint_message import librechat_mobile.feature.chat.generated.resources.hint_message
import librechat_android.feature.chat.generated.resources.hint_message_model import librechat_mobile.feature.chat.generated.resources.hint_message_model
import librechat_android.feature.chat.generated.resources.recording import librechat_mobile.feature.chat.generated.resources.recording
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
@Immutable @Immutable

View file

@ -17,8 +17,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Tablet-layout comparison view with two side-by-side panes. * Tablet-layout comparison view with two side-by-side panes.

View file

@ -22,8 +22,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**

View file

@ -19,8 +19,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Dialog shown when a user taps thumbs-down on an AI message. * Dialog shown when a user taps thumbs-down on an AI message.

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.request.ForkOption import com.garfiec.librechat.core.model.request.ForkOption
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable

View file

@ -38,8 +38,8 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImage
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
data class ImageGenResult( data class ImageGenResult(
val imageUrl: String? = null, val imageUrl: String? = null,

View file

@ -30,8 +30,8 @@ import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter

View file

@ -24,8 +24,8 @@ import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
fun InlineEditInput( fun InlineEditInput(

View file

@ -26,8 +26,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import kotlin.time.Clock import kotlin.time.Clock
import kotlinx.datetime.TimeZone import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime

View file

@ -38,8 +38,8 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
data class LogContent( data class LogContent(
val title: String = "Log Output", val title: String = "Log Output",

View file

@ -28,8 +28,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Data class representing an MCP resource parsed from tool call output. * Data class representing an MCP resource parsed from tool call output.

View file

@ -34,8 +34,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.chat.McpServerDisplayData import com.garfiec.librechat.feature.chat.McpServerDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
fun McpServerSelector( fun McpServerSelector(

View file

@ -28,8 +28,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Data class representing a memory artifact parsed from tool call output. * Data class representing a memory artifact parsed from tool call output.

View file

@ -32,8 +32,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.Message import com.garfiec.librechat.core.model.Message
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
/** /**

View file

@ -47,8 +47,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImage
import com.garfiec.librechat.core.model.FileReference import com.garfiec.librechat.core.model.FileReference
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Renders files attached to a message. Splits files into images (shown as * Renders files attached to a message. Splits files into images (shown as

View file

@ -39,8 +39,8 @@ import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ChatLayoutConstants import com.garfiec.librechat.core.common.ChatLayoutConstants
import com.garfiec.librechat.core.model.FeedbackRating import com.garfiec.librechat.core.model.FeedbackRating
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.util.MessageNode import com.garfiec.librechat.feature.chat.util.MessageNode
import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
import com.garfiec.librechat.feature.chat.viewmodel.SearchMatch import com.garfiec.librechat.feature.chat.viewmodel.SearchMatch

View file

@ -16,8 +16,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
fun ModelSelectorButton( fun ModelSelectorButton(

View file

@ -51,8 +51,8 @@ import com.garfiec.librechat.core.model.EndpointConfig
import com.garfiec.librechat.core.ui.components.endpointIconPainter import com.garfiec.librechat.core.ui.components.endpointIconPainter
import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon import com.garfiec.librechat.core.ui.components.isMonochromeEndpointIcon
import com.garfiec.librechat.feature.chat.util.FuzzyMatch import com.garfiec.librechat.feature.chat.util.FuzzyMatch
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
private val IconSize = 20.dp private val IconSize = 20.dp

View file

@ -29,8 +29,8 @@ import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.feature.chat.PresetDisplayData import com.garfiec.librechat.feature.chat.PresetDisplayData
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable

View file

@ -17,8 +17,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
fun SavePresetDialog( fun SavePresetDialog(

View file

@ -16,8 +16,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.common.ChatLayoutConstants import com.garfiec.librechat.core.common.ChatLayoutConstants
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.util.MessageNode import com.garfiec.librechat.feature.chat.util.MessageNode
import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall

View file

@ -17,8 +17,8 @@ import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
fun SiblingNavigator( fun SiblingNavigator(

View file

@ -19,8 +19,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Blinking cursor indicator shown during streaming. Displays a pipe character (|) * Blinking cursor indicator shown during streaming. Displays a pipe character (|)

View file

@ -33,8 +33,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall import com.garfiec.librechat.feature.chat.viewmodel.ActiveToolCall
@Composable @Composable

View file

@ -16,8 +16,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import com.garfiec.librechat.core.common.ToolConstants import com.garfiec.librechat.core.common.ToolConstants
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
private data class ToolMenuItem( private data class ToolMenuItem(
val id: String, val id: String,

View file

@ -36,8 +36,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImage
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* Data class representing a single web search result parsed from tool call output. * Data class representing a single web search result parsed from tool call output.

View file

@ -32,8 +32,8 @@ import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
@Composable @Composable
fun ArtifactButton( fun ArtifactButton(

View file

@ -16,8 +16,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** Prev/next version navigation for artifacts. [currentIndex] is 0-based; display shows 1-based "v1/N". */ /** Prev/next version navigation for artifacts. [currentIndex] is 0-based; display shows 1-based "v1/N". */
@Composable @Composable

View file

@ -31,8 +31,8 @@ import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.ui.components.LibreChatTopBar import com.garfiec.librechat.core.ui.components.LibreChatTopBar
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import com.garfiec.librechat.feature.chat.prompts.components.PromptPreviewPanel import com.garfiec.librechat.feature.chat.prompts.components.PromptPreviewPanel
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)

View file

@ -35,8 +35,8 @@ import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.garfiec.librechat.core.ui.components.LoadingIndicator import com.garfiec.librechat.core.ui.components.LoadingIndicator
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)

View file

@ -15,8 +15,8 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
private val VARIABLE_REGEX = Regex("\\{\\{\\s*(\\w+)\\s*\\}\\}") private val VARIABLE_REGEX = Regex("\\{\\{\\s*(\\w+)\\s*\\}\\}")

View file

@ -26,8 +26,8 @@ import org.jetbrains.compose.resources.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.garfiec.librechat.core.model.Prompt import com.garfiec.librechat.core.model.Prompt
import librechat_android.feature.chat.generated.resources.Res import librechat_mobile.feature.chat.generated.resources.Res
import librechat_android.feature.chat.generated.resources.* import librechat_mobile.feature.chat.generated.resources.*
/** /**
* A ModalBottomSheet that shows the version history of prompts within a group. * A ModalBottomSheet that shows the version history of prompts within a group.

Some files were not shown because too many files have changed in this diff Show more