use crate::brain::provider::factory::{active_provider_stt, active_provider_tts};
use crate::config::Config;
const OPENCRABS_HOST_ROOT: &str = "https://inference.opencrabs.com";
const AUDIO_MODEL: &str = "qwen3.8-omni-flash";
fn cfg(toml: &str) -> Config {
toml::from_str(toml).expect("config toml parses")
}
fn opencrabs_toml(api_key: Option<&str>, with_audio_models: bool) -> String {
let key_line = match api_key {
Some(k) => format!("api_key = \"{k}\""),
None => String::new(),
};
let audio_lines = if with_audio_models {
format!("stt_model = \"{AUDIO_MODEL}\"\ntts_model = \"{AUDIO_MODEL}\"\n")
} else {
String::new()
};
format!(
r#"
[providers.opencrabs]
enabled = true
{key_line}
default_model = "deepseek-v4.1-flash"
{audio_lines}"#
)
}
#[test]
fn opencrabs_with_token_is_an_stt_candidate_at_the_host_root() {
let config = cfg(&opencrabs_toml(Some("ocp_test_token"), true));
let cand = active_provider_stt(&config).expect("built-in provider must be an STT candidate");
assert_eq!(
cand.0, "ocp_test_token",
"install token must be the credential"
);
assert_eq!(
cand.1, OPENCRABS_HOST_ROOT,
"base URL must be the host root; the chat-route client appends v1/chat/completions"
);
assert_eq!(cand.2, AUDIO_MODEL);
}
#[test]
fn opencrabs_is_never_a_tts_candidate() {
let config = cfg(&opencrabs_toml(Some("ocp_test_token"), true));
assert!(
active_provider_tts(&config).is_none(),
"the built-in endpoint serves no speech route, so it cannot be a candidate"
);
}
#[test]
fn opencrabs_without_token_is_not_an_audio_candidate() {
let config = cfg(&opencrabs_toml(None, true));
assert!(
active_provider_stt(&config).is_none(),
"keyless remote endpoint must be excluded (#1792)"
);
assert!(
active_provider_tts(&config).is_none(),
"keyless remote endpoint must be excluded (#1792)"
);
}
#[test]
fn opencrabs_without_audio_models_is_not_an_audio_candidate() {
let config = cfg(&opencrabs_toml(Some("ocp_test_token"), false));
assert!(active_provider_stt(&config).is_none());
assert!(active_provider_tts(&config).is_none());
}
#[test]
fn opencrabs_audio_base_url_is_reduced_from_the_v1_default() {
let config = cfg(&opencrabs_toml(Some("ocp_test_token"), true));
let (_, url, _) = active_provider_stt(&config).expect("candidate");
assert!(
!url.ends_with("/v1"),
"trailing /v1 must be stripped, got: {url}"
);
assert_eq!(url, OPENCRABS_HOST_ROOT);
}
const CUSTOM_TTS_TOML: &str = r#"
[providers.custom.lm-studio]
enabled = true
base_url = "http://localhost:1234/v1"
api_key = "local-key"
default_model = "some-chat-model"
tts_model = "tts-1"
"#;
#[test]
fn a_custom_provider_with_a_tts_model_stays_a_tts_candidate() {
let config = cfg(CUSTOM_TTS_TOML);
let cand = active_provider_tts(&config).expect("a real speech endpoint must stay a candidate");
assert_eq!(cand.0, "local-key");
assert_eq!(cand.1, "http://localhost:1234");
assert_eq!(cand.2, "tts-1");
}
#[test]
fn a_custom_section_pointing_at_the_built_in_host_is_not_a_tts_candidate() {
let config = cfg(r#"
[providers.custom.copied]
enabled = true
base_url = "https://inference.opencrabs.com/v1"
api_key = "ocp_test_token"
default_model = "deepseek-v4.1-flash"
tts_model = "qwen3.8-omni-flash"
"#);
assert!(
active_provider_tts(&config).is_none(),
"a custom section on the built-in host serves no speech either"
);
}
#[test]
fn the_stt_candidate_carries_the_published_alias_not_a_routing_id() {
let config = cfg(&opencrabs_toml(Some("ocp_test_token"), true));
let (_, _, model) = active_provider_stt(&config).expect("candidate");
assert_eq!(model, "qwen3.8-omni-flash");
assert!(
!model.contains('/'),
"a routing id leaked into the client candidate: {model}"
);
}
#[test]
fn a_speech_model_alone_is_neither_an_stt_nor_a_tts_candidate() {
let config = cfg(r#"
[providers.opencrabs]
enabled = true
api_key = "ocp_test_token"
default_model = "deepseek-v4.1-flash"
tts_model = "qwen3.8-omni-flash"
"#);
assert!(
active_provider_stt(&config).is_none(),
"transcription needs stt_model, not tts_model"
);
assert!(
active_provider_tts(&config).is_none(),
"the endpoint serves no speech route in any shape"
);
}