Skip to content

Commit c65b774

Browse files
comments
1 parent 56973f0 commit c65b774

File tree

4 files changed

+23
-29
lines changed

4 files changed

+23
-29
lines changed

dspy/adapters/types/reasoning.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,19 @@ def adapt_to_native_lm_feature(cls, lm, lm_kwargs) -> bool:
4444
if not litellm.supports_reasoning(lm.model):
4545
return False
4646

47+
reasoning_effort = "unspecified"
4748
if "reasoning_effort" in lm_kwargs:
4849
# `lm_kwargs` overrides `lm.kwargs`
4950
reasoning_effort = lm_kwargs["reasoning_effort"]
5051
elif "reasoning_effort" in lm.kwargs:
5152
reasoning_effort = lm.kwargs["reasoning_effort"]
52-
else:
53-
reasoning_effort = None
5453

5554
if reasoning_effort is None:
56-
# Turn on the native reasoning
57-
lm_kwargs["reasoning_effort"] = "low"
55+
# If users explicitly set `reasoning_effort` to None, we don't enable native reasoning
56+
return False
5857

58+
# Turn on the native reasoning
59+
lm_kwargs["reasoning_effort"] = "low"
5960
return True
6061

6162
@classmethod

dspy/clients/lm.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,6 @@ def __init__(
103103

104104
self._warn_zero_temp_rollout(self.kwargs.get("temperature"), self.kwargs.get("rollout_id"))
105105

106-
# Normalize reasoning_effort to get reasoning summaries (for OpenAI reasoning models which don't expose
107-
# reasoning content)
108-
if "reasoning_effort" in self.kwargs and (
109-
self.model_type == "responses"
110-
or ("openai/" in self.model.lower() and litellm.supports_reasoning(self.model))
111-
):
112-
effort = self.kwargs.pop("reasoning_effort")
113-
self.kwargs["reasoning"] = {"effort": effort, "summary": "auto"}
114-
115106
def _warn_zero_temp_rollout(self, temperature: float | None, rollout_id):
116107
if not self._warned_zero_temp_rollout and rollout_id is not None and (temperature is None or temperature == 0):
117108
warnings.warn(
@@ -463,4 +454,8 @@ def _convert_chat_request_to_responses_request(request: dict[str, Any]):
463454
elif isinstance(c, list):
464455
content_blocks.extend(c)
465456
request["input"] = [{"role": msg.get("role", "user"), "content": content_blocks}]
457+
# Convert reasoning_effort to reasoning format supported by the Responses API
458+
if "reasoning_effort" in request:
459+
effort = request.pop("reasoning_effort")
460+
request["reasoning"] = {"effort": effort, "summary": "auto"}
466461
return request

dspy/predict/chain_of_thought.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import logging
12
from typing import Any
23

34
import dspy
45
from dspy.primitives.module import Module
56
from dspy.signatures.field import OutputField
67
from dspy.signatures.signature import Signature, ensure_signature
78

9+
logger = logging.getLogger(__name__)
10+
811

912
class ChainOfThought(Module):
1013
def __init__(
@@ -22,6 +25,9 @@ def __init__(
2225
super().__init__()
2326
signature = ensure_signature(signature)
2427

28+
if "rationale_field" in config or "rationale_field_type" in config:
29+
logger.warning("`rationale_field` and `rationale_field_type` are deprecated, they are no-op now.")
30+
2531
from dspy.adapters.types.reasoning import Reasoning
2632

2733
extended_signature = signature.prepend(name="reasoning", field=OutputField(), type_=Reasoning)

tests/clients/test_lm.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -565,25 +565,17 @@ def test_responses_api_tool_calls(litellm_test_server):
565565
assert dspy_responses.call_args.kwargs["model"] == "openai/dspy-test-model"
566566

567567

568-
def test_reasoning_effort_normalization():
569-
"""Test that reasoning_effort gets normalized to reasoning format for OpenAI models."""
570-
with mock.patch("litellm.supports_reasoning", return_value=True):
568+
def test_reasoning_effort_responses_api():
569+
"""Test that reasoning_effort gets normalized to reasoning format for Responses API."""
570+
with mock.patch("litellm.responses") as mock_responses:
571571
# OpenAI model with Responses API - should normalize
572-
lm1 = dspy.LM(
572+
lm = dspy.LM(
573573
model="openai/gpt-5", model_type="responses", reasoning_effort="low", max_tokens=16000, temperature=1.0
574574
)
575-
assert "reasoning_effort" not in lm1.kwargs
576-
assert lm1.kwargs["reasoning"] == {"effort": "low", "summary": "auto"}
577-
578-
# OpenAI model with Chat API - should normalize
579-
lm2 = dspy.LM(model="openai/gpt-5", reasoning_effort="medium", max_tokens=16000, temperature=1.0)
580-
assert "reasoning_effort" not in lm2.kwargs
581-
assert lm2.kwargs["reasoning"] == {"effort": "medium", "summary": "auto"}
582-
583-
# Non-OpenAI model - should NOT normalize
584-
lm3 = dspy.LM(model="deepseek-ai/DeepSeek-R1", reasoning_effort="low", max_tokens=4000, temperature=0.7)
585-
assert "reasoning_effort" in lm3.kwargs
586-
assert "reasoning" not in lm3.kwargs
575+
lm("openai query")
576+
call_kwargs = mock_responses.call_args.kwargs
577+
assert "reasoning_effort" not in call_kwargs
578+
assert call_kwargs["reasoning"] == {"effort": "low", "summary": "auto"}
587579

588580

589581
def test_reasoning_content_extraction():

0 commit comments

Comments
 (0)