deepseek_rust_cli/agent/
history.rs1use std::{fs, path::PathBuf};
2
3use crate::api::types::Message;
4
5fn repair_history(mut messages: Vec<Message>) -> Vec<Message> {
10 while messages.last().is_some_and(|m| m.role == "tool") {
12 messages.pop();
13 }
14 if messages
16 .last()
17 .is_some_and(|m| m.role == "assistant" && m.tool_calls.is_some())
18 {
19 messages.pop();
20 }
21
22 let mut i = 0;
26 while i < messages.len() {
27 if messages[i].role == "tool" {
28 let tool_id = messages[i].tool_call_id.as_deref().unwrap_or("");
29 let mut found = false;
31 for j in (0..i).rev() {
32 if messages[j].role == "assistant" {
33 if let Some(ref tcs) = messages[j].tool_calls {
34 if tcs.iter().any(|tc| tc.id == tool_id) {
35 found = true;
36 }
37 }
38 break; }
40 }
41 if !found {
42 messages.remove(i);
44 continue;
45 }
46 } else if messages[i].role == "assistant" && messages[i].tool_calls.is_some() {
47 let mut has_tool_response = false;
50 for msg in messages.iter().skip(i + 1) {
51 match msg.role.as_str() {
52 "tool" => {
53 has_tool_response = true;
54 }
55 "user" | "assistant" => {
56 break;
57 }
58 _ => {}
59 }
60 }
61 if !has_tool_response {
62 messages.remove(i);
64 continue;
65 }
66 }
67 i += 1;
68 }
69
70 messages
71}
72
73pub fn load_history(session_id: &str) -> Vec<Message> {
74 let path = get_history_path(session_id);
75 if let Some(msgs) = fs::read_to_string(path)
76 .ok()
77 .and_then(|c| serde_json::from_str::<Vec<Message>>(&c).ok())
78 {
79 let original_len = msgs.len();
80 let repaired = repair_history(msgs);
81 if repaired.len() != original_len {
83 save_history(session_id, &repaired);
84 }
85 return repaired;
86 }
87 Vec::new()
88}
89
90pub fn save_history(session_id: &str, messages: &[Message]) {
91 let path = get_history_path(session_id);
92 let _ = fs::create_dir_all(path.parent().unwrap());
93 if let Ok(json) = serde_json::to_string_pretty(messages) {
94 let _ = fs::write(path, json);
95 }
96}
97
98fn get_history_path(session_id: &str) -> PathBuf {
99 let mut path = PathBuf::from(".deep/history");
100 path.push(format!("{}.json", session_id));
101 path
102}