Skip to main content

cognee_http_server/
components.rs

1//! `ComponentHandles` — pre-built component instances passed to P2 handlers.
2//!
3//! This struct is a lightweight alternative to `cognee_lib::ComponentManager`
4//! that avoids a dependency cycle: `cognee-lib` may eventually import
5//! `cognee-http-server`, so `cognee-http-server` must not import `cognee-lib`.
6//!
7//! All components are eagerly initialized in `AppState::build`; there is no
8//! lazy caching here (unlike `ComponentManager`'s `RwLock` slots).
9
10use std::sync::Arc;
11
12use cognee_core::CpuPool;
13use cognee_database::AclDb;
14use cognee_database::{CheckpointStore, DatabaseConnection};
15use cognee_delete::DeleteService;
16use cognee_embedding::EmbeddingEngine;
17use cognee_graph::GraphDBTrait;
18use cognee_llm::Llm;
19use cognee_llm::ResponsesClient;
20use cognee_llm::Transcriber;
21use cognee_ontology::{OntologyManager, OntologyResolver};
22use cognee_search::{SearchOrchestrator, SessionManager, SessionStore};
23use cognee_storage::StorageTrait;
24use cognee_vector::VectorDB;
25
26use crate::cloud_client::CloudDeleteClient;
27use crate::notebook_runner::NotebookRunner;
28
29/// Pre-initialized pipeline component handles shared across all P2 handlers.
30///
31/// Obtained from `state.components()`.
32#[derive(Clone)]
33pub struct ComponentHandles {
34    /// SeaORM database connection (implements `IngestDb`, `DeleteDb`).
35    /// The `AclDb` implementation is provided by the closed
36    /// `cognee-access-control` crate and wired through [`Self::acl_db`].
37    pub database: Arc<DatabaseConnection>,
38
39    /// Optional ACL backend. `None` in pure-OSS builds (which do not enforce
40    /// permissions). Wired by the closed cloud assembly to a newtype that
41    /// implements `AclDb` over the shared `DatabaseConnection`.
42    pub acl_db: Option<Arc<dyn AclDb>>,
43
44    /// File storage backend.
45    pub storage: Arc<dyn StorageTrait>,
46
47    /// Fully configured `DeleteService` (with storage + DB wired).
48    pub delete_service: Arc<DeleteService>,
49
50    /// Optional cloud delete proxy used by `POST /api/v1/forget`.
51    pub cloud_client: Option<Arc<dyn CloudDeleteClient>>,
52
53    /// Ontology manager (per-user file storage).
54    pub ontology_manager: Arc<OntologyManager>,
55
56    // ── P4 read-path slots ────────────────────────────────────────────────
57    //
58    // Optional handles wired by embedders that want the full read-path
59    // surface. Each slot is `None` by default; the relevant routers
60    // surface a 500-level error when the corresponding handle is missing.
61    /// Pre-built search orchestrator. `None` means HTTP search is unwired
62    /// — handlers return `SearchError {500, "Internal server error"}`.
63    pub search_orchestrator: Option<Arc<SearchOrchestrator>>,
64
65    /// Configured LLM adapter for `/api/v1/llm/*` handlers.
66    pub llm: Option<Arc<dyn Llm>>,
67
68    /// Transcriber for audio document processing (Whisper). `None` when the
69    /// configured LLM provider does not support audio transcription.
70    pub transcriber: Option<Arc<dyn Transcriber>>,
71
72    /// Knowledge-graph DB used by the visualize router.
73    pub graph_db: Option<Arc<dyn GraphDBTrait>>,
74
75    /// Vector DB handle required by [`cognee_core::TaskContext`] when the
76    /// add / cognify / memify convenience functions route through
77    /// `pipeline::execute` (LIB-06). `None` means the corresponding
78    /// pipeline handlers surface a 500 / 409 envelope at runtime.
79    pub vector_db: Option<Arc<dyn VectorDB>>,
80
81    /// CPU pool used by [`cognee_core::TaskContext`]. Same routing notes
82    /// as [`vector_db`](Self::vector_db).
83    pub thread_pool: Option<Arc<dyn CpuPool>>,
84
85    /// Text embedding engine used by the cognify pipeline (chunks, entities,
86    /// summaries). `None` means the cognify / update handlers surface a 500
87    /// envelope at runtime.
88    pub embedding_engine: Option<Arc<dyn EmbeddingEngine>>,
89
90    /// Ontology resolver passed into the cognify pipeline. `None` means
91    /// the cognify / update handlers fall back to a pass-through
92    /// `NoOpOntologyResolver`, matching the CLI default when no
93    /// `ontology_file_path` is configured.
94    pub ontology_resolver: Option<Arc<dyn OntologyResolver>>,
95
96    /// Backing store for session Q&A history — wires the `session` source
97    /// of `POST /api/v1/recall` (Python `_search_session`,
98    /// `recall.py:146-208`). `None` means session-source recall returns
99    /// empty (matches Python's `is_available` short-circuit at
100    /// `recall.py:170-171`). Reuses the `SessionStore` re-exported by
101    /// `cognee-search` to avoid pulling `cognee-session` into the crate's
102    /// non-dev dependency graph.
103    pub session_store: Option<Arc<dyn SessionStore>>,
104
105    /// Manager for agent-trace sessions and the per-session graph context
106    /// snapshot — wires the `trace` and `graph_context` sources of
107    /// `POST /api/v1/recall` (Python `_search_trace` /
108    /// `_fetch_graph_context`). `None` means both sources return empty.
109    pub session_manager: Option<Arc<SessionManager>>,
110
111    /// Checkpoint store used by improve Stage 4 (`sync_graph_to_session`) to
112    /// persist per-session high-water marks and avoid re-syncing old edges.
113    pub checkpoint_store: Option<Arc<dyn CheckpointStore>>,
114
115    /// OpenAI Responses API client — wires `POST /api/v1/responses`
116    /// (Python `get_responses_router.py`). `None` means the handler
117    /// returns `500` "responses client is not wired" until embedders
118    /// populate it.
119    pub responses_client: Option<Arc<dyn ResponsesClient>>,
120
121    /// Notebook cell execution backend used by
122    /// `POST /api/v1/notebooks/{notebook_id}/{cell_id}/run`. `None` means
123    /// the handler returns 501 — the same envelope it returned in Stage A
124    /// before Stage B landed — preserving wire compatibility for embedders
125    /// that don't want to expose code execution.
126    pub notebook_runner: Option<Arc<dyn NotebookRunner>>,
127}
128
129impl ComponentHandles {
130    /// Return the formatted knowledge-graph data for a dataset as the JSON
131    /// shape `{"nodes": [...], "edges": [...]}`.
132    ///
133    /// Wires to `cognee_graph::get_formatted_graph_data` when both a
134    /// `graph_db` handle and a `dataset_id` are available. When either is
135    /// missing — e.g. the server is running in test mode without backends —
136    /// returns the empty-graph fallback `{"nodes": [], "edges": []}` so that
137    /// the WS frame still has a valid shape.
138    ///
139    /// Python parity: `cognee.modules.graph.methods.get_formatted_graph_data`.
140    pub async fn formatted_graph_data(
141        &self,
142        dataset_id: Option<uuid::Uuid>,
143        user_id: uuid::Uuid,
144    ) -> Result<serde_json::Value, anyhow::Error> {
145        let Some(graph_db) = self.graph_db.as_ref() else {
146            return Ok(serde_json::json!({"nodes": [], "edges": []}));
147        };
148        let Some(did) = dataset_id else {
149            return Ok(serde_json::json!({"nodes": [], "edges": []}));
150        };
151        cognee_graph::get_formatted_graph_data(graph_db.as_ref(), did, user_id)
152            .await
153            .map_err(|e| anyhow::anyhow!("get_formatted_graph_data failed: {e}"))
154    }
155}