github_mcp/prompts/
mod.rs1pub mod router;
6
7use rmcp::schemars;
8use serde::Deserialize;
9
10#[derive(Debug, Deserialize, schemars::JsonSchema)]
11pub struct MasterWorkflowArgs {
12 pub goal: Option<String>,
14}
15
16#[derive(Debug, Deserialize, schemars::JsonSchema)]
17pub struct PullRequestWorkflowArgs {
18 pub owner: Option<String>,
20 pub repo: Option<String>,
22 pub base_branch: Option<String>,
24 pub head_branch: Option<String>,
26}
27
28pub(crate) fn render_context_header(fields: &[(&str, Option<&str>)]) -> String {
33 if fields.is_empty() {
34 return String::new();
35 }
36 let mut out = String::from("## Context already provided\n");
37 let mut any_known = false;
38 for (name, value) in fields {
39 if let Some(v) = value {
40 out.push_str(&format!("- `{name}` = \"{v}\"\n"));
41 any_known = true;
42 }
43 }
44 if !any_known {
45 out.push_str("- (none — no arguments were supplied with this prompt request)\n");
46 }
47 let missing: Vec<_> = fields
48 .iter()
49 .filter(|(_, v)| v.is_none())
50 .map(|(n, _)| *n)
51 .collect();
52 if !missing.is_empty() {
53 out.push_str(&format!(
54 "\nStill unknown, ask the user before the step that needs it: {}\n",
55 missing.join(", ")
56 ));
57 }
58 out
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn empty_field_list_renders_nothing() {
67 assert_eq!(render_context_header(&[]), "");
68 }
69
70 #[test]
71 fn all_fields_supplied_lists_each_and_no_missing_section() {
72 let header =
73 render_context_header(&[("owner", Some("octocat")), ("repo", Some("hello-world"))]);
74 assert!(header.contains("`owner` = \"octocat\""));
75 assert!(header.contains("`repo` = \"hello-world\""));
76 assert!(!header.contains("Still unknown"));
77 }
78
79 #[test]
80 fn all_fields_missing_notes_none_supplied_and_lists_all_as_missing() {
81 let header = render_context_header(&[("owner", None), ("repo", None)]);
82 assert!(header.contains("(none — no arguments were supplied"));
83 assert!(
84 header
85 .contains("Still unknown, ask the user before the step that needs it: owner, repo")
86 );
87 }
88
89 #[test]
90 fn mixed_fields_report_supplied_and_missing_separately() {
91 let header = render_context_header(&[("owner", Some("octocat")), ("repo", None)]);
92 assert!(header.contains("`owner` = \"octocat\""));
93 assert!(!header.contains("`repo` ="));
94 assert!(header.contains("Still unknown, ask the user before the step that needs it: repo"));
95 }
96}