System Architecture
High-Level Runtime
flowchart LR
ArchMain["main.py"] --> ArchBootstrap["Bootstrap"]
ArchBootstrap --> ArchRuntime["Async Runtime"]
ArchBootstrap --> ArchEvents["Event Buses"]
ArchBootstrap --> ArchLifecycle["Lifecycle"]
ArchRuntime --> ArchVoice["Voice Pipeline"]
ArchRuntime --> ArchVision["Vision Auto-Capture"]
ArchRuntime --> ArchCognition["Cognition"]
ArchRuntime --> ArchWebUI["WebUI"]
ArchVision --> ArchDiagnostics["Diagnostics"]
ArchDiagnostics --> ArchWebUI
ArchCognition --> ArchPersistence["Persistence"] Voice Pipeline
flowchart LR
VoiceWake["Wakeword"] --> VoiceCapture["Capture"]
VoiceCapture --> VoiceSTT["STT"]
VoiceSTT --> VoiceTranscript["Transcript"]
VoiceTranscript --> VoiceConversation["Conversation"]
VoiceConversation --> VoiceResponse["Response"]
VoiceResponse --> VoiceTTS["TTS"]
VoiceTTS --> VoiceSpeaker["Speaker"] WakewordManager owns the microphone only while the runtime mode is idle. When runtime moves into listening, transcribing, thinking, speaking, or cooldown, the wakeword PyAudio stream is closed so STT can own capture without wakeword backlog or stream-draining conflicts. After wakeword detection, the wakeword stream is closed before the listen/STT handoff.
Vision Pipeline
flowchart LR
Camera["CameraManager"] --> FrameStore["FrameStore"]
Camera --> Analyzer["VisionAnalyzer"]
Analyzer --> Metrics["Image Metrics"]
Analyzer --> FaceReady["face_ready"]
Camera --> Detector["FaceDetector"]
Detector --> FacePayload["face_detection"]
Metrics --> Diagnostics["DiagnosticsManager"]
FacePayload --> Diagnostics
Diagnostics --> WebUI["/vision WebUI"] The vision pipeline is implemented as an experimental local camera pipeline. VisionAutoCapture keeps a periodic capture loop when enabled, and CameraManager may keep the camera session open while that loop is active.
Cognition and Persistence
ResponseGeneratorroutes text through local commands, personality commands, or the configured LLM provider.MemoryManagerextracts and filters durable facts before persistence.- SQLite stores conversations, memories, events, logs, and command metadata.
FaceRepositoryexists as a persistence layer for future face enrollment/recognition, but enrollment and identity matching are not active yet.
Observability
- The WebUI reads diagnostics snapshots, runtime state, event-bus metrics, and SQLite repositories.
- The
/visionpage reads compact diagnostics and renders image quality, face detection counters, reject reasons, and bounding boxes over the latest snapshot. - Endpoints stay read-only; operational changes happen through voice commands or direct database access.
Core Responsibilities
| Component | Path | Purpose |
|---|---|---|
| Entry point | cosmo/main.py | Starts async bootstrap. |
| Bootstrap | cosmo/core/bootstrap/bootstrap.py | Initializes lifecycle, imports listeners, starts event bus and wakeword task. |
| Runtime state | cosmo/core/runtime/runtime_state.py | 7-state machine; guards wake, capture, thinking, speaking. |
| Async event bus | cosmo/core/events/async_event_bus.py | Priority queue, listener dispatch, metrics, resilience. |
| Wakeword | cosmo/audio/wakeword/ | Vosk-based word detection with energy thresholding. |
| Audio capture | cosmo/audio/capture/audio_capture_manager.py | Records user speech with RMS silence detection. |
| STT | cosmo/audio/stt/ | Vosk transcription engine. |
| Vision manager | cosmo/vision/vision_manager.py | Starts/stops camera capture, saves snapshots, emits vision events. |
| Vision auto-capture | cosmo/vision/vision_auto_capture.py | Periodic snapshot/analysis loop when vision.auto_capture is enabled. |
| Camera | cosmo/vision/camera/ | Camera access, fresh frame reading, frame store, snapshot saving. |
| Vision analysis | cosmo/vision/analysis/ | Image metrics, blur/backlight/exposure classification, face readiness. |
| Face detection | cosmo/vision/detection/ | Experimental Haar Cascade baseline with filters and eye validation. |
| Conversation | cosmo/cognition/conversation/ | Short-term history and pipeline orchestration. |
| Response generation | cosmo/cognition/response/response_generator.py | Command/personality/LLM routing. |
| TTS | cosmo/audio/tts/ | Provider-based synthesis with Piper and Espeak. |
| Memory | cosmo/cognition/memory/ | Rule-based extraction, filtering, persistence. |
| Database | cosmo/data/database/ | SQLite connection and repository types. |
| Diagnostics | cosmo/data/diagnostics/diagnostics_manager.py | Runtime snapshots. |
| WebUI | cosmo/interfaces/webui/ | FastAPI page-based observability dashboard. |
| Logging | cosmo/core/logger/ | Console, file, and SQLite handlers. |
| Configuration | cosmo/core/config/ | YAML settings loader. |
Source Code Structure
| Path | Status | Responsibility |
|---|---|---|
cosmo/main.py | Active | Application entry point. |
cosmo/core/bootstrap/ | Active | Lifecycle startup and listener registration. |
cosmo/core/events/ | Active | Event types, buses, and listener modules. |
cosmo/core/runtime/ | Active | Runtime state machine, task registry, thread helpers. |
cosmo/audio/vad/ | Present | WebRTC VAD wrapper; not used because capture uses RMS. |
cosmo/interfaces/webui/templates/ | Active | Page-based templates: dashboard, vision, logs, events, memory, conversations, status. |
cosmo/interfaces/webui/static/js/ | Active | Page-specific JavaScript plus shared helpers. |
cosmo/interfaces/webui/static/css/ | Active | Modular CSS split into base.css, layout.css, components.css, tables.css, dashboard.css, inspectors.css, vision.css, with webui.css as import entrypoint. |
cosmo/vision/camera/ | Active | Camera access, fresh frame reading, frame store, snapshot saving. |
cosmo/vision/analysis/ | Active | Image quality metrics, blur/backlight/exposure classification, face readiness. |
cosmo/vision/detection/ | Active / Experimental | Haar-based face detection baseline with filtering and eye validation. |
cosmo/vision/recognition/ | Pending | Future embeddings, enrollment, and identity matching. |
cosmo/vision/tracking/ | Pending | Future tracking and temporal smoothing. |
cosmo/cognition/planner/ | Pending | Future task planning. |
Startup and Bootstrap Flow
Startup begins in cosmo/main.py:
import asyncio
from cosmo.core.bootstrap.bootstrap import bootstrap
if __name__ == "__main__":
asyncio.run(bootstrap.start()) Listener registration happens through import side effects in bootstrap.py.
| Module | Bus | Event | Handler |
|---|---|---|---|
system_listener.py | sync | system_started | on_system_started |
system_async_listener.py | async | system_started | on_system_started |
wakeword_listener.py | async | wake_word_detected | on_wake_word_detected |
stt_listener.py | async | audio_captured | on_audio_captured |
transcript_listener.py | async | transcript_ready | on_transcript_ready |
tts_listener.py | async | response_generated | on_response_generated |
conversation_listener.py | sync | command_received | on_command_received (legacy) |
vision_listener.py | sync | user_recognized, face_unknown | Legacy recognition events are registered; recognition/enrollment producers are pending. |
Shutdown sets lifecycle.running = False, emits system_shutdown on the sync bus, calls async_runtime.shutdown(), and logs completion.

