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

@@ -94,38 +94,6 @@ class PoetryDataSource(DataSource):
return [SourceItem(content=t, source=s, timestamp=ts) for t, s, ts in items]
class PipelineDataSource(DataSource):
"""Data source for pipeline visualization (demo mode). Dynamic - updates every frame."""
def __init__(self, viewport_width: int = 80, viewport_height: int = 24):
self.viewport_width = viewport_width
self.viewport_height = viewport_height
self.frame = 0
@property
def name(self) -> str:
return "pipeline"
@property
def is_dynamic(self) -> bool:
return True
def fetch(self) -> list[SourceItem]:
from engine.pipeline_viz import generate_large_network_viewport
buffer = generate_large_network_viewport(
self.viewport_width, self.viewport_height, self.frame
)
self.frame += 1
content = "\n".join(buffer)
return [
SourceItem(content=content, source="pipeline", timestamp=f"f{self.frame}")
]
def get_items(self) -> list[SourceItem]:
return self.fetch()
class MetricsDataSource(DataSource):
"""Data source that renders live pipeline metrics as ASCII art.
@@ -340,9 +308,6 @@ class SourceRegistry:
def create_poetry(self) -> PoetryDataSource:
return PoetryDataSource()
def create_pipeline(self, width: int = 80, height: int = 24) -> PipelineDataSource:
return PipelineDataSource(width, height)
_global_registry: SourceRegistry | None = None