1use assistant_context_editor::SavedContextMetadata;
2use chrono::{DateTime, Utc};
3use gpui::{Entity, prelude::*};
4
5use crate::thread_store::{SerializedThreadMetadata, ThreadStore};
6
7pub enum HistoryEntry {
8 Thread(SerializedThreadMetadata),
9 Context(SavedContextMetadata),
10}
11
12impl HistoryEntry {
13 pub fn updated_at(&self) -> DateTime<Utc> {
14 match self {
15 HistoryEntry::Thread(thread) => thread.updated_at,
16 HistoryEntry::Context(context) => context.mtime.to_utc(),
17 }
18 }
19}
20
21pub struct HistoryStore {
22 thread_store: Entity<ThreadStore>,
23 context_store: Entity<assistant_context_editor::ContextStore>,
24}
25
26impl HistoryStore {
27 pub fn new(
28 thread_store: Entity<ThreadStore>,
29 context_store: Entity<assistant_context_editor::ContextStore>,
30 _cx: &mut Context<Self>,
31 ) -> Self {
32 Self {
33 thread_store,
34 context_store,
35 }
36 }
37
38 /// Returns the number of history entries.
39 pub fn entry_count(&self, cx: &mut Context<Self>) -> usize {
40 self.entries(cx).len()
41 }
42
43 pub fn entries(&self, cx: &mut Context<Self>) -> Vec<HistoryEntry> {
44 let mut history_entries = Vec::new();
45
46 #[cfg(debug_assertions)]
47 if std::env::var("ZED_SIMULATE_NO_THREAD_HISTORY").is_ok() {
48 return history_entries;
49 }
50
51 for thread in self.thread_store.update(cx, |this, _cx| this.threads()) {
52 history_entries.push(HistoryEntry::Thread(thread));
53 }
54
55 for context in self.context_store.update(cx, |this, _cx| this.contexts()) {
56 history_entries.push(HistoryEntry::Context(context));
57 }
58
59 history_entries.sort_unstable_by_key(|entry| std::cmp::Reverse(entry.updated_at()));
60 history_entries
61 }
62
63 pub fn recent_entries(&self, limit: usize, cx: &mut Context<Self>) -> Vec<HistoryEntry> {
64 self.entries(cx).into_iter().take(limit).collect()
65 }
66}