* feat: add Apple model backends and context compaction
* Add Apple on-device and PCC direct providers
* dev: show all onboarding backends in debug builds
* Fix short response pin-to-top settlement
* Polish Direct Connections context settings
* Fix onboarding selection row spacing
* Address PR review feedback
* Harden context and native request bounds
* Strengthen compaction regression coverage
* Close final context and image review gaps
* Validate structured array bounds
* feat(l10n): add Polish localization
- add complete Polish Flutter localization (app_pl.arb) mirroring app_en.arb
- add pl to preferred-supported-locales, language selector, and native language sheets
- add Polish iOS native resources (pl.lproj) and Xcode project registration
- add Polish release notes and language count documentation
- add focused tests for locale resolution, resource completeness, and Polish plurals
* fix(l10n): address Polish localization review feedback
- localize the 'polish' language name per catalog (Polish/Polnisch/Polonais/Poľština/...)
- label the credentials auth mode 'E-mail i hasło' instead of 'Hasło'
- pluralize the active-schedule count in hermesSchedulesSummary (1 aktywny / 2 aktywne / 5 aktywnych)
- use feminine 'Poprzednia' for the previous-version action label
- replace literal 'szybkie pigułki' with 'szybkie akcje'
- reword server-downgrade instruction, shared-chat notice, and direct-connection delete message
- use the official product name 'Open Web UI' in user-facing values
- make the placeholder parity test robust to Dart identity-based set/list equality
* fix(l10n): address remaining Polish review feedback
- use a username-inclusive label 'Dane logowania' for the credentials auth mode
- reword the prompt version delete confirmation to 'Ta wersja zostanie usunięta'
- keep channelMembers plural forms unchanged (with digits, '2 członków' is correct, not '2 członkowie')
Assisted-by: Open WebUI
* fix(l10n): rebase Polish catalog onto current English keys
Polish was complete against an older template; fill the 134 strings added on main (Hermes jobs/sessions, voice barge-in, sidebar) so locale validation can pass after merge.
---------
Co-authored-by: Kamil Maciąg <6450912+Dragonk@users.noreply.github.com>
Co-authored-by: cogwheel <172976095+cogwheel0@users.noreply.github.com>
* fix: resolve reported rendering, voice, terminal, and connection bugs
LaTeX (#642, #533): render complex MathJax SVGs through the compatible
renderer so underbrace/boxed/pmatrix no longer glitch or leak `amp`, and
center block equations horizontally.
Fonts (#501): rebuild the bundled Geist faces, which mapped lowercase
Greek omega to the uppercase glyph.
Hermes (#637): connection tests now exercise authenticated capability and
toolset discovery instead of the unauthenticated health endpoint, so a
server that only answers /health no longer reports "connected".
Voice (#632): request microphone permission before starting the Android
foreground service, which crashed when permission had never been granted.
Voice (#630): stop local STT while TTS plays so the model no longer hears
itself. Barge-in is off by default and opt-in from Audio settings, and the
voice overlay gains a speakerphone toggle.
Transport (#629): drop the plaintext-HTTP restriction for Hermes and
direct connections. Tailscale/Headscale CGNAT addresses and other private
networks were rejected outright. Custom headers and the self-signed
certificate toggle are now shared by all backends via a single Hermes
transport configurator.
Terminal (#626): download now opens the native save dialog instead of the
share sheet.
Terminal (#608): route the `terminal:display_file` event into the Terminal
files panel rather than dropping it in the chat event handler.
Auth (#606): drive reverse-proxy login through the real WebView identity
and cookie store so Authelia and similar providers finish sign-in.
Also fixes pre-existing test failures on main: three assertions still
expected the single-newline block join replaced in #641, and six expected
the "Delete connection" button label renamed to "Delete" in #628.
* fix: route Android speakerphone and address review feedback
Speakerphone on Android: setSpeakerphoneOn is deprecated and no-ops on
Android 12+ once a communication device is selected, which the voice
session does for Bluetooth SCO. The toggle rendered but never changed the
route. Select the built-in speaker as the communication device instead,
keeping the legacy call as the pre-31 fallback, and tear down the active
SCO route before re-routing so a headset cannot keep owning playback.
Voice: treat TtsError as a terminal assistant-speech event. With barge-in
disabled the recognizer is stopped for playback and only TtsCompleted
restarted it, so a failed TTS request left voice mode active with no way
to accept the next utterance.
Hermes: cancel active runs when certificate trust changes. A trust-only
edit rebuilt the transport while old cancellation tokens stayed live.
Terminal: sanitize the download file name, which comes from the server's
Content-Disposition header, before passing it to the save dialog.
Hermes settings: use the existing headerName/headerValue/addHeader/
removeHeader localizations instead of hardcoded English.
Adds coverage for the speakerphone toggle, TTS-error recovery, and
HttpClient forwarding through the desktop RPC channel factory.
* fix: fall back for dot-only download file names
`.` and `..` survive character sanitization but name a directory rather
than a file, so writing them throws instead of producing a download. Use
the timestamp fallback for those, and cover the sanitizer directly.
Windows reserved device names are not handled: this app ships only iOS and
Android targets.
* fix: gate reasoning effort by model support
Automatic previously omitted the params key, so OpenWebUI's shallow settings merge retained the old reasoning_effort value. Explicitly replace the params map when clearing and fail closed at the request boundary for models that do not advertise support.
* address reasoning effort review feedback
* fix: hydrate workspace reasoning effort details
The earlier fix trusted the OpenWebUI model catalog, but current OpenWebUI deliberately strips workspace model params from /api/models. Fetch and cache the selected workspace model detail so its configured custom effort wins over the user-level fallback and reaches the native selector.
* fix: avoid workspace effort hydration race
Do not fall back to the user-level effort while private workspace model params are still loading. Omitting the override during that window lets OpenWebUI apply its model configuration, and the held-response regression test prevents the first-send race from returning.
* refactor: generate workspace effort provider
* fix: retry workspace effort after failures
* fix: handle unavailable workspace effort
* fix: hide unhydrated native effort controls
* fix: progressively hydrate native reasoning effort
* fix: guard native effort callback rollback
* fix: serialize native effort updates
* test: distinguish native effort update callbacks
* feat: bundled JSON release notes for 4.0, polished changelog sheet, remove IAP
- Move release-note content from ARB to assets/release_notes/<locale>.json
with locale-fallback repository and schema-checked validator
- Polish the release notes sheet (staggered reveal, version badge,
feature glyph bullets, action cards) and add the 4.0 note in 13 locales
- Prune pre-4.0 notes
- Remove in_app_purchase and the tip jar entirely; keep the Buy Me a
Coffee donation link on all platforms
* Refresh release notes sheet and localized copy
* Add release notes banner and native review support
* Redesign release announcement sheet
* Target release announcement to 4.0.1
* Address release announcement review feedback
* Tighten release note locale handling
* feat: add first-party OpenRouter support
* fix: address OpenRouter review feedback
* fix: preserve OpenRouter server auth options
* fix: localize reviewed catalog entries
* feat: normalize OpenRouter reasoning effort
* fix: validate raw OpenRouter PDF filenames
* fix: refine connection setup and reasoning defaults
* fix: keep selected models visible in picker
* fix: restore OpenRouter image generation defaults
A review fix conflated native image output modalities with OpenRouter server-tool eligibility. Restore the image tool for every device-owned Chat Completions model, localize the provider label, and add a persisted Personalization override for the image model.
* fix: preserve image model during settings hydration
Wait for the pending preferences load before applying the OpenRouter image-model override so a startup write cannot be replaced by stale persisted state.
* fix: localize OpenRouter image settings
Translate the new image-model preference in every supported locale and complete the German, Korean, and Dutch OpenRouter settings strings identified during review.
* fix: correct Dutch OpenRouter description
* fix: expose image model in native Chats sheet
The setting was added to an unreachable legacy Personalization detail while the live iOS profile menu routes model defaults through Chats. Build the visibility row from one tested helper and include it in the active Chats detail.
* fix: buffer OpenRouter image tool completions
Image server-tool child jobs can succeed before the parent streaming continuation fails, and a committed SSE response cannot fail over. Buffer only image-tool requests so OpenRouter returns the complete markdown image result while all other completions remain streamed.
* fix: decode OpenRouter generated image results
The buffered image-tool fix still assumed generated images lived in message content, so successful message.images payloads were rejected and nested choice errors were masked. Normalize bounded image outputs into markdown, surface choice-level errors, and require the captured direct route to remain selected across preparation awaits.
* fix: keep OpenRouter images on continuation errors
The earlier decoder fix still prioritized choices[].error before message.images, and Gemini server tools can return both after generating successfully. Treat usable OpenRouter images as completion while preserving top-level and image-less choice failures.
* fix: retain direct route ownership through preflight
The earlier route fix covered initial preparation but the later dispatch guard still accepted any live captured binding. Require the captured model to remain selected after attachment/message preflight, with a regression that keeps both bindings live while selection changes.
* fix: restore direct answer when regeneration preflight stops
A late model switch could cancel regeneration after its empty same-id placeholder had replaced the completed answer. Restore and persist the captured previous assistant on preflight cancellation, with a regression covering the UI and durable timeline.
* feat: use OpenRouter dedicated image API
Generate and persist image assets independently from parent narration. Prompt refinement and acknowledgement are best-effort, while dedicated Image API output remains authoritative across continuation and transport failures.
* fix: preserve image and route progress
Exclude immediate image durability writes from provider stream timeouts, and retain trusted binding authority across metadata-only catalog refreshes while still revoking edited or removed profiles.
* fix: harden OpenRouter image responses
* refactor: remove legacy OpenRouter image parsing
* fix: preserve completed answer across chained regeneration
A superseding direct regeneration could capture the first run's empty same-ID preflight placeholder, so a later cancellation restored and persisted an empty answer. Normalize pristine streaming placeholders back to their last completed version before building the next placeholder, while retaining any partial or generated output. Add a deterministic two-preflight regression covering visible and durable restoration.
* fix: stabilize OpenRouter follow-ups and source favicons
* fix: preserve follow-up timeline state across remounts
Keep the assistant shell stable when a live tail enters history so generated images do not collapse and re-expand above the pinned prompt. Remember the running haptic per message so list virtualization cannot replay feedback.
* fix: apply OpenRouter review feedback
Adds sign-out retention choices, clears local preferences and Direct/Hermes connections by default, and fixes the iOS post-sign-out provider lifecycle hang.
* Optimize performance and harden lifecycle handling
* Address PR review feedback
* Clean up duplicate App Intent image retries
* Fix follow-up pin-to-top routing
* Restore no-jump pin dismissal on user scroll
A later timeline optimization kept the synthetic pin spacer active through every manual scroll, undoing the guarded dismissal from #560 and allowing iOS range correction to snap the viewport. Restore the phantom-free range guard and cover both unsafe and safe dismissal offsets so the regression cannot recur silently.
* Rebuild chat turn anchoring like T3 Code
Create the anchor from the exact optimistic user-message ID, replace the full-screen phantom range and capped physics with measured anchored end space, and use item-level layout correction until real content fills the viewport. Cancel automatic corrections on the first user gesture so streaming growth cannot reintroduce scroll jumps.
* Fix Android cookie-clear verification and allow https-upgrade capture origins
The verified cookie clear treated Android's unimplemented getAllCookies as
failure, blocking SSO sign-in on empty stores and permanently arming the
incomplete-logout fence. Exact-origin capture checks silently dropped token
capture for http-configured servers upgraded to https by their proxy; capture
now also trusts the default-port https upgrade of the configured origin.
Also stabilize the background-validation sanitization test's poll deadline.
* Restore same-origin redirect recovery, pool warmup, and native fixes
- Replay credential-safe 3xx hops (same origin or default-port https
upgrade) for idempotent methods on the shared API client; cross-origin
hops still surface to the caller.
- Warm the completion client's actual connection pool at startup again;
checkHealth's request-scoped probe no longer touches it.
- Graceful ApiService dispose so provider rebuilds cannot abort in-flight
SSE streams; cap connectivity failure backoff at the healthy interval.
- iOS: thread the trusted origin into native sheet avatar loads so auth
headers are attached again; let oversized STT tap buffers fall back to
one-off copies instead of being dropped.
* Harden PR re-application: auth, upload/share, and provider regression fixes
Auth: logout preserves connection prerequisites (custom headers, mTLS)
while still revoking session credentials (legacy apiKey, captured proxy
Cookie headers); config-header edits and legacy apiKey migration no
longer sign the user out; cold-start background validation retries for
~7s to cover slow tunnels; interactively reissued byte-identical tokens
are accepted after logout; SSO button failures surface visibly.
Uploads/share: native-share durable keys derive from payload id +
ordinal instead of mutable content checksums; Hermes/direct-model
shares route through the local composer path instead of retrying
forever; pre-connection network failures defer instead of failing
terminally; orphaned receipt-held rows are garbage collected once
native storage is confirmed drained; disposed-queue persistence reports
failure so staged files survive; legacy staging roots are reclaimable.
Providers/UI: queued-completion banner watches every ownership-fence
input so retry/cancel cannot silently no-op; drawer keeps previous rows
during pagination reloads; authenticated image cache keys derive from a
stable server+token digest so the disk cache survives restarts while
accounts stay isolated.
* Make share staging indeterminate-ownership test hermetic under concurrency
The test snapshotted the process-global staging temp root, so files staged
or cleaned by concurrently running suites broke exact set equality. Assert
only that this test's own artifact never appears.
* Stabilize streaming UI and pending share persistence
Persist Android pending-share state atomically with migration coverage. Keep prompt anchoring and streaming haptics stable across row remounts, and reduce markdown streaming churn while hardening placeholder cleanup.
* Make streaming Markdown preparation incremental
* Reuse stable Markdown render inputs
* Avoid cumulative structured stream rebuilds
* Instrument and streamline structured output
* Hide dismissed sidebar native chrome
* Reduce streaming platform view retention
Refactor chat timeline anchoring and streaming rendering, extend Hermes session and history support, and preserve stable native navigation and Liquid Glass controls.
Validated with flutter analyze and flutter test (4,012 passed; 2 skipped).
* feat: add direct provider connections
* fix: harden direct connection workflows
* fix: stabilize direct connection state
* fix: ignore failed direct image attachments
* fix: serialize direct profile reloads
* fix: recheck queued media upload routes
* fix: prune stale direct models during refresh
* feat: polish adaptive backend onboarding
* fix: restore explicit backend onboarding back paths
Hermes and Direct onboarding are entered with replacement routes, so they cannot rely on an implicit navigator pop. Give both flows explicit destinations and align their setup screens with the adaptive auth shell.
* fix: harden direct onboarding state
Re-read profiles after asynchronous confirmation, guard discovery writes after disposal, and keep disabled segments unselected. Consolidate the shared onboarding shell and header-security resets to prevent drift.
* fix: keep local backends independent after logout
Logout intentionally retains OpenWebUI server state, so routing and model selection now key off resolved backend usability, terminal auth, trusted Direct bindings, and auth-session identity across loading, error, retained-value, cold-start, and backend-switch races.
* fix: preserve chat storage boundaries on recovery
Treat OpenWebUI cache reads as best-effort only when ownership is explicit, retain ambiguity and Direct-local failures instead of crossing providers, and contain asynchronous default-model cache write errors. Regression tests cover all three paths.
* fix: retain legacy OpenWebUI chat ownership
When the merged chat list is still loading, an explicitly OpenWebUI-scoped active summary now restores ownership for legacy raw IDs without trusting Direct-local or unannotated rows. This prevents same-ID local chats from making a valid OpenWebUI conversation ambiguous.
* feat: migrate direct providers to typed SDKs
* fix: isolate direct transport and reject blank streams
* fix: hide stale direct model bindings
* fix: apply CodeRabbit auto-fixes
* feat: support Hermes attachments via Responses API
* fix: address direct and Hermes review findings
* fix: avoid OpenWebUI settings load in direct composer
* fix: preserve images during direct regeneration
* fix: preserve repeated direct images across turns
* fix: settle direct reasoning and Android chrome
* fix: harden multi-backend streaming ownership
* fix: harden multi-backend recovery lifecycles
* fix: close adversarial multi-backend edge cases
* fix: separate Responses reasoning items
* fix: preserve streamed reasoning boundaries
* fix: address final multi-backend review findings
* fix: close remaining security review findings
* fix: address PR review findings
Adds capability-aware Workspace management for Models, Knowledge, Prompts, Skills, and Tools, and unifies settings navigation across Android and iOS. Includes native-sheet routing fixes, adaptive Workspace back navigation, Hermes settings integration, localization, and regression coverage.
- Replaced the deprecated receive_sharing_intent package with flutter_sharing_intent for improved sharing capabilities.
- Updated pubspec.yaml and pubspec.lock to reflect the new dependency and removed the old package.
- Refactored iOS AppDelegate and SceneDelegate to accommodate changes in the sharing logic and method names.
- Modified share receiver service to utilize the new package for processing shared media files.
- Updated tests to ensure compatibility with the new sharing implementation and validate shared content handling.
- Introduced new methods in MainActivity and AppDelegate to manage pending share imports, including status checks and payload retrieval.
- Updated share handling logic to accommodate staged share payloads, improving the user experience for shared content.
- Enhanced the share receiver service to support new import status tracking and error handling for shared attachments.
- Implemented a skeleton UI for file attachments during import, providing visual feedback to users.
- Updated tests to validate the new share import features and ensure robust handling of shared content across platforms.
- Updated localization files to include Czech and Slovak language options.
- Modified l10n.yaml, Info.plist, and various .arb files to incorporate translations for Czech and Slovak.
- Enhanced native language handling in the app to support new languages in dropdowns and labels.
- Introduced avatarBytes property to the PlatformNativeSheetModelOption data structure in Kotlin, Swift, Dart, and other related files.
- Updated serialization and deserialization logic to handle the new avatarBytes property.
- Enhanced the NativeSheetBridge and hydration service to support avatarBytes, allowing for improved avatar handling.
- Added a new fetchImageBytes method in ApiService to retrieve image data as bytes.
- Updated tests to validate the integration of avatarBytes in various components.
- Added the receive_sharing_intent package to manage shared content from other applications.
- Updated pubspec.yaml and pubspec.lock to include the new dependency.
- Refactored MainActivity and AppDelegate to remove deprecated share handling logic and streamline intent processing.
- Introduced ShareExtension for iOS to handle shared content effectively.
- Enhanced share receiver service to utilize the new package for processing shared media files.
- Updated tests to cover new sharing functionality and ensure proper handling of shared content.
- Added support for CarPlay by implementing `ConduitCarPlayBridge` and `ConduitCarPlaySceneDelegate`.
- Enhanced `AppDelegate` to manage a shared Flutter engine and window scene for CarPlay functionality.
- Updated `Info.plist` to support multiple scenes and CarPlay configurations.
- Refactored `ConduitSceneDelegate` to handle scene lifecycle events and URL contexts for CarPlay.
- Introduced method channel for cookie management to facilitate communication between native and Flutter components.
- Changed `NativeModelTagLabel` to `NativeModelTagButton` to enhance UI consistency and interactivity.
- Updated button configuration to utilize `UIButton.Configuration` for improved styling and accessibility.
- Adjusted tag handling in `NativeModelSelectorTableViewCell` to incorporate the new button implementation, ensuring proper layout and display of tags.
- Updated the `PlatformNativeSheetModelOption` to include a `tags` field, allowing for better categorization and filtering of models.
- Enhanced serialization and deserialization logic to handle tags in both Dart and Swift implementations.
- Modified UI components to display tags, improving user experience by providing additional context for each model.
- Updated search functionality to include tags, enabling users to find models more efficiently based on associated tags.
- Added tests to ensure correct extraction and handling of tags from model data.
- Refactored the logic for determining whether to keep the conversation anchored to the bottom based on inset changes, enhancing accuracy in user interactions.
- Added new tests to verify the behavior of bottom anchoring during keyboard inset changes, ensuring correct functionality for various scenarios.
- Added an exception for `conduit_platform_apis.g.dart` in .gitignore to ensure it is tracked.
- Updated analysis options to exclude `pigeons/**` and added `riverpod_lint` plugin.
- Bumped versions of several dependencies in pubspec.lock, including `analyzer`, `flutter_riverpod`, and `json_serializable`, while removing outdated dependencies like `custom_lint`.
- Introduced methods for persisting and restoring pending share payloads in MainActivity, improving share functionality.
- Implemented intent sanitization for home widget launches to prevent unintended behavior when re-launching from history.
- Updated share handling logic to ensure accurate delivery and cleanup of share payloads across the application.
- Removed the deprecated HomeWidgetPlugin, streamlining the widget integration process.
- Refactored related services to support new share staging cleanup processes, enhancing file management during share operations.
- Bumped version of home_widget to 0.9.2 in pubspec files.
- Removed share_handler dependency from pubspec.yaml and related references.
- Refactored ConduitWidgetProvider and MainActivity to utilize new share handling logic.
- Implemented a new share receiver service to manage shared content more effectively.
- Updated iOS ShareExtension to handle shared files and text with improved constraints.
- Enhanced the NativeModelSelectorConfiguration to support pinned models, allowing users to pin and unpin models within the selection interface.
- Updated the NativeSheetBridge to handle pin toggle actions and communicate changes to the UI.
- Introduced methods for managing pinned models in the ServerUserSettings and SettingsService, ensuring persistence across sessions.
- Modified the chat and folder pages to utilize the new pinning features, including context menus for toggling pin states.
- Added tests to validate the behavior of pinned models, ensuring correct functionality and state management.
- Replaced instances of `webview_flutter_plus` with `flutter_inappwebview` across the codebase for enhanced web view capabilities.
- Updated related methods and classes to accommodate the new web view implementation, including cookie management and navigation handling.
- Ensured compatibility with existing features while improving performance and functionality of web content rendering.
- Updated Podfile.lock to reflect changes in the Podfile checksum.
- Corrected the formatting of the CADisableMinimumFrameDurationOnPhone key in Info.plist for proper XML structure.
- Added geolocation dependencies in `pubspec.lock` and updated `pubspec.yaml` to include `geolocator`.
- Updated AndroidManifest.xml to request location permissions.
- Enhanced iOS Podfile to bypass location permission prompts for `geolocator_apple`.
- Modified Info.plist to clarify location usage description.
- Implemented `updateUserInfo` method in `ApiService` to handle user location updates.
- Refactored chat providers to resolve user location when needed and updated tests to validate new functionality.
- Introduced new properties in `NativeSheetItemConfig` and `NativeSheetLinkConfig` to support additional metadata such as source information, snippets, and favicon URLs.
- Refactored the `StreamingStatusWidget` and `OpenWebUISourcesWidget` to utilize the new configurations, improving the structure and clarity of source and status updates.
- Updated the iOS deployment target in the project settings for compatibility.
- Added utility functions for favicon URL generation based on source domains, enhancing visual representation in the UI.
- Improved the handling of markdown rendering in the `BlockRenderer` for better image handling.
- Updated versions of several packages in pubspec.lock, including meta (1.18.0), test (1.31.0), test_api (0.7.11), and test_core (0.6.17).
- Cleaned up Podfile.lock by removing unused dependencies to streamline the project.
- Added FlutterGeneratedPluginSwiftPackage to the Xcode project for better integration with Flutter plugins.
- Introduced a pre-action script in the Xcode scheme to prepare the Flutter framework during build.
- Introduced new configurations for iOS audio session management to improve microphone capture during server-side recording.
- Updated `VoiceInputService` to support external management of the audio session, allowing for better handling of duplex audio routes.
- Refactored `beginListening` and `_startListeningInternal` methods to accept a parameter for managing the audio session externally.
- Adjusted `VoiceInputEngineSpeech` to utilize the new audio session management feature.
- Changed the APP_GROUP_ID from 'group.app.cogwheel.conduit.debug' to 'group.app.cogwheel.conduit.x2662v5dt2.debug' in multiple build configurations to ensure consistency across the project.
- Updated the corresponding constant in home_widget_service.dart to reflect the new debug app group identifier.