3.3.1
Breaking Changes📦 dspyView on GitHub →
⚠ 1 breaking✨ 16 features🐛 12 fixes⚡ 1 deprecations🔧 10 symbols
Summary
DSPy 3.3.1 introduces significant improvements to `PythonInterpreter`, including managed runtime installation, enhanced isolation, and lifecycle visibility. The release also boosts optimizer throughput with GEPA 0.1.4, enhances adapter reliability, and ensures MCP SDK v2 compatibility.
⚠️ Breaking Changes
- The `max_reflection_cost` parameter for the DSPy GEPA adapter is no longer silently ignored when set. It will now raise a clear error if used, as it is not yet supported. Users should remove this parameter or ensure it is not set.
Migration Steps
- To use the managed runtime for `PythonInterpreter`, install with `pip install "dspy[deno]"`.
- When using GEPA, remove the `max_reflection_cost` parameter if it is set, as it is not supported and will now raise an error.
- For new code, use `dspy.RLM` instead of `dspy.CodeAct` or `dspy.ProgramOfThought`.
- To opt into machine-readable MCP results, set `result_mode="structured"` when creating a `dspy.Tool` from an MCP tool.
✨ New Features
- Optional managed runtime installation for `PythonInterpreter` with `pip install "dspy[deno]"`.
- Enhanced sandbox isolation and request handling in `PythonInterpreter`, including protection against unsolicited diagnostics, rejection of recursive tool execution, protection of bundled runtime files, revocation of Deno-cache access after startup, prevention of silent basename collisions for mounted files, and protection against guest code mutation of JavaScript globals/prototypes.
- Complete interpreter lifecycle visibility through DSPy's callback API, including interpreter execution start/end, sandbox-to-host tool-call start/end, and interpreter process startup/shutdown.
- Optimizer `compile()` runs now have start/end coverage in the callback API.
- `PythonInterpreter.execution_instructions` provides RLM with an accurate description of the Pyodide environment, including state persistence and unavailable native process capabilities.
- Tool defaults and `NoneType` annotations serialize correctly across the sandbox boundary.
- LM-facing execution errors use a consistent formatter across interpreter and agent modules.
- Support for GEPA 0.1.4 with multi-proposal sampling, selection, acceptance, and tracking.
- DSPy's adapter saves and restores RNG state for consistent resumed proposal sampling.
- Concurrent evaluation of multiple candidates when a sampling strategy produces them, sharing the `num_threads` budget.
- GEPA can now use objective-aware frontiers (quality, privacy, cost) when selecting parents and merges, in addition to the scalar metric.
- Tracked results in GEPA expose aggregate objective scores, best candidates per objective, and each objective's independently achieved maximum.
- Structured adapter outputs now apply declared fallbacks when an LM omits an output field with a default, default factory, or `None`-allowing annotation.
- XMLAdapter now formats and parses nested Pydantic models, typed dictionaries, lists, mappings, nullable fields, and unions as nested XML.
- DSPy's MCP bridge supports both MCP SDK v1 and v2 field names, v1 `ClientSession`, and the v2 high-level `Client`.
- Applications can opt into machine-readable MCP results using `result_mode="structured"`.
🐛 Bug Fixes
- Unsolicited sandbox diagnostics can no longer desynchronize JSON-RPC replies in `PythonInterpreter`.
- Request IDs are unpredictable, and recursive execution through one of an interpreter's own host tools is rejected.
- Bundled runtime files are protected and Deno-cache access is revoked after startup.
- Mounted files with distinct host paths cannot silently collide at the same sandbox basename.
- Guest code cannot change host-tool identity by mutating JavaScript globals or prototypes.
- End callbacks now receive terminating `BaseException` values (e.g., cancellation, interruption) instead of incorrectly reporting operations as successful.
- `CodeInterpreterError` is now a `DSPyError` while retaining `RuntimeError` compatibility.
- The default single-proposal GEPA strategy retains its previous execution shape.
- Missing required outputs in adapters continue to raise `AdapterParseError`.
- Adapter fallback is no longer triggered merely because a provider omitted a native optional output.
- XMLAdapter continues to accept the previous JSON-inside-an-outer-XML-field representation for backward compatibility.
- The default tool-result semantics for MCP are unchanged; historical text and non-text content remains authoritative.
Affected Symbols
⚡ Deprecations
- `dspy.CodeAct` and `dspy.ProgramOfThought` are deprecated and will be removed in DSPy 3.5. Use `dspy.RLM` for new code.