1use crate::error::CliResult;
4use rustyline::DefaultEditor;
5
6pub struct ChatSession {
8 pub provider: String,
9 pub model: String,
10 pub history: Vec<ChatMessage>,
11}
12
13#[derive(Debug, Clone)]
15pub struct ChatMessage {
16 pub role: String,
17 pub content: String,
18}
19
20impl ChatSession {
21 pub fn new(provider: String, model: String) -> Self {
23 Self {
24 provider,
25 model,
26 history: Vec::new(),
27 }
28 }
29
30 pub fn start(&mut self) -> CliResult<()> {
32 let mut rl =
33 DefaultEditor::new().map_err(|e| crate::error::CliError::Internal(e.to_string()))?;
34
35 println!("Entering chat mode. Type 'exit' to quit.");
36 println!("Provider: {}, Model: {}", self.provider, self.model);
37
38 loop {
39 let readline = rl.readline("r[ > ");
40 match readline {
41 Ok(line) => {
42 if line.trim() == "exit" {
43 println!("Goodbye!");
44 break;
45 }
46
47 if !line.trim().is_empty() {
48 self.history.push(ChatMessage {
50 role: "user".to_string(),
51 content: line.clone(),
52 });
53
54 println!("Processing: {}", line);
56 }
57 }
58 Err(_) => {
59 println!("Goodbye!");
60 break;
61 }
62 }
63 }
64
65 Ok(())
66 }
67
68 pub fn add_message(&mut self, role: String, content: String) {
70 self.history.push(ChatMessage { role, content });
71 }
72
73 pub fn get_history(&self) -> &[ChatMessage] {
75 &self.history
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_chat_session_creation() {
85 let session = ChatSession::new("openai".to_string(), "gpt-4".to_string());
86 assert_eq!(session.provider, "openai");
87 assert_eq!(session.model, "gpt-4");
88 assert!(session.history.is_empty());
89 }
90
91 #[test]
92 fn test_add_message() {
93 let mut session = ChatSession::new("openai".to_string(), "gpt-4".to_string());
94 session.add_message("user".to_string(), "Hello".to_string());
95 assert_eq!(session.history.len(), 1);
96 assert_eq!(session.history[0].role, "user");
97 assert_eq!(session.history[0].content, "Hello");
98 }
99
100 #[test]
101 fn test_get_history() {
102 let mut session = ChatSession::new("openai".to_string(), "gpt-4".to_string());
103 session.add_message("user".to_string(), "Hello".to_string());
104 session.add_message("assistant".to_string(), "Hi there!".to_string());
105
106 let history = session.get_history();
107 assert_eq!(history.len(), 2);
108 }
109}