Skip to content

Commit 1be1cdd

Browse files
rithulkameshclaude
andcommitted
feat(prompt_optimizer): dspy/gepa as default — noop only when explicit
Auto-detect replaces hard-coded noop default: - dspy if dspy-ai is importable - gepa otherwise (built-in evolutionary loop, zero extra deps) - noop only when provider = "noop" is set explicitly PromptOptimizerConfig.provider defaults to "" (auto). Updated test: factory default asserts dspy|gepa, not noop. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent fe9e55d commit 1be1cdd

3 files changed

Lines changed: 19 additions & 5 deletions

File tree

devsper/config/schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class PromptOptimizerConfig(BaseModel):
315315
provider: "noop" | "dspy" | "gepa" (override with DEVSPER_PROMPT_OPTIMIZER env var)
316316
"""
317317

318-
provider: str = "noop"
318+
provider: str = "" # "" = auto (dspy if installed, else gepa). "noop" disables.
319319
# DSPy-specific
320320
dspy_optimizer: str = "bootstrap" # "bootstrap" | "mipro" | "bootstrap_random"
321321
max_demos: int = 4

devsper/prompt_optimizer/factory.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
Resolution order:
55
1. DEVSPER_PROMPT_OPTIMIZER env var
66
2. config.prompt_optimizer.provider (devsper.toml)
7-
3. Default: "noop"
7+
3. Auto-detect: "dspy" if dspy-ai is importable, else "gepa"
8+
(GEPABackend ships a built-in evolutionary loop — no extra install needed)
9+
10+
Set provider = "noop" explicitly to disable optimization.
811
"""
912

1013
from __future__ import annotations
@@ -75,7 +78,17 @@ def _resolve_provider_name(config=None) -> str:
7578
if provider:
7679
return provider
7780

78-
return "noop"
81+
# 3. Auto-detect: prefer dspy if importable, otherwise gepa
82+
return _autodetect()
83+
84+
85+
def _autodetect() -> str:
86+
"""Return 'dspy' if dspy-ai is installed, else 'gepa' (always available)."""
87+
try:
88+
import dspy # noqa: F401
89+
return "dspy"
90+
except ImportError:
91+
return "gepa"
7992

8093

8194
def _opt_cfg(config=None):

tests/test_evals.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,13 @@ def test_noop_backend_health():
232232
assert asyncio.run(backend.health()) is True
233233

234234

235-
def test_factory_default_is_noop():
235+
def test_factory_default_is_dspy_or_gepa():
236+
"""Default is dspy if installed, gepa otherwise — never noop."""
236237
reset_prompt_optimizer()
237238
import os
238239
os.environ.pop("DEVSPER_PROMPT_OPTIMIZER", None)
239240
opt = get_prompt_optimizer()
240-
assert opt.name == "noop"
241+
assert opt.name in ("dspy", "gepa"), f"Expected dspy or gepa, got {opt.name}"
241242
reset_prompt_optimizer()
242243

243244

0 commit comments

Comments
 (0)