Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 22 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ Add DSRs to your `Cargo.toml`:
```toml
[dependencies]
# Option 1: Use the shorter alias (recommended)
dsrs = { package = "dspy-rs", version = "0.7.0" }
dsrs = { package = "dspy-rs", version = "0.7.1" }

# Option 2: Use the full name
dspy-rs = "0.7.0"
dspy-rs = "0.7.1"
```

Or use cargo:
Expand Down Expand Up @@ -64,17 +64,15 @@ struct SentimentAnalyzer {

#[tokio::main]
async fn main() -> Result<()> {
let lm = LM::builder()
.api_key(std::env::var("OPENAI_API_KEY")?.into())
.config(
LMConfig::builder()
.model("gpt-4.1-nano".to_string())
.temperature(0.5)
.build(),
)
.build();

configure(lm, ChatAdapter);
// API key automatically read from OPENAI_API_KEY env var
configure(
LM::builder()
.model("gpt-4o-mini".to_string())
.temperature(0.5)
.build()
.await?,
ChatAdapter,
);

// Create a predictor
let predictor = Predict::new(SentimentAnalyzer::new());
Expand Down Expand Up @@ -154,13 +152,20 @@ let predict = Predict::new(MySignature::new());

#### 4. **Language Models** - Configurable LM Backends
```rust
// Configure with OpenAI
// Configure with OpenAI (API key read from OPENAI_API_KEY env var)
let lm = LM::builder()
.api_key(secret_key)
.model("gpt-4")
.model("gpt-4o-mini".to_string())
.temperature(0.7)
.max_tokens(1000)
.build();
.build()
.await?;

// For local models (e.g., vLLM, Ollama)
let lm = LM::builder()
.base_url("http://localhost:11434".to_string())
.model("llama3".to_string())
.build()
.await?;
```

#### 5. **Evaluation** - Evaluating your Modules
Expand Down
4 changes: 2 additions & 2 deletions crates/dspy-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "dspy-rs"
authors = ["Herumb Shandilya <herumb@stanford.edu>"]
version = "0.7.0"
version = "0.7.1"
edition = "2024"
description = "A DSPy rewrite(not port) to Rust."
readme = "../../README.md"
Expand All @@ -25,7 +25,7 @@ tokio = { version = "1.46.1", features = ["full"] }
async-trait = "0.1.83"
anyhow = "1.0.99"
bon = "3.7.0"
dsrs_macros = { version = "0.7.0", path = "../dsrs-macros" }
dsrs_macros = { version = "0.7.1", path = "../dsrs-macros" }
csv = { version = "1.3.1" }
hf-hub = { version = "0.4.3", features = ["tokio"] }
parquet = { version = "56.1.0" }
Expand Down
14 changes: 7 additions & 7 deletions crates/dspy-rs/examples/01-simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ cargo run --example 01-simple
use anyhow::Result;
use bon::Builder;
use dspy_rs::{
ChatAdapter, Example, LM, LMConfig, Module, Predict, Prediction, Predictor, Signature,
configure, example, prediction,
ChatAdapter, Example, LM, Module, Predict, Prediction, Predictor, Signature, configure,
example, prediction,
};

#[Signature(cot)]
Expand Down Expand Up @@ -70,11 +70,11 @@ impl Module for QARater {
#[tokio::main]
async fn main() -> Result<()> {
configure(
LM::new(LMConfig {
model: "openai:gpt-4o-mini".to_string(),
..LMConfig::default()
})
.await,
LM::builder()
.model("openai:gpt-4o-mini".to_string())
.build()
.await
.unwrap(),
ChatAdapter,
);

Expand Down
9 changes: 8 additions & 1 deletion crates/dspy-rs/examples/03-evaluate-hotpotqa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ impl Evaluator for QARater {

#[tokio::main]
async fn main() -> anyhow::Result<()> {
configure(LM::default(), ChatAdapter {});
configure(
LM::builder()
.model("openai:gpt-4o-mini".to_string())
.build()
.await
.unwrap(),
ChatAdapter {},
);

let examples = DataLoader::load_hf(
"hotpotqa/hotpot_qa",
Expand Down
9 changes: 8 additions & 1 deletion crates/dspy-rs/examples/04-optimize-hotpotqa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ impl Evaluator for QARater {

#[tokio::main]
async fn main() -> anyhow::Result<()> {
configure(LM::default(), ChatAdapter {});
configure(
LM::builder()
.model("openai:gpt-4o-mini".to_string())
.build()
.await
.unwrap(),
ChatAdapter {},
);

let examples = DataLoader::load_hf(
"hotpotqa/hotpot_qa",
Expand Down
9 changes: 8 additions & 1 deletion crates/dspy-rs/examples/05-heterogenous-examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ use dspy_rs::{ChatAdapter, LM, Predict, Predictor, configure, example, sign};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
configure(LM::default(), ChatAdapter {});
configure(
LM::builder()
.model("openai:gpt-4o-mini".to_string())
.build()
.await
.unwrap(),
ChatAdapter {},
);

let exp = example! {
"number": "input" => 10,
Expand Down
24 changes: 12 additions & 12 deletions crates/dspy-rs/examples/06-other-providers-batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ cargo run --example 01-simple
use anyhow::Result;
use bon::Builder;
use dspy_rs::{
ChatAdapter, Example, LM, LMConfig, Module, Predict, Prediction, Predictor, Signature,
configure, example, hashmap, prediction,
ChatAdapter, Example, LM, Module, Predict, Prediction, Predictor, Signature, configure,
example, hashmap, prediction,
};

#[Signature(cot)]
Expand Down Expand Up @@ -77,11 +77,11 @@ impl Module for QARater {
async fn main() {
// Anthropic
configure(
LM::new(LMConfig {
model: "anthropic:claude-sonnet-4-5-20250929".to_string(),
..LMConfig::default()
})
.await,
LM::builder()
.model("anthropic:claude-sonnet-4-5-20250929".to_string())
.build()
.await
.unwrap(),
ChatAdapter,
);

Expand All @@ -103,11 +103,11 @@ async fn main() {

// Gemini
configure(
LM::new(LMConfig {
model: "gemini:gemini-2.0-flash".to_string(),
..LMConfig::default()
})
.await,
LM::builder()
.model("gemini:gemini-2.0-flash".to_string())
.build()
.await
.unwrap(),
ChatAdapter,
);

Expand Down
6 changes: 5 additions & 1 deletion crates/dspy-rs/examples/07-inspect-history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ impl Module for QARater {

#[tokio::main]
async fn main() {
let lm = LM::default();
let lm = LM::builder()
.model("openai:gpt-4o-mini".to_string())
.build()
.await
.unwrap();
configure(lm, ChatAdapter);

let example = example! {
Expand Down
6 changes: 1 addition & 5 deletions crates/dspy-rs/examples/09-gepa-sentiment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,7 @@ async fn main() -> Result<()> {
println!("GEPA Sentiment Analysis Optimization Example\n");

// Setup LM
let lm = LM::new(LMConfig {
temperature: 0.7,
..LMConfig::default()
})
.await;
let lm = LM::builder().temperature(0.7).build().await.unwrap();

configure(lm.clone(), ChatAdapter);

Expand Down
12 changes: 2 additions & 10 deletions crates/dspy-rs/examples/10-gepa-llm-judge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,18 +223,10 @@ async fn main() -> Result<()> {

// Setup: Configure the LLM
// Main LM for the task
let task_lm = LM::new(LMConfig {
temperature: 0.7,
..LMConfig::default()
})
.await;
let task_lm = LM::builder().temperature(0.7).build().await.unwrap();

// Judge LM (could use a different/cheaper model)
let judge_lm = LM::new(LMConfig {
temperature: 0.3,
..LMConfig::default()
})
.await;
let judge_lm = LM::builder().temperature(0.3).build().await.unwrap();

configure(task_lm, ChatAdapter);

Expand Down
4 changes: 2 additions & 2 deletions crates/dspy-rs/src/adapter/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl Adapter for ChatAdapter {
inputs: Example,
) -> Result<Prediction> {
// Check cache first (release lock immediately after checking)
if lm.config.cache
if lm.cache
&& let Some(cache) = lm.cache_handler.as_ref()
{
let cache_key = inputs.clone();
Expand All @@ -304,7 +304,7 @@ impl Adapter for ChatAdapter {
};

// Store in cache if enabled
if lm.config.cache
if lm.cache
&& let Some(cache) = lm.cache_handler.as_ref()
{
let (tx, rx) = tokio::sync::mpsc::channel(1);
Expand Down
Loading