vector-graph-rag 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/PKG-INFO +17 -3
  2. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/README.md +11 -0
  3. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/faq.md +1 -1
  4. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/getting-started.md +6 -0
  5. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/README.md +1 -1
  6. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/pyproject.toml +6 -4
  7. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/__init__.py +8 -8
  8. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/api/app.py +130 -68
  9. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/config.py +14 -27
  10. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/graph/builder.py +5 -8
  11. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/graph/graph.py +45 -21
  12. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/graph/knowledge_graph.py +14 -11
  13. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/graph/retriever.py +9 -10
  14. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/llm/__init__.py +2 -2
  15. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/llm/cache.py +23 -33
  16. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/llm/extractor.py +22 -22
  17. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/llm/reranker.py +7 -20
  18. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/loaders/__init__.py +11 -19
  19. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/loaders/chunker.py +3 -3
  20. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/loaders/converter.py +7 -8
  21. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/loaders/url_fetcher.py +25 -26
  22. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/models.py +23 -36
  23. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/rag.py +42 -37
  24. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/storage/embeddings.py +19 -23
  25. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/storage/milvus.py +27 -14
  26. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/uv.lock +61 -54
  27. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/.dockerignore +0 -0
  28. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/.env.example +0 -0
  29. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/.github/workflows/docs.yml +0 -0
  30. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/.github/workflows/release.yml +0 -0
  31. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/.gitignore +0 -0
  32. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/Dockerfile +0 -0
  33. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/LICENSE +0 -0
  34. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/api/__init__.py +0 -0
  35. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/api/main.py +0 -0
  36. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/api/schemas.py +0 -0
  37. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/assets/logo.png +0 -0
  38. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/assets/logo.svg +0 -0
  39. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/design-philosophy.md +0 -0
  40. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/evaluation.md +0 -0
  41. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/frontend.md +0 -0
  42. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/how-it-works.md +0 -0
  43. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/index.md +0 -0
  44. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/python-api.md +0 -0
  45. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/rest-api.md +0 -0
  46. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/stylesheets/custom.css +0 -0
  47. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/docs/use-cases.md +0 -0
  48. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/2wikimultihopqa.json +0 -0
  49. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/2wikimultihopqa_corpus.json +0 -0
  50. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/hotpotqa.json +0 -0
  51. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/hotpotqa_corpus.json +0 -0
  52. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/musique.json +0 -0
  53. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/musique_corpus.json +0 -0
  54. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/ner_cache/2wikimultihopqa_queries.named_entity_output.tsv +0 -0
  55. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/ner_cache/hotpotqa_queries.named_entity_output.tsv +0 -0
  56. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/ner_cache/hotpotqa_train_queries.named_entity_output.tsv +0 -0
  57. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/ner_cache/musique_queries.named_entity_output.tsv +0 -0
  58. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/ner_cache/sample_queries.named_entity_output.tsv +0 -0
  59. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/openie_2wikimultihopqa_results_ner_gpt-3.5-turbo-1106_6119.json +0 -0
  60. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/openie_hotpotqa_results_ner_gpt-3.5-turbo-1106_9221.json +0 -0
  61. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/openie_musique_results_ner_gpt-3.5-turbo-1106_11656.json +0 -0
  62. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/openie_test_sample_results_ner_gpt-3.5-turbo-1106_20.json +0 -0
  63. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/test_sample.json +0 -0
  64. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/data/test_sample_corpus.json +0 -0
  65. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/evaluation/evaluate.py +0 -0
  66. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/.gitignore +0 -0
  67. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/README.md +0 -0
  68. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/eslint.config.js +0 -0
  69. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/index.html +0 -0
  70. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/package-lock.json +0 -0
  71. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/package.json +0 -0
  72. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/public/vite.svg +0 -0
  73. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/App.css +0 -0
  74. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/App.tsx +0 -0
  75. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/api/client.ts +0 -0
  76. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/api/queries.ts +0 -0
  77. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/assets/react.svg +0 -0
  78. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/graph/EntityNode.tsx +0 -0
  79. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/graph/GraphCanvas.tsx +0 -0
  80. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/graph/GraphLegend.tsx +0 -0
  81. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/graph/RelationEdge.tsx +0 -0
  82. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/graph/index.ts +0 -0
  83. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/CreateGraphDialog.tsx +0 -0
  84. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/FileUploader.tsx +0 -0
  85. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/GraphSelector.tsx +0 -0
  86. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/GraphStatsPreview.tsx +0 -0
  87. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/ImportDialog.tsx +0 -0
  88. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/ImportProgress.tsx +0 -0
  89. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/ImportSettings.tsx +0 -0
  90. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/import/UrlInput.tsx +0 -0
  91. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/panels/AnswerPanel.tsx +0 -0
  92. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/panels/NodeDetailPanel.tsx +0 -0
  93. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/panels/index.ts +0 -0
  94. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/search/SearchInput.tsx +0 -0
  95. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/search/index.ts +0 -0
  96. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/settings/SettingsDialog.tsx +0 -0
  97. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/timeline/ProcessTimeline.tsx +0 -0
  98. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/timeline/index.ts +0 -0
  99. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/Header.tsx +0 -0
  100. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/button.tsx +0 -0
  101. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/dialog.tsx +0 -0
  102. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/input.tsx +0 -0
  103. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/label.tsx +0 -0
  104. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/progress.tsx +0 -0
  105. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/switch.tsx +0 -0
  106. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/components/ui/tabs.tsx +0 -0
  107. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/hooks/use-toast.ts +0 -0
  108. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/index.css +0 -0
  109. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/main.tsx +0 -0
  110. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/stores/datasetStore.ts +0 -0
  111. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/stores/graphStore.ts +0 -0
  112. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/stores/searchStore.ts +0 -0
  113. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/types/api.ts +0 -0
  114. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/utils/cn.ts +0 -0
  115. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/src/utils/graphLayout.ts +0 -0
  116. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/tsconfig.app.json +0 -0
  117. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/tsconfig.json +0 -0
  118. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/tsconfig.node.json +0 -0
  119. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/frontend/vite.config.ts +0 -0
  120. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/mkdocs.yml +0 -0
  121. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/api/__init__.py +0 -0
  122. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/graph/__init__.py +4 -4
  123. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/src/vector_graph_rag/storage/__init__.py +1 -1
  124. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/tests/__init__.py +0 -0
  125. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/tests/conftest.py +0 -0
  126. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/tests/test_api.py +0 -0
  127. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/tests/test_graph.py +0 -0
  128. {vector_graph_rag-0.1.3 → vector_graph_rag-0.1.4}/tests/test_milvus_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vector-graph-rag
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: A Graph RAG implementation using pure vector search with Milvus
5
5
  Project-URL: Homepage, https://github.com/zilliztech/vector-graph-rag
6
6
  Project-URL: Documentation, https://zilliztech.github.io/vector-graph-rag/
@@ -31,14 +31,14 @@ Requires-Dist: scipy>=1.10.0
31
31
  Requires-Dist: setuptools<71
32
32
  Requires-Dist: tenacity>=8.2.0
33
33
  Requires-Dist: tiktoken>=0.5.0
34
- Requires-Dist: torch>=2.0.0
35
34
  Requires-Dist: tqdm>=4.65.0
36
- Requires-Dist: transformers>=4.30.0
37
35
  Provides-Extra: all
38
36
  Requires-Dist: fastapi>=0.109.0; extra == 'all'
39
37
  Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
40
38
  Requires-Dist: pytest>=7.0.0; extra == 'all'
41
39
  Requires-Dist: ruff>=0.1.0; extra == 'all'
40
+ Requires-Dist: torch>=2.0.0; extra == 'all'
41
+ Requires-Dist: transformers>=4.30.0; extra == 'all'
42
42
  Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'all'
43
43
  Provides-Extra: api
44
44
  Requires-Dist: fastapi>=0.109.0; extra == 'api'
@@ -49,6 +49,9 @@ Requires-Dist: pytest>=7.0.0; extra == 'dev'
49
49
  Requires-Dist: ruff>=0.1.0; extra == 'dev'
50
50
  Provides-Extra: docs
51
51
  Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
52
+ Provides-Extra: hf
53
+ Requires-Dist: torch>=2.0.0; extra == 'hf'
54
+ Requires-Dist: transformers>=4.30.0; extra == 'hf'
52
55
  Provides-Extra: loaders
53
56
  Requires-Dist: lxml-html-clean; extra == 'loaders'
54
57
  Requires-Dist: markitdown[docx,pdf]>=0.1.4; extra == 'loaders'
@@ -108,6 +111,17 @@ uv add "vector-graph-rag[loaders]"
108
111
 
109
112
  </details>
110
113
 
114
+ <details>
115
+ <summary><b>With local HuggingFace embedding models</b></summary>
116
+
117
+ ```bash
118
+ pip install "vector-graph-rag[hf]"
119
+ # or
120
+ uv add "vector-graph-rag[hf]"
121
+ ```
122
+
123
+ </details>
124
+
111
125
  ## 🚀 Quick Start
112
126
 
113
127
  ```python
@@ -51,6 +51,17 @@ uv add "vector-graph-rag[loaders]"
51
51
 
52
52
  </details>
53
53
 
54
+ <details>
55
+ <summary><b>With local HuggingFace embedding models</b></summary>
56
+
57
+ ```bash
58
+ pip install "vector-graph-rag[hf]"
59
+ # or
60
+ uv add "vector-graph-rag[hf]"
61
+ ```
62
+
63
+ </details>
64
+
54
65
  ## 🚀 Quick Start
55
66
 
56
67
  ```python
@@ -70,7 +70,7 @@ Frequently asked questions about Vector Graph RAG — covering when to use it, c
70
70
  ```
71
71
 
72
72
  ??? note "Can I use my own embeddings?"
73
- Vector Graph RAG uses OpenAI embedding models by default (`text-embedding-3-large`), but you can configure the embedding model via the `embedding_model` parameter. Any model accessible through the OpenAI-compatible API will work. If you are using a local or custom embedding endpoint, set the appropriate base URL and model name. The embedding dimensionality is detected automatically. Note that all entities, relations, and passages in a single graph must use the same embedding model — mixing models within one collection prefix is not supported.
73
+ Vector Graph RAG uses OpenAI embedding models by default (`text-embedding-3-large`), but you can configure the embedding model via the `embedding_model` parameter. Any model accessible through the OpenAI-compatible API will work. If you are using a local HuggingFace embedding model, install the optional dependencies with `pip install "vector-graph-rag[hf]"`. The embedding dimensionality is detected automatically. Note that all entities, relations, and passages in a single graph must use the same embedding model — mixing models within one collection prefix is not supported.
74
74
 
75
75
  ??? note "How do I deploy to production?"
76
76
  For production deployments, use a remote Milvus instance instead of Milvus Lite for better performance, scalability, and persistence. Run the FastAPI backend behind a reverse proxy (e.g., Nginx) with appropriate rate limiting and authentication. The frontend can be built as static files and served from any CDN or static file server.
@@ -20,6 +20,12 @@
20
20
  pip install "vector-graph-rag[loaders]"
21
21
  ```
22
22
 
23
+ === "With local embeddings"
24
+
25
+ ```bash
26
+ pip install "vector-graph-rag[hf]"
27
+ ```
28
+
23
29
  !!! note "Prerequisites"
24
30
  - Python 3.9+
25
31
  - An OpenAI API key (set `OPENAI_API_KEY` environment variable)
@@ -74,7 +74,7 @@ These triplets were extracted using GPT-3.5-Turbo (1106) with HippoRAG's OpenIE
74
74
 
75
75
  1. Install dependencies:
76
76
  ```bash
77
- uv sync
77
+ uv sync --extra hf
78
78
  ```
79
79
 
80
80
  2. Set environment variables:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vector-graph-rag"
3
- version = "0.1.3"
3
+ version = "0.1.4"
4
4
  description = "A Graph RAG implementation using pure vector search with Milvus"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -32,8 +32,6 @@ dependencies = [
32
32
  "tqdm>=4.65.0",
33
33
  "tiktoken>=0.5.0",
34
34
  "tenacity>=8.2.0",
35
- "transformers>=4.30.0",
36
- "torch>=2.0.0",
37
35
  "langchain-core>=0.3.0",
38
36
  "python-multipart>=0.0.22",
39
37
  "setuptools<71", # Required for pkg_resources used by milvus-lite
@@ -49,8 +47,12 @@ api = [
49
47
  "fastapi>=0.109.0",
50
48
  "uvicorn[standard]>=0.27.0",
51
49
  ]
50
+ hf = [
51
+ "transformers>=4.30.0",
52
+ "torch>=2.0.0",
53
+ ]
52
54
  all = [
53
- "vector-graph-rag[dev,api]",
55
+ "vector-graph-rag[dev,api,hf]",
54
56
  ]
55
57
  loaders = [
56
58
  "markitdown[docx,pdf]>=0.1.4",
@@ -6,19 +6,19 @@ using only vector similarity search, without requiring a separate graph database
6
6
  """
7
7
 
8
8
  from vector_graph_rag.config import Settings
9
- from vector_graph_rag.models import Document, Triplet, Entity, Relation, Passage
10
- from vector_graph_rag.llm.extractor import TripletExtractor
11
- from vector_graph_rag.storage.embeddings import EmbeddingModel
12
- from vector_graph_rag.storage.milvus import MilvusStore
13
9
  from vector_graph_rag.graph.builder import GraphBuilder
14
- from vector_graph_rag.graph.retriever import GraphRetriever
15
- from vector_graph_rag.graph.knowledge_graph import SubGraph
16
10
  from vector_graph_rag.graph.graph import Graph
11
+ from vector_graph_rag.graph.knowledge_graph import SubGraph
12
+ from vector_graph_rag.graph.retriever import GraphRetriever
13
+ from vector_graph_rag.llm.cache import LLMCache, get_llm_cache
14
+ from vector_graph_rag.llm.extractor import TripletExtractor
17
15
  from vector_graph_rag.llm.reranker import LLMReranker
16
+ from vector_graph_rag.models import Document, Entity, Passage, Relation, Triplet
18
17
  from vector_graph_rag.rag import VectorGraphRAG, create_rag
19
- from vector_graph_rag.llm.cache import LLMCache, get_llm_cache
18
+ from vector_graph_rag.storage.embeddings import EmbeddingModel
19
+ from vector_graph_rag.storage.milvus import MilvusStore
20
20
 
21
- __version__ = "0.1.3"
21
+ __version__ = "0.1.4"
22
22
 
23
23
  __all__ = [
24
24
  "Settings",
@@ -9,34 +9,35 @@ Provides RESTful API endpoints for:
9
9
  - Graph exploration (stats, neighbors)
10
10
  """
11
11
 
12
- import os
13
- import tempfile
14
12
  import shutil
13
+ import tempfile
15
14
  from pathlib import Path
16
- from typing import List, Optional, Dict, Any
17
- from fastapi import FastAPI, HTTPException, Query, File, UploadFile, Form
15
+ from typing import Any, Dict, List, Optional
16
+
17
+ from fastapi import FastAPI, File, Form, HTTPException, Query, UploadFile
18
18
  from fastapi.middleware.cors import CORSMiddleware
19
- from fastapi.staticfiles import StaticFiles
20
19
  from fastapi.responses import FileResponse
20
+ from fastapi.staticfiles import StaticFiles
21
21
  from pydantic import BaseModel, Field
22
22
 
23
23
  from vector_graph_rag import VectorGraphRAG, __version__
24
24
  from vector_graph_rag.config import Settings, get_settings
25
- from vector_graph_rag.storage.milvus import MilvusStore
26
25
  from vector_graph_rag.graph.graph import Graph
27
- from vector_graph_rag.models import Triplet
28
-
26
+ from vector_graph_rag.storage.milvus import MilvusStore
29
27
 
30
28
  # ==================== Request/Response Schemas ====================
31
29
 
30
+
32
31
  class HealthResponse(BaseModel):
33
32
  """Health check response."""
33
+
34
34
  status: str = Field(default="ok", description="Service status")
35
35
  version: str = Field(default=__version__, description="API version")
36
36
 
37
37
 
38
38
  class GraphInfo(BaseModel):
39
39
  """Information about a graph."""
40
+
40
41
  name: str = Field(..., description="Graph name (collection prefix)")
41
42
  entity_collection: str = Field(..., description="Entity collection name")
42
43
  relation_collection: str = Field(..., description="Relation collection name")
@@ -46,11 +47,13 @@ class GraphInfo(BaseModel):
46
47
 
47
48
  class ListGraphsResponse(BaseModel):
48
49
  """Response for listing graphs."""
50
+
49
51
  graphs: List[GraphInfo] = Field(default_factory=list, description="Available graphs")
50
52
 
51
53
 
52
54
  class TripletInput(BaseModel):
53
55
  """Input for a triplet."""
56
+
54
57
  subject: str = Field(..., description="Subject entity")
55
58
  predicate: str = Field(..., description="Predicate/relationship")
56
59
  object: str = Field(..., description="Object entity")
@@ -58,17 +61,20 @@ class TripletInput(BaseModel):
58
61
 
59
62
  class AddDocumentsRequest(BaseModel):
60
63
  """Request to add documents."""
64
+
61
65
  documents: List[str] = Field(..., description="List of document texts")
62
66
  ids: Optional[List[str]] = Field(default=None, description="Optional list of document IDs")
63
- extract_triplets: bool = Field(default=True, description="Whether to extract triplets using LLM")
67
+ extract_triplets: bool = Field(
68
+ default=True, description="Whether to extract triplets using LLM"
69
+ )
64
70
  triplets: Optional[List[List[TripletInput]]] = Field(
65
- default=None,
66
- description="Optional pre-extracted triplets for each document"
71
+ default=None, description="Optional pre-extracted triplets for each document"
67
72
  )
68
73
 
69
74
 
70
75
  class AddDocumentsResponse(BaseModel):
71
76
  """Response after adding documents."""
77
+
72
78
  num_documents: int = Field(..., description="Number of documents added")
73
79
  num_entities: int = Field(..., description="Number of entities created")
74
80
  num_relations: int = Field(..., description="Number of relations created")
@@ -77,10 +83,11 @@ class AddDocumentsResponse(BaseModel):
77
83
 
78
84
  class ImportRequest(BaseModel):
79
85
  """Request to import documents from various sources."""
86
+
80
87
  sources: List[str] = Field(
81
88
  ...,
82
89
  description="List of file paths or URLs to import",
83
- examples=["/path/to/doc.pdf", "https://example.com/article"]
90
+ examples=["/path/to/doc.pdf", "https://example.com/article"],
84
91
  )
85
92
  chunk_documents: bool = Field(True, description="Whether to chunk large documents")
86
93
  chunk_size: int = Field(1000, description="Max characters per chunk")
@@ -91,6 +98,7 @@ class ImportRequest(BaseModel):
91
98
 
92
99
  class ImportResponse(BaseModel):
93
100
  """Response from document import."""
101
+
94
102
  success: bool
95
103
  num_sources: int = Field(..., description="Number of input sources")
96
104
  num_documents: int = Field(..., description="Number of documents after conversion")
@@ -102,15 +110,19 @@ class ImportResponse(BaseModel):
102
110
 
103
111
  class QueryRequest(BaseModel):
104
112
  """Request to query the knowledge base."""
113
+
105
114
  question: str = Field(..., description="Question to answer")
106
115
  use_reranking: bool = Field(default=True, description="Whether to use LLM reranking")
107
116
  entity_top_k: Optional[int] = Field(default=None, description="Number of entities to retrieve")
108
- relation_top_k: Optional[int] = Field(default=None, description="Number of relations to retrieve")
117
+ relation_top_k: Optional[int] = Field(
118
+ default=None, description="Number of relations to retrieve"
119
+ )
109
120
  expansion_degree: Optional[int] = Field(default=None, description="Subgraph expansion degree")
110
121
 
111
122
 
112
123
  class EntitySchema(BaseModel):
113
124
  """Schema for an entity in the subgraph."""
125
+
114
126
  id: str = Field(..., description="Entity ID")
115
127
  name: str = Field(..., description="Entity name")
116
128
  relation_ids: List[str] = Field(default_factory=list, description="Connected relation IDs")
@@ -119,61 +131,84 @@ class EntitySchema(BaseModel):
119
131
 
120
132
  class RelationSchema(BaseModel):
121
133
  """Schema for a relation in the subgraph."""
134
+
122
135
  id: str = Field(..., description="Relation ID")
123
136
  text: str = Field(..., description="Full relation text")
124
137
  subject: str = Field(..., description="Subject entity name")
125
138
  predicate: str = Field(..., description="Predicate/relationship")
126
139
  object: str = Field(..., description="Object entity name")
127
- entity_ids: List[str] = Field(default_factory=list, description="Connected entity IDs [subject_id, object_id]")
140
+ entity_ids: List[str] = Field(
141
+ default_factory=list, description="Connected entity IDs [subject_id, object_id]"
142
+ )
128
143
  passage_ids: List[str] = Field(default_factory=list, description="Source passage IDs")
129
144
 
130
145
 
131
146
  class PassageSchema(BaseModel):
132
147
  """Schema for a passage in the subgraph."""
148
+
133
149
  id: str = Field(..., description="Passage ID")
134
150
  text: str = Field(..., description="Passage text")
135
151
 
136
152
 
137
153
  class ExpansionStepSchema(BaseModel):
138
154
  """Schema for an expansion step in the history."""
155
+
139
156
  step: int = Field(..., description="Step number")
140
157
  operation: str = Field(..., description="Operation type")
141
158
  description: Optional[str] = Field(default=None, description="Operation description")
142
- added_entity_ids: List[str] = Field(default_factory=list, description="Entity IDs added in this step")
143
- added_relation_ids: List[str] = Field(default_factory=list, description="Relation IDs added in this step")
159
+ added_entity_ids: List[str] = Field(
160
+ default_factory=list, description="Entity IDs added in this step"
161
+ )
162
+ added_relation_ids: List[str] = Field(
163
+ default_factory=list, description="Relation IDs added in this step"
164
+ )
144
165
  total_entities: int = Field(default=0, description="Total entities after this step")
145
166
  total_relations: int = Field(default=0, description="Total relations after this step")
146
167
 
147
168
 
148
169
  class SubGraphSchema(BaseModel):
149
170
  """Schema for the expanded subgraph."""
171
+
150
172
  entity_ids: List[str] = Field(default_factory=list, description="All entity IDs in subgraph")
151
- relation_ids: List[str] = Field(default_factory=list, description="All relation IDs in subgraph")
173
+ relation_ids: List[str] = Field(
174
+ default_factory=list, description="All relation IDs in subgraph"
175
+ )
152
176
  passage_ids: List[str] = Field(default_factory=list, description="All passage IDs in subgraph")
153
177
  entities: List[EntitySchema] = Field(default_factory=list, description="Entity details")
154
178
  relations: List[RelationSchema] = Field(default_factory=list, description="Relation details")
155
179
  passages: List[PassageSchema] = Field(default_factory=list, description="Passage details")
156
- expansion_history: List[ExpansionStepSchema] = Field(default_factory=list, description="Expansion history")
180
+ expansion_history: List[ExpansionStepSchema] = Field(
181
+ default_factory=list, description="Expansion history"
182
+ )
157
183
 
158
184
 
159
185
  class RetrievalDetailSchema(BaseModel):
160
186
  """Schema for retrieval details."""
187
+
161
188
  entity_ids: List[str] = Field(default_factory=list, description="Retrieved entity IDs")
162
189
  entity_texts: List[str] = Field(default_factory=list, description="Retrieved entity names")
163
190
  entity_scores: List[float] = Field(default_factory=list, description="Entity similarity scores")
164
191
  relation_ids: List[str] = Field(default_factory=list, description="Retrieved relation IDs")
165
192
  relation_texts: List[str] = Field(default_factory=list, description="Retrieved relation texts")
166
- relation_scores: List[float] = Field(default_factory=list, description="Relation similarity scores")
193
+ relation_scores: List[float] = Field(
194
+ default_factory=list, description="Relation similarity scores"
195
+ )
167
196
 
168
197
 
169
198
  class RerankResultSchema(BaseModel):
170
199
  """Schema for rerank results."""
171
- selected_relation_ids: List[str] = Field(default_factory=list, description="Selected relation IDs")
172
- selected_relation_texts: List[str] = Field(default_factory=list, description="Selected relation texts")
200
+
201
+ selected_relation_ids: List[str] = Field(
202
+ default_factory=list, description="Selected relation IDs"
203
+ )
204
+ selected_relation_texts: List[str] = Field(
205
+ default_factory=list, description="Selected relation texts"
206
+ )
173
207
 
174
208
 
175
209
  class EvictionResultSchema(BaseModel):
176
210
  """Schema for eviction results (when relations exceed threshold)."""
211
+
177
212
  occurred: bool = Field(default=False, description="Whether eviction occurred")
178
213
  before_count: int = Field(default=0, description="Number of relations before eviction")
179
214
  after_count: int = Field(default=0, description="Number of relations after eviction")
@@ -181,44 +216,62 @@ class EvictionResultSchema(BaseModel):
181
216
 
182
217
  class QueryResponse(BaseModel):
183
218
  """Response for a query."""
219
+
184
220
  question: str = Field(..., description="Original question")
185
221
  answer: str = Field(..., description="Generated answer")
186
- query_entities: List[str] = Field(default_factory=list, description="Entities extracted from query")
187
- subgraph: Optional[SubGraphSchema] = Field(default=None, description="Expanded subgraph for visualization")
222
+ query_entities: List[str] = Field(
223
+ default_factory=list, description="Entities extracted from query"
224
+ )
225
+ subgraph: Optional[SubGraphSchema] = Field(
226
+ default=None, description="Expanded subgraph for visualization"
227
+ )
188
228
  retrieved_passages: List[str] = Field(default_factory=list, description="Retrieved passages")
189
229
  stats: Dict[str, Any] = Field(default_factory=dict, description="Query statistics")
190
- retrieval_detail: Optional[RetrievalDetailSchema] = Field(default=None, description="Initial retrieval details")
191
- rerank_result: Optional[RerankResultSchema] = Field(default=None, description="LLM rerank results")
192
- eviction_result: Optional[EvictionResultSchema] = Field(default=None, description="Eviction results if relations exceeded threshold")
230
+ retrieval_detail: Optional[RetrievalDetailSchema] = Field(
231
+ default=None, description="Initial retrieval details"
232
+ )
233
+ rerank_result: Optional[RerankResultSchema] = Field(
234
+ default=None, description="LLM rerank results"
235
+ )
236
+ eviction_result: Optional[EvictionResultSchema] = Field(
237
+ default=None, description="Eviction results if relations exceeded threshold"
238
+ )
193
239
 
194
240
 
195
241
  class DocumentResponse(BaseModel):
196
242
  """Response for a single document."""
243
+
197
244
  id: str = Field(..., description="Document ID")
198
245
  text: str = Field(..., description="Document text")
199
246
  entity_ids: List[str] = Field(default_factory=list, description="Entity IDs in this document")
200
- relation_ids: List[str] = Field(default_factory=list, description="Relation IDs from this document")
247
+ relation_ids: List[str] = Field(
248
+ default_factory=list, description="Relation IDs from this document"
249
+ )
201
250
 
202
251
 
203
252
  class ListDocumentsResponse(BaseModel):
204
253
  """Response for listing documents."""
254
+
205
255
  documents: List[DocumentResponse] = Field(default_factory=list, description="List of documents")
206
256
  total: int = Field(..., description="Total number of documents returned")
207
257
 
208
258
 
209
259
  class UpdateDocumentRequest(BaseModel):
210
260
  """Request to update a document."""
261
+
211
262
  text: Optional[str] = Field(default=None, description="New document text")
212
263
 
213
264
 
214
265
  class DeleteResponse(BaseModel):
215
266
  """Response for delete operations."""
267
+
216
268
  success: bool = Field(..., description="Whether deletion succeeded")
217
269
  message: str = Field(default="", description="Additional message")
218
270
 
219
271
 
220
272
  class GraphStatsResponse(BaseModel):
221
273
  """Response for graph statistics."""
274
+
222
275
  graph_name: str = Field(..., description="Graph name")
223
276
  entity_count: int = Field(default=0, description="Number of entities")
224
277
  relation_count: int = Field(default=0, description="Number of relations")
@@ -227,13 +280,17 @@ class GraphStatsResponse(BaseModel):
227
280
 
228
281
  class NeighborResponse(BaseModel):
229
282
  """Response for entity neighbors."""
283
+
230
284
  entity_id: str = Field(..., description="Central entity ID")
231
285
  neighbors: List[EntitySchema] = Field(default_factory=list, description="Neighbor entities")
232
- relations: List[RelationSchema] = Field(default_factory=list, description="Connecting relations")
286
+ relations: List[RelationSchema] = Field(
287
+ default_factory=list, description="Connecting relations"
288
+ )
233
289
 
234
290
 
235
291
  class SettingsResponse(BaseModel):
236
292
  """Response for system settings."""
293
+
237
294
  llm_model: str = Field(..., description="LLM model name")
238
295
  embedding_model: str = Field(..., description="Embedding model name")
239
296
  embedding_dimension: int = Field(..., description="Embedding dimension")
@@ -245,6 +302,7 @@ class SettingsResponse(BaseModel):
245
302
 
246
303
  # ==================== Application Factory ====================
247
304
 
305
+
248
306
  def create_app(settings: Optional[Settings] = None) -> FastAPI:
249
307
  """
250
308
  Create and configure the FastAPI application.
@@ -314,9 +372,7 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
314
372
  milvus_token=app.state.settings.milvus_token,
315
373
  milvus_db=app.state.settings.milvus_db,
316
374
  )
317
- return ListGraphsResponse(
318
- graphs=[GraphInfo(**g) for g in graphs]
319
- )
375
+ return ListGraphsResponse(graphs=[GraphInfo(**g) for g in graphs])
320
376
 
321
377
  @app.get("/settings", response_model=SettingsResponse, tags=["System"])
322
378
  async def get_system_settings():
@@ -362,19 +418,15 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
362
418
  if deleted:
363
419
  return DeleteResponse(
364
420
  success=True,
365
- message=f"Successfully deleted graph '{graph_name}' and all its collections"
421
+ message=f"Successfully deleted graph '{graph_name}' and all its collections",
366
422
  )
367
423
  else:
368
424
  return DeleteResponse(
369
- success=False,
370
- message=f"Graph '{graph_name}' not found or already deleted"
425
+ success=False, message=f"Graph '{graph_name}' not found or already deleted"
371
426
  )
372
427
 
373
428
  except Exception as e:
374
- raise HTTPException(
375
- status_code=500,
376
- detail=f"Failed to delete graph: {str(e)}"
377
- )
429
+ raise HTTPException(status_code=500, detail=f"Failed to delete graph: {str(e)}")
378
430
 
379
431
  @app.post("/add_documents", response_model=AddDocumentsResponse, tags=["Documents"])
380
432
  async def add_documents(
@@ -395,10 +447,9 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
395
447
  for i, text in enumerate(request.documents):
396
448
  doc_data = {
397
449
  "passage": text,
398
- "triplets": [
399
- [t.subject, t.predicate, t.object]
400
- for t in request.triplets[i]
401
- ] if i < len(request.triplets) else [],
450
+ "triplets": [[t.subject, t.predicate, t.object] for t in request.triplets[i]]
451
+ if i < len(request.triplets)
452
+ else [],
402
453
  }
403
454
  if request.ids and i < len(request.ids):
404
455
  doc_data["id"] = request.ids[i]
@@ -575,9 +626,9 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
575
626
  if result.subgraph:
576
627
  sg = result.subgraph
577
628
  subgraph_schema = SubGraphSchema(
578
- entity_ids=list(sg.entity_ids) if hasattr(sg, 'entity_ids') else [],
579
- relation_ids=list(sg.relation_ids) if hasattr(sg, 'relation_ids') else [],
580
- passage_ids=list(sg.passage_ids) if hasattr(sg, 'passage_ids') else [],
629
+ entity_ids=list(sg.entity_ids) if hasattr(sg, "entity_ids") else [],
630
+ relation_ids=list(sg.relation_ids) if hasattr(sg, "relation_ids") else [],
631
+ passage_ids=list(sg.passage_ids) if hasattr(sg, "passage_ids") else [],
581
632
  entities=[
582
633
  EntitySchema(
583
634
  id=e.id,
@@ -585,7 +636,7 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
585
636
  relation_ids=e.relation_ids,
586
637
  passage_ids=e.passage_ids,
587
638
  )
588
- for e in (sg.entities if hasattr(sg, 'entities') else [])
639
+ for e in (sg.entities if hasattr(sg, "entities") else [])
589
640
  ],
590
641
  relations=[
591
642
  RelationSchema(
@@ -597,23 +648,27 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
597
648
  entity_ids=r.entity_ids,
598
649
  passage_ids=r.passage_ids,
599
650
  )
600
- for r in (sg.relations if hasattr(sg, 'relations') else [])
651
+ for r in (sg.relations if hasattr(sg, "relations") else [])
601
652
  ],
602
653
  passages=[
603
654
  PassageSchema(id=p.id, text=p.text)
604
- for p in (sg.passages if hasattr(sg, 'passages') else [])
655
+ for p in (sg.passages if hasattr(sg, "passages") else [])
605
656
  ],
606
657
  expansion_history=[
607
658
  ExpansionStepSchema(
608
- step=h.get('step', i),
609
- operation=h.get('operation', 'unknown'),
610
- description=h.get('description'),
611
- added_entity_ids=h.get('added_entity_ids', h.get('new_entity_ids', [])),
612
- added_relation_ids=h.get('added_relation_ids', h.get('new_relation_ids', [])),
613
- total_entities=h.get('total_entities', 0),
614
- total_relations=h.get('total_relations', 0),
659
+ step=h.get("step", i),
660
+ operation=h.get("operation", "unknown"),
661
+ description=h.get("description"),
662
+ added_entity_ids=h.get("added_entity_ids", h.get("new_entity_ids", [])),
663
+ added_relation_ids=h.get(
664
+ "added_relation_ids", h.get("new_relation_ids", [])
665
+ ),
666
+ total_entities=h.get("total_entities", 0),
667
+ total_relations=h.get("total_relations", 0),
668
+ )
669
+ for i, h in enumerate(
670
+ sg.expansion_history if hasattr(sg, "expansion_history") else []
615
671
  )
616
- for i, h in enumerate(sg.expansion_history if hasattr(sg, 'expansion_history') else [])
617
672
  ],
618
673
  )
619
674
 
@@ -681,11 +736,11 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
681
736
  stats = graph.get_stats()
682
737
  return GraphStatsResponse(
683
738
  graph_name=graph_name,
684
- entity_count=stats.get('entity_count', 0),
685
- relation_count=stats.get('relation_count', 0),
686
- passage_count=stats.get('passage_count', 0),
739
+ entity_count=stats.get("entity_count", 0),
740
+ relation_count=stats.get("relation_count", 0),
741
+ passage_count=stats.get("passage_count", 0),
687
742
  )
688
- except Exception as e:
743
+ except Exception:
689
744
  # If stats not available, return zeros
690
745
  return GraphStatsResponse(
691
746
  graph_name=graph_name,
@@ -694,7 +749,9 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
694
749
  passage_count=0,
695
750
  )
696
751
 
697
- @app.get("/graph/{graph_name}/neighbors/{entity_id}", response_model=NeighborResponse, tags=["Graph"])
752
+ @app.get(
753
+ "/graph/{graph_name}/neighbors/{entity_id}", response_model=NeighborResponse, tags=["Graph"]
754
+ )
698
755
  async def get_entity_neighbors(
699
756
  graph_name: str,
700
757
  entity_id: str,
@@ -729,12 +786,14 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
729
786
  for nid in list(neighbor_ids)[:limit]:
730
787
  neighbor = graph.get_entity(nid)
731
788
  if neighbor:
732
- neighbors.append(EntitySchema(
733
- id=neighbor.id,
734
- name=neighbor.name,
735
- relation_ids=neighbor.relation_ids,
736
- passage_ids=neighbor.passage_ids,
737
- ))
789
+ neighbors.append(
790
+ EntitySchema(
791
+ id=neighbor.id,
792
+ name=neighbor.name,
793
+ relation_ids=neighbor.relation_ids,
794
+ passage_ids=neighbor.passage_ids,
795
+ )
796
+ )
738
797
 
739
798
  # Convert relations to schema
740
799
  relation_schemas = [
@@ -786,7 +845,9 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
786
845
  @app.get("/documents", response_model=ListDocumentsResponse, tags=["Documents"])
787
846
  async def list_documents(
788
847
  graph_name: Optional[str] = Query(default=None, description="Graph name to use"),
789
- query: Optional[str] = Query(default=None, description="Optional search query for vector similarity"),
848
+ query: Optional[str] = Query(
849
+ default=None, description="Optional search query for vector similarity"
850
+ ),
790
851
  top_k: int = Query(default=10, description="Number of documents to return"),
791
852
  ):
792
853
  """
@@ -921,6 +982,7 @@ def run_server(host: str = "0.0.0.0", port: int = 8000, reload: bool = False):
921
982
  reload: Whether to enable auto-reload.
922
983
  """
923
984
  import uvicorn
985
+
924
986
  uvicorn.run("vector_graph_rag.api.app:app", host=host, port=port, reload=reload)
925
987
 
926
988