feat(pipeline): add metrics collection and v2 run mode
- Add RenderStage adapter that handles rendering pipeline - Add EffectPluginStage with proper EffectContext - Add DisplayStage with init handling - Add ItemsStage for pre-fetched items - Add metrics collection to Pipeline (StageMetrics, FrameMetrics) - Add get_metrics_summary() and reset_metrics() methods - Add --pipeline and --pipeline-preset flags for v2 mode - Add PipelineNode.metrics for self-documenting introspection - Add introspect_new_pipeline() method with performance data - Add mise tasks: run-v2, run-v2-demo, run-v2-poetry, run-v2-websocket, run-v2-firehose
This commit is contained in:
132
engine/app.py
132
engine/app.py
@@ -839,12 +839,17 @@ def run_preset_mode(preset_name: str):
|
||||
|
||||
def main():
|
||||
from engine import config
|
||||
from engine.pipeline import generate_pipeline_diagram
|
||||
|
||||
if config.PIPELINE_DIAGRAM:
|
||||
from engine.pipeline import generate_pipeline_diagram
|
||||
|
||||
print(generate_pipeline_diagram())
|
||||
return
|
||||
|
||||
if config.PIPELINE_MODE:
|
||||
run_pipeline_mode(config.PIPELINE_PRESET)
|
||||
return
|
||||
|
||||
if config.PIPELINE_DEMO:
|
||||
run_pipeline_demo()
|
||||
return
|
||||
@@ -955,3 +960,128 @@ def main():
|
||||
print(f" {G_DIM}> {config.HEADLINE_LIMIT} SIGNALS PROCESSED{RST}")
|
||||
print(f" {W_GHOST}> end of stream{RST}")
|
||||
print()
|
||||
|
||||
|
||||
def run_pipeline_mode(preset_name: str = "demo"):
|
||||
"""Run using the new unified pipeline architecture."""
|
||||
import effects_plugins
|
||||
from engine.display import DisplayRegistry
|
||||
from engine.effects import get_registry
|
||||
from engine.fetch import fetch_all, fetch_poetry, load_cache
|
||||
from engine.pipeline import (
|
||||
Pipeline,
|
||||
PipelineConfig,
|
||||
get_preset,
|
||||
)
|
||||
from engine.pipeline.adapters import (
|
||||
RenderStage,
|
||||
create_items_stage,
|
||||
create_stage_from_display,
|
||||
create_stage_from_effect,
|
||||
)
|
||||
|
||||
print(" \033[1;38;5;46mPIPELINE MODE\033[0m")
|
||||
print(" \033[38;5;245mUsing unified pipeline architecture\033[0m")
|
||||
|
||||
effects_plugins.discover_plugins()
|
||||
|
||||
preset = get_preset(preset_name)
|
||||
if not preset:
|
||||
print(f" \033[38;5;196mUnknown preset: {preset_name}\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
print(f" \033[38;5;245mPreset: {preset.name} - {preset.description}\033[0m")
|
||||
|
||||
params = preset.to_params()
|
||||
params.viewport_width = 80
|
||||
params.viewport_height = 24
|
||||
|
||||
pipeline = Pipeline(
|
||||
config=PipelineConfig(
|
||||
source=preset.source,
|
||||
display=preset.display,
|
||||
camera=preset.camera,
|
||||
effects=preset.effects,
|
||||
)
|
||||
)
|
||||
|
||||
print(" \033[38;5;245mFetching content...\033[0m")
|
||||
cached = load_cache()
|
||||
if cached:
|
||||
items = cached
|
||||
elif preset.source == "poetry":
|
||||
items, _, _ = fetch_poetry()
|
||||
else:
|
||||
items, _, _ = fetch_all()
|
||||
|
||||
if not items:
|
||||
print(" \033[38;5;196mNo content available\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
print(f" \033[38;5;82mLoaded {len(items)} items\033[0m")
|
||||
|
||||
display = DisplayRegistry.create(preset.display)
|
||||
if not display:
|
||||
print(f" \033[38;5;196mFailed to create display: {preset.display}\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
display.init(80, 24)
|
||||
|
||||
effect_registry = get_registry()
|
||||
|
||||
pipeline.add_stage("source", create_items_stage(items, preset.source))
|
||||
pipeline.add_stage(
|
||||
"render",
|
||||
RenderStage(
|
||||
items,
|
||||
width=80,
|
||||
height=24,
|
||||
camera_speed=params.camera_speed,
|
||||
camera_mode=preset.camera,
|
||||
firehose_enabled=params.firehose_enabled,
|
||||
),
|
||||
)
|
||||
|
||||
for effect_name in preset.effects:
|
||||
effect = effect_registry.get(effect_name)
|
||||
if effect:
|
||||
pipeline.add_stage(
|
||||
f"effect_{effect_name}", create_stage_from_effect(effect, effect_name)
|
||||
)
|
||||
|
||||
pipeline.add_stage("display", create_stage_from_display(display, preset.display))
|
||||
|
||||
pipeline.build()
|
||||
|
||||
if not pipeline.initialize():
|
||||
print(" \033[38;5;196mFailed to initialize pipeline\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
print(" \033[38;5;82mStarting pipeline...\033[0m")
|
||||
print(" \033[38;5;245mPress Ctrl+C to exit\033[0m\n")
|
||||
|
||||
ctx = pipeline.context
|
||||
ctx.params = params
|
||||
ctx.set("display", display)
|
||||
ctx.set("items", items)
|
||||
ctx.set("pipeline", pipeline)
|
||||
|
||||
try:
|
||||
frame = 0
|
||||
while True:
|
||||
params.frame_number = frame
|
||||
ctx.params = params
|
||||
|
||||
result = pipeline.execute(items)
|
||||
if result.success:
|
||||
display.show(result.data)
|
||||
|
||||
time.sleep(1 / 60)
|
||||
frame += 1
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
pipeline.cleanup()
|
||||
display.cleanup()
|
||||
print("\n \033[38;5;245mPipeline stopped\033[0m")
|
||||
|
||||
Reference in New Issue
Block a user