Commit graph

24 commits

Author SHA1 Message Date
Garfie
92192498ca feat(ui): render custom endpoint iconURL in drawer and conversation list
Render `EndpointConfig.iconURL` in drawer + conversation list rows with
per-conversation override via `Conversation.iconURL`. Extract shared
`EndpointIcon` composable to `:core:ui`. Eager `/api/config` fetch via
`EndpointConfigFetchSessionTask` so cold-start has icons. Clear config
cache on logout to prevent cross-user leak.

Closes #68.
2026-04-29 20:19:11 -06:00
Garfie
2b44937368 fix(chat): wire format for custom and user_provided endpoints (#60)
ChatPayloadBuilder caught EModelEndpoint.valueOf for custom endpoint
names (OpenRouter, Deepseek, etc.) and silently sent endpoint=agents,
producing 403 "Forbidden: Insufficient permissions" on the server.

Type endpoint identity as String end-to-end, add EndpointClassifier to
derive endpointType / key / modelDisplayLabel from /api/config, and
propagate the dispatch fields to all five chat-send sites in
ChatViewModel (doSendMessage, editUserMessage, editAiMessage,
regenerateMessageNow, continueGenerationNow). A normalization shim in
ConversationMapper converts legacy enum-name rows in the Room cache
back to wire format on read.

Verified end-to-end against a docker LibreChat v0.8.5 instance with
OpenRouter user_provided keys; built-in .env Anthropic regression also
passes.
2026-04-28 20:21:28 -06:00
Garfie
abde86ca4e chore(sync): sync to upstream LibreChat v0.8.5
Targets upstream tag v0.8.5 (commit 9ccc8d9be). Bumps the supported
backend version constant, advances the upstream submodule pin, and
adds wire-protocol parity for new server features.

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

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

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

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

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

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

Out of scope (by design)
- /api/admin/** route family - web-only feature.
- Full ACL migration for agent sharing - replaced by version-gating
  the legacy isCollaborative toggle.
- Spec-pinning UI on mobile - UserFavorite.spec round-trips for
  fidelity with web-authored pins, but mobile does not yet surface
  a spec picker.
2026-04-26 23:48:14 -06:00
Garfie
6fde5c55cb fix(permissions): gate mobile surfaces on server role permissions (#49) 2026-04-24 21:21:05 -05:00
Garfie
c613175c6e fix(navigation): fully reset ConversationListStateHolder on logout
reset() now clears pagination cursor, hasMore, isLoadingMore and
isRefreshing state so the next user session does not inherit stuck
spinners or stale cursors from the previous session. Also cancel and
restart the search debounce collector so an in-flight debounced
emission from the previous session cannot land after reset() and
clobber the cleared grouped conversations list.
2026-04-14 21:30:30 -05:00
Garfie
4a6c1f9a29 fix(ios): stream SSE via NWConnection to bypass NSURLSession text/* buffering 2026-04-14 07:21:48 -05:00
Garfie
0483581f23 feat(favorites): move bookmarks to server-backed tags with offline cache 2026-04-13 19:40:14 -05:00
Garfie
63d87c843b cleanup: burn down detekt baselines and rename Compose Resources package 2026-04-11 12:35:19 -05:00
Garfie
b4872e4de0 feat: add detekt-koin, .editorconfig, GitHub Actions CI for android + ios 2026-04-09 23:48:41 -05:00
Garfie
e8bda6ca05 refactor: replace fully-qualified names with proper imports across codebase 2026-04-08 19:15:49 -05:00
Garfie
00055c515e refactor: extract supporting types to own files and organize into sub-packages 2026-04-07 21:49:15 -05:00
Garfie
ebcae8478e refactor: NavHostViewModel stage 5 - extract drawer models and display mapping 2026-04-07 20:45:44 -05:00
Garfie
72054ad442 refactor: NavHostViewModel stage 4 - extract favorites state holder 2026-04-07 20:19:20 -05:00
Garfie
4875072e54 refactor: NavHostViewModel stage 3 - extract conversation list state holder 2026-04-07 19:52:22 -05:00
Garfie
58654ca245 refactor: NavHostViewModel stage 2 - extract banner and version check state holders 2026-04-06 23:31:19 -05:00
Garfie
c422408de6 refactor: NavHostViewModel stage 1 - extract constants, fix races, deduplicate, and modernize search debounce 2026-04-06 22:38:38 -05:00
Garfie
4c0b76a9b3 fix: iOS image rendering and consolidate content part dispatch to commonMain
- Configure Coil ImageLoader with authenticated Ktor HttpClient on iOS
- Extract ContentPartRenderer sub-composables and tool call dispatch into shared commonMain (SharedContentParts.kt, ToolCallParsing.kt)
- Add missing iOS handlers: AGENT_UPDATE, VIDEO_URL null fallback
- Fix error text fallback inconsistency across platforms
- Add memory cache to iOS ImageLoader
2026-04-06 12:25:48 -05:00
Garfie
acd83661cc refactor: consolidate duplicate navigation code between app and shared modules 2026-04-05 20:50:48 -05:00
Garfie
2d06b7e2f6 chore: fix iOS setup docs, remove dead Swift files, fix Xcode release build config 2026-04-05 18:25:53 -05:00
Garfie
40ee348b12 refactor: migrate from Navigation Compose 2 to Navigation Compose 3 2026-04-04 22:26:27 -05:00
Garfie
2756efa812 refactor: convert navigation to type-safe routes with polymorphic serialization 2026-04-04 21:39:25 -05:00
Garfie
00056b634b chore: rename project from LibreChat Android to LibreChat Mobile 2026-04-03 16:56:36 -05:00
Garfie
e5c5b549db chore: rename package com.librechat to com.garfiec.librechat 2026-04-03 16:12:37 -05:00
Garfie
770603e466 KMP iOS migration
Complete Kotlin Multiplatform migration with iOS parity:
- All 13 modules converted to KMP (commonMain + androidMain + iosMain)
- 100% feature parity: auth, chat, SSE streaming, conversations,
  settings, agents, files, voice input, TTS, OAuth, file picker,
  clipboard paste
- Platform consolidation: DataStore path, SessionCacheCleaner,
  bubble layouts, ChatInput core, MIME types, mention parsing,
  TextField styling, FilterChip components extracted to commonMain
- iOS crash reporting via Kotlin/Native exception hook
- YAML parsing via custom pure-Kotlin parser (zero dependencies)
- Dependency health: Timber removed, kaml replaced, FuzzyWuzzy removed,
  security-crypto stabilized
- CONTRIBUTING.md
- Gradle configuration cache enabled
2026-04-02 19:54:58 -05:00