You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
proposal(client): let embedded LLM clients classify routing failures #865
An embedded RoutedLlmClient may already know why a model call failed and whether another Switchyard candidate can safely serve it. Some of this is now covered by existing LlmClientError variants. #887 added TemporarilyUnavailable, and #922 added Host while preserving the original error. Their fallback behavior is fixed by the variant.
What is still missing is a way to report the failure kind separately from whether routing should stop or try the next target.
Agree on the smallest provider-neutral contract that lets a client return:
a bounded, stable failure kind for telemetry; and
an explicit routing disposition such as Stop or NextTarget.
Existing built-in errors should keep their current behavior. Focused coverage should prove that NextTarget tries the next candidate and Stop terminates routing.
Non-goals
adopting a large provider failure taxonomy;
provider-exhaustion partitions or summaries;
implementing circuit-breaker state;
changing retry policy;
defining new server error bodies;
judge fail-open behavior; or
reclassifying connection timeouts.
LlmClientError is already #[non_exhaustive], so a new variant would be an additive Rust API change for external callers.
I'd like to take this on. Before opening a PR, I'd like to confirm this minimal API:
#[non_exhaustive]pubenumClientFailureKind{Unavailable,RequestRejected,Other,}pubenumRoutingDisposition{Stop,NextTarget,}// New variant in the existing non-exhaustive LlmClientError:Classified{kind:ClientFailureKind,disposition:RoutingDisposition,source:BoxError,}
The kind supplies a fixed telemetry label. The disposition alone controls whether the completed routing outcome tries another candidate. Stop returns the original failure. NextTarget advances if a candidate remains; otherwise it returns the last failure. The boxed source preserves the client's original error.
Existing error variants keep their fallback behavior. This leaves retries, judge failures, response-stream failures, connection-timeout classification, and server error bodies unchanged. It adds no circuit-breaker state or provider-exhaustion summary.
I have a local prototype with tests covering both dispositions across the three kinds, source preservation, and bounded telemetry labels. Rust workspace tests and workspace clippy pass.
The names and three failure kinds are proposed. Would this API and scope work for this issue?
Activity
ting-hong-shieh commentedon Sep 30, 2026
I'd like to take this on. Before opening a PR, I'd like to confirm this minimal API:
The kind supplies a fixed telemetry label. The disposition alone controls whether the completed routing outcome tries another candidate. Stop returns the original failure. NextTarget advances if a candidate remains; otherwise it returns the last failure. The boxed source preserves the client's original error.
Existing error variants keep their fallback behavior. This leaves retries, judge failures, response-stream failures, connection-timeout classification, and server error bodies unchanged. It adds no circuit-breaker state or provider-exhaustion summary.
I have a local prototype with tests covering both dispositions across the three kinds, source preservation, and bounded telemetry labels. Rust workspace tests and workspace clippy pass.
The names and three failure kinds are proposed. Would this API and scope work for this issue?