Miraculum1729/OpenVibe

The open source typeless tool for free.

0

stars

2

commits

Swift

primary language

Jul 24, 2026

updated

README

OpenVibe

OpenVibe is an open-source, local-first macOS voice input app inspired by Typeless. It lives in the menu bar, records speech, sends audio to a local dictation service, and inserts polished text into the active app.

OpenVibe currently uses a hybrid pipeline:

microphone audio
  -> Qwen3-ASR-0.6B raw transcript
  -> optional Gemma 4 E2B audio verification
  -> Gemma 4 E2B cleanup, formatting, dictionary and style control
  -> auto-insert into the active macOS text field

Features

  • Menu bar macOS app built with Swift/AppKit.
  • Global voice hotkey, default Option + Space.
  • Local FastAPI server at http://127.0.0.1:8765.
  • Qwen3-ASR + Gemma 4 E2B hybrid dictation.
  • Three model modes: fast, accurate, and auto.
  • Optional live draft typing while recording.
  • Final cleanup for filler words, repetitions, self-corrections, lists, and app-aware tone.
  • Chinese output preference: Simplified, Traditional Taiwan, or Traditional Hong Kong.
  • Local recent history with text, audio playback, search, and configurable limit.
  • Manual and automatic personal dictionary.
  • Local-first design. Audio, history, and dictionary data stay on your Mac.

Requirements

  • macOS 14 or later.
  • Full Xcode installed at /Applications/Xcode.app.
  • Python 3.11 or 3.12.
  • uv.
  • Hugging Face access for the model repositories you use.
  • Apple Silicon is strongly recommended.

Install command line prerequisites:

xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license accept
sudo xcodebuild -runFirstLaunch

brew install uv python@3.11

If model downloads need a proxy:

export HTTPS_PROXY=http://127.0.0.1:7897
export HTTP_PROXY=http://127.0.0.1:7897

Model Setup

OpenVibe uses LiteRT-LM for Gemma 4 E2B by default. Import the LiteRT model once:

uv tool install litert-lm

litert-lm import \
  --from-huggingface-repo litert-community/gemma-4-E2B-it-litert-lm \
  gemma-4-E2B-it.litertlm \
  gemma-4-e2b-it

The expected Gemma model path after import is:

~/.litert-lm/models/gemma-4-e2b-it/model.litertlm

Qwen3-ASR is installed by the server extras on first run:

Qwen/Qwen3-ASR-0.6B

If Hugging Face asks for authentication:

huggingface-cli login

Do not commit Hugging Face tokens or .env files to the repository.

Run From Source

Clone and enter the repo:

git clone https://github.com/Miraculum1729/OpenVibe.git
cd OpenVibe

Start the local server:

./scripts/run-server

The first run creates .venv and installs:

services/gemma-server[hybrid]

In another terminal, start the macOS app:

./scripts/run-mac

For UI testing without loading Qwen/Gemma:

./scripts/run-mock-server
./scripts/run-mac

Package The macOS App

Recommended:

./scripts/package-mac
open dist/OpenVibe.app

If SwiftPM or xcrun is confused by SDK/compiler state, use the direct Xcode compiler fallback:

./scripts/package-mac-direct
open dist/OpenVibe.app

The app automatically starts the local server on launch and listens on the configured port, default 127.0.0.1:8765.

macOS Permissions

OpenVibe needs:

  • Microphone: record speech.
  • Accessibility: auto-insert text into other apps.

Enable them in:

System Settings -> Privacy & Security -> Microphone
System Settings -> Privacy & Security -> Accessibility

If auto-insert fails after rebuilding the app:

  1. Open System Settings -> Privacy & Security -> Accessibility.
  2. Remove old OpenVibe entries.
  3. Add the current dist/OpenVibe.app.
  4. Enable it.
  5. Quit and reopen OpenVibe.

Without Accessibility permission, OpenVibe still copies the result to the clipboard, but macOS may block automatic insertion.

Usage

  1. Open OpenVibe.app.
  2. Click the menu bar icon and open 设置.
  3. Check that local service is running.
  4. Put your cursor in any text field.
  5. Press Option + Space to start recording.
  6. Speak naturally.
  7. Press Option + Space again to stop.
  8. OpenVibe transcribes, polishes, copies, and auto-inserts the final text.

The menu bar only contains:

  • 设置
  • 退出 OpenVibe

Settings

通用

  • Local service status.
  • Server address and port.
  • Dictation hotkey.
  • Temporary audio directory.
  • Model mode.
  • Chinese output variant.
  • Live draft typing toggle.

最近

  • Recent dictation history.
  • Audio duration.
  • Active app name.
  • Play or delete recordings.
  • Search history.
  • Configure history limit, default 50.

词典

  • Manual dictionary: terms you explicitly add.
  • Automatic dictionary: high-value personal terms learned from your corrections.
  • Terms are displayed as colored #term chips.
  • Manual and automatic terms can be edited or deleted.

The automatic dictionary is correction-based, not frequency-based. After OpenVibe inserts text, it observes short-term edits in the target text field and extracts useful corrected terms such as product names, acronyms, mixed Chinese/English names, and domain-specific terms. It avoids adding ordinary filler words and simple numeric formatting changes.

Model Modes

  • Fast: Qwen3-ASR produces raw text, then Gemma cleans and formats it.
  • Accurate: adds Gemma audio+ASR verification in roughly 20 second chunks.
  • Auto: uses the fast path for short/simple clips and verification for longer clips.

Gemma verification uses roughly 20 second audio chunks to stay within Gemma 4 E2B's audio limits and keep latency manageable.

Server Configuration

The server reads OPENVIBE_ environment variables:

OPENVIBE_HOST=127.0.0.1
OPENVIBE_PORT=8765
OPENVIBE_BACKEND=litert
OPENVIBE_ASR_BACKEND=qwen3
OPENVIBE_ASR_MODEL_ID=Qwen/Qwen3-ASR-0.6B
OPENVIBE_ASR_LANGUAGE=
OPENVIBE_GEMMA_VERIFICATION_CHUNK_SECONDS=20
OPENVIBE_LITERT_MODEL_PATH=~/.litert-lm/models/gemma-4-e2b-it/model.litertlm
OPENVIBE_MODEL_ID=google/gemma-4-E2B-it
OPENVIBE_MAX_NEW_TOKENS=512
OPENVIBE_ENABLE_MOCK=false

Run with a different server setting:

OPENVIBE_PORT=8766 ./scripts/run-server

Use the Transformers backend instead of LiteRT-LM:

OPENVIBE_BACKEND=transformers ./scripts/run-server

Check server health:

curl http://127.0.0.1:8765/health

Expected real-model health response includes:

{
  "ok": true,
  "pipeline": "hybrid",
  "backend": "litert",
  "asr": "Qwen/Qwen3-ASR-0.6B",
  "mock": false
}

Local Data

Default local data locations:

~/Library/Application Support/OpenVibe/Recordings

Ignored development artifacts:

.venv/
.build/
dist/
*.wav
*.log
hf_cache/

Model files are expected outside the repo, for example:

~/.litert-lm/models/

Troubleshooting

Server stays "starting"

Check whether something is listening on the port:

lsof -nP -iTCP:8765 -sTCP:LISTEN
curl http://127.0.0.1:8765/health

Quit OpenVibe and reopen it. On launch, OpenVibe tries to free the configured port before starting its managed server.

Could not auto-insert text

This means the text was copied to the clipboard, but macOS blocked automatic insertion. Re-add the current OpenVibe.app under Accessibility permissions.

Microphone permission is requested again

This usually means macOS sees a rebuilt app bundle as a new app identity. Re-add the latest dist/OpenVibe.app in Privacy & Security.

Model download is slow

Use a proxy if needed:

export HTTPS_PROXY=http://127.0.0.1:7897
export HTTP_PROXY=http://127.0.0.1:7897

Use mock mode first

If you only want to test the menu bar app, settings UI, permissions, and insertion flow:

./scripts/run-mock-server
./scripts/run-mac

Development

Build:

swift build

Run the app:

./scripts/run-mac

Run the server:

./scripts/run-server

Package:

./scripts/package-mac-direct

Git identity used during local development:

git config user.email "pfp23@mails.tsinghua.edu.cn"

License

See LICENSE.

Contributors

Miraculum1729

2 commits

Miraculum1729/OpenVibe

The open source typeless tool for free.

0

stars

2

commits

Swift

primary language

Jul 24, 2026

updated

README

OpenVibe

OpenVibe is an open-source, local-first macOS voice input app inspired by Typeless. It lives in the menu bar, records speech, sends audio to a local dictation service, and inserts polished text into the active app.

OpenVibe currently uses a hybrid pipeline:

microphone audio
  -> Qwen3-ASR-0.6B raw transcript
  -> optional Gemma 4 E2B audio verification
  -> Gemma 4 E2B cleanup, formatting, dictionary and style control
  -> auto-insert into the active macOS text field

Features

  • Menu bar macOS app built with Swift/AppKit.
  • Global voice hotkey, default Option + Space.
  • Local FastAPI server at http://127.0.0.1:8765.
  • Qwen3-ASR + Gemma 4 E2B hybrid dictation.
  • Three model modes: fast, accurate, and auto.
  • Optional live draft typing while recording.
  • Final cleanup for filler words, repetitions, self-corrections, lists, and app-aware tone.
  • Chinese output preference: Simplified, Traditional Taiwan, or Traditional Hong Kong.
  • Local recent history with text, audio playback, search, and configurable limit.
  • Manual and automatic personal dictionary.
  • Local-first design. Audio, history, and dictionary data stay on your Mac.

Requirements

  • macOS 14 or later.
  • Full Xcode installed at /Applications/Xcode.app.
  • Python 3.11 or 3.12.
  • uv.
  • Hugging Face access for the model repositories you use.
  • Apple Silicon is strongly recommended.

Install command line prerequisites:

xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license accept
sudo xcodebuild -runFirstLaunch

brew install uv python@3.11

If model downloads need a proxy:

export HTTPS_PROXY=http://127.0.0.1:7897
export HTTP_PROXY=http://127.0.0.1:7897

Model Setup

OpenVibe uses LiteRT-LM for Gemma 4 E2B by default. Import the LiteRT model once:

uv tool install litert-lm

litert-lm import \
  --from-huggingface-repo litert-community/gemma-4-E2B-it-litert-lm \
  gemma-4-E2B-it.litertlm \
  gemma-4-e2b-it

The expected Gemma model path after import is:

~/.litert-lm/models/gemma-4-e2b-it/model.litertlm

Qwen3-ASR is installed by the server extras on first run:

Qwen/Qwen3-ASR-0.6B

If Hugging Face asks for authentication:

huggingface-cli login

Do not commit Hugging Face tokens or .env files to the repository.

Run From Source

Clone and enter the repo:

git clone https://github.com/Miraculum1729/OpenVibe.git
cd OpenVibe

Start the local server:

./scripts/run-server

The first run creates .venv and installs:

services/gemma-server[hybrid]

In another terminal, start the macOS app:

./scripts/run-mac

For UI testing without loading Qwen/Gemma:

./scripts/run-mock-server
./scripts/run-mac

Package The macOS App

Recommended:

./scripts/package-mac
open dist/OpenVibe.app

If SwiftPM or xcrun is confused by SDK/compiler state, use the direct Xcode compiler fallback:

./scripts/package-mac-direct
open dist/OpenVibe.app

The app automatically starts the local server on launch and listens on the configured port, default 127.0.0.1:8765.

macOS Permissions

OpenVibe needs:

  • Microphone: record speech.
  • Accessibility: auto-insert text into other apps.

Enable them in:

System Settings -> Privacy & Security -> Microphone
System Settings -> Privacy & Security -> Accessibility

If auto-insert fails after rebuilding the app:

  1. Open System Settings -> Privacy & Security -> Accessibility.
  2. Remove old OpenVibe entries.
  3. Add the current dist/OpenVibe.app.
  4. Enable it.
  5. Quit and reopen OpenVibe.

Without Accessibility permission, OpenVibe still copies the result to the clipboard, but macOS may block automatic insertion.

Usage

  1. Open OpenVibe.app.
  2. Click the menu bar icon and open 设置.
  3. Check that local service is running.
  4. Put your cursor in any text field.
  5. Press Option + Space to start recording.
  6. Speak naturally.
  7. Press Option + Space again to stop.
  8. OpenVibe transcribes, polishes, copies, and auto-inserts the final text.

The menu bar only contains:

  • 设置
  • 退出 OpenVibe

Settings

通用

  • Local service status.
  • Server address and port.
  • Dictation hotkey.
  • Temporary audio directory.
  • Model mode.
  • Chinese output variant.
  • Live draft typing toggle.

最近

  • Recent dictation history.
  • Audio duration.
  • Active app name.
  • Play or delete recordings.
  • Search history.
  • Configure history limit, default 50.

词典

  • Manual dictionary: terms you explicitly add.
  • Automatic dictionary: high-value personal terms learned from your corrections.
  • Terms are displayed as colored #term chips.
  • Manual and automatic terms can be edited or deleted.

The automatic dictionary is correction-based, not frequency-based. After OpenVibe inserts text, it observes short-term edits in the target text field and extracts useful corrected terms such as product names, acronyms, mixed Chinese/English names, and domain-specific terms. It avoids adding ordinary filler words and simple numeric formatting changes.

Model Modes

  • Fast: Qwen3-ASR produces raw text, then Gemma cleans and formats it.
  • Accurate: adds Gemma audio+ASR verification in roughly 20 second chunks.
  • Auto: uses the fast path for short/simple clips and verification for longer clips.

Gemma verification uses roughly 20 second audio chunks to stay within Gemma 4 E2B's audio limits and keep latency manageable.

Server Configuration

The server reads OPENVIBE_ environment variables:

OPENVIBE_HOST=127.0.0.1
OPENVIBE_PORT=8765
OPENVIBE_BACKEND=litert
OPENVIBE_ASR_BACKEND=qwen3
OPENVIBE_ASR_MODEL_ID=Qwen/Qwen3-ASR-0.6B
OPENVIBE_ASR_LANGUAGE=
OPENVIBE_GEMMA_VERIFICATION_CHUNK_SECONDS=20
OPENVIBE_LITERT_MODEL_PATH=~/.litert-lm/models/gemma-4-e2b-it/model.litertlm
OPENVIBE_MODEL_ID=google/gemma-4-E2B-it
OPENVIBE_MAX_NEW_TOKENS=512
OPENVIBE_ENABLE_MOCK=false

Run with a different server setting:

OPENVIBE_PORT=8766 ./scripts/run-server

Use the Transformers backend instead of LiteRT-LM:

OPENVIBE_BACKEND=transformers ./scripts/run-server

Check server health:

curl http://127.0.0.1:8765/health

Expected real-model health response includes:

{
  "ok": true,
  "pipeline": "hybrid",
  "backend": "litert",
  "asr": "Qwen/Qwen3-ASR-0.6B",
  "mock": false
}

Local Data

Default local data locations:

~/Library/Application Support/OpenVibe/Recordings

Ignored development artifacts:

.venv/
.build/
dist/
*.wav
*.log
hf_cache/

Model files are expected outside the repo, for example:

~/.litert-lm/models/

Troubleshooting

Server stays "starting"

Check whether something is listening on the port:

lsof -nP -iTCP:8765 -sTCP:LISTEN
curl http://127.0.0.1:8765/health

Quit OpenVibe and reopen it. On launch, OpenVibe tries to free the configured port before starting its managed server.

Could not auto-insert text

This means the text was copied to the clipboard, but macOS blocked automatic insertion. Re-add the current OpenVibe.app under Accessibility permissions.

Microphone permission is requested again

This usually means macOS sees a rebuilt app bundle as a new app identity. Re-add the latest dist/OpenVibe.app in Privacy & Security.

Model download is slow

Use a proxy if needed:

export HTTPS_PROXY=http://127.0.0.1:7897
export HTTP_PROXY=http://127.0.0.1:7897

Use mock mode first

If you only want to test the menu bar app, settings UI, permissions, and insertion flow:

./scripts/run-mock-server
./scripts/run-mac

Development

Build:

swift build

Run the app:

./scripts/run-mac

Run the server:

./scripts/run-server

Package:

./scripts/package-mac-direct

Git identity used during local development:

git config user.email "pfp23@mails.tsinghua.edu.cn"

License

See LICENSE.

Contributors

Miraculum1729

2 commits

Languages

Swift

82.7%

Python

16.0%

Shell

1.3%