1use anyhow::{Context, Result};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct AutoResponse {
7 pub mode: String,
8 pub reason: String,
9}
10
11pub type AskResponse = String;
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
16pub struct CommandSuggestion {
17 pub cmd: String,
18 pub description: String,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct SuggestResponse {
24 pub suggestions: Vec<CommandSuggestion>,
25}
26
27pub fn parse_auto_mode(json_str: &str) -> Result<AutoResponse> {
29 let cleaned = extract_json(json_str);
30
31 serde_json::from_str(&cleaned).context("Failed to parse Auto Mode response")
32}
33
34pub fn parse_suggest(json_str: &str) -> Result<SuggestResponse> {
36 let cleaned = extract_json(json_str);
37
38 serde_json::from_str(&cleaned).context("Failed to parse Suggest response")
39}
40
41fn extract_json(text: &str) -> String {
43 let text = text.trim();
44
45 if let Some(start) = text.find("```")
47 && let Some(end) = text[start + 3..].find("```")
48 {
49 let json_block = &text[start + 3..start + 3 + end];
50 let json_content = if let Some(newline) = json_block.find('\n') {
51 &json_block[newline + 1..]
52 } else {
53 json_block
54 };
55 return json_content.trim().to_string();
56 }
57
58 if let Some(start) = text.find('{')
60 && let Some(end) = text.rfind('}')
61 && end > start
62 {
63 return text[start..=end].to_string();
64 }
65
66 text.to_string()
68}