Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/buildcompiler/stages/assembly_lvl2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle empty region_order in fallback check

The new fallback only runs when constraints.get("region_order") is truthy, so a provided but empty region_order ([]) skips the relaxed retry and still returns BLOCKED even when a compatible route exists without ordering constraints. Since this commit’s behavior change is to recover from unsatisfiable region_order values, the empty-list case is an unsatisfied constraint that should also trigger the fallback path and warning.

Useful? React with 👍 / 👎.

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:
Expand All @@ -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,
],
)

Expand Down Expand Up @@ -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).",
],
)

Expand Down Expand Up @@ -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,
],
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/stages/test_assembly_lvl2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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([]))
Expand All @@ -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)
Loading