Skip to content

Commit af0bbfd

Browse files
committed
Added: AgentDefaults::with_model() constructor for simpler defaults
Add convenience method to create AgentDefaults with only a model specified, letting temperature and top_p inherit provider defaults. Changes: - Added AgentDefaults::with_model(model) constructor - Updated 14 call sites to use with_model() instead of struct literal - Simplified example to use API key constants instead of env var check - Updated documentation examples to use new shorthand Benefits: - Reduces boilerplate from 5 lines to 1 for common case - Makes code intent clearer at a glance - Example no longer requires pre-setting environment variables
1 parent 1f6d146 commit af0bbfd

9 files changed

Lines changed: 35 additions & 81 deletions

File tree

src/llm-coding-tools-agents/README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,7 @@ loader.add_directory(&mut catalog, "/home/user/.opencode")?;
6363
6464
let runtime = AgentRuntimeBuilder::new()
6565
.catalog(catalog)
66-
.defaults(AgentDefaults {
67-
model: Some("openai/gpt-4o-mini".into()),
68-
temperature: Some(0.2),
69-
top_p: Some(0.95),
70-
})
66+
.defaults(AgentDefaults::with_model("openai/gpt-4o-mini"))
7167
// .tools(my_custom_tools) // optional; defaults to read/write/edit/glob/grep/bash/webfetch/todoread/todowrite
7268
.build();
7369

src/llm-coding-tools-agents/src/runtime/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@
2727
//!
2828
//! let runtime = AgentRuntimeBuilder::new()
2929
//! .catalog(AgentCatalog::new())
30-
//! .defaults(AgentDefaults {
31-
//! model: Some("openai/gpt-4o".into()),
32-
//! temperature: Some(0.7),
33-
//! top_p: Some(0.9),
34-
//! })
30+
//! .defaults(AgentDefaults::with_model("openai/gpt-4o"))
3531
//! .build();
3632
//!
3733
//! assert!(runtime.catalog().iter().count() == 0);

src/llm-coding-tools-agents/src/runtime/model.rs

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,7 @@ mod tests {
327327
)],
328328
vec![("openai", "gpt-4.1-mini", model_info(128_000, 16_384))],
329329
);
330-
let defaults = AgentDefaults {
331-
model: Some("openai/gpt-4.1-mini".into()),
332-
temperature: None,
333-
top_p: None,
334-
};
330+
let defaults = AgentDefaults::with_model("openai/gpt-4.1-mini");
335331
let agent = config_with_model("planner", None);
336332

337333
let resolved = resolve_model_with_catalog(&catalog, &defaults, &agent)
@@ -362,11 +358,7 @@ mod tests {
362358
("openrouter", "openai/gpt-4o", model_info(128_000, 16_384)),
363359
],
364360
);
365-
let defaults = AgentDefaults {
366-
model: Some("openrouter/openai/gpt-4.1-mini".into()),
367-
temperature: None,
368-
top_p: None,
369-
};
361+
let defaults = AgentDefaults::with_model("openrouter/openai/gpt-4.1-mini");
370362
let agent = config_with_model("planner", Some("openrouter/openai/gpt-4o"));
371363

372364
let resolved = resolve_model_with_catalog(&catalog, &defaults, &agent)
@@ -389,11 +381,7 @@ mod tests {
389381
)],
390382
vec![("openai", "gpt-4.1-mini", model_info(128_000, 16_384))],
391383
);
392-
let defaults = AgentDefaults {
393-
model: Some("openai/gpt-4.1-mini".into()),
394-
temperature: None,
395-
top_p: None,
396-
};
384+
let defaults = AgentDefaults::with_model("openai/gpt-4.1-mini");
397385
let agent = config_with_model("planner", Some("openai-only"));
398386

399387
let err = resolve_model_with_catalog(&catalog, &defaults, &agent)
@@ -514,11 +502,7 @@ mod tests {
514502
)],
515503
vec![("openai", "gpt-4o", model_info(128_000, 16_384))],
516504
);
517-
let defaults = AgentDefaults {
518-
model: Some("openai-only".into()),
519-
temperature: None,
520-
top_p: None,
521-
};
505+
let defaults = AgentDefaults::with_model("openai-only");
522506
let agent = config_with_model("planner", None);
523507

524508
let err = resolve_model_with_catalog(&catalog, &defaults, &agent)

src/llm-coding-tools-agents/src/runtime/state.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ pub struct AgentDefaults {
1919
pub top_p: Option<f32>,
2020
}
2121

22+
impl AgentDefaults {
23+
/// Creates defaults with only a model specified; temperature and top_p inherit provider defaults.
24+
#[inline]
25+
pub fn with_model(model: impl Into<Box<str>>) -> Self {
26+
Self {
27+
model: Some(model.into()),
28+
temperature: None,
29+
top_p: None,
30+
}
31+
}
32+
}
33+
2234
/// Your loaded agents plus their default settings and available tools.
2335
#[derive(Debug, Clone)]
2436
pub struct AgentRuntime {

src/llm-coding-tools-serdesai/examples/serdesai-agents.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
//! The model catalog is loaded from models.dev, which provides up-to-date
77
//! provider and model information from <https://models.dev/api.json>.
88
//!
9-
//! Run: cargo run --example serdesai-agents -p llm-coding-tools-serdesai
9+
//! Run: Edit the API_KEY_NAME and API_KEY_VALUE constants below, then:
10+
//! cargo run --example serdesai-agents -p llm-coding-tools-serdesai
1011
1112
use llm_coding_tools_agents::{AgentCatalog, AgentLoader, AgentRuntimeBuilder};
1213
use llm_coding_tools_models_dev::ModelsDevCatalog;
@@ -15,20 +16,16 @@ use std::path::PathBuf;
1516

1617
const AGENT_NAME: &str = "basic/file-reader";
1718
const MODEL_ID: &str = "synthetic/hf:zai-org/GLM-4.7";
18-
const PROVIDER_ENV_VAR: &str = "SYNTHETIC_API_KEY";
19+
const API_KEY_NAME: &str = "SYNTHETIC_API_KEY";
20+
const API_KEY_VALUE: &str = ""; // <-- Set your API key here
1921

2022
#[tokio::main]
2123
async fn main() -> Result<(), Box<dyn std::error::Error>> {
24+
unsafe { std::env::set_var(API_KEY_NAME, API_KEY_VALUE) };
25+
2226
let examples_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples");
2327
let readme_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("README.md");
2428

25-
if std::env::var(PROVIDER_ENV_VAR).map_or(true, |value| value.is_empty()) {
26-
return Err(format!(
27-
"set {PROVIDER_ENV_VAR} before running this example; the runtime resolves provider credentials from the models.dev catalog"
28-
)
29-
.into());
30-
}
31-
3229
// Load model catalog from models.dev (online-first with local cache fallback)
3330
let load_result = ModelsDevCatalog::load().await?;
3431
println!(
@@ -41,11 +38,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
4138

4239
let runtime = AgentRuntimeBuilder::new()
4340
.catalog(catalog)
44-
.defaults(AgentDefaults {
45-
model: Some(MODEL_ID.into()),
46-
temperature: Some(0.2),
47-
top_p: Some(0.95),
48-
})
41+
.defaults(AgentDefaults::with_model(MODEL_ID))
4942
.build();
5043

5144
println!(

src/llm-coding-tools-serdesai/src/agent_runtime/build.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,7 @@ mod tests {
316316
),
317317
agent("no-tools", IndexMap::new(), "prompt"),
318318
]))
319-
.defaults(AgentDefaults {
320-
model: Some("openrouter/openai/gpt-4.1-mini".into()),
321-
temperature: None,
322-
top_p: None,
323-
})
319+
.defaults(AgentDefaults::with_model("openrouter/openai/gpt-4.1-mini"))
324320
.build();
325321

326322
// Agent with permissions gets only the allowed tools
@@ -376,11 +372,7 @@ mod tests {
376372

377373
// Unknown agent name returns clear error
378374
let runtime = AgentRuntimeBuilder::new()
379-
.defaults(AgentDefaults {
380-
model: Some("openrouter/openai/gpt-4.1-mini".into()),
381-
temperature: None,
382-
top_p: None,
383-
})
375+
.defaults(AgentDefaults::with_model("openrouter/openai/gpt-4.1-mini"))
384376
.build();
385377
let err = prepare_build(&runtime, "missing", &catalog, &credentials)
386378
.err()

src/llm-coding-tools-serdesai/src/agent_runtime/model.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,7 @@ mod tests {
112112
)],
113113
);
114114
// Agent uses default model, no override
115-
let defaults = AgentDefaults {
116-
model: Some("openrouter/openai/gpt-4.1-mini".into()),
117-
temperature: None,
118-
top_p: None,
119-
};
115+
let defaults = AgentDefaults::with_model("openrouter/openai/gpt-4.1-mini");
120116
let agent = config_with_model("planner", None);
121117

122118
// Should resolve to provider and model components

src/llm-coding-tools-serdesai/src/agent_runtime/provider_bridge/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,9 @@ fn build_antigravity(
923923
"an access token",
924924
is_credential_env_var,
925925
)?;
926-
let project_id = first_matching_env_value(credentials, env_vars, is_antigravity_project_id_env_var)
927-
.unwrap_or_else(|| serdes_ai_models::antigravity::DEFAULT_PROJECT_ID.to_owned());
926+
let project_id =
927+
first_matching_env_value(credentials, env_vars, is_antigravity_project_id_env_var)
928+
.unwrap_or_else(|| serdes_ai_models::antigravity::DEFAULT_PROJECT_ID.to_owned());
928929
let mut model =
929930
serdes_ai_models::AntigravityModel::new(model_name, access_token, project_id);
930931
if let Some(api_url) = api_url {

src/llm-coding-tools-serdesai/src/agent_runtime/provider_bridge/tests.rs

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,7 @@ fn resolve_case(case: &Case) -> ResolvedSerdesModel {
8888
)],
8989
);
9090
let model = format!("{}/{}", case.provider_key, case.model_name);
91-
let defaults = AgentDefaults {
92-
model: Some(model.into()),
93-
temperature: None,
94-
top_p: None,
95-
};
91+
let defaults = AgentDefaults::with_model(&*model);
9692
let agent = config_with_model("planner", None);
9793
let mut credentials = CredentialResolver::without_env();
9894
// Bedrock is special: the AWS SDK reads credentials directly from environment variables
@@ -348,11 +344,7 @@ fn build_serdes_model_skips_empty_credential_env_vars() {
348344
model_info(128_000, 16_384),
349345
)],
350346
);
351-
let defaults = AgentDefaults {
352-
model: Some("synthetic/hf:zai-org/GLM-4.7".into()),
353-
temperature: None,
354-
top_p: None,
355-
};
347+
let defaults = AgentDefaults::with_model("synthetic/hf:zai-org/GLM-4.7");
356348
let agent = config_with_model("planner", None);
357349
let mut credentials = CredentialResolver::without_env();
358350
credentials.set_override("PRIMARY_API_KEY", "");
@@ -381,11 +373,7 @@ fn build_serdes_model_returns_clear_error_when_required_credential_missing() {
381373
model_info(128_000, 16_384),
382374
)],
383375
);
384-
let defaults = AgentDefaults {
385-
model: Some("synthetic/hf:zai-org/GLM-4.7".into()),
386-
temperature: None,
387-
top_p: None,
388-
};
376+
let defaults = AgentDefaults::with_model("synthetic/hf:zai-org/GLM-4.7");
389377
let agent = config_with_model("planner", None);
390378
let credentials = CredentialResolver::without_env();
391379

@@ -406,11 +394,7 @@ fn build_serdes_model_rejects_unknown_provider_type() {
406394
vec![("mystery", provider("", &[], ProviderType::Unknown))],
407395
vec![("mystery", "m1", model_info(1, 1))],
408396
);
409-
let defaults = AgentDefaults {
410-
model: Some("mystery/m1".into()),
411-
temperature: None,
412-
top_p: None,
413-
};
397+
let defaults = AgentDefaults::with_model("mystery/m1");
414398
let agent = config_with_model("planner", None);
415399
let credentials = CredentialResolver::without_env();
416400

0 commit comments

Comments
 (0)