diff --git a/server.py b/server.py index 22a06f4..f493ab0 100644 --- a/server.py +++ b/server.py @@ -1425,9 +1425,9 @@ async def load_plan_for_run_with_fallback(run: RunStatus) -> Optional[dict]: return None -@app.get("/run/{run_id}/plan/node/{step_id}", response_class=HTMLResponse) -async def run_plan_node_detail(run_id: str, step_id: str, request: Request): - """HTMX partial: Get node detail HTML fragment.""" +@app.get("/run/{run_id}/plan/node/{cache_id}", response_class=HTMLResponse) +async def run_plan_node_detail(run_id: str, cache_id: str, request: Request): + """HTMX partial: Get node detail HTML fragment by cache_id.""" ctx = await get_user_context_from_cookie(request) if not ctx: return HTMLResponse('
Login required
', status_code=401) @@ -1442,23 +1442,28 @@ async def run_plan_node_detail(run_id: str, step_id: str, request: Request): if not plan_data: return HTMLResponse('Plan not found
') - # Find the step - step = None + # Build a lookup from cache_id to step and step_id to step + steps_by_cache_id = {} + steps_by_step_id = {} for s in plan_data.get("steps", []): - if s.get("step_id") == step_id: - step = s - break + if s.get("cache_id"): + steps_by_cache_id[s["cache_id"]] = s + if s.get("step_id"): + steps_by_step_id[s["step_id"]] = s + # Find the step by cache_id + step = steps_by_cache_id.get(cache_id) if not step: - return HTMLResponse(f'Step {step_id} not found
') + return HTMLResponse(f'Step with cache {cache_id[:16]}... not found
') # Get step info + step_id = step.get("step_id", "") step_name = step.get("name", step_id[:20]) node_type = step.get("node_type", "EFFECT") - cache_id = step.get("cache_id", "") config = step.get("config", {}) level = step.get("level", 0) input_steps = step.get("input_steps", []) + input_hashes = step.get("input_hashes", {}) # Check for IPFS CID step_cid = None @@ -1470,69 +1475,105 @@ async def run_plan_node_detail(run_id: str, step_id: str, request: Request): has_cached = cache_manager.has_content(cache_id) if cache_id else False color = NODE_COLORS.get(node_type, NODE_COLORS["default"]) - # Build preview HTML - preview_html = "" + # Build INPUT media previews - show each input's cached content + inputs_html = "" + if input_steps: + input_items = "" + for inp_step_id in input_steps: + inp_step = steps_by_step_id.get(inp_step_id) + if inp_step: + inp_cache_id = inp_step.get("cache_id", "") + inp_name = inp_step.get("name", inp_step_id[:12]) + inp_has_cached = cache_manager.has_content(inp_cache_id) if inp_cache_id else False + + # Build preview thumbnail for input + inp_preview = "" + if inp_has_cached and inp_cache_id: + inp_media_type = detect_media_type(get_cache_path(inp_cache_id)) + if inp_media_type == "video": + inp_preview = f'' + elif inp_media_type == "image": + inp_preview = f'{config_json}
-