from dataclasses import dataclass from techdocs_graphrag.answering import GraphRAGAssistant from techdocs_graphrag.config import Settings, get_settings from techdocs_graphrag.extraction import GraphExtractor from techdocs_graphrag.graph_store import Neo4jGraphStore from techdocs_graphrag.indexing import IndexingPipeline from techdocs_graphrag.ingestion import ParagraphSplitter from techdocs_graphrag.llm import OpenAIGateway from techdocs_graphrag.retrieval import HybridRetriever @dataclass(frozen=True, slots=True) class Services: settings: Settings store: Neo4jGraphStore assistant: GraphRAGAssistant indexer: IndexingPipeline def close(self) -> None: self.store.close() def build_services(settings: Settings | None = None) -> Services: settings = settings or get_settings() llm = OpenAIGateway(settings) store = Neo4jGraphStore(settings) retriever = HybridRetriever( llm=llm, store=store, top_k=settings.vector_top_k, max_hops=settings.graph_max_hops, max_facts=settings.graph_max_facts, ) indexer = IndexingPipeline( splitter=ParagraphSplitter(settings.chunk_size, settings.chunk_overlap), llm=llm, extractor=GraphExtractor(llm), store=store, workers=settings.extraction_workers, ) return Services( settings=settings, store=store, assistant=GraphRAGAssistant(retriever=retriever, llm=llm), indexer=indexer, )