GraphRAG Engine Contract¶
Feature: 016-graphrag-integration Date: 2025-12-27 Type: Internal Python API
1. Overview¶
This contract defines the internal Python API for the GraphRAG engine integration. It specifies the interfaces between HoloDeck components and the GraphRAG library.
2. GraphRAGEngine Class¶
The main interface for GraphRAG operations, matching the existing VectorStoreTool pattern.
2.1 Class Definition¶
class GraphRAGEngine:
"""GraphRAG engine for knowledge graph-based retrieval.
Provides initialization, indexing, and search capabilities
for GraphRAG-based vectorstore tools.
"""
def __init__(
self,
config: VectorstoreTool,
base_dir: str | None = None,
execution_config: ExecutionConfig | None = None,
) -> None:
"""Initialize GraphRAG engine.
Args:
config: VectorstoreTool configuration with engine="graphrag"
base_dir: Base directory for resolving paths
execution_config: Execution settings (for interface compat)
Raises:
ValueError: If config.engine != "graphrag"
ImportError: If graphrag package not installed
"""
...
@property
def is_initialized(self) -> bool:
"""Whether the engine has been initialized."""
...
@property
def index_stats(self) -> dict[str, int]:
"""Statistics about the built index.
Returns:
Dict with keys: entities, relationships, communities, files
"""
...
async def initialize(
self,
force_reindex: bool = False,
) -> None:
"""Initialize the GraphRAG engine.
Steps:
1. Resolve source path
2. Set up storage directories
3. Build or load index
4. Initialize search engine
Args:
force_reindex: Force rebuild even if index is current
Raises:
FileNotFoundError: If source path doesn't exist
IndexingError: If GraphRAG indexing fails
"""
...
async def search(self, query: str) -> str:
"""Search the knowledge graph.
Args:
query: The search query
Returns:
Formatted search results as string
Raises:
RuntimeError: If engine not initialized
"""
...
async def close(self) -> None:
"""Clean up resources."""
...
3. GraphRAGStorage Class¶
Manages artifact storage and index metadata.
3.1 Class Definition¶
class GraphRAGStorage:
"""Manages GraphRAG artifact storage and index metadata.
Storage layout:
.holodeck/graphrag/{tool_name}/
├── output/ # GraphRAG parquet artifacts
├── cache/ # LLM call cache
├── logs/ # Pipeline logs
├── lancedb/ # Entity embeddings
└── index.meta # Index metadata
"""
REQUIRED_TABLES: ClassVar[list[str]] = [
"create_final_entities",
"create_final_relationships",
"create_final_communities",
"create_final_community_reports",
"create_final_text_units",
]
def __init__(
self,
tool_config: VectorstoreTool,
base_dir: Path | None = None,
) -> None:
"""Initialize storage manager."""
...
@property
def storage_dir(self) -> Path:
"""Root storage directory for this tool."""
...
@property
def output_dir(self) -> Path:
"""Directory for GraphRAG parquet output."""
...
def ensure_directories(self) -> None:
"""Create storage directories if needed."""
...
def has_valid_index(self) -> bool:
"""Check if all required output tables exist."""
...
def get_metadata(self) -> IndexMetadata | None:
"""Load index metadata if exists."""
...
def save_metadata(self, metadata: IndexMetadata) -> None:
"""Save index metadata to disk."""
...
def compute_source_hash(self, source_path: Path) -> str:
"""Compute hash of source files for change detection."""
...
def needs_reindex(self, source_path: Path) -> bool:
"""Check if source files changed since last index."""
...
def clear_index(self) -> None:
"""Delete all index artifacts."""
...
def load_table(self, table_name: str) -> pd.DataFrame:
"""Load a parquet table as DataFrame."""
...
4. GraphRAGIndexer Class¶
Orchestrates the indexing pipeline.
4.1 Class Definition¶
class GraphRAGIndexer:
"""Orchestrates GraphRAG indexing pipeline."""
def __init__(
self,
tool_config: VectorstoreTool,
storage: GraphRAGStorage,
) -> None:
"""Initialize indexer."""
...
async def build_index(
self,
source_path: Path,
force: bool = False,
) -> IndexMetadata:
"""Build or update the GraphRAG index.
Args:
source_path: Path to source documents
force: Force rebuild even if current
Returns:
Index metadata
Raises:
IndexingError: If indexing fails
"""
...
5. Config Generation Function¶
5.1 Function Definition¶
def build_graphrag_config(
tool_config: VectorstoreTool,
storage_dir: Path,
input_dir: Path,
) -> GraphRagConfig:
"""Build GraphRagConfig from HoloDeck configuration.
Maps HoloDeck VectorstoreTool settings to GraphRAG's
native GraphRagConfig format.
Args:
tool_config: VectorstoreTool with engine="graphrag"
storage_dir: Directory for GraphRAG artifacts
input_dir: Directory containing source documents
Returns:
GraphRagConfig ready for indexing/search
Raises:
ValueError: If required configuration missing
"""
...
6. Error Types¶
6.1 Custom Exceptions¶
class IndexingError(Exception):
"""Raised when GraphRAG indexing fails."""
pass
7. Integration Points¶
7.1 VectorStoreTool Modifications¶
# In vectorstore_tool.py
class VectorStoreTool:
_graphrag_engine: GraphRAGEngine | None = None
async def initialize(
self,
force_ingest: bool = False,
provider_type: str | None = None,
) -> None:
# NEW: Branch on engine type
if self.config.engine == "graphrag":
await self._initialize_graphrag(force_ingest)
return
# Existing code for default engine...
async def _initialize_graphrag(
self,
force_ingest: bool = False,
) -> None:
"""Initialize GraphRAG engine."""
if not GRAPHRAG_AVAILABLE:
raise ImportError(
"GraphRAG requires: pip install holodeck[graphrag]"
)
from holodeck.lib.graphrag.engine import GraphRAGEngine
self._graphrag_engine = GraphRAGEngine(
config=self.config,
base_dir=self._base_dir,
)
await self._graphrag_engine.initialize(force_reindex=force_ingest)
self.is_initialized = True
async def search(self, query: str) -> str:
# NEW: Delegate to GraphRAG engine
if self.config.engine == "graphrag":
if self._graphrag_engine is None:
raise RuntimeError("GraphRAG engine not initialized")
return await self._graphrag_engine.search(query)
# Existing search code...
8. YAML Configuration Schema¶
8.1 Minimal Configuration¶
tools:
- name: knowledge_graph
type: vectorstore
engine: graphrag
source: data/documents/
description: Search knowledge graph
8.2 Full Configuration¶
tools:
- name: entity_search
type: vectorstore
engine: graphrag
source: data/company_docs/
description: Search for entities and relationships
graphrag:
search_mode: local
community_level: 2
indexing_model:
provider: openai
name: gpt-4o-mini
temperature: 0.0
search_model:
provider: openai
name: gpt-4o
temperature: 0.0
entity_types:
- organization
- person
- product
- technology
chunk_size: 300
chunk_overlap: 100
max_gleanings: 1
skip_claim_extraction: true
9. Response Format¶
9.1 Search Response¶
def _format_result(result: SearchResult) -> str:
"""Format GraphRAG search result for agent consumption."""
lines = [
f"**GraphRAG {result.search_mode.title()} Search Result**",
"",
result.response,
"",
"---",
f"*Mode: {result.search_mode} | "
f"Entities: {result.entities_used} | "
f"Communities: {result.communities_used}*",
]
if result.sources:
lines.append("")
lines.append("**Sources:**")
for source in result.sources[:5]:
lines.append(f"- {source}")
return "\n".join(lines)
10. Thread Safety¶
All public methods are async and designed for single-threaded async execution within an agent loop. No special thread-safety considerations required.
11. Version Compatibility¶
| Component | Version Requirement |
|---|---|
| graphrag | >=0.5.0,<1.0.0 |
| Python | >=3.10 |
| pandas | >=2.0 |
| pydantic | >=2.0 |