diff --git a/app/routers/runs.py b/app/routers/runs.py index 1e4e219..643c691 100644 --- a/app/routers/runs.py +++ b/app/routers/runs.py @@ -27,6 +27,59 @@ from ..services.run_service import RunService router = APIRouter() logger = logging.getLogger(__name__) + +def plan_to_sexp(plan: dict, recipe_name: str = None) -> str: + """Convert a plan to S-expression format for display.""" + if not plan or not plan.get("steps"): + return ";; No plan available" + + lines = [] + lines.append(f'(plan "{recipe_name or "unknown"}"') + + # Group nodes by type for cleaner output + steps = plan.get("steps", []) + + for step in steps: + step_id = step.get("id", "?") + step_type = step.get("type", "EFFECT") + inputs = step.get("inputs", []) + config = step.get("config", {}) + + # Build the step S-expression + if step_type == "SOURCE": + if config.get("input"): + # Variable input + input_name = config.get("name", config.get("input", "input")) + lines.append(f' (source :input "{input_name}")') + elif config.get("asset"): + # Fixed asset + lines.append(f' (source {config.get("asset", step_id)})') + else: + lines.append(f' (source {step_id})') + elif step_type == "EFFECT": + effect_name = config.get("effect", step_id) + if inputs: + inp_str = " ".join(inputs) + lines.append(f' (-> {inp_str} (effect {effect_name}))') + else: + lines.append(f' (effect {effect_name})') + elif step_type == "SEQUENCE": + if inputs: + inp_str = " ".join(inputs) + lines.append(f' (sequence {inp_str})') + else: + lines.append(f' (sequence)') + else: + # Generic node + if inputs: + inp_str = " ".join(inputs) + lines.append(f' ({step_type.lower()} {inp_str})') + else: + lines.append(f' ({step_type.lower()} {step_id})') + + lines.append(')') + return "\n".join(lines) + RUNS_KEY_PREFIX = "artdag:run:" @@ -258,6 +311,9 @@ async def get_run( } }) + # Generate S-expression representation of the plan + plan_sexp = plan_to_sexp(plan, run.get("recipe_name")) + templates = get_templates(request) return render(templates, "runs/detail.html", request, run=run, @@ -266,6 +322,7 @@ async def get_run( run_inputs=run_inputs, dag_elements=dag_elements, output_media_type=output_media_type, + plan_sexp=plan_sexp, active_tab="runs", ) diff --git a/app/templates/runs/detail.html b/app/templates/runs/detail.html index cd9c32f..b2eb06a 100644 --- a/app/templates/runs/detail.html +++ b/app/templates/runs/detail.html @@ -156,15 +156,41 @@ {% endfor %} - -
+ +
- Show Plan JSON + Plan (S-expression)
-
{{ plan | tojson(indent=2) }}
+
{{ plan_sexp }}
+ + + {% else %}

No plan available for this run.

{% endif %}