Core Utilities¶
Small, focused modules that every higher-level LunaVox component depends
on. Each one is a single-point-of-truth enforced by AGENT.md rules:
other code imports from here rather than probing the OS, re-reading
paths, or spinning up Rich consoles directly.
Platform detection¶
platform
¶
Host-platform helpers.
All sys.platform / platform.system() branches in the Python side
live here. The rule mirrors the C++ side: other modules must not probe the
OS directly — they import from here so the selection logic stays in one
file and future platforms only require one edit.
The build.factory / build.get_*_class entry points are the single
allowed exception because they bind a host tag to an entire Builder class
rather than to a scalar.
shared_lib_name
¶
Return the platform-appropriate shared-library filename for stem.
Windows: {stem}.dll; macOS: lib{stem}.dylib; Linux / other POSIX:
lib{stem}.so.
Source code in src/lunavox/core/platform.py
executable_suffix
¶
Empty on POSIX, .exe on Windows. Useful when resolving binary
paths like build/lunavox-cli.
is_windows
¶
is_macos
¶
Project root resolution¶
resolve_project_root
¶
Find and return the project root directory, creating 'models' and 'lib' if missing.
Source code in src/lunavox/core/project.py
Dependency management¶
ensure_dependency_group
¶
ensure_dependency_group(
group: str, policy: DependencyPolicy, project_root: Path | None = None
) -> None
Source code in src/lunavox/core/deps.py
has_module
¶
missing_modules
¶
Session logging¶
logging
¶
Unified process-wide logger for the Python side.
Every writer — CLI session header, build driver stage output, conversion
pipeline subprocess capture, GUI-bridged C++ log callback — appends to the
same logs/latest.log through this module. A single threading.Lock
serializes writes so concurrent tasks (e.g. Rich status spinner + build
subprocess + model download) cannot corrupt each other.
Design notes:
- The log file is a plain append stream. No level filtering and no handler chain; the consumer decides what to write, we just persist.
session_start(path)truncates and writes a session header. The CLI calls this once per invocation; nothing else should.- Writers call
append(text). The module is a no-op untilsession_starthas been called, so importing the logger from a library module is safe even in contexts where no log file exists (tests, sdist builds, IDE completion). - Keep this file dependency-free: no Rich, no lunavox imports. The UI
console lives in
core.uiand is separate on purpose — users can silence the console without losing the log, and vice versa.
session_start
¶
Truncate path and register it as the process-wide log file.
Subsequent :func:append calls will go here. Safe to call multiple
times per process — the last call wins (CLI does this once at
startup; tests may rebind to a tmp path).
Source code in src/lunavox/core/logging.py
append
¶
Append text to the active session log. No-op if unbound.