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