pub mod model_fetcher;
pub mod openai_compat;
pub mod openai_responses;
pub mod request_overrides;
pub mod responses_debug;
pub mod sse;
pub mod stream_tool_accumulator;
pub mod tool_schema;
pub(crate) fn looks_like_reasoning_unsupported_error(
status: reqwest::StatusCode,
body: &str,
) -> bool {
if !(status == 400 || status == 404 || status == 405 || status == 409 || status == 422) {
return false;
}
let b = body.to_ascii_lowercase();
let mentions_reasoning =
b.contains("reasoning") || b.contains("thinking") || b.contains("budget_tokens");
let indicates_unsupported = b.contains("unsupported")
|| b.contains("not supported")
|| b.contains("does not support")
|| b.contains("unknown parameter")
|| b.contains("unexpected parameter")
|| b.contains("unrecognized")
|| b.contains("invalid parameter");
mentions_reasoning && indicates_unsupported
}
#[cfg(test)]
mod reasoning_heuristic_tests {
use super::looks_like_reasoning_unsupported_error as f;
use reqwest::StatusCode;
#[test]
fn fires_only_on_reasoning_parameter_rejection() {
let bad = StatusCode::BAD_REQUEST;
assert!(f(bad, "reasoning_effort is not supported for this model"));
assert!(f(bad, "Unknown parameter: reasoning_effort"));
assert!(f(bad, "This model does not support reasoning"));
assert!(f(bad, "Unrecognized request argument: thinking"));
assert!(!f(bad, "Unknown parameter: temperature")); assert!(!f(
bad,
"Invalid value for 'reasoning_effort': must be one of low, medium, high"
)); assert!(!f(
bad,
"Invalid request: missing required field 'messages'"
));
assert!(!f(bad, "The model gpt-x is unknown or unsupported"));
assert!(!f(
StatusCode::INTERNAL_SERVER_ERROR,
"reasoning not supported"
));
}
}