graphrag_core/graphrag/
lifecycle.rs1#![allow(unused_imports)]
2
3use crate::config::Config;
4use crate::core::{
5 ChunkId, Document, DocumentId, Entity, EntityId, GraphRAGError, KnowledgeGraph, Relationship,
6 Result, TextChunk,
7};
8use crate::{critic, ollama, persistence, query, retrieval};
9
10#[cfg(feature = "parallel-processing")]
11#[allow(unused_imports)]
12use crate::parallel;
13
14use super::GraphRAG;
15
16impl GraphRAG {
17 pub fn new(config: Config) -> Result<Self> {
19 Ok(Self {
20 config,
21 knowledge_graph: None,
22 retrieval_system: None,
23 query_planner: None,
24 critic: None,
25 #[cfg(feature = "parallel-processing")]
26 parallel_processor: None,
27 })
28 }
29
30 pub fn default_local() -> Result<Self> {
33 let mut config = Config::default();
34 config.ollama.enabled = true;
36 Self::new(config)
39 }
40
41 pub fn builder() -> crate::builder::GraphRAGBuilder {
56 crate::builder::GraphRAGBuilder::new()
57 }
58
59 pub fn initialize(&mut self) -> Result<()> {
65 let loaded = self.try_load_from_workspace();
67
68 if !loaded {
69 self.knowledge_graph = Some(KnowledgeGraph::new());
70 }
71
72 self.retrieval_system = Some(retrieval::RetrievalSystem::new(&self.config)?);
73
74 if self.config.ollama.enabled {
75 let client = ollama::OllamaClient::new(self.config.ollama.clone());
76 self.query_planner = Some(query::planner::QueryPlanner::new(client));
77 }
78
79 Ok(())
80 }
81
82 fn try_load_from_workspace(&mut self) -> bool {
85 if !self.config.auto_save.enabled {
86 return false;
87 }
88 let base_dir = match &self.config.auto_save.base_dir {
89 Some(d) => d.clone(),
90 None => return false,
91 };
92 let workspace_name = self
93 .config
94 .auto_save
95 .workspace_name
96 .as_deref()
97 .unwrap_or("default");
98
99 let manager = match persistence::WorkspaceManager::new(&base_dir) {
100 Ok(m) => m,
101 Err(_e) => {
102 #[cfg(feature = "tracing")]
103 tracing::warn!("Could not open workspace base dir '{}': {}", base_dir, _e);
104 return false;
105 },
106 };
107
108 if !manager.workspace_exists(workspace_name) {
109 return false;
110 }
111
112 match manager.load_graph(workspace_name) {
113 Ok(graph) => {
114 #[cfg(feature = "tracing")]
115 tracing::info!(
116 "Loaded graph from workspace '{}' ({} entities, {} relationships)",
117 workspace_name,
118 graph.entity_count(),
119 graph.relationship_count(),
120 );
121 self.knowledge_graph = Some(graph);
122 true
123 },
124 Err(_e) => {
125 #[cfg(feature = "tracing")]
126 tracing::warn!(
127 "Failed to load graph from workspace '{}': {}",
128 workspace_name,
129 _e
130 );
131 false
132 },
133 }
134 }
135
136 pub fn save_to_workspace(&self) -> Result<()> {
139 if !self.config.auto_save.enabled {
140 return Ok(());
141 }
142 let base_dir = match &self.config.auto_save.base_dir {
143 Some(d) => d,
144 None => return Ok(()),
145 };
146 let workspace_name = self
147 .config
148 .auto_save
149 .workspace_name
150 .as_deref()
151 .unwrap_or("default");
152
153 let graph = self
154 .knowledge_graph
155 .as_ref()
156 .ok_or_else(|| GraphRAGError::Config {
157 message: "Knowledge graph not initialized".to_string(),
158 })?;
159
160 let manager = persistence::WorkspaceManager::new(base_dir)?;
161 manager.save_graph(graph, workspace_name)?;
162
163 #[cfg(feature = "tracing")]
164 tracing::info!(
165 "Saved graph to workspace '{}' in '{}' ({} entities, {} relationships)",
166 workspace_name,
167 base_dir,
168 graph.entity_count(),
169 graph.relationship_count(),
170 );
171 Ok(())
172 }
173
174 pub fn clear_graph(&mut self) -> Result<()> {
179 let graph = self
180 .knowledge_graph
181 .as_mut()
182 .ok_or_else(|| GraphRAGError::Config {
183 message: "Knowledge graph not initialized".to_string(),
184 })?;
185
186 #[cfg(feature = "tracing")]
187 tracing::info!("Clearing knowledge graph (preserving documents and chunks)");
188
189 graph.clear_entities_and_relationships();
190 Ok(())
191 }
192}