OpenPay (3 crates, ~13k LOC, 175 tests) op-connect sub-merchant onboarding + KYB + split-payments + payouts + 1099-K op-3ds2 3DS2.3 SCA processor (AReq/ARes/CReq/CRes/RReq/RRes + exemptions) op-tax US/EU/UK/AU/CA/IN tax with Avalara/Stripe/CCH/Vertex/TaxJar adapters Smart Byte (3 crates, ~7k LOC, 57 tests) smart-byte-libp2p libp2p transport (kad/gossipsub/mdns/autonat/relay/dcutr/identify/ping/req_resp) smart-byte-crdt LWW/GCounter/PnCounter/OrSet/LwwMap/RgaList/2P-Set + HLC + vector clock + Automerge/Yjs interop smart-byte-keri-witness KERI key-rotation cycle + witness layer + watchers + recovery + delegation EOC (3 crates, ~8k LOC, 108 tests) eoc-tools function-calling across Anthropic/OpenAI/Google/Mistral/Cohere + parallel exec + sandbox eoc-multimodal vision (CLIP/SigLIP/ColPali) + audio (Whisper/MMS) + video sampling + modality router eoc-spec-decode vanilla + SpS-with-temp + lookahead speculative decoding + EAGLE/Medusa stubs All three workspaces compile cleanly. Forbidden-unsafe, no unwrap outside tests. Co-Authored-By: Claude Opus 4.7 <[email protected]>
93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
//! Typed errors for the multi-modal surface.
|
|
|
|
use thiserror::Error;
|
|
|
|
/// Errors raised by multi-modal ingestion, preprocessing, transport, or
|
|
/// routing.
|
|
#[derive(Debug, Error)]
|
|
pub enum MultimodalError {
|
|
/// Underlying transport (HTTP) failed.
|
|
#[error("network error: {0}")]
|
|
Network(String),
|
|
|
|
/// Vendor returned a non-2xx status code or rejected the payload.
|
|
#[error("vendor error (status={status}): {body}")]
|
|
Vendor {
|
|
/// HTTP status code.
|
|
status: u16,
|
|
/// Truncated response body.
|
|
body: String,
|
|
},
|
|
|
|
/// HTTP 429 — the vendor rate-limited the request.
|
|
#[error("rate limited (retry-after: {retry_after_secs:?}s)")]
|
|
RateLimited {
|
|
/// Seconds the vendor asked us to wait, when provided.
|
|
retry_after_secs: Option<u64>,
|
|
},
|
|
|
|
/// HTTP 401/403 — the API key was rejected.
|
|
#[error("invalid api key")]
|
|
InvalidApiKey,
|
|
|
|
/// The named model is not known to the vendor / local registry.
|
|
#[error("model not found: {0}")]
|
|
ModelNotFound(String),
|
|
|
|
/// I/O failure while reading a file-backed reference.
|
|
#[error("io error: {0}")]
|
|
Io(String),
|
|
|
|
/// Image / audio decoding failed.
|
|
#[error("decode error: {0}")]
|
|
Decode(String),
|
|
|
|
/// A required modality is missing from the [`crate::MultimodalQuery`].
|
|
#[error("missing modality: {0:?}")]
|
|
MissingModality(crate::Modality),
|
|
|
|
/// The configured backend cannot satisfy the requested modality.
|
|
#[error("unsupported modality: {0:?}")]
|
|
Unsupported(crate::Modality),
|
|
|
|
/// A feature-gated backend was invoked but the feature is disabled.
|
|
#[error("feature not enabled: {0}")]
|
|
FeatureDisabled(&'static str),
|
|
|
|
/// Response payload could not be parsed.
|
|
#[error("parse error: {0}")]
|
|
Parse(String),
|
|
}
|
|
|
|
/// Convenience alias.
|
|
pub type MultimodalResult<T> = std::result::Result<T, MultimodalError>;
|
|
|
|
impl From<reqwest::Error> for MultimodalError {
|
|
fn from(err: reqwest::Error) -> Self {
|
|
MultimodalError::Network(err.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<serde_json::Error> for MultimodalError {
|
|
fn from(err: serde_json::Error) -> Self {
|
|
MultimodalError::Parse(err.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<std::io::Error> for MultimodalError {
|
|
fn from(err: std::io::Error) -> Self {
|
|
MultimodalError::Io(err.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<image::ImageError> for MultimodalError {
|
|
fn from(err: image::ImageError) -> Self {
|
|
MultimodalError::Decode(err.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<base64::DecodeError> for MultimodalError {
|
|
fn from(err: base64::DecodeError) -> Self {
|
|
MultimodalError::Decode(err.to_string())
|
|
}
|
|
}
|