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