anveesa 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/package.json +1 -1
- package/src/provider/openai_compatible.rs +47 -1
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
package/package.json
CHANGED
|
@@ -105,7 +105,10 @@ pub async fn ask(
|
|
|
105
105
|
usage_requested = false;
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
108
|
-
bail!(
|
|
108
|
+
bail!(
|
|
109
|
+
"provider '{provider_name}' HTTP {status}: {}",
|
|
110
|
+
extract_api_error(&response_body)
|
|
111
|
+
);
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
let mut state = StreamState::default();
|
|
@@ -1017,6 +1020,49 @@ fn is_stream_options_error(body: &str) -> bool {
|
|
|
1017
1020
|
lower.contains("stream_options") || lower.contains("include_usage")
|
|
1018
1021
|
}
|
|
1019
1022
|
|
|
1023
|
+
/// Extract a concise, human-readable error message from a provider HTTP error body.
|
|
1024
|
+
/// Parses `{"error":{"message":"..."}}`, strips verbose class prefixes (e.g. litellm.*),
|
|
1025
|
+
/// takes only the first line, and truncates to 120 chars.
|
|
1026
|
+
fn extract_api_error(body: &str) -> String {
|
|
1027
|
+
// Try to pull error.message out of the JSON
|
|
1028
|
+
let extracted = serde_json::from_str::<Value>(body)
|
|
1029
|
+
.ok()
|
|
1030
|
+
.and_then(|v| {
|
|
1031
|
+
v.pointer("/error/message")
|
|
1032
|
+
.or_else(|| v.get("message"))
|
|
1033
|
+
.and_then(|m| m.as_str())
|
|
1034
|
+
.map(str::to_string)
|
|
1035
|
+
});
|
|
1036
|
+
|
|
1037
|
+
let raw = extracted.as_deref().unwrap_or(body);
|
|
1038
|
+
|
|
1039
|
+
// First line only
|
|
1040
|
+
let line = raw.lines().next().unwrap_or(raw).trim();
|
|
1041
|
+
|
|
1042
|
+
// Strip a leading "Namespace.ErrorClass: " or "ClassName: " prefix once
|
|
1043
|
+
// (covers litellm.BadRequestError, OpenAIException, etc.)
|
|
1044
|
+
let stripped = if let Some(colon) = line.find(": ") {
|
|
1045
|
+
let prefix = &line[..colon];
|
|
1046
|
+
if !prefix.is_empty()
|
|
1047
|
+
&& prefix
|
|
1048
|
+
.chars()
|
|
1049
|
+
.all(|c| c.is_alphanumeric() || c == '.' || c == '_')
|
|
1050
|
+
{
|
|
1051
|
+
line[colon + 2..].trim_start()
|
|
1052
|
+
} else {
|
|
1053
|
+
line
|
|
1054
|
+
}
|
|
1055
|
+
} else {
|
|
1056
|
+
line
|
|
1057
|
+
};
|
|
1058
|
+
|
|
1059
|
+
if stripped.len() > 120 {
|
|
1060
|
+
format!("{}…", &stripped[..120])
|
|
1061
|
+
} else {
|
|
1062
|
+
stripped.to_string()
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1020
1066
|
#[cfg(test)]
|
|
1021
1067
|
mod tests {
|
|
1022
1068
|
use super::*;
|