diff --git a/src/buildcompiler/stages/assembly_lvl2.py b/src/buildcompiler/stages/assembly_lvl2.py index 3ea312a..31d6eb6 100644 --- a/src/buildcompiler/stages/assembly_lvl2.py +++ b/src/buildcompiler/stages/assembly_lvl2.py @@ -74,6 +74,22 @@ def run( region_identities=region_identities, constraints=constraints, ) + warning_logs: list[str] = [] + if route_selection.selected is None and constraints.get("region_order"): + relaxed_constraints = { + key: value for key, value in constraints.items() if key != "region_order" + } + relaxed_selection = self.selector.select_lvl2_route( + request_id=request.id, + region_identities=region_identities, + constraints=relaxed_constraints, + ) + if relaxed_selection.selected is not None: + route_selection = relaxed_selection + warning_logs.append( + "Unable to satisfy region_order constraint; proceeding with an arbitrary compatible order." + ) + route = route_selection.selected artifacts = self._route_artifacts(route, route_selection.rejected) if route is None: @@ -85,7 +101,8 @@ def run( protocol_artifacts=artifacts, logs=[ "No lvl2 route selected by CompatibilitySelector. Provide explicit region_order " - "or enable large-order search for large designs." + "or enable large-order search for large designs.", + *warning_logs, ], ) @@ -157,7 +174,8 @@ def run( missing_inputs=missing_inputs, protocol_artifacts=artifacts, logs=[ - f"Blocked lvl2 assembly for {request.id}; missing {len(missing_inputs)} required input(s)." + *warning_logs, + f"Blocked lvl2 assembly for {request.id}; missing {len(missing_inputs)} required input(s).", ], ) @@ -208,6 +226,7 @@ def run( json_intermediate=json_intermediate, protocol_artifacts=artifacts, logs=[ + *warning_logs, f"Selected lvl2 route with {len(route.selected_lvl1_plasmids)} lvl1 plasmid(s).", *assembly_result.logs, ], diff --git a/tests/unit/stages/test_assembly_lvl2.py b/tests/unit/stages/test_assembly_lvl2.py index bfaeab3..17466c7 100644 --- a/tests/unit/stages/test_assembly_lvl2.py +++ b/tests/unit/stages/test_assembly_lvl2.py @@ -191,7 +191,7 @@ def test_assembly_lvl2_region_order_constraint_is_hard(): assert result.protocol_artifacts["selected_route"]["region_order"] == order -def test_assembly_lvl2_incomplete_region_order_blocks(): +def test_assembly_lvl2_incomplete_region_order_falls_back_with_warning(): doc, module, regions = _module_doc() inv = _inventory(regions) stage = AssemblyLvl2Stage(inventory=inv, assembly_service=_FakeAssemblyService([])) @@ -203,5 +203,6 @@ def test_assembly_lvl2_incomplete_region_order_blocks(): target_document=sbol2.Document(), ) - assert result.status == StageStatus.BLOCKED - assert result.protocol_artifacts["selected_route"] is None + assert result.status == StageStatus.SUCCESS + assert result.protocol_artifacts["selected_route"] is not None + assert any("Unable to satisfy region_order constraint" in log for log in result.logs)