agixt_sdk/client/
conversations.rs

1use crate::error::Result;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Debug, Serialize, Deserialize)]
6pub struct ConversationHistory {
7    pub conversation_history: Vec<Message>,
8}
9
10#[derive(Debug, Serialize, Deserialize)]
11pub struct Message {
12    pub role: String,
13    pub content: String,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub id: Option<String>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub timestamp: Option<String>,
18}
19
20impl super::AGiXTSDK {
21    /// Get list of conversations
22    pub async fn get_conversations(&self, _agent_name: Option<&str>) -> Result<Vec<String>> {
23        let response = self
24            .client
25            .get(&format!("{}/api/conversations", self.base_uri))
26            .headers(self.headers.lock().await.clone())
27            .send()
28            .await?;
29
30        let status = response.status();
31        let text = response.text().await?;
32
33        if self.verbose {
34            self.parse_response(status, &text).await?;
35        }
36
37        #[derive(Deserialize)]
38        struct ConversationsResponse {
39            conversations: Vec<String>,
40        }
41
42        let result: ConversationsResponse = serde_json::from_str(&text)?;
43        Ok(result.conversations)
44    }
45
46    /// Get conversations with IDs
47    pub async fn get_conversations_with_ids(&self) -> Result<Vec<HashMap<String, String>>> {
48        let response = self
49            .client
50            .get(&format!("{}/api/conversations", self.base_uri))
51            .headers(self.headers.lock().await.clone())
52            .send()
53            .await?;
54
55        let status = response.status();
56        let text = response.text().await?;
57
58        if self.verbose {
59            self.parse_response(status, &text).await?;
60        }
61
62        #[derive(Deserialize)]
63        struct ConversationsResponse {
64            conversations_with_ids: Vec<HashMap<String, String>>,
65        }
66
67        let result: ConversationsResponse = serde_json::from_str(&text)?;
68        Ok(result.conversations_with_ids)
69    }
70
71    /// Get conversation history
72    pub async fn get_conversation(
73        &self,
74        agent_name: &str,
75        conversation_name: &str,
76        limit: Option<i32>,
77        page: Option<i32>,
78    ) -> Result<Vec<Message>> {
79        let request = serde_json::json!({
80            "conversation_name": conversation_name,
81            "agent_name": agent_name,
82            "limit": limit.unwrap_or(100),
83            "page": page.unwrap_or(1),
84        });
85
86        let response = self
87            .client
88            .get(&format!("{}/api/conversation", self.base_uri))
89            .headers(self.headers.lock().await.clone())
90            .json(&request)
91            .send()
92            .await?;
93
94        let status = response.status();
95        let text = response.text().await?;
96
97        if self.verbose {
98            self.parse_response(status, &text).await?;
99        }
100
101        let result: ConversationHistory = serde_json::from_str(&text)?;
102        Ok(result.conversation_history)
103    }
104
105    /// Fork a conversation
106    pub async fn fork_conversation(&self, conversation_name: &str, message_id: &str) -> Result<String> {
107        let request = serde_json::json!({
108            "conversation_name": conversation_name,
109            "message_id": message_id,
110        });
111
112        let response = self
113            .client
114            .post(&format!("{}/api/conversation/fork", self.base_uri))
115            .headers(self.headers.lock().await.clone())
116            .json(&request)
117            .send()
118            .await?;
119
120        let status = response.status();
121        let text = response.text().await?;
122
123        if self.verbose {
124            self.parse_response(status, &text).await?;
125        }
126
127        #[derive(Deserialize)]
128        struct MessageResponse {
129            message: String,
130        }
131
132        let result: MessageResponse = serde_json::from_str(&text)?;
133        Ok(result.message)
134    }
135
136    /// Create a new conversation
137    pub async fn new_conversation(
138        &self,
139        agent_name: &str,
140        conversation_name: &str,
141        conversation_content: Option<Vec<Message>>,
142    ) -> Result<Vec<Message>> {
143        let request = serde_json::json!({
144            "conversation_name": conversation_name,
145            "agent_name": agent_name,
146            "conversation_content": conversation_content.unwrap_or_default(),
147        });
148
149        let response = self
150            .client
151            .post(&format!("{}/api/conversation", self.base_uri))
152            .headers(self.headers.lock().await.clone())
153            .json(&request)
154            .send()
155            .await?;
156
157        let status = response.status();
158        let text = response.text().await?;
159
160        if self.verbose {
161            self.parse_response(status, &text).await?;
162        }
163
164        let result: ConversationHistory = serde_json::from_str(&text)?;
165        Ok(result.conversation_history)
166    }
167
168    /// Rename a conversation
169    pub async fn rename_conversation(
170        &self,
171        agent_name: &str,
172        conversation_name: &str,
173        new_name: &str,
174    ) -> Result<String> {
175        let request = serde_json::json!({
176            "conversation_name": conversation_name,
177            "new_conversation_name": new_name,
178            "agent_name": agent_name,
179        });
180
181        let response = self
182            .client
183            .put(&format!("{}/api/conversation", self.base_uri))
184            .headers(self.headers.lock().await.clone())
185            .json(&request)
186            .send()
187            .await?;
188
189        let status = response.status();
190        let text = response.text().await?;
191
192        if self.verbose {
193            self.parse_response(status, &text).await?;
194        }
195
196        #[derive(Deserialize)]
197        struct ConversationResponse {
198            conversation_name: String,
199        }
200
201        let result: ConversationResponse = serde_json::from_str(&text)?;
202        Ok(result.conversation_name)
203    }
204
205    /// Delete a conversation
206    pub async fn delete_conversation(&self, agent_name: &str, conversation_name: &str) -> Result<String> {
207        let request = serde_json::json!({
208            "conversation_name": conversation_name,
209            "agent_name": agent_name,
210        });
211
212        let response = self
213            .client
214            .delete(&format!("{}/api/conversation", self.base_uri))
215            .headers(self.headers.lock().await.clone())
216            .json(&request)
217            .send()
218            .await?;
219
220        let status = response.status();
221        let text = response.text().await?;
222
223        if self.verbose {
224            self.parse_response(status, &text).await?;
225        }
226
227        #[derive(Deserialize)]
228        struct MessageResponse {
229            message: String,
230        }
231
232        let result: MessageResponse = serde_json::from_str(&text)?;
233        Ok(result.message)
234    }
235
236    /// Add a new message to a conversation
237    pub async fn new_conversation_message(
238        &self,
239        role: &str,
240        message: &str,
241        conversation_name: &str,
242    ) -> Result<String> {
243        let request = serde_json::json!({
244            "role": role,
245            "message": message,
246            "conversation_name": conversation_name,
247        });
248
249        let response = self
250            .client
251            .post(&format!("{}/api/conversation/message", self.base_uri))
252            .headers(self.headers.lock().await.clone())
253            .json(&request)
254            .send()
255            .await?;
256
257        let status = response.status();
258        let text = response.text().await?;
259
260        if self.verbose {
261            self.parse_response(status, &text).await?;
262        }
263
264        #[derive(Deserialize)]
265        struct MessageResponse {
266            message: String,
267        }
268
269        let result: MessageResponse = serde_json::from_str(&text)?;
270        Ok(result.message)
271    }
272}
273
274#[cfg(test)]
275mod tests {
276    use crate::AGiXTSDK;
277    use mockito;
278
279    #[tokio::test]
280    async fn test_get_conversations() {
281        let mut mock_server = mockito::Server::new();
282        let _mock = mock_server
283            .mock("GET", "/api/conversations")
284            .with_status(200)
285            .with_header("content-type", "application/json")
286            .with_body(r#"{"conversations": ["conv1", "conv2"]}"#)
287            .create();
288
289        let client = AGiXTSDK::new(Some(mock_server.url()), None, false);
290        let conversations = client.get_conversations(None).await.unwrap();
291        
292        assert_eq!(conversations, vec!["conv1", "conv2"]);
293    }
294}