Add interactive plan node selection with media previews

- Click plan nodes (in DAG or list) to see details in side panel
- URL updates to #node-{id} for direct linking
- Node detail panel shows: type, status, inputs, output, config
- Inputs can be clicked to navigate to that node
- Inputs tab now shows media previews (image/video/audio)
- Steps include config data for display

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-11 23:30:43 +00:00
parent d73592fbe2
commit 8e70a9b9f2
2 changed files with 275 additions and 19 deletions

View File

@@ -133,6 +133,7 @@ async def get_run(
"type": node.get("type", "EFFECT"),
"status": "completed", # Run completed
"inputs": node.get("inputs", []),
"config": node.get("config", {}),
})
elif isinstance(nodes, dict):
for node_id, node in nodes.items():
@@ -142,6 +143,7 @@ async def get_run(
"type": node.get("type", "EFFECT"),
"status": "completed",
"inputs": node.get("inputs", []),
"config": node.get("config", {}),
})
if steps:
@@ -174,6 +176,25 @@ async def get_run(
"media_type": media_type or "application/octet-stream",
})
# Build inputs list with media types
run_inputs = []
if run.get("inputs"):
import mimetypes
cache_manager = get_cache_manager()
for i, input_hash in enumerate(run["inputs"]):
media_type = None
try:
cache_path = cache_manager.get_path(input_hash)
if cache_path and cache_path.exists():
media_type, _ = mimetypes.guess_type(str(cache_path))
except Exception:
pass
run_inputs.append({
"hash": input_hash,
"name": f"Input {i + 1}",
"media_type": media_type,
})
# Build DAG elements for visualization
dag_elements = []
if plan and plan.get("steps"):
@@ -209,6 +230,7 @@ async def get_run(
run=run,
plan=plan,
artifacts=artifacts,
run_inputs=run_inputs,
dag_elements=dag_elements,
active_tab="runs",
)