|
1 | | -from unittest.mock import Mock |
| 1 | +from unittest.mock import Mock, patch |
2 | 2 |
|
3 | 3 | import dspy |
4 | | -from dspy.teleprompt.utils import eval_candidate_program |
| 4 | +from dspy.teleprompt.utils import create_n_fewshot_demo_sets, eval_candidate_program |
| 5 | +from dspy.utils.dummies import DummyLM |
5 | 6 |
|
6 | 7 |
|
7 | 8 | class DummyModule(dspy.Module): |
@@ -50,3 +51,47 @@ def test_eval_candidate_program_failure(): |
50 | 51 | result = eval_candidate_program(batch_size, trainset, candidate_program, evaluate) |
51 | 52 |
|
52 | 53 | assert result.score == 0.0 |
| 54 | + |
| 55 | + |
| 56 | +def test_create_n_fewshot_demo_sets_passes_metric_threshold_for_unshuffled(): |
| 57 | + """Verify that metric_threshold is passed to BootstrapFewShot for the unshuffled (seed=-1) case. |
| 58 | +
|
| 59 | + Regression test for https://github.com/stanfordnlp/dspy/issues/9308 |
| 60 | + """ |
| 61 | + student = DummyModule() |
| 62 | + student.predictor = dspy.Predict("input -> output") |
| 63 | + trainset = [dspy.Example(input="test", output="test").with_inputs("input")] |
| 64 | + |
| 65 | + lm = DummyLM([{"output": "test"}]) |
| 66 | + dspy.configure(lm=lm) |
| 67 | + |
| 68 | + with patch("dspy.teleprompt.utils.BootstrapFewShot") as MockBootstrap: |
| 69 | + mock_instance = Mock() |
| 70 | + mock_instance.compile.return_value = student |
| 71 | + MockBootstrap.return_value = mock_instance |
| 72 | + |
| 73 | + create_n_fewshot_demo_sets( |
| 74 | + student=student, |
| 75 | + num_candidate_sets=4, # -3, -2, -1, 0 → hits seed=-1 |
| 76 | + trainset=trainset, |
| 77 | + max_labeled_demos=1, |
| 78 | + max_bootstrapped_demos=1, |
| 79 | + metric=lambda ex, pred, trace=None: 1.0, |
| 80 | + teacher_settings={}, |
| 81 | + metric_threshold=0.9, |
| 82 | + ) |
| 83 | + |
| 84 | + # Find the call where seed == -1 (unshuffled few-shot) |
| 85 | + # BootstrapFewShot should be called at least twice: once for seed=-1, once for seed>=0 |
| 86 | + calls = MockBootstrap.call_args_list |
| 87 | + assert len(calls) >= 1, "BootstrapFewShot was never called" |
| 88 | + |
| 89 | + # Every BootstrapFewShot call should include metric_threshold |
| 90 | + for call in calls: |
| 91 | + _, kwargs = call |
| 92 | + assert "metric_threshold" in kwargs, ( |
| 93 | + f"metric_threshold missing from BootstrapFewShot call: {kwargs}" |
| 94 | + ) |
| 95 | + assert kwargs["metric_threshold"] == 0.9, ( |
| 96 | + f"metric_threshold={kwargs['metric_threshold']}, expected 0.9" |
| 97 | + ) |
0 commit comments