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 route(self: Arc<Self>, driver: Driver, request: Request) -> Result<Response> {
33        let decision: Decision = Decision::new(
34            self.target.semantic_name.clone(),
35            Some(format!(
36                "passthrough selected target '{}'",
37                self.target.semantic_name
38            )),
39            true,
40        );
41        driver.decide(decision.clone()).await?;
42        driver.call_model(request, decision).await
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use std::sync::Arc;
49
50    use super::Passthrough;
51    use crate::core::algorithm::{Algorithm, LlmTarget};
52    use crate::core::testing::{echo, test_drive};
53    use switchyard_protocol::{Request, completion_text, text_request};
54
55    #[tokio::test]
56    async fn test_passthrough() -> crate::Result<()> {
57        const MODEL_ID: &str = "testing/passthrough";
58        let request = Request {
59            llm_request: text_request(Some("auto".to_string()), "hi"),
60            raw_request: None,
61            metadata: None,
62        };
63        let algorithm: Arc<dyn Algorithm> = Arc::new(Passthrough::new(LlmTarget {
64            semantic_name: MODEL_ID.to_string(),
65        }));
66        let (trace, response) = test_drive(algorithm, request, echo()).await?;
67
68        assert_eq!(
69            response
70                .llm_response
71                .as_agg()
72                .map(completion_text)
73                .unwrap_or_default(),
74            MODEL_ID
75        );
76        assert_eq!(trace.len(), 1);
77        assert_eq!(trace[0].selected_model_id(), MODEL_ID);
78        assert!(trace[0].is_answer_call());
79        Ok(())
80    }
81}