switchyard_libsy/algorithms/
passthrough.rs1use std::sync::Arc;
7
8use switchyard_protocol::{Category, Request};
9
10use crate::core::algorithm::{Algorithm, Driver};
11use crate::{LibsyError, Result, RoutingOutcome};
12
13pub struct Passthrough;
15
16#[async_trait::async_trait]
17impl Algorithm for Passthrough {
18 fn name(&self) -> &str {
19 "passthrough"
20 }
21
22 async fn route(self: Arc<Self>, driver: Driver, request: Request) -> Result<RoutingOutcome> {
23 let models = driver.models_for(&Category::Any).to_vec();
24 let Some(target) = models.first() else {
26 return Err(LibsyError::NoTargets);
27 };
28 tracing::info!(target = %target, "passthrough selected target");
29 Ok(RoutingOutcome::route_to(
30 target.clone(),
31 models[1..].to_vec(),
32 request,
33 ))
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use std::sync::Arc;
40
41 use super::Passthrough;
42 use crate::core::algorithm::Algorithm;
43 use crate::core::testing::{category_models, echo, test_drive_with_models};
44 use switchyard_protocol::{Category, Request, completion_text, text_request};
45
46 #[tokio::test]
47 async fn test_passthrough() -> crate::Result<()> {
48 const MODEL_ID: &str = "testing/passthrough";
49 let request = Request {
50 llm_request: text_request(Some("auto".to_string()), "hi"),
51 raw_request: None,
52 metadata: None,
53 };
54 let algorithm: Arc<dyn Algorithm> = Arc::new(Passthrough);
55 let models = category_models(Category::Any, &[MODEL_ID]);
56 let (selected_model, response) =
57 test_drive_with_models(algorithm, request, models, echo()).await?;
58
59 assert_eq!(
60 response
61 .llm_response
62 .as_agg()
63 .map(completion_text)
64 .unwrap_or_default(),
65 MODEL_ID
66 );
67 assert_eq!(selected_model, MODEL_ID);
68 Ok(())
69 }
70}