use crate::error::SdkError;
impl From<String> for SdkError {
fn from(msg: String) -> Self {
SdkError::Config(msg)
}
}
pub fn parse_model_string(model: &str) -> Result<(String, String), SdkError> {
match model.split_once('/') {
Some((provider, model_name)) if !provider.is_empty() && !model_name.is_empty() => {
Ok((provider.to_string(), model_name.to_string()))
}
_ => Err(SdkError::Config(format!(
"Model string must be \"provider/model\" (e.g. \"anthropic/claude-sonnet-4\"), got: \"{model}\""
))),
}
}
#[cfg(test)]
mod tests {
use super::*;
use lingshu_types::AgentError;
#[test]
fn parse_provider_model() {
let (p, m) = parse_model_string("anthropic/claude-sonnet-4").unwrap();
assert_eq!(p, "anthropic");
assert_eq!(m, "claude-sonnet-4");
}
#[test]
fn parse_rejects_bare_model_name() {
let result = parse_model_string("claude-sonnet-4");
assert!(result.is_err());
}
#[test]
fn parse_rejects_empty_provider() {
let result = parse_model_string("/claude-sonnet-4");
assert!(result.is_err());
}
#[test]
fn parse_rejects_empty_model() {
let result = parse_model_string("anthropic/");
assert!(result.is_err());
}
#[test]
fn sdk_error_from_agent_error() {
let agent_err = AgentError::Config("test".into());
let sdk_err: SdkError = agent_err.into();
assert_eq!(sdk_err.category(), "agent");
}
#[test]
fn sdk_error_retryable() {
let rate_err = SdkError::Agent(AgentError::RateLimited {
provider: "anthropic".into(),
retry_after_ms: 1000,
});
assert!(rate_err.is_retryable());
let config_err = SdkError::Config("bad".into());
assert!(!config_err.is_retryable());
}
}