fix(providers/openai): preserve custom API path in base_url derivation (#9649)
Signed-off-by: Douwe M Osinga <douwe@sidewalklabs.com> Co-authored-by: Douwe M Osinga <douwe@sidewalklabs.com>
This commit is contained in:
@@ -475,13 +475,21 @@ impl OpenAiProvider {
|
||||
let normalized = stripped.trim_end_matches('/');
|
||||
if normalized.is_empty() {
|
||||
"v1/chat/completions".to_string()
|
||||
} else if normalized == "v1" || normalized.ends_with("/v1") {
|
||||
} else if normalized.ends_with("chat/completions") {
|
||||
stripped.to_string()
|
||||
} else if Self::ends_with_version_segment(normalized) {
|
||||
format!("{}/chat/completions", normalized)
|
||||
} else {
|
||||
stripped.to_string()
|
||||
format!("{}/v1/chat/completions", normalized)
|
||||
}
|
||||
}
|
||||
|
||||
fn ends_with_version_segment(path: &str) -> bool {
|
||||
let last = path.rsplit('/').next().unwrap_or(path);
|
||||
last.strip_prefix('v')
|
||||
.is_some_and(|rest| !rest.is_empty() && rest.bytes().all(|b| b.is_ascii_digit()))
|
||||
}
|
||||
|
||||
fn normalize_base_path(base_path: &str) -> String {
|
||||
if let Some(path) = base_path.strip_prefix('/') {
|
||||
format!("/{}", path.trim_end_matches('/'))
|
||||
@@ -1280,6 +1288,39 @@ mod tests {
|
||||
assert!(!r.has_v1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_base_path_not_removing_api_path() {
|
||||
let r = OpenAiProvider::derive_base_path("https://opencode.ai/zen/go");
|
||||
assert_eq!(r, "https://opencode.ai/zen/go/v1/chat/completions");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_base_path_should_support_v1() {
|
||||
let r = OpenAiProvider::derive_base_path("https://opencode.ai/zen/go/v1");
|
||||
assert_eq!(r, "https://opencode.ai/zen/go/v1/chat/completions");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_base_path_should_support_no_base_path() {
|
||||
let r = OpenAiProvider::derive_base_path("https://opencode.ai/");
|
||||
assert_eq!(r, "https://opencode.ai/v1/chat/completions");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_base_path_preserves_non_v1_version_prefix() {
|
||||
// Zhipu's default base_url is https://open.bigmodel.cn/api/paas/v4 and
|
||||
// from_custom_config passes url.path() ("/api/paas/v4") here. The
|
||||
// existing /api/paas/v4 version must not gain an extra /v1 segment.
|
||||
let r = OpenAiProvider::derive_base_path("/api/paas/v4");
|
||||
assert_eq!(r, "api/paas/v4/chat/completions");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_base_path_does_not_treat_v_word_as_version() {
|
||||
let r = OpenAiProvider::derive_base_path("/api/voice");
|
||||
assert_eq!(r, "api/voice/v1/chat/completions");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_base_url_preserves_query_params() {
|
||||
let r = OpenAiProvider::parse_base_url("https://gw.example.com/v1?api-version=2024-02-01")
|
||||
|
||||
Reference in New Issue
Block a user