Skip to main content

switchyard_libsy/algorithms/
passthrough.rs

1// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Single-target routing for direct model calls and integration diagnostics.
5
6use std::sync::Arc;
7
8use switchyard_protocol::{Request, Response};
9
10use crate::Result;
11use crate::core::algorithm::{Algorithm, Driver, LlmTarget};
12use switchyard_protocol::Decision;
13
14/// Routing algorithm that always calls one configured target.
15pub struct Passthrough {
16    target: LlmTarget,
17}
18
19impl Passthrough {
20    /// Creates an algorithm that always calls `target`.
21    pub fn new(target: LlmTarget) -> Self {
22        Passthrough { target }
23    }
24}
25
26#[async_trait::async_trait]
27impl Algorithm for Passthrough {
28    fn name(&self) -> &str {
29        "passthrough"
30    }
31
32    async fn create_run_task(
33        self: Arc<Self>,
34        driver: Driver,
35        request: Request,
36    ) -> Result<Response> {
37        let decision: Decision = Decision::new(
38            self.target.semantic_name.clone(),
39            Some(format!(
40                "passthrough selected target '{}'",
41                self.target.semantic_name
42            )),
43            true,
44        );
45        driver.info(decision.clone()).await?;
46        driver.call_model(request, decision).await
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use std::sync::Arc;
53
54    use super::Passthrough;
55    use crate::core::algorithm::{Algorithm, LlmTarget};
56    use crate::core::testing::{echo, test_drive};
57    use switchyard_protocol::{Request, completion_text, text_request};
58
59    #[tokio::test]
60    async fn test_passthrough() -> crate::Result<()> {
61        const MODEL_ID: &str = "testing/passthrough";
62        let request = Request {
63            llm_request: text_request(Some("auto".to_string()), "hi"),
64            raw_request: None,
65            metadata: None,
66        };
67        let algorithm: Arc<dyn Algorithm> = Arc::new(Passthrough::new(LlmTarget {
68            semantic_name: MODEL_ID.to_string(),
69        }));
70        let (trace, response) = test_drive(algorithm, request, echo()).await?;
71
72        assert_eq!(
73            response
74                .llm_response
75                .as_agg()
76                .map(completion_text)
77                .unwrap_or_default(),
78            MODEL_ID
79        );
80        assert_eq!(trace.len(), 1);
81        assert_eq!(trace[0].selected_model_id(), MODEL_ID);
82        assert!(trace[0].is_answer_call());
83        Ok(())
84    }
85}