Code Patterns¶
Conventions and patterns used throughout the Kiwi Voice codebase.
Logging¶
Always use kiwi_log() — never bare print():
from kiwi.utils import kiwi_log
kiwi_log("TAG", "message", level="INFO")
# → [14:08:25.342] [INFO] [TAG] message
Project Root Paths¶
Use PROJECT_ROOT for paths to project-level assets:
i18n Strings¶
User-facing strings always go through t(). Developer-facing log messages do not:
from kiwi.i18n import t
# User-facing — use t()
self._speak(t("responses.greeting"))
self._speak(t("responses.heard", command=cmd))
# Developer-facing — plain string
kiwi_log("TAG", "Internal log message", level="INFO")
Module-level constants are kept as fallback defaults. Instance attributes override them from i18n at init time:
self.wake_word = t("wake_word.keyword") or WAKE_WORD
self.hallucination_phrases = set(t("hallucinations.phrases") or HALLUCINATION_PHRASES)
Optional Module Loading¶
Modules with optional dependencies use try/except with availability flags:
try:
from kiwi.speaker_manager import SpeakerManager
SPEAKER_MANAGER_AVAILABLE = True
except ImportError:
SPEAKER_MANAGER_AVAILABLE = False
Then check the flag before using:
GPU Auto-Detection¶
CUDA is used when available, with automatic CPU fallback:
Threading¶
All background work uses daemon threads with crash protection:
import threading
thread = threading.Thread(target=self._worker, daemon=True)
thread.start()
def _worker(self):
while self._running:
try:
# work
pass
except Exception as e:
kiwi_log("WORKER", f"Error: {e}", level="ERROR")
time.sleep(1)
continue
Shared resources are guarded by threading.Lock:
Windows UTF-8¶
Console codepage is set for Unicode output:
Tests¶
Run tests:
Smoke tests verify module imports and basic config loading: