* Support Open WebUI 0.12.2 servers without the version warning
The vendored Open WebUI source now points at the v0.12.2 release, and the
newest server version Conduit accepts without a compatibility warning rises
from 0.12.0 to 0.12.2. Servers newer than 0.12.2 still see the warning, and
0.11 and 0.12.0 servers stay supported.
* Stop voice calls from pausing on each avatar gesture
Since Open WebUI 0.12.1, a model with voice avatar gestures and native
function calling can play a gesture in a Standard voice call. The server
then asks the client to play it and waits up to three seconds for an
answer. Conduit never answered, so every gesture held up the spoken reply
for those three seconds.
Conduit shows no voice avatar, so it now answers at once that the gesture
is unavailable, as Open WebUI's web client does when it has no avatar on
screen, and the reply goes on.
* Keep the voice talking through background noise in realtime calls
The voice of a realtime call stopped as soon as voice detection heard
anything, so wind or background noise cut it off mid-sentence. Open WebUI
0.12.1 no longer has the voice stop itself when speech starts, and its web
client holds the voice until the words are transcribed instead.
Conduit now does the same. When speech is heard, the voice pauses with what
it had left to say kept; once real words are transcribed it stops where the
user cut in, and when nothing intelligible was said it carries on from
where it paused. The iOS and Android audio engines gained a pause that
keeps the queued speech. On Open WebUI 0.12.0, whose voice still cancels
its own reply when speech starts, the held rest of the reply is dropped as
before.
Direct calls run the same bridge on the device, so they now leave the voice
running when speech starts, and take noise that was not understood out of
the voice's history, as the Open WebUI 0.12.2 server does, so it no longer
confuses later answers. Gestures are no longer reported as cancelled just
because the user started speaking.
* Title and tag the chats that realtime voice calls start
A chat a realtime call started kept a title cut from the user's first words
and got no tags. The voice answered that first exchange itself, so no chat
completion ran to generate them. Open WebUI 0.12.1's web client generates
them when such a chat is created.
Conduit now does the same. Once the chat the call created has reached the
server, Conduit asks the server for a title and tags based on the user's
first words, with the chat's model. The title replaces the one cut from the
words unless the chat was renamed meanwhile, and the tags are added to the
chat. Each follows the user's automatic title and tag settings, as titles
for typed chats do.
* Show channel apps' cards, buttons and private replies, and follow mute
Open WebUI 0.12.1 lets administrators connect external apps that answer in
channels, and lets each person set a channel or direct message to notify
for mentions only. Conduit showed neither.
Apps
- A message an app posts now shows the app's name, picture and an App
label, with its cards (author, linked title, description, thumbnail,
fields and footer) and its buttons and links. A message that was only a
card used to show as an empty bubble, and replies to it quoted nothing;
replies now quote the card's text.
- Pressing a button sends it to the app as Open WebUI's web client does,
and shows what the app answers. A Markdown file an app offers can be
saved through the share sheet.
- Replies an app shows only to the person who asked, from a button or a
failed mention, appear under the message they answer, marked as visible
only to you, until dismissed. They are not saved, as on the web.
- Back-to-back messages from two different apps were grouped under the
first app's name, since app messages have no user id. Each app's message
now shows its own name.
- Edit was briefly offered on app messages while the account was still
loading. It is now offered only on your own messages.
Mute
- The channel and direct message menus have All messages and Mentions only.
- A channel set to Mentions only shows no unread badge in the list and
sends no banner, sound or system notification, unless the message
mentions you. Its messages still count as unread.
- A change made in another session or on the web reaches Conduit at once.
App content is untrusted: card text goes through the same Markdown
rendering as channel messages, links through the external link checks, and
images carry the server's credentials only when they come from the server
itself.
* Keep apostrophes in generated voice-chat titles and tags
The title and tag answers were read the way Open WebUI's web client reads
them, which first turns every single or curly quote into a double quote.
That broke valid answers holding an apostrophe, so a title like "What's
next?" was lost and such tags were dropped. Answers are now read as
written first, and with their quotes made double only when that fails.
* Let a held voice go on when the user's words are never transcribed
The voice of a realtime call is now held from the moment speech is heard
until the words are transcribed. If no transcript arrived, the voice
stayed silent and nothing more could be asked of it until the user spoke
again. Ten seconds after the user stops speaking without a transcript,
the voice now carries on from where it paused.
* Draw the accent of colored channel app cards without a paint error
An app card with an accent color painted a rounded border with a colored
left side, which Flutter refuses ("A borderRadius can only be given on
borders with uniform colors"), so every colored card failed to paint. The
card now has a uniform rounded border, and the accent is a bar laid over
its left edge.
* Keep a channel app button's state with its message
The channel and thread lists reuse their rows by position. When a new
message arrived, the row of a message whose button was still working, or
had failed, was given to the new message, which then showed that state.
Rows are now keyed by message, so their state moves with it, and app cards
are keyed by message as well.
* Show a mute change on an open channel that is not in the list yet
A mute change from another session updated only the channel list. A
channel opened before the list held it, such as from a notification, kept
showing the old setting, and choosing that setting again sent nothing. The
open channel now takes the change too.
* Keep a rename made while a voice chat's title is being generated
A title generated for a chat a realtime call started replaced the one from
the first words only when the stored title had not changed. A rename still
on its way to the server, or made on the web, did not show there yet, so
the generated title could overwrite it.
The generated title is now checked against the title the server holds,
as Open WebUI's web client does, and renames and generated titles for one
chat take turns: one started first finishes before the other looks.
* Send a voice chat's title requests only as the account that made it
Titling and tagging a chat a realtime call started waits for the chat to
reach the server, then asks for a title and tags from the user's first
words. Those requests used whichever session was signed in when they went
out, so after an account switch on the same server they could send one
account's words, and write the chat, with another account's credentials.
Each request now carries the session that sent the words, so a sign-in
change on the way cancels the rest instead.
* Keep a mute change on an open channel the list is still loading
A mute change for an open channel the list did not hold yet was applied to
that channel only. A channel list still loading could then bring the
channel back with its old setting, which the page and notifications read
first. Such a change now drops that load's answer and loads the list again.
* Keep one title lock across database changes
The lock that orders renames and generated titles was made anew whenever
the database changed. A title generated after a long wait held the old
lock, while a rename made after the change took the new one, so the two
could overlap again. Title locks are keyed by server chat ids, so one
instance now serves the whole app.
* Keep a mute change on any channel the list is still loading
A list load still in flight could bring back a channel's old setting after
a mute change for it, unless the channel was the open one. Any mute change
for a channel the list does not hold now drops that load's answer and loads
the list again.
|
||
|---|---|---|
| .github | ||
| android | ||
| assets | ||
| docs | ||
| hermes-src@939e45c91d | ||
| ios | ||
| lib | ||
| openwebui-src@6a18585ff4 | ||
| packages | ||
| pigeons | ||
| scripts | ||
| test | ||
| third_party | ||
| tool | ||
| .gitignore | ||
| .gitmodules | ||
| .metadata | ||
| analysis_options.yaml | ||
| cargokit_options.yaml | ||
| devtools_options.yaml | ||
| l10n.yaml | ||
| LICENSE | ||
| paseo.json | ||
| PRIVACY_POLICY.md | ||
| pubspec.lock | ||
| pubspec.yaml | ||
| README.md | ||
| THIRD_PARTY_NOTICES.md | ||
Conduit
A native mobile client for Open WebUI, your own model endpoints, and self-hosted agents.
Connect · Screenshots · Features · Getting Started · Privacy · Build from Source
Open WebUI is excellent on the desktop. On mobile it breaks down at the edges: authentication behind a reverse proxy, streaming that drops when the app backgrounds, getting a screenshot into a prompt, starting a chat from the home screen. Conduit is a real Flutter app built to close that gap, and as of 4.0 it works with or without an Open WebUI server at all.
Your chats live on your device first. Nothing routes through a backend the maintainer operates.
Ways to connect
On first launch Conduit asks how you want to connect. Pick one, add the others later, and skip any sign-in you don't need.
| Open WebUI | Your self-hosted server | Full feature set: chats, folders, notes, channels, workspace, tools, web search, image generation |
| Direct | OpenAI-compatible, Ollama, OpenRouter | Talk straight to a provider or a model on your own machine. No Open WebUI account required |
| Apple On-Device | Apple Intelligence | Run Apple's local model offline on eligible iOS 26 devices without an API key |
| Apple PCC | Apple Private Cloud Compute | Use Apple's private cloud model on eligible iOS 27 devices without an API key |
| Hermes | Your self-hosted agent | An agent that runs tools, asks before sensitive steps, and works on a schedule |
Direct connections cover OpenAI-compatible endpoints (Chat Completions or Responses), LM Studio, Azure-style API versions, native Ollama, and first-party OpenRouter. Bring an API key, or skip it for a local endpoint that doesn't want one. Direct connections you already configured in Open WebUI come along automatically. Keys and custom headers stay in platform secure storage.
Apple On-Device is an iOS-only Direct provider backed by Apple's local SystemLanguageModel. It requires iOS 26 and Apple Intelligence, works offline, and supports streaming, sampling controls, and JSON-schema responses with a 4K context window. Image input, reasoning controls, and tool calling are not available.
Apple Private Cloud Compute is an iOS-only Direct provider. It uses Apple's Foundation Models framework, streams responses through the same chat path as other Direct models, and requires iOS 27, Apple Intelligence availability, and Apple's managed PCC entitlement. It supports image input, reasoning levels, sampling and output limits, JSON-schema responses, live quota/context status, and an optional on-device fallback for PCC network failures. Tool calling is not enabled.
Hermes Agent connects to your own Hermes server. You watch its tools work live, approve sensitive steps before they run, and let scheduled agents run while you sleep. Conversations and schedules get their own tab, and Conduit only exposes the capabilities your server actually reports.
Screenshots
| Chat | Connect | Chats | Voice |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
What you get
Chat that survives mobile
Token-by-token streaming over WebSocket. The transcript holds its place while a response grows, pinned prompts stay put, and long conversations load without stalling the UI. Search across conversations, organize with folders, pin what matters, or start a temporary chat that leaves nothing behind.
Rendering that holds up on a phone
Native Flutter surfaces, not a web view wrapped in a shell:
- syntax-highlighted code blocks with copy and preview
- Mermaid diagrams rendered natively
- LaTeX and math
- expandable reasoning, tool-call, and code-execution sections
- inline citations, source cards, and follow-up suggestions
- Chart.js embeds
A real Workspace
Models, knowledge, prompts, tools, and skills as native screens with unified settings navigation. Sections you don't have permission for simply don't appear.
Everything else
| Area | What's included |
|---|---|
| Files and media | Uploads, re-attaching previously uploaded server files, multimodal prompts, clipboard image paste, audio attachments |
| Notes | Autosave, pinning, AI-generated titles, AI enhancement, audio recording, all available offline |
| Channels | Threads and reactions, when your server enables them |
| Voice | Voice input with on-device or server speech recognition, plus a full voice-call mode |
| Home screen | Widgets on iOS and Android for new chat, mic, camera, photos, and clipboard; app quick actions; iOS App Intents and Shortcuts |
| Sharing | Share-sheet ingestion from other apps straight into a prompt |
| Terminal | Interactive sessions over WebSocket with a file browser, shown only when your server exposes it |
| Personalization | Light, dark, and system themes; five accent palettes; adaptive Material and Cupertino UI; haptics |
| Languages | 14 locales: English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Russian, Simplified and Traditional Chinese, Czech, Slovak, Polish |
Server-dependent features (channels, notes, web search, image generation, toggle filters, terminal) appear only when your deployment exposes them.
Built for self-hosted reality
Most mobile clients assume a plain login form. Real deployments rarely look like that.
- Every auth path Open WebUI offers: username and password, LDAP, manual JWT entry, SSO and OAuth providers.
- Reverse proxies actually work:
oauth2-proxy, Authelia, Authentik, Pangolin, and Cloudflare Tunnel, by capturing the right cookies and session state on-device. - Custom headers during setup for environments that require
X-API-Key,Authorization, or organization routing headers. - Credentials in Keychain or Keystore, never plain-text local storage.
- Tracks upstream: Conduit supports Open WebUI 0.11.
Getting started
Install from the App Store or Google Play, then pick how you want to connect.
Open WebUI
- Launch Conduit and choose Open WebUI.
- Enter your instance's base URL.
- Add any required custom headers.
- Sign in with username and password, LDAP, JWT, SSO, or proxy auth.
- Pick a model and start chatting.
Direct connection
- Launch Conduit and choose Direct connection.
- Add an OpenAI-compatible or Ollama profile with its base URL and any API key or custom headers.
- Test the connection, enable it, and select a discovered or manually entered model.
- Choose whether new direct chats use Open WebUI history when one is signed in, or stay only on this device. Existing chats keep their current location.
- Start chatting. No Open WebUI account required.
Apple On-Device
- On an eligible iOS 26 device, launch Conduit and choose Apple On-Device.
- Conduit checks Apple Intelligence and local-model availability. No API key or network connection is required.
- Start chatting. New Apple-only installations keep Direct history on the device unless you later enable Open WebUI history.
Apple Private Cloud Compute
- On an eligible iOS 27 device, launch Conduit and choose Apple Private Cloud Compute.
- Conduit checks Apple Intelligence and PCC availability. No API key is required.
- Start chatting. New PCC-only installations keep Direct history on the device unless you later enable Open WebUI history.
Hermes Agent
- Launch Conduit and choose Hermes Agent.
- Enter your Hermes server URL and
API_SERVER_KEY. - Optionally set a memory key to scope the agent's long-term memory to you. One is generated automatically on first chat if you leave it blank.
- Open the Hermes tab for conversations and scheduled agents.
Privacy
- Chats, notes, and drafts are stored on your device. Notes and drafts stay available without a connection.
- Credentials use platform secure storage: Keychain on iOS, Keystore on Android.
- No third-party analytics or advertising SDKs.
- Diagnostic logging is local and transient.
- No developer-operated backend relays your data. Traffic goes from your device to the server or provider you configured, and nowhere else.
- Signing out lets you choose what stays behind. Clearing everything clears on-device chats too, and fails safely rather than half-deleting.
Full details in PRIVACY_POLICY.md.
Build from source
See docs/BUILDING.md for requirements, submodules, codegen, verification, project layout, and troubleshooting.
git clone --recursive https://github.com/cogwheel0/conduit.git
cd conduit
flutter pub get
dart run build_runner build
flutter run -d ios # or: flutter run -d android
Clone recursively and run build_runner. The Mermaid renderer is a submodule,
and generated Dart files are git-ignored.
Contributing
Conduit is actively developed and feedback is welcome.
- Bugs → GitHub Issues
- Features, deployment notes, questions → GitHub Discussions
Unsolicited pull requests are not the primary contribution path right now. Open an issue or discussion first so changes line up with the roadmap.
Enterprise and white-label
For private distribution, internal deployment support, or a custom enterprise/white-label build, open a discussion or reach the maintainer at cogwheel@cogwheel.app.
Support
If Conduit is useful to you, you can support development through GitHub Sponsors or Buy Me a Coffee.
Acknowledgements
- Supported by the Vercel OSS Program.
- Tested with BrowserStack.
- Code review provided by
.
License
Released under the GPL-3.0 License.
Conduit is an independent client and is not affiliated with Open WebUI.



