feat: add pipeline introspection demo mode

- Add PipelineIntrospectionSource that renders live ASCII DAG with metrics
- Add PipelineMetricsSensor exposing pipeline performance as sensor values
- Add PipelineIntrospectionDemo controller with 3-phase animation:
  - Phase 1: Toggle effects one at a time (3s each)
  - Phase 2: LFO drives intensity default→max→min→default
  - Phase 3: All effects with shared LFO (infinite loop)
- Add pipeline-inspect preset
- Add get_frame_times() to Pipeline for sparkline data
- Add tests for new components
- Update mise.toml with pipeline-inspect preset task
This commit is contained in:
2026-03-16 16:55:57 -07:00
parent 2a41a90d79
commit f638fb7597
14 changed files with 1186 additions and 55 deletions

View File

@@ -161,7 +161,7 @@ The project uses pytest with strict marker enforcement. Test configuration is in
### Test Coverage Strategy
Current coverage: 56% (433 tests)
Current coverage: 56% (434 tests)
Key areas with lower coverage (acceptable for now):
- **app.py** (8%): Main entry point - integration heavy, requires terminal
@@ -186,11 +186,18 @@ Performance regression tests are in `tests/test_benchmark.py` with `@pytest.mark
## Architecture Notes
- **ntfy.py** and **mic.py** are standalone modules with zero internal dependencies
- **ntfy.py** - standalone notification poller with zero internal dependencies
- **sensors/** - Sensor framework (MicSensor, OscillatorSensor) for real-time input
- **eventbus.py** provides thread-safe event publishing for decoupled communication
- **controller.py** coordinates ntfy/mic monitoring and event publishing
- **effects/** - plugin architecture with performance monitoring
- The render pipeline: fetch → render → effects → scroll → terminal output
- The new pipeline architecture: source → render → effects → display
#### Canvas & Camera
- **Canvas** (`engine/canvas.py`): 2D rendering surface with dirty region tracking
- **Camera** (`engine/camera.py`): Viewport controller for scrolling content
The Canvas tracks dirty regions automatically when content is written (via `put_region`, `put_text`, `fill`), enabling partial buffer updates for optimized effect processing.
### Pipeline Architecture
@@ -214,9 +221,24 @@ Stages declare capabilities (what they provide) and dependencies (what they need
- **SensorStage**: Pipeline adapter that provides sensor values to effects
- **MicSensor** (`engine/sensors/mic.py`): Self-contained microphone input
- **OscillatorSensor** (`engine/sensors/oscillator.py`): Test sensor for development
- **PipelineMetricsSensor** (`engine/sensors/pipeline_metrics.py`): Exposes pipeline metrics as sensor values
Sensors support param bindings to drive effect parameters in real-time.
#### Pipeline Introspection
- **PipelineIntrospectionSource** (`engine/pipeline_sources/pipeline_introspection.py`): Renders live ASCII visualization of pipeline DAG with metrics
- **PipelineIntrospectionDemo** (`engine/pipeline/pipeline_introspection_demo.py`): 3-phase demo controller for effect animation
Preset: `pipeline-inspect` - Live pipeline introspection with DAG and performance metrics
#### Partial Update Support
Effect plugins can opt-in to partial buffer updates for performance optimization:
- Set `supports_partial_updates = True` on the effect class
- Implement `process_partial(buf, ctx, partial)` method
- The `PartialUpdate` dataclass indicates which regions changed
### Preset System
Presets use TOML format (no external dependencies):