switchyard_libsy/algorithms/
noop.rs1use std::sync::Arc;
7
8use switchyard_protocol::{
9 AggLlmResponse, ContentBlock, LlmResponse, Request, Response, ResponseOutput, Role, StopReason,
10};
11
12use crate::Result;
13use crate::core::algorithm::{Algorithm, Driver};
14use switchyard_protocol::{Context, Decision};
15
16pub struct Noop {}
18
19pub struct NoopDecision {
21 model: String,
22}
23
24impl Decision for NoopDecision {
25 fn selected_model(&self) -> &str {
26 &self.model
27 }
28 fn reasoning(&self) -> Option<&str> {
29 None
30 }
31 fn as_any(&self) -> &dyn std::any::Any {
32 self
33 }
34}
35
36#[async_trait::async_trait]
37impl Algorithm for Noop {
38 fn name(&self) -> &str {
39 "noop"
40 }
41
42 async fn create_run_task(
43 self: Arc<Self>,
44 ctx: Context,
45 driver: Driver,
46 request: Request,
47 ) -> Result<Response> {
48 let model = request
49 .requested_model()
50 .unwrap_or("switchyard/noop")
51 .to_string();
52 let decision: Arc<dyn Decision> = Arc::new(NoopDecision {
53 model: model.clone(),
54 });
55 driver.info(ctx, decision.clone()).await?;
56
57 let llm_response = LlmResponse::Agg(AggLlmResponse {
58 id: Some("switchyard-noop".to_string()),
59 model: Some(model),
60 outputs: vec![ResponseOutput {
61 role: Role::Assistant,
62 content: vec![ContentBlock::Text {
63 text: "OK".to_string(),
64 }],
65 stop_reason: Some(StopReason::EndTurn),
66 }],
67 ..Default::default()
68 });
69 let response = Response {
70 llm_response,
71 metadata: request.metadata.clone(),
72 };
73 Ok(response)
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use switchyard_protocol::{LlmRequest, Message, Role};
80
81 use super::*;
82
83 #[tokio::test]
84 async fn test_noop_algo() -> Result<()> {
85 const TEST_MODEL: &str = "test_noop_algo";
86 let request = Request {
87 llm_request: LlmRequest {
88 model: Some(TEST_MODEL.to_string()),
89 messages: vec![Message::text(Role::User, "hi")],
90 ..LlmRequest::default()
91 },
92 raw_request: None,
93 metadata: None,
94 };
95
96 let a: Arc<dyn Algorithm> = Arc::new(Noop {});
97 let (decisions, response) = a.run(Context::default(), request).await?;
98 let Some(decision) = decisions.first() else {
99 panic!("Expected exactly one Decision");
100 };
101 assert_eq!(decision.selected_model(), TEST_MODEL);
102 assert_eq!(response.selected_model(), Some(TEST_MODEL));
103 Ok(())
104 }
105}