Skip to content

Runtime and Configuration

The runtime system manages Vector Companion's 12-phase startup sequence, global singletons, and the SharedState singleton that coordinates async primitives across modules.

Startup Sequence

LifecycleManager.initialize() executes 12 phases in order. Each phase has a specific post-condition that must hold before the next phase begins:

Phase Method Post-Condition
0B JSON-to-SQLite migration (main.py) Legacy JSON files renamed to .migrated
1 setup_environment() OLLAMA_HOST set, faulthandler active
2 setup_logging() data/logs/ created, rotation configured, StructuredLogger init
3 detect_device() Device = "cuda:<N>", "mps", or "cpu"
4 setup_torch() CuDNN benchmark/deterministic set, cache cleared
5 initialize_shared_state() SharedState singleton with all asyncio primitives
6 load_audio_model() STTBackendAdapter wrapping Parakeet-TDT backend chain
7 load_tts_model() ChatterboxTTS loaded, T3 cast to bfloat16
8 load_reranker() Deferred to LazyLoader (loaded on first memory_mode use)
build_agents(tool_host) (explicit after init) Agents populated, tool_handlers registered
10 load_history() Messages initialized, legacy JSON fallback
11 load_tools() tool_calls_active populated (11 default tools)
12 setup_telemetry() MetricsCollector singleton created

Agents Built After Init

Agent creation happens explicitly after LifecycleManager.initialize(), not as a phase within it. This ensures the ToolHost is created before any agent is instantiated.

Runtime Invariants

Six invariants are enforced by design and verified in tests:

Invariant Description
I1: SharedState Singleton All modules use get_shared_state(). Never create new asyncio events directly.
I2: ToolHost Mandatory Gate build_agents() raises ValueError when tool_host=None.
I3: Approval Workflow Async-Only Sync wrappers deadlock if called from existing event loop.
I4: Mode Registry (single source of truth) ModeRegistry is canonical; changes propagate via callback to globals/config.
I5: OLLAMA_HOST Early Init Set in phase 1 before any model loading. Default: 127.0.0.1:11434.
I6: TTS dtype Consistency T3 cast to bfloat16 in phase 7. Never create fresh ChatterboxTTS outside lifecycle.

SharedState Singleton

SharedState (core/runtime/shared_state.py) is a lazy-initialized singleton holding all cross-module asyncio primitives:

Primitive Purpose
tts_interrupt_event Signal TTS synthesis to stop mid-stream
can_speak_event Wake main loop for new messages
stop_recording_event Halt audio recording (desktop text input)
text_only_flag Skip audio transcription path
audio_playback_lock Serialize TTS playback
image_lock Coordinate screenshot capture

Access via get_shared_state(). This avoids event-loop affinity issues by creating all primitives in the same loop context.

Global Singletons

Nine singletons are created during startup, each owned by a specific phase:

Singleton Phase Module
SharedState 5 core/runtime/shared_state.py
StructuredLogger 2 core/logging/
MetricsCollector 12 core/util/telemetry.py
SQLiteStore main.py core/data/sqlite_store.py
EventBus main.py core/infrastructure/event_bus.py
ApprovalWorkflow main.py core/security/approval_workflow.py
IsolationManager main.py core/security/isolation.py
ToolHost main.py core/security/tool_host.py
StreamingCoordinator main.py core/streaming/streaming_coordinator.py

Runtime Files

The application creates several files for IPC and state management:

Path Created By Purpose
.runtime/ Startup (phase 0) Directory for runtime IPC files
data/logs/ Phase 2 Structured + plain text log output
.runtime/controls.json chat_streaming IPC control messages
.runtime/onboarding.json OnboardingManager First-run state
.runtime/session_secret.json ApiServer Per-session API auth secret
ui/chat.log chat_streaming Streaming protocol message log
data/store/vector_companion.db SQLiteStore (first use) WAL-mode database, schema v2

Configuration Module

config/config.py defines all runtime configuration: models, sampling parameters, agent personalities, system prompts, and mode defaults. It is a data-only module — no instantiation occurs at import time.

Config Export

config/export_config.py serializes public config attributes to config/config.json for the Tauri frontend. The _ui_sampling_overrides dict tracks which widget values differ from config defaults.

RuntimeApp

RuntimeApp (core/runtime/runtime_app.py) is the top-level container: - Combines RuntimeConfig + ServiceRegistry + LifecycleManager - run() is the async entry point - initialize(skip_heavy=True) skips phases 6–12 for CI/test mode

See Also