use crate::brain::provider::custom_openai_compatible::OpenAIProvider;
use crate::brain::provider::glm_reasoning::{
GlmThinking, effort_for, glm_version, serves_zai, thinking_for, tool_stream_for,
};
use crate::brain::provider::{LLMRequest, Message};
const ZAI_API: &str = "https://api.z.ai/api/paas/v4/chat/completions";
const ZAI_CODING: &str = "https://api.z.ai/api/coding/paas/v4/chat/completions";
const BIGMODEL: &str = "https://open.bigmodel.cn/api/paas/v4/chat/completions";
const OPENROUTER: &str = "https://openrouter.ai/api/v1";
fn provider(base_url: &str) -> OpenAIProvider {
OpenAIProvider::with_base_url("test-key".to_string(), base_url.to_string()).with_name("zai")
}
fn body(base_url: &str, model: &str, stream: bool) -> serde_json::Value {
body_with(provider(base_url), model, stream)
}
fn body_with(provider: OpenAIProvider, model: &str, stream: bool) -> serde_json::Value {
let mut req = LLMRequest::new(model.to_string(), vec![Message::user("hi".to_string())]);
req.stream = stream;
serde_json::to_value(provider.to_openai_request(req)).expect("serialize")
}
#[test]
fn both_documented_zai_hosts_are_recognised() {
assert!(serves_zai(ZAI_API));
assert!(serves_zai(ZAI_CODING));
assert!(serves_zai(BIGMODEL));
}
#[test]
fn a_glm_model_on_another_gateway_is_not_zai() {
assert!(!serves_zai(OPENROUTER));
assert_eq!(tool_stream_for(OPENROUTER, true), None);
}
#[test]
fn tool_stream_rides_only_on_streamed_zai_requests() {
assert_eq!(tool_stream_for(ZAI_API, true), Some(true));
assert_eq!(tool_stream_for(BIGMODEL, true), Some(true));
assert_eq!(
tool_stream_for(ZAI_API, false),
None,
"documented as streaming-only"
);
}
#[test]
fn the_wire_body_carries_tool_stream_for_zai_and_omits_it_elsewhere() {
assert_eq!(
body(ZAI_API, "glm-5.3", true)["tool_stream"],
serde_json::json!(true)
);
assert!(body(ZAI_API, "glm-5.3", false).get("tool_stream").is_none());
assert!(
body(OPENROUTER, "z-ai/glm-5.3", true)
.get("tool_stream")
.is_none()
);
}
#[test]
fn glm_versions_parse_through_prefix_case_and_suffix() {
assert_eq!(glm_version("glm-5.3"), Some((5, 3)));
assert_eq!(glm_version("glm-5.3-flash"), Some((5, 3)));
assert_eq!(glm_version("z-ai/GLM-5"), Some((5, 0)));
assert_eq!(glm_version("glm-4.7"), Some((4, 7)));
assert_eq!(glm_version("qwen3.8-max"), None);
assert_eq!(glm_version("glm-"), None);
}
#[test]
fn glm_5_on_zai_gets_preserved_thinking() {
let t = thinking_for(ZAI_API, "glm-5.3", None).expect("glm-5.3 on z.ai");
assert_eq!(
t,
GlmThinking {
enabled: true,
off_ignored: false
}
);
assert_eq!(
t.to_json(),
serde_json::json!({ "type": "enabled", "clear_thinking": false })
);
}
#[test]
fn nothing_changes_off_zai_or_below_glm_5() {
assert_eq!(thinking_for(OPENROUTER, "z-ai/glm-5.3", None), None);
assert_eq!(thinking_for(ZAI_API, "glm-4.7", None), None);
assert_eq!(thinking_for(ZAI_API, "some-alias", None), None);
assert!(body(ZAI_API, "glm-4.7", true).get("thinking").is_none());
}
#[test]
fn thinking_off_is_honoured_before_5_3_and_reported_ignored_after() {
let older = thinking_for(ZAI_API, "glm-5.1", Some(false)).expect("glm-5.1");
assert!(!older.enabled);
assert_eq!(older.to_json(), serde_json::json!({ "type": "disabled" }));
let newer = thinking_for(ZAI_API, "glm-5.3-flash", Some(false)).expect("glm-5.3-flash");
assert!(newer.enabled, "5.3+ cannot turn thinking off");
assert!(newer.off_ignored, "the caller must be told to log it");
}
#[test]
fn the_wire_body_carries_the_thinking_object_for_glm_5_on_zai() {
let b = body(ZAI_API, "glm-5.3", true);
assert_eq!(
b["thinking"],
serde_json::json!({ "type": "enabled", "clear_thinking": false })
);
let off = body_with(provider(ZAI_API).with_enable_thinking(false), "glm-5", true);
assert_eq!(off["thinking"], serde_json::json!({ "type": "disabled" }));
}
#[test]
fn a_wire_rung_passes_through_unnoted() {
for rung in ["low", "high", "max", " High "] {
let e = effort_for(ZAI_API, "glm-5.3", Some(rung)).expect(rung);
assert_eq!(e.effort, rung.trim().to_ascii_lowercase(), "{rung}");
assert_eq!(e.note, None, "{rung}");
}
}
#[test]
fn foreign_rungs_map_to_the_nearest_one_and_say_so() {
for (given, want) in [
("xhigh", "max"),
("medium", "high"),
("minimal", "low"),
("none", "low"),
("off", "low"),
("bananas", "max"),
] {
let e = effort_for(ZAI_API, "glm-5.3-flash", Some(given)).expect(given);
assert_eq!(e.effort, want, "{given}");
let note = e.note.expect(given);
assert!(note.contains(given) && note.contains(want), "{note}");
}
}
#[test]
fn the_ladder_applies_only_to_glm_5_3_plus_on_zai() {
assert_eq!(effort_for(ZAI_API, "glm-5.2", Some("xhigh")), None);
assert_eq!(effort_for(OPENROUTER, "z-ai/glm-5.3", Some("xhigh")), None);
assert_eq!(effort_for(ZAI_API, "glm-5.3", None), None);
assert_eq!(effort_for(ZAI_API, "glm-5.3", Some(" ")), None);
}
#[test]
fn the_wire_body_carries_the_mapped_effort() {
let b = body_with(
provider(ZAI_API).with_reasoning("xhigh".into()),
"glm-5.3",
true,
);
assert_eq!(b["reasoning_effort"], serde_json::json!("max"));
let older = body_with(
provider(ZAI_API).with_reasoning("xhigh".into()),
"glm-5.2",
true,
);
assert_eq!(older["reasoning_effort"], serde_json::json!("xhigh"));
}