switchyard_libsy/algorithms/
passthrough.rs1use std::sync::Arc;
7
8use switchyard_protocol::{ModelId, Request, Response};
9
10use crate::Result;
11use crate::core::algorithm::{Algorithm, Driver};
12use switchyard_protocol::Decision;
13
14pub struct Passthrough {
16 target: ModelId,
17}
18
19impl Passthrough {
20 pub fn new(target: impl Into<ModelId>) -> Self {
22 Passthrough {
23 target: target.into(),
24 }
25 }
26}
27
28#[async_trait::async_trait]
29impl Algorithm for Passthrough {
30 fn name(&self) -> &str {
31 "passthrough"
32 }
33
34 async fn route(self: Arc<Self>, driver: Driver, request: Request) -> Result<Response> {
35 let decision: Decision = Decision::new(
36 self.target.clone(),
37 Some(format!("passthrough selected target '{}'", self.target)),
38 true,
39 );
40 driver.decide(decision.clone()).await?;
41 driver.call_model(request, decision).await
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use std::sync::Arc;
48
49 use super::Passthrough;
50 use crate::core::algorithm::Algorithm;
51 use crate::core::testing::{echo, test_drive};
52 use switchyard_protocol::{Request, completion_text, text_request};
53
54 #[tokio::test]
55 async fn test_passthrough() -> crate::Result<()> {
56 const MODEL_ID: &str = "testing/passthrough";
57 let request = Request {
58 llm_request: text_request(Some("auto".to_string()), "hi"),
59 raw_request: None,
60 metadata: None,
61 };
62 let algorithm: Arc<dyn Algorithm> = Arc::new(Passthrough::new(MODEL_ID));
63 let (trace, response) = test_drive(algorithm, request, echo()).await?;
64
65 assert_eq!(
66 response
67 .llm_response
68 .as_agg()
69 .map(completion_text)
70 .unwrap_or_default(),
71 MODEL_ID
72 );
73 assert_eq!(trace.len(), 1);
74 assert_eq!(trace[0].selected_model_id(), MODEL_ID);
75 assert!(trace[0].is_answer_call());
76 Ok(())
77 }
78}