1pub fn normalize_chat_url(base_url: Option<&str>, default_url: &str) -> String {
4 let base_url = base_url
5 .map(|s| s.to_string())
6 .unwrap_or_else(|| default_url.to_string());
7
8 if base_url.ends_with("/chat/completions") || base_url.ends_with("/v1/chat/completions") {
10 return base_url;
11 }
12
13 if let Ok(mut parsed) = url::Url::parse(&base_url) {
15 let path = parsed.path().trim_end_matches('/');
16
17 if path.ends_with("/v1") {
19 parsed.set_path(&format!("{path}/chat/completions"));
20 } else if path.is_empty() || path == "/" {
21 parsed.set_path("/v1/chat/completions");
23 } else {
24 parsed.set_path(&format!("{path}/v1/chat/completions"));
26 }
27 parsed.to_string()
28 } else {
29 if base_url.ends_with('/') {
31 format!("{base_url}v1/chat/completions")
32 } else {
33 format!("{base_url}/v1/chat/completions")
34 }
35 }
36}
37
38pub fn normalize_responses_url(base_url: Option<&str>, default_url: &str) -> String {
41 let base_url = base_url
42 .map(|s| s.to_string())
43 .unwrap_or_else(|| default_url.to_string());
44
45 if base_url.ends_with("/responses") || base_url.ends_with("/v1/responses") {
46 return base_url;
47 }
48
49 if let Ok(mut parsed) = url::Url::parse(&base_url) {
50 let path = parsed.path().trim_end_matches('/');
51 if path.ends_with("/v1") {
52 parsed.set_path(&format!("{path}/responses"));
53 } else if path.is_empty() || path == "/" {
54 parsed.set_path("/v1/responses");
55 } else {
56 parsed.set_path(&format!("{path}/v1/responses"));
57 }
58 parsed.to_string()
59 } else if base_url.ends_with('/') {
60 format!("{base_url}v1/responses")
61 } else {
62 format!("{base_url}/v1/responses")
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_normalize_chat_url() {
72 assert_eq!(
73 normalize_chat_url(Some("https://api.example.com"), ""),
74 "https://api.example.com/v1/chat/completions"
75 );
76
77 assert_eq!(
78 normalize_chat_url(Some("https://api.example.com/"), ""),
79 "https://api.example.com/v1/chat/completions"
80 );
81
82 assert_eq!(
83 normalize_chat_url(Some("https://api.example.com/v1"), ""),
84 "https://api.example.com/v1/chat/completions"
85 );
86
87 assert_eq!(
88 normalize_chat_url(Some("https://api.example.com/chat/completions"), ""),
89 "https://api.example.com/chat/completions"
90 );
91
92 assert_eq!(
93 normalize_chat_url(Some("https://api.example.com/v1/chat/completions"), ""),
94 "https://api.example.com/v1/chat/completions"
95 );
96
97 assert_eq!(
98 normalize_chat_url(None, "https://default.com/v1/chat/completions"),
99 "https://default.com/v1/chat/completions"
100 );
101 }
102
103 #[test]
104 fn test_normalize_responses_url() {
105 assert_eq!(
106 normalize_responses_url(Some("https://api.example.com"), ""),
107 "https://api.example.com/v1/responses"
108 );
109 assert_eq!(
110 normalize_responses_url(Some("https://api.example.com/"), ""),
111 "https://api.example.com/v1/responses"
112 );
113 assert_eq!(
114 normalize_responses_url(Some("https://api.example.com/v1"), ""),
115 "https://api.example.com/v1/responses"
116 );
117 assert_eq!(
118 normalize_responses_url(Some("https://api.example.com/responses"), ""),
119 "https://api.example.com/responses"
120 );
121 assert_eq!(
122 normalize_responses_url(Some("https://api.example.com/v1/responses"), ""),
123 "https://api.example.com/v1/responses"
124 );
125 assert_eq!(
126 normalize_responses_url(None, "https://default.com/v1/responses"),
127 "https://default.com/v1/responses"
128 );
129 }
130}