github stanfordnlp/dspy 3.2.0

6 hours ago

Highlights

BetterTogether Allows Chaining Optimizers — @dilarasoylu

BetterTogether now accepts arbitrary optimizers as keyword arguments and chains them via strategy strings. For example, BetterTogether(metric=m, p=GEPA(...), w=BootstrapFinetune(...)) with strategy="p -> w -> p" will prompt-optimize, fine-tune, then prompt-optimize again -- evaluating each step on a valset and returning the best program. (#9149)

There are many promising strategies that may come from running multiple GEPA steps in sequence, or combining prompt and weight optimization steps in sequence, and we are excited to see what the community comes up with.

Beginning of decoupling DSPy from LiteLLM — @MaximeRivest

@MaximeRivest has an ongoing effort to decouple DSPy from LiteLLM, making it much easier to use custom LMs with DSPy. In this release, adapters no longer import litellm at all -- BaseLM now exposes capability properties (supports_function_calling, supports_reasoning, supports_response_schema, supported_params) and a new dspy.ContextWindowExceededError replaces the litellm error throughout. Custom BaseLM backends can now integrate with DSPy's retry/truncation logic without any litellm dependency. (#9516, #9521, #9522)

Warning on Input field type mismatch — @michaelisaac-dev

Passing a value that doesn't match a signature's declared type now logs a warning (using typeguard). Extra fields not in the signature also warn. Disable with dspy.configure(warn_on_type_mismatch=False). (#9313)

Hardened RLM and PythonInterpreter — @isaacbmiller

Tool calls now use kwargs-only dispatch, the JS tool bridge returns structured errors instead of throwing (preventing Deno crashes), and stdout parsing skips non-JSON lines instead of crashing. Subprocess restarts now correctly replay tool/mount registration. (#9341, #9351)

Notices

Restricted pickle for disk cache

We have added an opt-in dspy.configure_cache(restrict_pickle=True) that swaps pickle.load with a restricted unpickler that only allows litellm/openai types, numpy reconstruction helpers, and user-registered safe_types. Prevents arbitrary code execution from corrupted or malicious cache files. (#9629)

In a future release, we will make this restriction the default behavior.

optuna is now optional

Moved from a required dependency to pip install dspy[optuna]. Saves ~12.7 MB. Only MIPROv2 and BootstrapFewShotWithOptuna use it. (#9397)


All Changes

Features

Bug Fixes

  • fix(adapters): skip JSON schema for DSPy custom types in prompt by @darinkishore (#9257)
  • fix: ColBERTv2RetrieverLocal forward method variable scoping bug by @veeceey (#9272)
  • fix(predict): remove code corruption in ProgramOfThought._parse_code by @adityasingh2400 (#9276)
  • fix(RLM): show head and tail for RLM outputs by @isaacbmiller (#9282)
  • fix(rlm): change repl_variable preview to 1000 chars by @isaacbmiller (#9296)
  • fix(dspy): SemanticF1 and CompleteAndGrounded now return dspy.Prediction by @Copilot (#9302)
  • refactor(rlm): enhance code fence parsing and REPL entry formatting by @isaacbmiller (#9309)
  • Fix false rollout_id warning when LM temperature is unset by @okhat (#9316)
  • fix: pass metric_threshold to BootstrapFewShot for unshuffled case by @kvr06-ai (#9317)
  • fix: only suggest reducing valset in GEPA when it is large by @bledden (#9320)
  • fix: make DummyLM delegate to forward() instead of overriding call by @bledden (#9322)
  • fix: run evaluation on main thread when num_threads=1 by @zamal-db (#9328)
  • fix(saving): block unsafe LM loading keys by @isaacbmiller (#9334)
  • fix(settings): add allow_pickle flag to settings loading by @isaacbmiller (#9339)
  • fix(interpreter): Harden JSONRPC communication and tool bridge by @isaacbmiller (#9341)
  • fix(interpreter): reset tools/mounts when Deno subprocess restarts by @isaacbmiller (#9351)
  • fix(adapters): pass use_native_function_calling in JSONAdapter.acall by @isaacbmiller (#9374)
  • fix(adapters): raise AdapterParseError on empty LM response instead of silent None by @isaacbmiller (#9389)
  • Deprecation warning for prefix, format, and parser kwargs in InputField/OutputField by @MaximeRivest (#9394)
  • fix(signature): reject duplicate input and output field names by @MaximeRivest (#9432)
  • fix(adapter): guard annotation subclass checks for ReAct tool args by @isaacbmiller (#9433)
  • fix(JSONAdapter): Ensure JSON serialization handles diacritics correctly for Pydantic BaseModel by @matrn (#9493)
  • Restrict litellm version to <=1.82.6 by @isaacbmiller (#9498)
  • fix(deps): pin typeguard==4.4.3 to prevent supply chain attacks by @isaacbmiller (#9551)
  • fix(lm): preserve per-message structure in Responses API conversion by @lawrence3699 (#9580)
  • fix: cloudpickle serialization of Signature on Python 3.14 by @isaacbmiller (#9616)
  • fix: correct demo index assignment in MIPROv2 raw_chosen_params by @Ricardo-M-L (#9627)
  • Fix cache bugs: os.fspath(None) crash, double disk lookups, lazy logging by @isaacbmiller (#9628)
  • Add restrict_pickle option for safe disk cache deserialization by @isaacbmiller (#9629)
  • Revert "fix: set LITELLM_LOCAL_MODEL_COST_MAP before litellm import to avoid HTTP fetch" by @isaacbmiller (#9637)
  • fix(base_lm): guard response.usage access to handle missing usage field by @isaacbmiller (#9638)

Refactors

  • Refactor: Make DummyLM and callbacks depend on BaseLM instead of LM by @MaximeRivest (#9515)
  • Refactor: Move model capability checks to BaseLM to remove litellm from adapters by @MaximeRivest (#9516)
  • Refactor: Introduce DSPy-owned ContextWindowExceededError to decouple error handling by @MaximeRivest (#9521)
  • refactor: type-hint adapters with BaseLM instead of LM by @MaximeRivest (#9522)

Security

Testing

Docs

CI / Infrastructure

Dependency updates (Dependabot)

  • orjson 3.11.2 -> 3.11.8 (#9597)
  • requests 2.32.4 -> 2.33.1 (#9603)
  • anthropic 0.54.0 -> 0.89.0 (#9599)
  • tqdm 4.67.1 -> 4.67.3 (#9623)
  • pre-commit 4.2.0 -> 4.5.1 (#9622)
  • denoland/setup-deno 2.0.3 -> 2.0.4 (#9596)
  • actions/checkout 3.6.0 -> 6.0.2 (#9595)
  • actions/setup-node 3.9.1 -> 6.3.0 (#9600)
  • stefanzweifel/git-auto-commit-action 5.2.0 -> 7.1.0 (#9598)
  • pypa/gh-action-pypi-publish 1.13.0 -> 1.14.0 (#9618)
  • mkdocs-jupyter 0.25.1 -> 0.26.1 (#9605)
  • mkdocstrings 0.29.0 -> 1.0.3 (#9609)
  • mkdocs-material 9.6.9 -> 9.7.6 (#9608)
  • mkdocs-redirects 1.2.2 -> 1.2.3 (#9607)
  • mistune 3.0.2 -> 3.2.0 (#9625)

New Contributors

Full Changelog: 3.1.3...3.2.0

Don't miss a new dspy release

NewReleases is sending notifications on new releases.