1use super::types::{
5 Prompt, PromptArgument, PromptContent, PromptMessage, PromptRole, PromptsGetResult, TextContent,
6};
7use std::collections::HashMap;
8
9#[derive(Debug, Default)]
11pub struct PromptRegistry {
12 prompts: HashMap<String, RegisteredPrompt>,
13}
14
15#[derive(Debug, Clone)]
17pub struct RegisteredPrompt {
18 pub definition: Prompt,
19 pub template: String,
20}
21
22impl PromptRegistry {
23 pub fn new() -> Self {
25 let mut registry = Self::default();
26 registry.register_default_prompts();
27 registry
28 }
29
30 fn register_default_prompts(&mut self) {
32 self.register(RegisteredPrompt {
34 definition: Prompt {
35 name: "voice-command".to_string(),
36 description: Some(
37 "Process a voice command and generate an appropriate response".to_string(),
38 ),
39 arguments: Some(vec![
40 PromptArgument {
41 name: "command".to_string(),
42 description: Some("The transcribed voice command".to_string()),
43 required: true,
44 },
45 PromptArgument {
46 name: "context".to_string(),
47 description: Some("Additional context about the user's environment".to_string()),
48 required: false,
49 },
50 ]),
51 },
52 template: "You are a voice assistant. Process this command: {{command}}\n\nContext: {{context}}".to_string(),
53 });
54
55 self.register(RegisteredPrompt {
57 definition: Prompt {
58 name: "haptic-feedback".to_string(),
59 description: Some(
60 "Generate haptic feedback pattern based on notification type".to_string(),
61 ),
62 arguments: Some(vec![
63 PromptArgument {
64 name: "notification_type".to_string(),
65 description: Some(
66 "Type of notification (alert, message, reminder)".to_string(),
67 ),
68 required: true,
69 },
70 PromptArgument {
71 name: "urgency".to_string(),
72 description: Some("Urgency level (low, medium, high)".to_string()),
73 required: false,
74 },
75 ]),
76 },
77 template:
78 "Generate a haptic pattern for: {{notification_type}} with urgency: {{urgency}}"
79 .to_string(),
80 });
81
82 self.register(RegisteredPrompt {
84 definition: Prompt {
85 name: "code-assist".to_string(),
86 description: Some("Assist with code-related tasks via voice".to_string()),
87 arguments: Some(vec![
88 PromptArgument {
89 name: "task".to_string(),
90 description: Some("The coding task to perform".to_string()),
91 required: true,
92 },
93 PromptArgument {
94 name: "language".to_string(),
95 description: Some("Programming language".to_string()),
96 required: false,
97 },
98 PromptArgument {
99 name: "file_context".to_string(),
100 description: Some("Current file or code context".to_string()),
101 required: false,
102 },
103 ]),
104 },
105 template: "Help with this coding task: {{task}}\nLanguage: {{language}}\nContext: {{file_context}}".to_string(),
106 });
107
108 self.register(RegisteredPrompt {
110 definition: Prompt {
111 name: "system-control".to_string(),
112 description: Some("Control system settings and preferences".to_string()),
113 arguments: Some(vec![PromptArgument {
114 name: "action".to_string(),
115 description: Some("The system action to perform".to_string()),
116 required: true,
117 }]),
118 },
119 template: "Execute system control action: {{action}}".to_string(),
120 });
121 }
122
123 pub fn register(&mut self, prompt: RegisteredPrompt) {
125 self.prompts.insert(prompt.definition.name.clone(), prompt);
126 }
127
128 pub fn list(&self) -> Vec<Prompt> {
130 self.prompts
131 .values()
132 .map(|p| p.definition.clone())
133 .collect()
134 }
135
136 pub fn get(
138 &self,
139 name: &str,
140 arguments: Option<&HashMap<String, String>>,
141 ) -> Option<PromptsGetResult> {
142 let registered = self.prompts.get(name)?;
143
144 let mut rendered = registered.template.clone();
146 if let Some(args) = arguments {
147 for (key, value) in args {
148 rendered = rendered.replace(&format!("{{{{{}}}}}", key), value);
149 }
150 }
151 rendered = regex::Regex::new(r"\{\{[^}]+\}\}")
153 .ok()?
154 .replace_all(&rendered, "")
155 .to_string();
156
157 Some(PromptsGetResult {
158 description: registered.definition.description.clone(),
159 messages: vec![PromptMessage {
160 role: PromptRole::User,
161 content: PromptContent::Text(TextContent::new(rendered)),
162 }],
163 })
164 }
165
166 pub fn contains(&self, name: &str) -> bool {
168 self.prompts.contains_key(name)
169 }
170}