Skip to content

Commit cbb6930

Browse files
committed
Squashed commit of the following:
commit 056d54e Author: Isaac Miller <17116851+isaacbmiller@users.noreply.github.com> Date: Wed Oct 29 17:23:09 2025 +0100 fix(MIPROv2): zero shot not taking .compile parameters into account before determining if the program was zero shot (stanfordnlp#8909) * fix(MIPROv2): zero shot not taking .compile parameters into account before determining if the program was zero shot * remove extra logs * Remove log * Fix merge conflict * Remove extra whitespace commit da69f9d Author: TomuHirata <tomu.hirata@gmail.com> Date: Wed Oct 29 13:23:34 2025 +0900 Update anthropic model name (stanfordnlp#8992) Signed-off-by: TomuHirata <tomu.hirata@gmail.com> commit aaadf05 Author: Chen Qian <chen.qian@databricks.com> Date: Tue Oct 28 12:21:55 2025 -0700 lints (stanfordnlp#8987) commit e842ba1 Author: eramis73 <130156545+eramis73@users.noreply.github.com> Date: Tue Oct 28 02:40:34 2025 +0300 [docs] Add Google-style docstrings for dspy/evaluate/metrics.py (stanfordnlp#8954) * docs(metrics): add Google-style docstrings for public metrics * docs(metrics): address review feedback (concise openings, mkdocs block examples); revert non-doc changes * fixes --------- Co-authored-by: chenmoneygithub <chen.qian@databricks.com> commit 6c43880 Author: TomuHirata <tomu.hirata@gmail.com> Date: Tue Oct 28 07:21:06 2025 +0900 Cache Ollama to speed up CI (stanfordnlp#8972) * Cache Ollama to speed up CI * fix permission commit 462baef Author: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon Oct 27 11:57:27 2025 -0700 Fix TypeError when tracking usage with Anthropic models returning Pydantic objects (stanfordnlp#8978) * Initial plan * Fix TypeError when merging Anthropic CacheCreation objects in usage tracker Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com> * Enhance _flatten_usage_entry to convert Pydantic models on first add Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com> * Fix potential TypeError when both usage entries are None Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com> * simplify * small fix * lint * robust version handling --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com> Co-authored-by: chenmoneygithub <chen.qian@databricks.com> commit 9b467b5 Author: Noah Ziems <nziems2@nd.edu> Date: Mon Oct 27 13:32:07 2025 -0400 Add Disable Fallback Option in ChatAdapter (stanfordnlp#8984) commit bf022c7 Author: Lakshya A Agrawal <lakshyaaagrawal@berkeley.edu> Date: Sat Oct 25 23:37:42 2025 +0530 Update gepa[dspy] dependency version to 0.0.18 (stanfordnlp#8969) * Update gepa[dspy] dependency version to 0.0.18 * Update pyproject.toml * fix test --------- Co-authored-by: TomuHirata <tomu.hirata@gmail.com>
1 parent c78c655 commit cbb6930

File tree

18 files changed

+544
-113
lines changed

18 files changed

+544
-113
lines changed

.github/workflows/run_tests.yml

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,6 @@ jobs:
9191
llm_call_test:
9292
name: Run Tests with Real LM
9393
runs-on: ubuntu-latest
94-
services:
95-
ollama:
96-
image: ollama/ollama:latest
97-
ports:
98-
- 11434:11434
9994
steps:
10095
- uses: actions/checkout@v4
10196
- uses: actions/setup-python@v5
@@ -116,15 +111,33 @@ jobs:
116111
run: |
117112
uv sync --dev -p .venv --extra dev
118113
uv pip list
119-
- name: Pull LLM
114+
- name: Cache Ollama models
115+
id: cache-ollama
116+
uses: actions/cache@v4
117+
with:
118+
path: ollama-data
119+
key: ollama-llama3.2-3b-${{ runner.os }}-v1
120+
- name: Start Ollama service
120121
run: |
122+
mkdir -p ollama-data
123+
docker run -d --name ollama \
124+
-p 11434:11434 \
125+
-v ${{ github.workspace }}/ollama-data:/root/.ollama \
126+
ollama/ollama:latest
121127
timeout 60 bash -c 'until curl -f http://localhost:11434/api/version; do sleep 2; done'
122-
curl -X POST http://localhost:11434/api/pull \
123-
-H "Content-Type: application/json" \
124-
-d '{"name": "llama3.2:3b"}'
125-
echo "LM_FOR_TEST=ollama/llama3.2:3b" >> $GITHUB_ENV
128+
- name: Pull LLM
129+
if: steps.cache-ollama.outputs.cache-hit != 'true'
130+
run: docker exec ollama ollama pull llama3.2:3b
131+
- name: Set LM environment variable
132+
run: echo "LM_FOR_TEST=ollama/llama3.2:3b" >> $GITHUB_ENV
126133
- name: Run tests
127134
run: uv run -p .venv pytest -m llm_call --llm_call -vv --durations=5 tests/
135+
- name: Fix permissions for cache
136+
if: always()
137+
run: sudo chown -R $USER:$USER ollama-data || true
138+
- name: Stop Ollama service
139+
if: always()
140+
run: docker stop ollama && docker rm ollama
128141

129142
build_package:
130143
name: Build Package

docs/docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Instead of wrangling prompts or training jobs, DSPy (Declarative Self-improving
4040

4141
```python linenums="1"
4242
import dspy
43-
lm = dspy.LM("anthropic/claude-3-opus-20240229", api_key="YOUR_ANTHROPIC_API_KEY")
43+
lm = dspy.LM("anthropic/claude-sonnet-4-5-20250929", api_key="YOUR_ANTHROPIC_API_KEY")
4444
dspy.configure(lm=lm)
4545
```
4646

docs/docs/learn/programming/language_models.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dspy.configure(lm=lm)
3737

3838
```python linenums="1"
3939
import dspy
40-
lm = dspy.LM('anthropic/claude-3-opus-20240229', api_key='YOUR_ANTHROPIC_API_KEY')
40+
lm = dspy.LM('anthropic/claude-sonnet-4-5-20250929', api_key='YOUR_ANTHROPIC_API_KEY')
4141
dspy.configure(lm=lm)
4242
```
4343

docs/docs/tutorials/cache/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import os
6060

6161
os.environ["ANTHROPIC_API_KEY"] = "{your_anthropic_key}"
6262
lm = dspy.LM(
63-
"anthropic/claude-3-5-sonnet-20240620",
63+
"anthropic/claude-sonnet-4-5-20250929",
6464
cache_control_injection_points=[
6565
{
6666
"location": "message",

dspy/adapters/chat_adapter.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ class FieldInfoWithName(NamedTuple):
2626

2727

2828
class ChatAdapter(Adapter):
29+
def __init__(
30+
self,
31+
callbacks=None,
32+
use_native_function_calling: bool = False,
33+
native_response_types=None,
34+
use_json_adapter_fallback: bool = True,
35+
):
36+
super().__init__(
37+
callbacks=callbacks,
38+
use_native_function_calling=use_native_function_calling,
39+
native_response_types=native_response_types,
40+
)
41+
self.use_json_adapter_fallback = use_json_adapter_fallback
42+
2943
def __call__(
3044
self,
3145
lm: LM,
@@ -40,9 +54,13 @@ def __call__(
4054
# fallback to JSONAdapter
4155
from dspy.adapters.json_adapter import JSONAdapter
4256

43-
if isinstance(e, ContextWindowExceededError) or isinstance(self, JSONAdapter):
44-
# On context window exceeded error or already using JSONAdapter, we don't want to retry with a different
45-
# adapter.
57+
if (
58+
isinstance(e, ContextWindowExceededError)
59+
or isinstance(self, JSONAdapter)
60+
or not self.use_json_adapter_fallback
61+
):
62+
# On context window exceeded error, already using JSONAdapter, or use_json_adapter_fallback is False
63+
# we don't want to retry with a different adapter. Raise the original error instead of the fallback error.
4664
raise e
4765
return JSONAdapter()(lm, lm_kwargs, signature, demos, inputs)
4866

@@ -60,9 +78,13 @@ async def acall(
6078
# fallback to JSONAdapter
6179
from dspy.adapters.json_adapter import JSONAdapter
6280

63-
if isinstance(e, ContextWindowExceededError) or isinstance(self, JSONAdapter):
64-
# On context window exceeded error or already using JSONAdapter, we don't want to retry with a different
65-
# adapter.
81+
if (
82+
isinstance(e, ContextWindowExceededError)
83+
or isinstance(self, JSONAdapter)
84+
or not self.use_json_adapter_fallback
85+
):
86+
# On context window exceeded error, already using JSONAdapter, or use_json_adapter_fallback is False
87+
# we don't want to retry with a different adapter. Raise the original error instead of the fallback error.
6688
raise e
6789
return await JSONAdapter().acall(lm, lm_kwargs, signature, demos, inputs)
6890

dspy/adapters/types/base_type.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def parse_stream_chunk(cls, chunk: ModelResponseStream) -> Optional["Type"]:
8888
"""
8989
return None
9090

91-
9291
@classmethod
9392
def parse_lm_response(cls, response: str | dict[str, Any]) -> Optional["Type"]:
9493
"""Parse a LM response into the custom type.
@@ -101,6 +100,7 @@ def parse_lm_response(cls, response: str | dict[str, Any]) -> Optional["Type"]:
101100
"""
102101
return None
103102

103+
104104
def split_message_content_for_custom_types(messages: list[dict[str, Any]]) -> list[dict[str, Any]]:
105105
"""Split user message content into a list of content blocks.
106106

dspy/adapters/types/citation.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class AnswerWithSources(Signature):
5454

5555
class Citation(Type):
5656
"""Individual citation with character location information."""
57+
5758
type: str = "char_location"
5859
cited_text: str
5960
document_index: int
@@ -73,7 +74,7 @@ def format(self) -> dict[str, Any]:
7374
"cited_text": self.cited_text,
7475
"document_index": self.document_index,
7576
"start_char_index": self.start_char_index,
76-
"end_char_index": self.end_char_index
77+
"end_char_index": self.end_char_index,
7778
}
7879

7980
if self.document_title:
@@ -134,9 +135,7 @@ def validate_input(cls, data: Any):
134135
return data
135136

136137
# Handle case where data is a list of dicts with citation info
137-
if isinstance(data, list) and all(
138-
isinstance(item, dict) and "cited_text" in item for item in data
139-
):
138+
if isinstance(data, list) and all(isinstance(item, dict) and "cited_text" in item for item in data):
140139
return {"citations": [cls.Citation(**item) for item in data]}
141140

142141
# Handle case where data is a dict
@@ -147,8 +146,7 @@ def validate_input(cls, data: Any):
147146
if isinstance(citations_data, list):
148147
return {
149148
"citations": [
150-
cls.Citation(**item) if isinstance(item, dict) else item
151-
for item in citations_data
149+
cls.Citation(**item) if isinstance(item, dict) else item for item in citations_data
152150
]
153151
}
154152
elif "cited_text" in data:
@@ -197,7 +195,6 @@ def parse_stream_chunk(cls, chunk) -> Optional["Citations"]:
197195
pass
198196
return None
199197

200-
201198
@classmethod
202199
def parse_lm_response(cls, response: str | dict[str, Any]) -> Optional["Citations"]:
203200
"""Parse a LM response into Citations.

dspy/clients/lm.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def __init__(
8888
model_pattern = re.match(r"^(?:o[1345]|gpt-5)(?:-(?:mini|nano))?", model_family)
8989

9090
if model_pattern:
91-
9291
if (temperature and temperature != 1.0) or (max_tokens and max_tokens < 16000):
9392
raise ValueError(
9493
"OpenAI's reasoning models require passing temperature=1.0 or None and max_tokens >= 16000 or None to "
@@ -228,9 +227,7 @@ def thread_function_wrapper():
228227

229228
return job
230229

231-
def reinforce(
232-
self, train_kwargs
233-
) -> ReinforceJob:
230+
def reinforce(self, train_kwargs) -> ReinforceJob:
234231
# TODO(GRPO Team): Should we return an initialized job here?
235232
from dspy import settings as settings
236233

@@ -482,6 +479,7 @@ def _convert_chat_request_to_responses_request(request: dict[str, Any]):
482479

483480
return request
484481

482+
485483
def _get_headers(headers: dict[str, Any] | None = None):
486484
headers = headers or {}
487485
return {

0 commit comments

Comments
 (0)