switchyard_protocol/
lib.rs1#![warn(missing_docs)]
5#![doc = include_str!("../README.md")]
6
7pub mod client;
8pub mod envelope;
9pub mod format;
10pub mod llm;
11pub mod metadata;
12pub mod model_id;
13pub mod stream;
14
15pub use client::*;
16pub use envelope::*;
17pub use format::*;
18pub use llm::*;
19pub use metadata::*;
20pub use model_id::*;
21pub use stream::*;
22
23pub fn text_request(model: Option<String>, prompt: impl Into<String>) -> LlmRequest {
28 LlmRequest {
29 model,
30 messages: vec![Message::text(Role::User, prompt)],
31 ..LlmRequest::default()
32 }
33}
34
35pub fn prompt_text(request: &LlmRequest) -> String {
40 request
41 .messages
42 .iter()
43 .filter(|message| message.role == Role::User)
44 .filter_map(|message| message.text_content("\n"))
45 .collect::<Vec<_>>()
46 .join("\n")
47}
48
49pub fn text_response(model: Option<String>, completion: impl Into<String>) -> AggLlmResponse {
54 AggLlmResponse {
55 model,
56 outputs: vec![ResponseOutput {
57 role: Role::Assistant,
58 content: vec![ContentBlock::Text {
59 text: completion.into(),
60 }],
61 stop_reason: None,
62 }],
63 ..AggLlmResponse::default()
64 }
65}
66
67pub fn completion_text(response: &AggLlmResponse) -> String {
73 response
74 .outputs
75 .first()
76 .map(|output| {
77 output
78 .content
79 .iter()
80 .filter_map(|block| match block {
81 ContentBlock::Text { text } => Some(text.as_str()),
82 _ => None,
83 })
84 .collect::<String>()
85 })
86 .unwrap_or_default()
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn request_round_trips_prompt_text() {
95 let req = text_request(Some("m".to_string()), "hello world");
96 assert_eq!(req.model.as_deref(), Some("m"));
97 assert_eq!(prompt_text(&req), "hello world");
98 }
99
100 #[test]
101 fn response_round_trips_completion_text() {
102 let resp = text_response(None, "the answer");
103 assert_eq!(completion_text(&resp), "the answer");
104 }
105
106 #[test]
107 fn empty_text_helpers_are_empty_strings() {
108 assert_eq!(prompt_text(&LlmRequest::default()), "");
109 assert_eq!(completion_text(&AggLlmResponse::default()), "");
110 }
111}