Skip to content

fix(dspy): Guard use_tip on tip value in GroundedProposer to avoid rendering None in prompt - #83

Open
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-dspy-guard-use-tip-on-tip-value-in-groundedpro-4164ef
Open

fix(dspy): Guard use_tip on tip value in GroundedProposer to avoid rendering None in prompt#83
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-dspy-guard-use-tip-on-tip-value-in-groundedpro-4164ef

Conversation

@detail-app

@detail-app detail-app Bot commented Sep 6, 2026

Copy link
Copy Markdown

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

Bug
GroundedProposer (MIPROv2's instruction proposer) accepts use_tip and set_tip_randomly flags. When set_tip_randomly=False — a configuration explicitly supported by PR stanfordnlp#3919selected_tip stays None, but the constructor default use_tip=True was left unchanged. The generation signature still declared the tip input field and tip=None was forwarded into the prompt, where DSPy's adapter rendered it as the literal string "None", producing a meaningless [[ ## tip ## ]]\nNone block the LM is told to follow. The analogous use_instruct_history flag was already guarded with and instruction_history; use_tip lacked the equivalent guard.

Fix
Guard use_tip on whether a real tip value was supplied, mirroring the existing use_instruct_history guard in dspy/propose/grounded_proposer.py:

use_tip=self.use_tip and bool(tip),

This omits the tip field from the signature when no real tip is present, so the adapter no longer renders None. Only the buggy configuration (use_tip=True with tip=None) changes; all other paths (real tip supplied, use_tip=False, set_tip_randomly=True drawing "none" or a real tip) behave identically.

Testing

  • Added regression tests in tests/propose/test_grounded_proposer.py using a RecordingDummyLM that captures the exact prompt sent to the rollout LM copy (shared by reference through BaseLM's shallow copy). They assert the tip block is omitted when tip=None — both via the direct propose_instruction_for_predictor and the end-to-end propose_instructions_for_program with set_tip_randomly=False — and that a real tip is still rendered. These tests fail without the one-line fix and pass with it.
  • Unit tests (tests/propose/), the broader optimizer suite (tests/teleprompt/), ruff check, and ruff format --check on the test file all pass. The project configures no typechecker; an ad-hoc mypy run shows no new type errors versus the original file (all pre-existing).
  • A live-LM smoke test could not be run: no LM credentials or local server are available in this environment (confirmed via LMServerError: Missing credentials and LMTransportError: Connection error on attempted setup). The prompt-content invariant the smoke would verify is instead asserted deterministically by the RecordingDummyLM regression tests.

✅ Contributor Checklist

  • Pre-Commit checks pass locally (ruff check); remote CI pending run
  • Title of your PR / MR corresponds to the required format (fix(dspy): ...)
  • Commit message follows required format fix(dspy): Guard use_tip on tip value in GroundedProposer to avoid rendering None in prompt

⚠️ Warnings

  • Authored by Detail (automatic fixes). Verified locally as described above; the live-LM round-trip was not exercisable here (no credentials/endpoint) but is covered deterministically by the prompt-capture unit tests.
  • grounded_proposer.py retains some pre-existing ruff format style nits unrelated to this change; left untouched to keep the diff minimal (CI enforces ruff check, not ruff format).

Automatic Fixes PRs can be configured here.

@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR prevents GroundedProposer from declaring a tip input field when no meaningful tip value exists, avoiding a literal None block in generated prompts.

  • Conditions signature construction on both the configured use_tip flag and the supplied tip value.
  • Preserves prompt rendering when a real tip is supplied.
  • Adds direct and end-to-end regression coverage using captured rollout prompts.

Confidence Score: 5/5

The PR appears safe to merge; the focused guard fixes the unwanted prompt field without changing valid tip behavior.

No actionable failures remain: all reachable falsey tip values represent the intended absence of a tip, non-empty tips remain rendered, and the regression tests exercise the affected direct and end-to-end paths.

Important Files Changed

Filename Overview
dspy/propose/grounded_proposer.py Correctly omits the optional tip field for None or the intentionally empty no-tip value while preserving non-empty tips.
tests/propose/test_grounded_proposer.py Adds focused prompt-capture tests covering absent tips, supplied tips, and the end-to-end non-random configuration.

Reviews (1): Last reviewed commit: "fix(dspy): Guard use_tip on tip value in..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant