fix(dspy): Normalize COMPLETE sentinel detection in dataset summary loop - #86
Conversation
Greptile SummaryThis PR normalizes quoted COMPLETE responses in the dataset-summary loop and adds regression coverage for sentinel handling.
Confidence Score: 4/5The PR should not merge until legitimate observations beginning with the standalone word “Complete” are distinguished from the sentinel. The revised detector accepts every non-letter after COMPLETE as a sentinel boundary, causing realistic free-form observations such as “Complete analysis…” to be dropped and potentially triggering premature early termination. Files Needing Attention: dspy/propose/dataset_summary_generator.py, tests/propose/test_dataset_summary_generator.py Important Files Changed
Reviews (1): Last reviewed commit: "fix(dspy): Normalize COMPLETE sentinel d..." | Re-trigger Greptile |
| output = dspy.Predict(DatasetDescriptorWithPriorObservations, n=1, temperature=1.0)(prior_observations=observations, examples=order_input_keys_in_string(trainset[b:upper_lim].__repr__())) | ||
| if len(output["observations"]) >= 8 and output["observations"][:8].upper() == "COMPLETE": | ||
| obs = output["observations"].strip().strip("\"'").strip() | ||
| if obs.upper().startswith("COMPLETE") and (len(obs) == 8 or not obs[8].isalpha()): |
There was a problem hiding this comment.
A legitimate observation such as Complete analysis of the samples starts with COMPLETE and has a non-alphabetic ninth character, so this condition treats it as the sentinel. The observation is discarded and increments skips; repeated matches can stop dataset inspection early, producing an incomplete dataset summary. The detector should accept only COMPLETE or an explicitly supported punctuation-only form, rather than every non-letter suffix.
Warning
GitHub issue creation failed
Detail attempted to publish this bug to GitHub, but the issue could not be created. This fix PR was created without that issue, and missing tracker references are shown as
Unknown issue.You can review and merge this PR normally. Please review your tracker integration settings before the next publish run.
Detail bug report: View on Detail
📝 Changes Description
Closes Unknown issue
dspy/propose/dataset_summary_generator.py,create_dataset_summarydetects a "COMPLETE" early-stop signal with a brittle 8-character prefix check,output["observations"][:8].upper() == "COMPLETE". It mis-detects in both directions:DatasetDescriptorWithPriorObservationsprompt asks the model tosay 'COMPLETE'(single-quoted). When the model echoes that quoted form, the parsed value is'COMPLETE'; its first 8 chars ('COMPLET) don't match, so the sentinel is missed, the quoted token is appended verbatim to the observations, and theskips >= 5early-stop never fires (wasting LM calls). The corrupted observations are then fed toObservationSummarizerand onward toGroundedProposer'sdataset_description."Completely analyzed the data","Completed the review...") is silently dropped as if it were the sentinel.COMPLETEcloses the false positive (so"Completely..."is preserved whileCOMPLETE,'COMPLETE',"COMPLETE", andCOMPLETE.are still treated as the sentinel).tests/propose/test_dataset_summary_generator.py(7 cases) exercising the real detector line through DSPy'sChatAdapterparse path withDummyLM. Sentinels (COMPLETE,'COMPLETE',"COMPLETE",COMPLETE.) are skipped rather than appended to the observations passed toObservationSummarizer; real observations starting with "Complete" ("Completely analyzed the data","Completed the review of all samples") are preserved; repeated quoted'COMPLETE'triggers theskips >= 5early-stop (asserted via LM call count) instead of leaking quoted tokens into the summary input.COMPLETE,COMPLETE.) are intentional no-regression guards for the bare/punctuated forms the old code already handled. Fix restored after.GroundedProposerwith a non-empty trainset anduse_dataset_summary=Trueagainst a localollama/llama3.2:3bmodel — the produceddata_summarycontained no strayCOMPLETEtokens and instruction proposal succeeded.tests/propose/test_grounded_proposer.py, thetests/teleprompt/regression suite, the full default test suite (-m 'not extra and not deno'), theextra/denosuites, thellm_callsuite, andruff check/ruff format. No regressions.tests/clients/test_lm_direct_live.pywere skipped (not failed) becauseOPENAI_API_KEY/ANTHROPIC_API_KEY/GEMINI_API_KEYwere not set in the environment.✅ Contributor Checklist
This change was produced with assistance from Detail (an AI coding agent). The bug was reproduced against DSPy's real
ChatAdapterparse path before patching, and the fix was validated end-to-end against a local Ollama model; every line submitted was understood and tested. Submitting this PR myself per the repo's guidance — please review.Automatic Fixes PRs can be configured here.