From 965e070c6b18547fc16e401a8b40299ce0a967fd Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Fri, 16 Oct 2026 16:13:13 +0200 Subject: [PATCH 1/2] Use `fuzzy_row_match` for updating metadata The campaign did use `rec.index` for updating the metadata. This can cause issues for recommenders that might not preserve the original index order. --- baybe/campaign.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/baybe/campaign.py b/baybe/campaign.py index 3aa1d48273..fddec6ad97 100644 --- a/baybe/campaign.py +++ b/baybe/campaign.py @@ -637,7 +637,10 @@ def recommend( # Update metadata if self.searchspace.type in (SearchSpaceType.DISCRETE, SearchSpaceType.HYBRID): - self._searchspace_metadata.loc[rec.index, _RECOMMENDED] = True + idxs_matched = fuzzy_row_match( + self.searchspace.discrete.exp_rep, rec, self.parameters + ) + self._searchspace_metadata.loc[idxs_matched, _RECOMMENDED] = True return rec From 1c35984b185e3cf2d830d328af7d79811e5cbf79 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Fri, 16 Oct 2026 16:28:36 +0200 Subject: [PATCH 2/2] Add test for fuzzy matching --- tests/test_campaign.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/test_campaign.py b/tests/test_campaign.py index c2e9cdf9e0..c54f3d6f3f 100644 --- a/tests/test_campaign.py +++ b/tests/test_campaign.py @@ -11,7 +11,7 @@ from pytest import param from baybe.acquisition import qLogEI, qLogNEHVI, qTS, qUCB -from baybe.campaign import _EXCLUDED, Campaign +from baybe.campaign import _EXCLUDED, _RECOMMENDED, Campaign from baybe.constraints.conditions import SubSelectionCondition from baybe.constraints.discrete import DiscreteSelectionConstraint from baybe.exceptions import IncompatibilityError, NotEnoughPointsLeftError @@ -450,3 +450,30 @@ def test_cache_invalidation( assert campaign._cached_recommendation is None else: assert campaign._cached_recommendation is not None + + +def test_recommended_metadata_uses_content_not_index(): + """Metadata marks the correct rows even when the recommender resets the index.""" + params = [ + NumericalDiscreteParameter("x", [1, 2, 3]), + NumericalDiscreteParameter("y", [10, 20]), + ] + searchspace = SearchSpace.from_product(params) + objective = NumericalTarget("t").to_objective() + campaign = Campaign(searchspace, objective) + + # Choose the original indices of the rows we want to recommend + original_idx = [2, 4] + rec_content = searchspace.discrete.exp_rep.iloc[original_idx].reset_index(drop=True) + + mock_recommender = Mock(spec=RecommenderProtocol) + mock_recommender.recommend.return_value = rec_content + campaign.recommender = mock_recommender + + rec = campaign.recommend(2) + + # Verify that rec does not have the original indices but has a reset index + assert rec.index.tolist() == [0, 1] + + recommended = campaign._searchspace_metadata[_RECOMMENDED] + assert list(recommended[recommended].index) == original_idx