PyJippety is a desktop voice assistant for Python.
It listens for a local wake word with Porcupine, records a follow-up prompt, sends that prompt to OpenAI for transcription and response generation, and can speak the answer back through OpenAI speech.
The project is built to work in two modes:
- normal desktop use through a small GUI
- developer use through a simple Python package and CLI
- local wake-word detection with Porcupine
- microphone capture for the spoken prompt
- OpenAI transcription with fallback model support
- OpenAI chat responses
- OpenAI speech output with fallback model support
- a local wake chime when the wake word is detected
- lightweight local memory for saved notes and recent exchanges
- local action plugins for simple desktop tasks
- desktop control panel for settings, profiles, logs, transcripts, typed testing, memory review, and history
- optional tray/menu bar indicator for background operation
PyJippety now ships with a cross-platform Python installer.
Linux or macOS:
python3 install-pyjippety.pyWindows:
py install-pyjippety.pyThe installer will:
- create an isolated app environment in your user data directory
- create a persistent config file in your user config directory
- install a launcher script for your platform
- copy the app logo into the installed app directory
- add a Linux desktop entry when running on Linux
Typical install locations:
- Linux app data:
~/.local/share/pyjippety - Linux config:
~/.config/pyjippety/.env - macOS app data/config:
~/Library/Application Support/PyJippety - Windows app data:
%LOCALAPPDATA%\PyJippety - Windows config:
%APPDATA%\PyJippety\.env
System requirements by platform:
- Linux:
python3-tk, PortAudio development/runtime packages, and a supported tray backend are commonly required - macOS: use a Python build with Tk included; Homebrew PortAudio is commonly needed for PyAudio
- Windows: use a standard Python.org install with Tk included; a working build of PyAudio is still required
Linux example:
sudo apt update
sudo apt install portaudio19-dev python3-tk
python3 install-pyjippety.pyOpen the app, go to the Setup tab, and fill in:
OpenAI API keyPicovoice access key
Then:
- Save settings.
- Start voice mode.
- Say the wake word.
- Speak your prompt.
- If you want clarification, ask a quick follow-up right after the reply. You do not need the wake word again until the follow-up window closes.
If you want to test the assistant without using the wake word, use the typed request box in the Use tab.
Useful desktop shortcuts:
F8toggles voice modeCtrl+Spacetriggers push-to-talkEscapeinterrupts current output
If tray support is available, closing the window hides PyJippety to the system tray or menu bar instead of exiting. You can reopen it from the tray icon.
The app keeps spoken output focused on actual replies. Wake-word detection uses a short local chime instead of speaking status messages back to you.
If you want the assistant to remember something, say or type:
remember that I prefer short answers
You can also ask:
what do you remember about me
Small convenience features built into the UI:
Repeat: speak the last answer againCopy answer: copy the last answer to the clipboardClear view: clear the current transcript/answer area without touching memoryWake cue: play the configured wake soundMute speech: keep replies visible in the UI without speaking them out loudOpen config folder: jump to the profile/config storage locationOpen logs folder: jump to the local log directoryExport profile: save the current profile as a zip archiveRecent prompts: quickly reuse recent spoken or typed requests
PyJippety supports either:
- a built-in Porcupine keyword
- a custom Porcupine wake-word model (
.ppn)
The quickest path is to use one of Porcupine’s built-in keywords in the Setup tab:
- Leave
Custom keyword fileempty. - Set
Built-in keywordto the word you want to use. - Set
Wake word labelto the same word or phrase you want the UI to display. - Save settings.
If you want a custom wake word such as computer, create a Porcupine keyword model and point PyJippety at it.
Typical flow:
- Go to the Picovoice Console.
- Create a custom Porcupine wake word.
- Download the generated
.ppnmodel for your platform. - Save that file somewhere stable on your machine.
- In the
Setuptab:- set
Custom keyword fileto the path of the.ppnfile - set
Wake word labelto the phrase you want PyJippety to show in the UI
- set
- Save settings.
Notes:
- If
Custom keyword fileis set, it takes priority over the built-in keyword field. .ppnfiles are local assets and are ignored by Git in this repo by default.- If PyJippety says it cannot find the keyword file, open
Setupand either clear the field or point it to the correct file again.
Typical voice flow:
- Open PyJippety.
- Click
Start. - Wait for the app to enter listening mode.
- Say the wake word.
- Ask your question.
- Listen for the reply.
- If needed, ask a follow-up question immediately after the reply.
Examples:
porcupine what time is it
porcupine remember that I like concise answers
porcupine open website github.com
porcupine what do you remember about me
Useful interaction modes:
Start: enable wake-word listeningPush to talk: ask one question without the wake wordAsk: type a request instead of speaking itSend transcript: resend the last recognized speech after editing itInterrupt: stop current playbackSleep: stop active listening without quitting the app
If tray support is available:
- closing the window keeps the app running in the background
- you can reopen it from the tray or menu bar icon
If you want to run the project directly from source:
python -m venv .venv
source .venv/bin/activate
pip install -e .You can also install from requirements.txt:
pip install -r requirements.txtIf you want a project-local config file during development:
cp .env.example .envRun the desktop UI:
pyjippety-uiRun the voice loop from the terminal:
pyjippetyRun one cycle only:
pyjippety --onceIf you are running from source without installing entrypoints:
PYTHONPATH=src python -m pyjippety.gui
PYTHONPATH=src python -m pyjippety.botThe runtime pipeline is intentionally simple:
- Porcupine listens locally for a wake word.
- Once triggered, the app records a single spoken prompt.
- The prompt audio is sent to OpenAI transcription.
- The transcript is sent to an OpenAI chat model.
- The reply is spoken with OpenAI speech, or printed if speech is disabled or unavailable.
- The app keeps listening for a small number of follow-up questions before returning to wake-word mode.
Wake-word detection stays on-device. The transcription, response, and speech steps use the OpenAI API.
The app also has lightweight local actions for requests such as checking the time, checking the date, opening a website, and going to sleep. When safe tool mode is enabled, side-effect actions stay blocked unless you turn that protection off.
The desktop app is split into two focused areas:
Use- start or stop voice mode
- use push-to-talk
- type requests directly
- inspect and resend the last transcript
- inspect live activity logs
- keep memory notes and recent activity nearby without leaving the main work area
Setup- manage profiles and personality presets
- edit the common settings in a compact basic view
- reveal model fallbacks, timing values, safe tool mode, idle timeout, memory limits, and prompt tuning through
Show advanced settings
The goal is to feel like a small desktop utility, not a chat dashboard.
Most users should manage settings from the desktop UI. The app writes them to:
~/.config/pyjippety/.env
For manual editing, the main settings are:
OPENAI_API_KEYPICOVOICE_ACCESS_KEYASSISTANT_WAKE_WORDASSISTANT_PORCUPINE_KEYWORDASSISTANT_PORCUPINE_KEYWORD_PATHASSISTANT_DISPLAY_NAMEASSISTANT_CHAT_MODELASSISTANT_TRANSCRIPTION_MODELASSISTANT_TRANSCRIPTION_FALLBACK_MODELSASSISTANT_TTS_ENABLEDASSISTANT_MUTE_SPEECHASSISTANT_TTS_MODELASSISTANT_TTS_FALLBACK_MODELSASSISTANT_TTS_VOICEASSISTANT_TTS_SPEEDASSISTANT_SYSTEM_PROMPTASSISTANT_TTS_INSTRUCTIONSASSISTANT_MEMORY_ENABLEDASSISTANT_MEMORY_TURN_LIMITASSISTANT_MEMORY_FACT_LIMITASSISTANT_LOW_VERBOSITYASSISTANT_LISTEN_TIMEOUTASSISTANT_PHRASE_TIME_LIMITASSISTANT_FOLLOW_UP_ENABLEDASSISTANT_FOLLOW_UP_TURN_LIMITASSISTANT_FOLLOW_UP_TIMEOUTASSISTANT_START_HIDDENASSISTANT_CHIME_VOLUMEASSISTANT_SAFE_TOOL_MODEASSISTANT_IDLE_TIMEOUT_SECONDSASSISTANT_AMBIENT_ADJUST_SECONDSASSISTANT_ENERGY_THRESHOLDASSISTANT_AUDIO_DEVICE_INDEXASSISTANT_EXIT_WORDS
Notes:
- If you use a custom wake word such as
computer, pointASSISTANT_PORCUPINE_KEYWORD_PATHto a Picovoice.ppnfile. - If your OpenAI project cannot access the default transcription or speech models, the app will try configured fallback models.
- If speech is disabled or all speech models fail, replies stay visible in the UI log.
- Memory is stored locally in the user config area and reused as context for later prompts when memory is enabled.
- Profiles store their own settings, memory file, and action history under
~/.config/pyjippety/profiles/<profile-name>/. - Idle timeout stops voice mode after inactivity and puts the app into a sleeping state until you start it again.
To build a desktop bundle:
Linux or macOS:
python3 build-pyjippety-bundle.pyWindows:
py build-pyjippety-bundle.pyTo build release artifacts for the current platform:
Linux or macOS:
python3 package-pyjippety.pyWindows:
py package-pyjippety.pyCurrent packaging targets:
- Windows:
.exeand.zip - macOS:
.dmgand.tar.gz - Linux:
.deb,.tar.gz, and.AppImage - Linux:
.flatpakwhen Flatpak tooling is available
Artifacts are written to:
release/
The repository includes GitHub Actions workflows for CI and releases:
CI- runs unit tests on Linux, macOS, and Windows
- installs the platform-specific system dependencies needed for the current Python/audio stack
- compiles the Python sources to catch syntax regressions
Release- triggers on tags that start with
v - builds desktop bundles for Linux, macOS, and Windows
- packages release artifacts for each platform
- builds Python
sdistandwheelartifacts - publishes all bundled artifacts to a GitHub Release
- triggers on tags that start with
Flatpak builds are generated during releases too. The packaging script vendors the required Python wheels and installs the Flatpak runtime/SDK in CI so the Flatpak build can run without depending on network access inside the Flatpak build sandbox.
Flathub publishing is still a separate submission/review workflow through flathub/flathub; GitHub Releases can publish .flatpak artifacts, but that does not by itself publish the app on Flathub.
Typical release flow:
git tag v0.1.0
git push origin v0.1.0That tag will trigger the release workflow and publish the generated artifacts to GitHub Releases.
PYTHONPATH=src python -m unittest discover -s tests
python -m compileall src testsSome Linux systems print ALSA warnings even when the app still works. These messages are often noisy rather than fatal.
If you see 403 Forbidden or model_not_found, your OpenAI project likely does not have access to the configured model. Change the primary model in the UI or set a compatible fallback list.
If speech fails, the app will fall back to text output in the log. Check the speech model settings and your OpenAI project access.
Check:
- your Picovoice access key
- the chosen built-in keyword
- the custom
.ppnpath if you are using one - your microphone device selection
- Tkinter support depends on the Python distribution you installed.
- If PyAudio fails to build, install PortAudio first, for example with Homebrew.
- Use
py install-pyjippety.pyifpythonis not onPATH. - If PyAudio installation fails, install a compatible wheel for your Python version or use a Python environment known to work with PyAudio.
src/pyjippety/
bot.py CLI entrypoint
actions.py lightweight local command plugins
config.py config parsing and env loading
memory.py local memory storage and memory-aware prompting
runtime.py assistant orchestration
integrations.py OpenAI, Porcupine, audio, and wake chime adapters
gui.py desktop frontend
controller.py GUI control flow and side-effect orchestration
profile_store.py settings/history persistence by profile
ui_shared.py shared UI schema and constants
views.py Tk layout and widget construction
tests/
test_bot.py assistant loop tests
test_memory.py memory behavior tests
install-pyjippety.py
install-pyjippety.sh
build-pyjippety-bundle.py
build-pyjippety-bundle.sh
This is a phrase-based assistant, not a full duplex realtime conversation agent.
That keeps the app simpler to install, easier to reason about, and easier to package as a desktop utility.
