From 798bd1b3c924a797a678e6a68de26c9bd880e224 Mon Sep 17 00:00:00 2001 From: Victor Sumner Date: Wed, 25 Feb 2026 16:56:26 -0500 Subject: [PATCH 1/4] Fix Z.AI Coding Plan model remap for chat completions --- src/llm/model.rs | 50 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/src/llm/model.rs b/src/llm/model.rs index 4ba76e03d..7c533e5b8 100644 --- a/src/llm/model.rs +++ b/src/llm/model.rs @@ -824,16 +824,7 @@ impl SpacebotModel { /// Remap model name for providers that require a different format in API calls. fn remap_model_name_for_api(&self) -> String { - if self.provider == "zai-coding-plan" { - // Z.AI Coding Plan API expects "zai/glm-5" not "glm-5" - let model_name = self - .model_name - .strip_prefix("zai/") - .unwrap_or(&self.model_name); - format!("zai/{model_name}") - } else { - self.model_name.clone() - } + remap_model_name_for_api(&self.provider, &self.model_name) } /// Generic OpenAI-compatible API call with optional bearer auth. @@ -1526,6 +1517,18 @@ fn parse_openai_error_message(response_text: &str) -> Option { .map(ToOwned::to_owned) } +fn remap_model_name_for_api(provider: &str, model_name: &str) -> String { + if provider == "zai-coding-plan" { + // Coding Plan endpoint expects plain model ids (e.g. "glm-5"). + model_name + .strip_prefix("zai/") + .unwrap_or(model_name) + .to_string() + } else { + model_name.to_string() + } +} + #[cfg(test)] mod tests { use super::*; @@ -1568,4 +1571,31 @@ mod tests { panic!("expected ToolCall"); } } + #[test] + fn positive_max_tokens_omits_none_and_zero() { + assert_eq!(positive_max_tokens(None), None); + assert_eq!(positive_max_tokens(Some(0)), None); + } + + #[test] + fn positive_max_tokens_keeps_positive_values() { + assert_eq!(positive_max_tokens(Some(1)), Some(1)); + assert_eq!(positive_max_tokens(Some(2048)), Some(2048)); + } + + #[test] + fn coding_plan_model_name_uses_plain_glm_id() { + assert_eq!( + remap_model_name_for_api("zai-coding-plan", "glm-5"), + "glm-5" + ); + assert_eq!( + remap_model_name_for_api("zai-coding-plan", "zai/glm-5"), + "glm-5" + ); + assert_eq!( + remap_model_name_for_api("openai", "gpt-4o-mini"), + "gpt-4o-mini" + ); + } } From eea072aaec4b3a8e2dcdcbaf45d7a46d58fee4ba Mon Sep 17 00:00:00 2001 From: Victor Sumner Date: Wed, 25 Feb 2026 17:38:51 -0500 Subject: [PATCH 2/4] Align glm remap regression test with main branch --- src/llm/model.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/llm/model.rs b/src/llm/model.rs index 7c533e5b8..d8976611d 100644 --- a/src/llm/model.rs +++ b/src/llm/model.rs @@ -1571,18 +1571,6 @@ mod tests { panic!("expected ToolCall"); } } - #[test] - fn positive_max_tokens_omits_none_and_zero() { - assert_eq!(positive_max_tokens(None), None); - assert_eq!(positive_max_tokens(Some(0)), None); - } - - #[test] - fn positive_max_tokens_keeps_positive_values() { - assert_eq!(positive_max_tokens(Some(1)), Some(1)); - assert_eq!(positive_max_tokens(Some(2048)), Some(2048)); - } - #[test] fn coding_plan_model_name_uses_plain_glm_id() { assert_eq!( From 9b209d74a57729f5b088c01c9579d76bd37a4ba0 Mon Sep 17 00:00:00 2001 From: Victor Sumner Date: Wed, 25 Feb 2026 17:46:10 -0500 Subject: [PATCH 3/4] test: harden model remap coverage for zai prefixes --- src/llm/model.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/llm/model.rs b/src/llm/model.rs index d8976611d..55829ecb0 100644 --- a/src/llm/model.rs +++ b/src/llm/model.rs @@ -1585,5 +1585,9 @@ mod tests { remap_model_name_for_api("openai", "gpt-4o-mini"), "gpt-4o-mini" ); + assert_eq!( + remap_model_name_for_api("openai", "zai/glm-5"), + "zai/glm-5" + ); } } From b7cda98f0fe5ed2eebd629ca5c57253e22a329f4 Mon Sep 17 00:00:00 2001 From: Victor Sumner Date: Wed, 25 Feb 2026 21:11:00 -0500 Subject: [PATCH 4/4] fmt: apply rustfmt for glm remap test --- src/llm/model.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/llm/model.rs b/src/llm/model.rs index 55829ecb0..45036ff52 100644 --- a/src/llm/model.rs +++ b/src/llm/model.rs @@ -1585,9 +1585,6 @@ mod tests { remap_model_name_for_api("openai", "gpt-4o-mini"), "gpt-4o-mini" ); - assert_eq!( - remap_model_name_for_api("openai", "zai/glm-5"), - "zai/glm-5" - ); + assert_eq!(remap_model_name_for_api("openai", "zai/glm-5"), "zai/glm-5"); } }