switchyard_libsy/algorithms/
noop.rs1use std::sync::Arc;
7
8use switchyard_protocol::{
9 AggLlmResponse, ContentBlock, LlmResponse, ModelId, Request, Response, ResponseOutput, Role,
10 StopReason,
11};
12
13use crate::core::algorithm::{Algorithm, Driver};
14use crate::{Result, RoutingOutcome};
15
16pub struct Noop {}
18
19#[async_trait::async_trait]
20impl Algorithm for Noop {
21 fn name(&self) -> &str {
22 "noop"
23 }
24
25 async fn route(self: Arc<Self>, _driver: Driver, request: Request) -> Result<RoutingOutcome> {
26 let streaming = request.llm_request.stream;
27 let model_id = request
28 .model_id()
29 .unwrap_or_else(|| ModelId::from("switchyard/noop"));
30 tracing::info!(target = %model_id, "noop returned its synthetic response");
31 let aggregate = AggLlmResponse {
32 id: Some("switchyard-noop".to_string()),
33 model: Some(model_id.to_string()),
34 outputs: vec![ResponseOutput {
35 url_citations: Vec::new(),
36 role: Role::Assistant,
37 content: vec![ContentBlock::Text {
38 text: "OK".to_string(),
39 }],
40 stop_reason: Some(StopReason::EndTurn),
41 }],
42 ..Default::default()
43 };
44 let llm_response = if streaming {
45 LlmResponse::Stream(aggregate.into_stream())
46 } else {
47 LlmResponse::Agg(aggregate)
48 };
49 let response = Response {
50 llm_response,
51 metadata: request.metadata.clone(),
52 upstream_headers: http::HeaderMap::new(),
53 };
54 Ok(RoutingOutcome::answered(model_id, request, response))
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use switchyard_protocol::{LlmRequest, Message, Role};
61
62 use super::*;
63 use crate::core::testing::{echo, test_drive};
64
65 #[tokio::test]
66 async fn test_noop_algo() -> Result<()> {
67 const TEST_MODEL: &str = "test_noop_algo";
68 let request = Request {
69 llm_request: LlmRequest {
70 model: Some(TEST_MODEL.to_string()),
71 messages: vec![Message::text(Role::User, "hi")],
72 ..LlmRequest::default()
73 },
74 raw_request: None,
75 metadata: None,
76 };
77
78 let a: Arc<dyn Algorithm> = Arc::new(Noop {});
81 let (selected_model, response) = test_drive(a, request, echo()).await?;
82 assert_eq!(selected_model, TEST_MODEL);
83 assert_eq!(response.selected_model(), Some(TEST_MODEL));
84 Ok(())
85 }
86
87 #[tokio::test]
88 async fn test_noop_algo_streams_when_requested() -> Result<()> {
89 let request = Request {
90 llm_request: LlmRequest {
91 model: Some("streaming-noop".to_string()),
92 messages: vec![Message::text(Role::User, "hi")],
93 stream: true,
94 ..LlmRequest::default()
95 },
96 raw_request: None,
97 metadata: None,
98 };
99
100 let algorithm: Arc<dyn Algorithm> = Arc::new(Noop {});
101 let (_, response) = test_drive(algorithm, request, echo()).await?;
102
103 assert!(matches!(response.llm_response, LlmResponse::Stream(_)));
104 Ok(())
105 }
106}