diff --git a/app/routers/recipes.py b/app/routers/recipes.py index 38d1eff..c5924d5 100644 --- a/app/routers/recipes.py +++ b/app/routers/recipes.py @@ -370,14 +370,43 @@ async def run_recipe( nodes = nodes_dict dag_copy["nodes"] = nodes + # Build lookup for variable inputs: map input names to node IDs + # Variable inputs can be referenced by: node_id, config.name, config.input (if string) + input_name_to_node = {} + for node_id, node in nodes.items(): + if node.get("node_type") == "SOURCE": + config = node.get("config", {}) + # Only variable inputs (those with 'input' in config, not fixed assets) + if config.get("input"): + input_name_to_node[node_id] = node_id + # Map by config.name (e.g., "Second Video") + if config.get("name"): + name = config["name"] + input_name_to_node[name] = node_id + # Also allow snake_case version + input_name_to_node[name.lower().replace(" ", "_")] = node_id + input_name_to_node[name.lower().replace(" ", "-")] = node_id + # Map by node.name if available (def binding) + if node.get("name"): + input_name_to_node[node["name"]] = node_id + input_name_to_node[node["name"].replace("-", "_")] = node_id + # Map user-provided input names to content hashes (for variable inputs) for input_name, content_hash in req.inputs.items(): + # Try direct node ID match first if input_name in nodes: node = nodes[input_name] if node.get("node_type") == "SOURCE": if "config" not in node: node["config"] = {} node["config"]["content_hash"] = content_hash + # Try input name lookup + elif input_name in input_name_to_node: + node_id = input_name_to_node[input_name] + node = nodes[node_id] + if "config" not in node: + node["config"] = {} + node["config"]["content_hash"] = content_hash # Transform output to output_id if "output" in dag_copy: