mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-29 01:42:19 +00:00
* refactor(ocr): extract call completion boundary * fix(ocr): release completion state after dispatch * test(ocr): prove wrapper completion handoff * test(ocr): narrow mapped failure assertion * fix(ocr): preserve wrapper invocation kwargs * fix(ocr): retain completion through finalization * fix(ocr): make completion ownership explicit * refactor(ocr): resolve logging executor explicitly * fix(callbacks): preserve completion lifecycle behavior * refactor(ocr): move public OCR into native lifecycle * refactor(ocr): remove unused rust bridge capability * wip * wip * refactor * wip * fix(ocr): preserve reducto native compatibility * wip * fix(ocr): document native callable casts * perf(ocr): bound responses and reduce native scheduling overhead * refactor(python-bridge): organize placeholder routes * refactor test * fix(ocr): normalize DeepSeek document content * perf(ocr): skip unused callback work and benchmark callback overhead * fix(ocr): align conversion contracts * test(ocr): cover official provider response shapes * fix(ocr): restore Python fallback and honor Rust opt-out * fixes and refactor * fix(ocr): preserve Azure Document Intelligence authentication * fix(rust): enforce OCR response limits and lint contracts * test(rust): align native OCR contract coverage * test(ocr): isolate Azure auth precedence coverage
65 lines
2.5 KiB
Rust
65 lines
2.5 KiB
Rust
use litellm_core::error::Error;
|
|
use pyo3::exceptions::{PyRuntimeError, PyValueError};
|
|
use pyo3::prelude::*;
|
|
|
|
pyo3::create_exception!(
|
|
_native,
|
|
RustBridgeDeclined,
|
|
pyo3::exceptions::PyException,
|
|
"The route declined before calling the provider, so the host may retry on its own path."
|
|
);
|
|
|
|
pyo3::create_exception!(
|
|
_native,
|
|
RustUpstreamError,
|
|
pyo3::exceptions::PyException,
|
|
"The provider call was already issued and failed. Args are (status, message); status is 0 when there was no HTTP response."
|
|
);
|
|
|
|
pub(crate) fn core_error_to_pyerr(err: Error) -> PyErr {
|
|
match err {
|
|
Error::Auth(message) => PyValueError::new_err(message),
|
|
Error::InvalidProvider(_)
|
|
| Error::InvalidRequest(_)
|
|
| Error::InvalidType { .. }
|
|
| Error::MissingField(_)
|
|
| Error::MissingDocumentUrl => PyValueError::new_err(err.to_string()),
|
|
other => PyRuntimeError::new_err(other.to_string()),
|
|
}
|
|
}
|
|
|
|
/// Map a core error for a route whose host keeps a Python implementation.
|
|
///
|
|
/// The distinction the host needs is whether the provider was already called.
|
|
/// Everything raised before the request goes out is safe for the host to retry
|
|
/// on its own path; anything after it is not, because the provider has already
|
|
/// done the work and billed for it.
|
|
pub(crate) fn chat_completions_error_to_pyerr(err: Error) -> PyErr {
|
|
match err {
|
|
Error::Unsupported(_)
|
|
| Error::Auth(_)
|
|
| Error::InvalidProvider(_)
|
|
| Error::InvalidRequest(_)
|
|
| Error::InvalidType { .. }
|
|
| Error::MissingField(_)
|
|
| Error::MissingDocumentUrl
|
|
| Error::MissingApiKey { .. }
|
|
| Error::MissingAzureAiCredentials
|
|
| Error::MissingAzureDocumentIntelligenceCredentials
|
|
| Error::MissingReductoApiKey
|
|
| Error::Routing(_)
|
|
// Nothing reached the provider, so serving it on Python cannot double
|
|
// bill and is the only way the caller gets an answer at all.
|
|
| Error::Connect(_) => RustBridgeDeclined::new_err(err.to_string()),
|
|
Error::Http { status, body } => RustUpstreamError::new_err((status, body)),
|
|
Error::Network(message) | Error::InvalidResponse(message) => {
|
|
RustUpstreamError::new_err((0u16, message))
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
let py = module.py();
|
|
module.add("RustBridgeDeclined", py.get_type::<RustBridgeDeclined>())?;
|
|
module.add("RustUpstreamError", py.get_type::<RustUpstreamError>())
|
|
}
|