agentic-graphrag 0.0.2__tar.gz → 0.0.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 (233) hide show
  1. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/PKG-INFO +41 -16
  2. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/README.md +18 -11
  3. agentic_graphrag-0.0.4/agrag/agents/__init__.py +19 -0
  4. agentic_graphrag-0.0.4/agrag/agents/build.py +276 -0
  5. agentic_graphrag-0.0.4/agrag/agents/errors.py +16 -0
  6. agentic_graphrag-0.0.4/agrag/agents/harness.py +54 -0
  7. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/agents/ledger.py +25 -4
  8. agentic_graphrag-0.0.4/agrag/agents/middleware.py +289 -0
  9. agentic_graphrag-0.0.4/agrag/agents/prompts.py +91 -0
  10. agentic_graphrag-0.0.4/agrag/agents/result.py +21 -0
  11. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/agents/settings.py +14 -2
  12. agentic_graphrag-0.0.4/agrag/agents/subagents.py +79 -0
  13. agentic_graphrag-0.0.4/agrag/agents/tools/__init__.py +91 -0
  14. agentic_graphrag-0.0.4/agrag/agents/tools/aggregate.py +66 -0
  15. agentic_graphrag-0.0.4/agrag/agents/tools/search.py +465 -0
  16. agentic_graphrag-0.0.4/agrag/agents/tools/traversal.py +333 -0
  17. agentic_graphrag-0.0.4/agrag/agents/tracing.py +134 -0
  18. agentic_graphrag-0.0.4/agrag/agents/verification.py +92 -0
  19. agentic_graphrag-0.0.4/agrag/chunking/__init__.py +38 -0
  20. agentic_graphrag-0.0.4/agrag/chunking/_docling_adapters.py +69 -0
  21. agentic_graphrag-0.0.4/agrag/chunking/_text.py +159 -0
  22. agentic_graphrag-0.0.4/agrag/chunking/base.py +239 -0
  23. agentic_graphrag-0.0.4/agrag/chunking/docling.py +200 -0
  24. agentic_graphrag-0.0.4/agrag/chunking/extras.py +182 -0
  25. agentic_graphrag-0.0.4/agrag/chunking/heading.py +137 -0
  26. agentic_graphrag-0.0.4/agrag/chunking/parent_child.py +105 -0
  27. agentic_graphrag-0.0.4/agrag/chunking/recursive.py +72 -0
  28. agentic_graphrag-0.0.4/agrag/chunking/rules.py +119 -0
  29. agentic_graphrag-0.0.4/agrag/chunking/sentence.py +51 -0
  30. agentic_graphrag-0.0.4/agrag/chunking/token.py +49 -0
  31. agentic_graphrag-0.0.4/agrag/chunking/turns.py +115 -0
  32. agentic_graphrag-0.0.4/agrag/common/__init__.py +1 -0
  33. agentic_graphrag-0.0.4/agrag/common/data_models/__init__.py +43 -0
  34. agentic_graphrag-0.0.4/agrag/common/data_models/chunk.py +189 -0
  35. agentic_graphrag-0.0.4/agrag/common/data_models/community.py +65 -0
  36. agentic_graphrag-0.0.4/agrag/common/data_models/cutover_job.py +63 -0
  37. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/data_point.py +2 -3
  38. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/document.py +139 -31
  39. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/entity.py +9 -4
  40. agentic_graphrag-0.0.4/agrag/common/data_models/graph_record.py +148 -0
  41. agentic_graphrag-0.0.4/agrag/common/data_models/graph_schema.py +183 -0
  42. agentic_graphrag-0.0.4/agrag/common/data_models/normalization.py +25 -0
  43. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/provenance.py +5 -3
  44. agentic_graphrag-0.0.4/agrag/common/data_models/query_value.py +13 -0
  45. agentic_graphrag-0.0.4/agrag/common/data_models/resolved_entity.py +50 -0
  46. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/search_result.py +10 -3
  47. agentic_graphrag-0.0.4/agrag/common/data_models/stage_failure.py +77 -0
  48. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/vector_record.py +15 -0
  49. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/validation.py +6 -0
  50. agentic_graphrag-0.0.4/agrag/cypher/_pending_filter.py +28 -0
  51. agentic_graphrag-0.0.4/agrag/cypher/community_read.py +41 -0
  52. agentic_graphrag-0.0.4/agrag/cypher/community_write.py +19 -0
  53. agentic_graphrag-0.0.4/agrag/cypher/cutover_job_read.py +32 -0
  54. agentic_graphrag-0.0.4/agrag/cypher/cutover_job_write.py +319 -0
  55. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/cypher/entities.py +132 -49
  56. agentic_graphrag-0.0.4/agrag/cypher/relations.py +443 -0
  57. agentic_graphrag-0.0.4/agrag/cypher/resolution_read.py +141 -0
  58. agentic_graphrag-0.0.4/agrag/cypher/resolution_write.py +171 -0
  59. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/cypher/schema.py +104 -4
  60. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/__init__.py +18 -2
  61. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/fastembed_bm25.py +26 -4
  62. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/sentence_transformers.py +26 -7
  63. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/settings.py +4 -1
  64. agentic_graphrag-0.0.4/agrag/eval/__init__.py +109 -0
  65. agentic_graphrag-0.0.4/agrag/eval/adapter.py +112 -0
  66. agentic_graphrag-0.0.4/agrag/eval/answer.py +516 -0
  67. agentic_graphrag-0.0.4/agrag/eval/extraction.py +421 -0
  68. agentic_graphrag-0.0.4/agrag/eval/judge.py +108 -0
  69. agentic_graphrag-0.0.4/agrag/eval/resolution.py +201 -0
  70. agentic_graphrag-0.0.4/agrag/eval/settings.py +117 -0
  71. agentic_graphrag-0.0.4/agrag/eval/trajectory.py +708 -0
  72. agentic_graphrag-0.0.4/agrag/eval/verifier.py +176 -0
  73. agentic_graphrag-0.0.4/agrag/graphdb/__init__.py +61 -0
  74. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/graphdb/base.py +29 -5
  75. agentic_graphrag-0.0.4/agrag/graphdb/neo4j.py +1071 -0
  76. agentic_graphrag-0.0.4/agrag/graphdb/serialize.py +227 -0
  77. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/graphdb/settings.py +1 -1
  78. agentic_graphrag-0.0.4/agrag/ingestion/__init__.py +34 -0
  79. agentic_graphrag-0.0.4/agrag/ingestion/_clustering.py +36 -0
  80. agentic_graphrag-0.0.4/agrag/ingestion/_cutover.py +482 -0
  81. agentic_graphrag-0.0.4/agrag/ingestion/_document_lifecycle.py +115 -0
  82. agentic_graphrag-0.0.4/agrag/ingestion/_ingest_pipeline.py +1690 -0
  83. agentic_graphrag-0.0.4/agrag/ingestion/_lexical_backbone.py +114 -0
  84. agentic_graphrag-0.0.4/agrag/ingestion/_resume.py +327 -0
  85. agentic_graphrag-0.0.4/agrag/ingestion/community.py +669 -0
  86. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/ingestion/extract.py +100 -42
  87. agentic_graphrag-0.0.4/agrag/ingestion/graph.py +2079 -0
  88. agentic_graphrag-0.0.4/agrag/ingestion/materialize.py +587 -0
  89. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/ingestion/merge.py +193 -158
  90. agentic_graphrag-0.0.4/agrag/ingestion/reports/__init__.py +20 -0
  91. agentic_graphrag-0.0.4/agrag/ingestion/reports/add_result.py +67 -0
  92. agentic_graphrag-0.0.4/agrag/ingestion/reports/community_detection_report.py +25 -0
  93. agentic_graphrag-0.0.4/agrag/ingestion/reports/consolidation_report.py +26 -0
  94. agentic_graphrag-0.0.4/agrag/ingestion/reports/reevaluation_report.py +28 -0
  95. agentic_graphrag-0.0.4/agrag/ingestion/reports/update_result.py +25 -0
  96. agentic_graphrag-0.0.4/agrag/ingestion/resolve/__init__.py +48 -0
  97. agentic_graphrag-0.0.4/agrag/ingestion/resolve/batch_validation.py +50 -0
  98. agentic_graphrag-0.0.4/agrag/ingestion/resolve/candidate_source.py +329 -0
  99. agentic_graphrag-0.0.4/agrag/ingestion/resolve/comparators.py +23 -0
  100. agentic_graphrag-0.0.4/agrag/ingestion/resolve/exact_groups.py +33 -0
  101. agentic_graphrag-0.0.4/agrag/ingestion/resolve/resolver.py +917 -0
  102. agentic_graphrag-0.0.4/agrag/ingestion/resolve/zone_classifier.py +99 -0
  103. agentic_graphrag-0.0.4/agrag/ingestion/resolved_embeddings.py +418 -0
  104. agentic_graphrag-0.0.4/agrag/ingestion/settings.py +24 -0
  105. agentic_graphrag-0.0.4/agrag/ingestion/stats/__init__.py +26 -0
  106. agentic_graphrag-0.0.4/agrag/ingestion/stats/chunking.py +77 -0
  107. agentic_graphrag-0.0.4/agrag/ingestion/stats/extraction.py +27 -0
  108. agentic_graphrag-0.0.4/agrag/ingestion/stats/ingest.py +17 -0
  109. agentic_graphrag-0.0.4/agrag/ingestion/stats/merge.py +33 -0
  110. agentic_graphrag-0.0.4/agrag/ingestion/stats/resolution.py +22 -0
  111. agentic_graphrag-0.0.4/agrag/ingestion/stats/storage.py +32 -0
  112. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/async_client.py +119 -37
  113. agentic_graphrag-0.0.4/agrag/llm/baml_client/inlinedbaml.py +24 -0
  114. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/parser.py +32 -8
  115. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/stream_types.py +32 -2
  116. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/sync_client.py +117 -37
  117. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/type_builder.py +231 -3
  118. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/type_map.py +12 -0
  119. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/types.py +32 -2
  120. agentic_graphrag-0.0.4/agrag/llm/baml_src/community.baml +48 -0
  121. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_src/extraction.baml +12 -2
  122. agentic_graphrag-0.0.4/agrag/llm/baml_src/merge.baml +21 -0
  123. agentic_graphrag-0.0.4/agrag/llm/baml_src/resolution.baml +37 -0
  124. agentic_graphrag-0.0.4/agrag/llm/baml_src/retrieval.baml +31 -0
  125. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/client_config.py +3 -1
  126. agentic_graphrag-0.0.4/agrag/llm/retry.py +126 -0
  127. agentic_graphrag-0.0.4/agrag/llm/tracing.py +158 -0
  128. agentic_graphrag-0.0.4/agrag/loaders/__init__.py +52 -0
  129. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/__init__.py +3 -1
  130. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/_walk.py +106 -17
  131. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/decode.py +16 -11
  132. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/readers/_common.py +6 -0
  133. agentic_graphrag-0.0.4/agrag/loaders/corpus/readers/chat.py +168 -0
  134. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/types.py +13 -6
  135. agentic_graphrag-0.0.4/agrag/observability.py +100 -0
  136. agentic_graphrag-0.0.4/agrag/retrieval/__init__.py +52 -0
  137. agentic_graphrag-0.0.4/agrag/retrieval/community_context.py +207 -0
  138. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/errors.py +12 -0
  139. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/filters.py +2 -2
  140. agentic_graphrag-0.0.4/agrag/retrieval/fusion.py +92 -0
  141. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/identity.py +34 -17
  142. agentic_graphrag-0.0.4/agrag/retrieval/methods/traversal.py +348 -0
  143. agentic_graphrag-0.0.4/agrag/retrieval/methods/vector.py +131 -0
  144. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/recipes.py +19 -2
  145. agentic_graphrag-0.0.4/agrag/retrieval/rerank/cross_encoder.py +138 -0
  146. agentic_graphrag-0.0.4/agrag/retrieval/rerank/node_distance.py +105 -0
  147. agentic_graphrag-0.0.4/agrag/retrieval/resolved_entities.py +97 -0
  148. agentic_graphrag-0.0.4/agrag/retrieval/retrievers/bfs.py +156 -0
  149. agentic_graphrag-0.0.4/agrag/retrieval/retrievers/chunk.py +252 -0
  150. agentic_graphrag-0.0.4/agrag/retrieval/retrievers/community.py +131 -0
  151. agentic_graphrag-0.0.4/agrag/retrieval/retrievers/entity.py +400 -0
  152. agentic_graphrag-0.0.4/agrag/retrieval/retrievers/text2cypher.py +737 -0
  153. agentic_graphrag-0.0.4/agrag/retrieval/search_engine.py +561 -0
  154. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/settings.py +25 -4
  155. agentic_graphrag-0.0.4/agrag/retrieval/tracing.py +182 -0
  156. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/__init__.py +25 -9
  157. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/milvus.py +264 -90
  158. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/qdrant.py +224 -102
  159. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/settings.py +6 -3
  160. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/weaviate.py +234 -93
  161. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/pyproject.toml +25 -8
  162. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/pyproject.toml.orig +27 -8
  163. agentic_graphrag-0.0.2/agrag/agents/__init__.py +0 -1
  164. agentic_graphrag-0.0.2/agrag/agents/build.py +0 -169
  165. agentic_graphrag-0.0.2/agrag/agents/middleware.py +0 -55
  166. agentic_graphrag-0.0.2/agrag/agents/prompts.py +0 -28
  167. agentic_graphrag-0.0.2/agrag/agents/subagents.py +0 -36
  168. agentic_graphrag-0.0.2/agrag/agents/tools.py +0 -94
  169. agentic_graphrag-0.0.2/agrag/chunking/__init__.py +0 -24
  170. agentic_graphrag-0.0.2/agrag/chunking/text.py +0 -120
  171. agentic_graphrag-0.0.2/agrag/common/data_models/chunk.py +0 -114
  172. agentic_graphrag-0.0.2/agrag/common/data_models/graph_record.py +0 -48
  173. agentic_graphrag-0.0.2/agrag/common/data_models/graph_schema.py +0 -94
  174. agentic_graphrag-0.0.2/agrag/cypher/merge.py +0 -167
  175. agentic_graphrag-0.0.2/agrag/cypher/relations.py +0 -170
  176. agentic_graphrag-0.0.2/agrag/graphdb/__init__.py +0 -45
  177. agentic_graphrag-0.0.2/agrag/graphdb/neo4j.py +0 -618
  178. agentic_graphrag-0.0.2/agrag/graphdb/serialize.py +0 -58
  179. agentic_graphrag-0.0.2/agrag/ingestion/__init__.py +0 -6
  180. agentic_graphrag-0.0.2/agrag/ingestion/graph.py +0 -1722
  181. agentic_graphrag-0.0.2/agrag/ingestion/resolve.py +0 -323
  182. agentic_graphrag-0.0.2/agrag/ingestion/types.py +0 -187
  183. agentic_graphrag-0.0.2/agrag/llm/baml_client/inlinedbaml.py +0 -22
  184. agentic_graphrag-0.0.2/agrag/llm/baml_src/resolution.baml +0 -37
  185. agentic_graphrag-0.0.2/agrag/llm/baml_src/retrieval.baml +0 -14
  186. agentic_graphrag-0.0.2/agrag/llm/retry.py +0 -73
  187. agentic_graphrag-0.0.2/agrag/loaders/docling/chunking.py +0 -124
  188. agentic_graphrag-0.0.2/agrag/observability.py +0 -98
  189. agentic_graphrag-0.0.2/agrag/retrieval/__init__.py +0 -1
  190. agentic_graphrag-0.0.2/agrag/retrieval/fusion.py +0 -73
  191. agentic_graphrag-0.0.2/agrag/retrieval/methods/vector.py +0 -92
  192. agentic_graphrag-0.0.2/agrag/retrieval/rerank/cross_encoder.py +0 -74
  193. agentic_graphrag-0.0.2/agrag/retrieval/rerank/node_distance.py +0 -67
  194. agentic_graphrag-0.0.2/agrag/retrieval/retrievers/bfs.py +0 -115
  195. agentic_graphrag-0.0.2/agrag/retrieval/retrievers/chunk.py +0 -169
  196. agentic_graphrag-0.0.2/agrag/retrieval/retrievers/entity.py +0 -104
  197. agentic_graphrag-0.0.2/agrag/retrieval/retrievers/text2cypher.py +0 -451
  198. agentic_graphrag-0.0.2/agrag/retrieval/search_engine.py +0 -294
  199. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/LICENSE +0 -0
  200. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/__init__.py +0 -0
  201. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/agents/model.py +0 -0
  202. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/extraction.py +0 -0
  203. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/data_models/relation.py +0 -0
  204. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/common/text.py +0 -0
  205. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/cypher/__init__.py +0 -0
  206. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/cypher/safety.py +0 -0
  207. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/base.py +0 -0
  208. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/errors.py +0 -0
  209. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/embedding/sparse_base.py +0 -0
  210. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/graphdb/errors.py +0 -0
  211. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/__init__.py +0 -0
  212. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/config.py +0 -0
  213. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/globals.py +0 -0
  214. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/runtime.py +0 -0
  215. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/tracing.py +0 -0
  216. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_client/watchers.py +0 -0
  217. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/baml_src/generators.baml +0 -0
  218. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/llm/client_registry.py +0 -0
  219. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/base.py +0 -0
  220. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/errors.py +0 -0
  221. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/readers/html.py +0 -0
  222. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/readers/prose.py +0 -0
  223. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/readers/records.py +0 -0
  224. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/corpus/registry.py +0 -0
  225. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/docling/__init__.py +0 -0
  226. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/loaders/docling/loader.py +0 -0
  227. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/py.typed +0 -0
  228. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/methods/__init__.py +0 -0
  229. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/rerank/__init__.py +0 -0
  230. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/retrievers/__init__.py +0 -0
  231. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/retrieval/retrievers/base.py +0 -0
  232. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/base.py +0 -0
  233. {agentic_graphrag-0.0.2 → agentic_graphrag-0.0.4}/agrag/vectordb/errors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-graphrag
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Summary: Agentic GraphRAG: graph-based retrieval-augmented generation with agentic reasoning.
5
5
  Keywords: graphrag,rag,knowledge-graph,agents,retrieval
6
6
  Author: Ashwin Mathur, Varun Mathur
@@ -14,25 +14,38 @@ Requires-Dist: pydantic-settings>=2.0
14
14
  Requires-Dist: python-dotenv>=1.0
15
15
  Requires-Dist: chonkie>=1.7
16
16
  Requires-Dist: opentelemetry-api>=1.20
17
+ Requires-Dist: openinference-semantic-conventions
17
18
  Requires-Dist: charset-normalizer>=3.4
18
19
  Requires-Dist: markdown-it-py>=3.0
19
20
  Requires-Dist: selectolax>=0.3.21
20
21
  Requires-Dist: rapidfuzz>=3.0
22
+ Requires-Dist: scipy>=1.14
21
23
  Requires-Dist: langgraph>=1.2 ; extra == 'agents'
22
- Requires-Dist: deepagents>=0.7 ; extra == 'agents'
24
+ Requires-Dist: deepagents>=0.7.15 ; extra == 'agents'
23
25
  Requires-Dist: langchain-openai>=1.0 ; extra == 'agents'
26
+ Requires-Dist: chonkie[code]>=1.7 ; extra == 'chunk-code'
27
+ Requires-Dist: chonkie[neural]>=1.7 ; extra == 'chunk-neural'
28
+ Requires-Dist: chonkie[semantic]>=1.7 ; extra == 'chunk-semantic'
29
+ Requires-Dist: graspologic-native>=1.2.5 ; extra == 'community'
24
30
  Requires-Dist: docling>=2.0 ; extra == 'docling'
25
31
  Requires-Dist: sentence-transformers>=5 ; extra == 'embed-local'
32
+ Requires-Dist: deepeval>=4.2.6 ; extra == 'eval'
33
+ Requires-Dist: agentevals>=0.0.9 ; extra == 'eval'
34
+ Requires-Dist: er-evaluation>=2.3.0 ; extra == 'eval'
35
+ Requires-Dist: scikit-learn>=1.5 ; extra == 'eval'
36
+ Requires-Dist: langchain-openai>=1.0 ; extra == 'eval'
37
+ Requires-Dist: opentelemetry-sdk>=1.20 ; extra == 'eval'
38
+ Requires-Dist: openinference-instrumentation-langchain>=0.1.76,<0.2 ; extra == 'eval'
26
39
  Requires-Dist: gliner2[local] ; extra == 'extract'
27
40
  Requires-Dist: transformers<4.56 ; extra == 'extract'
28
41
  Requires-Dist: protobuf ; extra == 'extract'
29
42
  Requires-Dist: baml-py>=0.226.1,<0.227 ; extra == 'llm'
30
- Requires-Dist: pymilvus>=2.5.3 ; extra == 'milvus'
31
- Requires-Dist: neo4j>=5.0 ; extra == 'neo4j'
43
+ Requires-Dist: pymilvus>=3.0.0,<4 ; extra == 'milvus'
44
+ Requires-Dist: neo4j>=5.22 ; extra == 'neo4j'
32
45
  Requires-Dist: opentelemetry-sdk>=1.20 ; extra == 'observability'
33
46
  Requires-Dist: opentelemetry-exporter-otlp>=1.20 ; extra == 'observability'
34
47
  Requires-Dist: opentelemetry-instrumentation-asyncio ; extra == 'observability'
35
- Requires-Dist: openinference-semantic-conventions ; extra == 'observability'
48
+ Requires-Dist: openinference-instrumentation-langchain>=0.1.76,<0.2 ; extra == 'observability'
36
49
  Requires-Dist: qdrant-client>=1.12 ; extra == 'qdrant'
37
50
  Requires-Dist: fastembed>=0.4 ; extra == 'qdrant'
38
51
  Requires-Dist: weaviate-client>=4.9 ; extra == 'weaviate'
@@ -43,8 +56,13 @@ Project-URL: Documentation, https://ontogr.github.io/agentic-graphrag/
43
56
  Project-URL: Issues, https://github.com/ontogr/agentic-graphrag/issues
44
57
  Project-URL: Source, https://github.com/ontogr/agentic-graphrag
45
58
  Provides-Extra: agents
59
+ Provides-Extra: chunk-code
60
+ Provides-Extra: chunk-neural
61
+ Provides-Extra: chunk-semantic
62
+ Provides-Extra: community
46
63
  Provides-Extra: docling
47
64
  Provides-Extra: embed-local
65
+ Provides-Extra: eval
48
66
  Provides-Extra: extract
49
67
  Provides-Extra: llm
50
68
  Provides-Extra: milvus
@@ -71,7 +89,7 @@ Description-Content-Type: text/markdown
71
89
 
72
90
  </div>
73
91
 
74
- Agentic GraphRAG is a modular, schema-driven system for building knowledge graphs from unstructured and structured data, retrieving evidence across graph and vector indexes, and answering questions with agentic reasoning.
92
+ Agentic GraphRAG is a modular, schema-driven system. It builds knowledge graphs from unstructured and structured data. It retrieves evidence across graph and vector indexes. It answers questions with agentic reasoning.
75
93
 
76
94
  <p align="center">
77
95
  <img src="img/agentic_graphrag_pipeline.png" alt="Agentic GraphRAG pipeline from data loading through graph construction, storage, retrieval, and agentic reasoning" width="1200">
@@ -123,7 +141,7 @@ Documents keep their source URI, format, loader, content hash, and record identi
123
141
 
124
142
  Extraction produces mentions first, not graph nodes. Each mention keeps its source chunk, label, text span, confidence, and extractor provenance. Resolution then assigns canonical identities and merges aliases before storage.
125
143
 
126
- Relations are directed subject–predicate–object triples. The active schema constrains valid source type, relation type, and target type combinations, so invalid triples are removed before they reach the graph.
144
+ Relations are directed subject–predicate–object triples. The active schema constrains valid source type, relation type, and target type combinations. The validation stage removes invalid triples before they reach the graph.
127
145
 
128
146
  ### Communities
129
147
 
@@ -153,12 +171,12 @@ Query: question -> plan -> parallel retrieval -> verify -> cited answer
153
171
 
154
172
  `Graph.add()` is the single entry point for adding content. The complete pipeline is organized into these stages:
155
173
 
156
- 1. **Load:** Select a loader by format, decode or parse the source, preserve source metadata, and apply `RAISE`, `SKIP`, or `QUARANTINE` per-source error handling.
174
+ 1. **Load:** Select a loader by format. Decode or parse the source. Preserve source metadata. Apply `RAISE`, `SKIP`, or `QUARANTINE` as the error policy for each source.
157
175
  2. **Chunk:** Use Docling's layout-aware chunking before flattening rich documents; use Chonkie for text and record documents.
158
176
  3. **Extract:** Run GLiNER locally against the active schema. Escalate weak results to a typed BAML extraction function when configured.
159
177
  4. **Validate:** Drop entities and triples that do not conform to the schema.
160
178
  5. **Resolve:** Apply exact, fuzzy, embedding, and LLM-verified comparison tiers. Ambiguous or failed comparisons do not merge.
161
- 6. **Merge:** Resolve properties field by field, combine provenance, deduplicate repointed relations, and retain an audit trail.
179
+ 6. **Merge:** Resolve properties field by field. Combine provenance. Deduplicate repointed relations. Retain an audit trail.
162
180
  7. **Store:** Upsert canonical nodes and relations, then populate graph-native or dedicated vector indexes.
163
181
 
164
182
  The extraction cascade replaces a weak local result with the LLM result instead of combining two conflicting outputs. Exact matches use global store-backed lookup; more expensive fuzzy and LLM comparisons are blocked to a smaller candidate set.
@@ -178,7 +196,7 @@ The async `Embedder`, `GraphStore`, and `VectorStore` interfaces keep model and
178
196
 
179
197
  ### Graph storage
180
198
 
181
- The Neo4j backend supports local Neo4j and Aura over Bolt, managed read/write transactions, node and relation upserts, constraints, indexes, and native dense vector search. Dynamic labels and relation types are validated before Cypher interpolation.
199
+ The Neo4j backend supports local Neo4j and Aura over Bolt, managed read/write transactions, node and relation upserts, constraints, indexes, and native dense vector search. The query builders validate dynamic labels and relation types before they interpolate them into Cypher.
182
200
 
183
201
  ### Vector storage
184
202
 
@@ -251,6 +269,9 @@ uv pip install "agentic-graphrag[llm,embed-local]"
251
269
 
252
270
  # Neo4j with a dedicated Qdrant vector store and OTLP tracing
253
271
  uv pip install "agentic-graphrag[neo4j,qdrant,observability]"
272
+
273
+ # Hierarchical community detection
274
+ uv pip install "agentic-graphrag[community]"
254
275
  ```
255
276
 
256
277
  | Extra | Adds |
@@ -264,6 +285,7 @@ uv pip install "agentic-graphrag[neo4j,qdrant,observability]"
264
285
  | `weaviate` | Weaviate dense and hybrid search |
265
286
  | `milvus` | Milvus/Zilliz dense and hybrid search |
266
287
  | `observability` | OpenTelemetry SDK and OTLP export |
288
+ | `community` | Hierarchical Leiden community detection |
267
289
 
268
290
  ## Usage
269
291
 
@@ -278,11 +300,14 @@ from agrag.ingestion import Graph
278
300
  async def main() -> None:
279
301
  graph = await Graph.open()
280
302
 
281
- files = await graph.add(source="./corpus/**/*.md")
282
- text = await graph.add(text="Agentic GraphRAG turns evidence into a graph.")
303
+ files = await graph.add(source="./corpus/**/*.md", return_chunks=True)
304
+ text = await graph.add(
305
+ text="Agentic GraphRAG turns evidence into a graph.",
306
+ return_chunks=True,
307
+ )
283
308
 
284
- print(files.documents, len(files.chunks))
285
- print(text.documents, len(text.chunks))
309
+ print(files.ingestion.documents, len(files.chunks))
310
+ print(text.ingestion.documents, len(text.chunks))
286
311
 
287
312
 
288
313
  asyncio.run(main())
@@ -304,8 +329,8 @@ result = await graph.add(
304
329
  error_policy=ErrorPolicy.QUARANTINE,
305
330
  )
306
331
 
307
- for uri, reason in result.quarantined_items:
308
- print(uri, reason)
332
+ for item in result.ingestion.quarantined_items:
333
+ print(item.item_id, item.error_message)
309
334
  ```
310
335
 
311
336
  See the [documentation](https://ontogr.github.io/agentic-graphrag/) for guides and the generated API reference.
@@ -15,7 +15,7 @@
15
15
 
16
16
  </div>
17
17
 
18
- Agentic GraphRAG is a modular, schema-driven system for building knowledge graphs from unstructured and structured data, retrieving evidence across graph and vector indexes, and answering questions with agentic reasoning.
18
+ Agentic GraphRAG is a modular, schema-driven system. It builds knowledge graphs from unstructured and structured data. It retrieves evidence across graph and vector indexes. It answers questions with agentic reasoning.
19
19
 
20
20
  <p align="center">
21
21
  <img src="img/agentic_graphrag_pipeline.png" alt="Agentic GraphRAG pipeline from data loading through graph construction, storage, retrieval, and agentic reasoning" width="1200">
@@ -67,7 +67,7 @@ Documents keep their source URI, format, loader, content hash, and record identi
67
67
 
68
68
  Extraction produces mentions first, not graph nodes. Each mention keeps its source chunk, label, text span, confidence, and extractor provenance. Resolution then assigns canonical identities and merges aliases before storage.
69
69
 
70
- Relations are directed subject–predicate–object triples. The active schema constrains valid source type, relation type, and target type combinations, so invalid triples are removed before they reach the graph.
70
+ Relations are directed subject–predicate–object triples. The active schema constrains valid source type, relation type, and target type combinations. The validation stage removes invalid triples before they reach the graph.
71
71
 
72
72
  ### Communities
73
73
 
@@ -97,12 +97,12 @@ Query: question -> plan -> parallel retrieval -> verify -> cited answer
97
97
 
98
98
  `Graph.add()` is the single entry point for adding content. The complete pipeline is organized into these stages:
99
99
 
100
- 1. **Load:** Select a loader by format, decode or parse the source, preserve source metadata, and apply `RAISE`, `SKIP`, or `QUARANTINE` per-source error handling.
100
+ 1. **Load:** Select a loader by format. Decode or parse the source. Preserve source metadata. Apply `RAISE`, `SKIP`, or `QUARANTINE` as the error policy for each source.
101
101
  2. **Chunk:** Use Docling's layout-aware chunking before flattening rich documents; use Chonkie for text and record documents.
102
102
  3. **Extract:** Run GLiNER locally against the active schema. Escalate weak results to a typed BAML extraction function when configured.
103
103
  4. **Validate:** Drop entities and triples that do not conform to the schema.
104
104
  5. **Resolve:** Apply exact, fuzzy, embedding, and LLM-verified comparison tiers. Ambiguous or failed comparisons do not merge.
105
- 6. **Merge:** Resolve properties field by field, combine provenance, deduplicate repointed relations, and retain an audit trail.
105
+ 6. **Merge:** Resolve properties field by field. Combine provenance. Deduplicate repointed relations. Retain an audit trail.
106
106
  7. **Store:** Upsert canonical nodes and relations, then populate graph-native or dedicated vector indexes.
107
107
 
108
108
  The extraction cascade replaces a weak local result with the LLM result instead of combining two conflicting outputs. Exact matches use global store-backed lookup; more expensive fuzzy and LLM comparisons are blocked to a smaller candidate set.
@@ -122,7 +122,7 @@ The async `Embedder`, `GraphStore`, and `VectorStore` interfaces keep model and
122
122
 
123
123
  ### Graph storage
124
124
 
125
- The Neo4j backend supports local Neo4j and Aura over Bolt, managed read/write transactions, node and relation upserts, constraints, indexes, and native dense vector search. Dynamic labels and relation types are validated before Cypher interpolation.
125
+ The Neo4j backend supports local Neo4j and Aura over Bolt, managed read/write transactions, node and relation upserts, constraints, indexes, and native dense vector search. The query builders validate dynamic labels and relation types before they interpolate them into Cypher.
126
126
 
127
127
  ### Vector storage
128
128
 
@@ -195,6 +195,9 @@ uv pip install "agentic-graphrag[llm,embed-local]"
195
195
 
196
196
  # Neo4j with a dedicated Qdrant vector store and OTLP tracing
197
197
  uv pip install "agentic-graphrag[neo4j,qdrant,observability]"
198
+
199
+ # Hierarchical community detection
200
+ uv pip install "agentic-graphrag[community]"
198
201
  ```
199
202
 
200
203
  | Extra | Adds |
@@ -208,6 +211,7 @@ uv pip install "agentic-graphrag[neo4j,qdrant,observability]"
208
211
  | `weaviate` | Weaviate dense and hybrid search |
209
212
  | `milvus` | Milvus/Zilliz dense and hybrid search |
210
213
  | `observability` | OpenTelemetry SDK and OTLP export |
214
+ | `community` | Hierarchical Leiden community detection |
211
215
 
212
216
  ## Usage
213
217
 
@@ -222,11 +226,14 @@ from agrag.ingestion import Graph
222
226
  async def main() -> None:
223
227
  graph = await Graph.open()
224
228
 
225
- files = await graph.add(source="./corpus/**/*.md")
226
- text = await graph.add(text="Agentic GraphRAG turns evidence into a graph.")
229
+ files = await graph.add(source="./corpus/**/*.md", return_chunks=True)
230
+ text = await graph.add(
231
+ text="Agentic GraphRAG turns evidence into a graph.",
232
+ return_chunks=True,
233
+ )
227
234
 
228
- print(files.documents, len(files.chunks))
229
- print(text.documents, len(text.chunks))
235
+ print(files.ingestion.documents, len(files.chunks))
236
+ print(text.ingestion.documents, len(text.chunks))
230
237
 
231
238
 
232
239
  asyncio.run(main())
@@ -248,8 +255,8 @@ result = await graph.add(
248
255
  error_policy=ErrorPolicy.QUARANTINE,
249
256
  )
250
257
 
251
- for uri, reason in result.quarantined_items:
252
- print(uri, reason)
258
+ for item in result.ingestion.quarantined_items:
259
+ print(item.item_id, item.error_message)
253
260
  ```
254
261
 
255
262
  See the [documentation](https://ontogr.github.io/agentic-graphrag/) for guides and the generated API reference.
@@ -0,0 +1,19 @@
1
+ """Agentic layer: planner/researcher/verifier over SearchEngine.
2
+
3
+ ``build_agent`` lives in ``agrag.agents.build`` and is not re-exported here: it needs
4
+ the ``agents`` extra to import, and this package must import on a base install.
5
+ """
6
+
7
+ from agrag.agents.errors import AgentMissingExtraError
8
+ from agrag.agents.ledger import Ledger
9
+ from agrag.agents.result import AgentRunResult
10
+ from agrag.agents.settings import AgentLLMSettings, AgentSettings
11
+
12
+
13
+ __all__ = [
14
+ "AgentLLMSettings",
15
+ "AgentMissingExtraError",
16
+ "AgentRunResult",
17
+ "AgentSettings",
18
+ "Ledger",
19
+ ]
@@ -0,0 +1,276 @@
1
+ """Build the planner/researcher/verifier agent graph."""
2
+
3
+ import importlib.util
4
+ from contextlib import nullcontext
5
+ from typing import Any
6
+
7
+ from opentelemetry.trace import Tracer
8
+
9
+ from agrag.agents.harness import ensure_harness_profile, model_provider_key
10
+ from agrag.agents.ledger import Ledger
11
+ from agrag.agents.middleware import ResearchAttemptLimiter, VerifierEvidenceMiddleware
12
+ from agrag.agents.model import build_chat_model, build_model_middleware
13
+ from agrag.agents.prompts import PLANNER_SYSTEM, SIMPLE_ANSWER_SYSTEM
14
+ from agrag.agents.result import AgentRunResult
15
+ from agrag.agents.settings import AgentLLMSettings, AgentSettings
16
+ from agrag.agents.subagents import make_researcher_spec, make_verifier_spec
17
+ from agrag.agents.tools import make_tools
18
+ from agrag.agents.tracing import require_tracing, run_callbacks
19
+ from agrag.common.data_models.graph_schema import GraphSchema
20
+ from agrag.retrieval.filters import SearchFilters
21
+ from agrag.retrieval.search_engine import SearchEngine
22
+
23
+
24
+ def build_agent(
25
+ *,
26
+ engine: SearchEngine,
27
+ llm_settings: AgentLLMSettings,
28
+ agent_settings: AgentSettings | None = None,
29
+ filters: SearchFilters | None = None,
30
+ graph_schema: GraphSchema | None = None,
31
+ tracer: Tracer | None = None,
32
+ ) -> Any:
33
+ """Build the planner/researcher/verifier agent graph.
34
+
35
+ Constructs a LangGraph-based agent with three roles:
36
+ planner (decomposes the question), researcher (has tools),
37
+ and verifier (judges evidence sufficiency and returns a
38
+ structured verdict).
39
+
40
+ Each call to ``ainvoke`` creates a fresh ``Ledger`` so
41
+ citation numbering, identity mappings, and retrieved evidence
42
+ do not leak across runs, and a fresh ``ResearchAttemptLimiter``
43
+ so one question's retry budget does not spend another's.
44
+
45
+ Args:
46
+ engine: Retrieval to expose to the researcher subagent's
47
+ tools.
48
+ llm_settings: The model every subagent role calls, via
49
+ build_chat_model. With several clients, the remaining
50
+ ones compose per strategy through agent middleware.
51
+ agent_settings: Loop-level configuration; defaults from
52
+ environment. The recursion limit is enforced as the
53
+ LangGraph ``recursion_limit`` in the invoke config, and
54
+ ``max_research_attempts`` bounds how many times the
55
+ planner may re-research after an INSUFFICIENT verdict.
56
+ filters: Retrieval scope applied to every tool search,
57
+ e.g. document or tenant constraints. None searches
58
+ unfiltered. A non-empty scope also removes the
59
+ ``query_graph_directly`` tool, since a generated query
60
+ cannot be confined to a scope.
61
+ graph_schema: The schema the researcher prompt and the
62
+ ``query_graph_directly`` tool describe. None uses the
63
+ engine's own resolved schema; a value that differs from
64
+ the engine's raises, so the prompt cannot describe a
65
+ graph the engine does not search.
66
+ tracer: Receives OpenInference spans for every ``ainvoke``,
67
+ including the researcher and verifier subagents' tool and
68
+ model calls. None emits no spans. Spans carry the question,
69
+ tool inputs, and evidence text.
70
+
71
+ Returns:
72
+ An agent whose ``ainvoke`` returns an ``AgentRunResult``: the
73
+ run's ``messages`` plus its ``ledger``, which maps each
74
+ citation key in the answer back to its evidence. When
75
+ deepagents is not installed, a single-search-plus-synthesis
76
+ fallback with the same result shape.
77
+
78
+ Raises:
79
+ AgentMissingExtraError: ``tracer`` is set but the ``observability``
80
+ extra is not installed.
81
+ ValueError: ``graph_schema`` differs from the engine's schema.
82
+ """
83
+ if tracer is not None:
84
+ require_tracing()
85
+ settings = agent_settings or AgentSettings()
86
+ model = build_chat_model(llm_settings.clients[0])
87
+ middleware = build_model_middleware(
88
+ llm_settings.clients, strategy=llm_settings.strategy
89
+ )
90
+ schema = engine.graph_schema
91
+ if graph_schema is not None and graph_schema != schema:
92
+ raise ValueError(
93
+ "graph_schema does not match the engine's schema "
94
+ f"('{schema.name}'); the researcher prompt and the engine "
95
+ "must describe the same graph"
96
+ )
97
+
98
+ if importlib.util.find_spec("deepagents") is not None:
99
+ return _RunScopedAgent(
100
+ engine=engine,
101
+ model=model,
102
+ settings=settings,
103
+ middleware=middleware,
104
+ filters=filters,
105
+ graph_schema=schema,
106
+ model_provider=model_provider_key(llm_settings.clients[0].provider),
107
+ tracer=tracer,
108
+ )
109
+
110
+ # Fallback: a simple wrapper when deepagents is not installed,
111
+ # useful for unit testing without the full extra. If deepagents
112
+ # is present but broken, ainvoke raises its import error at call
113
+ # time instead of silently degrading here.
114
+ return _SimpleAgent(model=model, engine=engine, filters=filters, tracer=tracer)
115
+
116
+
117
+ class _RunScopedAgent:
118
+ """Builds the deepagents graph fresh per run.
119
+
120
+ Each ``ainvoke`` call constructs the graph with a new
121
+ ``Ledger``, a new tool set, and a new
122
+ ``ResearchAttemptLimiter`` so citation state and the retry
123
+ budget do not span runs, and enforces the configured LangGraph
124
+ recursion limit.
125
+ """
126
+
127
+ def __init__(
128
+ self,
129
+ *,
130
+ engine: SearchEngine,
131
+ model: Any,
132
+ settings: AgentSettings,
133
+ middleware: list[Any] | None = None,
134
+ filters: SearchFilters | None = None,
135
+ graph_schema: GraphSchema | None = None,
136
+ model_provider: str = "",
137
+ tracer: Tracer | None = None,
138
+ ) -> None:
139
+ """Construct the wrapper."""
140
+ self._engine = engine
141
+ self._model = model
142
+ self._settings = settings
143
+ self._middleware = middleware or []
144
+ self._filters = filters
145
+ self._graph_schema = (
146
+ graph_schema if graph_schema is not None else engine.graph_schema
147
+ )
148
+ self._model_provider = model_provider
149
+ self._tracer = tracer
150
+
151
+ async def ainvoke(self, input_data: dict) -> AgentRunResult:
152
+ """Delegate to inner agent with a fresh Ledger and limiter.
153
+
154
+ Builds the planner with the researcher and verifier as
155
+ subagents. The planner sees the task tool for delegation and
156
+ carries the attempt limiter; the researcher carries the
157
+ caller's tools and the engine's schema summary; the verifier
158
+ returns a structured verdict.
159
+
160
+ Args:
161
+ input_data: Dict with ``messages`` key.
162
+
163
+ Returns:
164
+ The graph's final state with this run's ``ledger`` added.
165
+ """
166
+ from deepagents import create_deep_agent # noqa: PLC0415
167
+
168
+ ensure_harness_profile(self._model_provider)
169
+ ledger = Ledger()
170
+ tools = make_tools(self._engine, ledger, filters=self._filters)
171
+ researcher = make_researcher_spec(tools, self._middleware, self._graph_schema)
172
+ verifier = make_verifier_spec(self._middleware)
173
+ limiter = ResearchAttemptLimiter(self._settings.max_research_attempts)
174
+ planner_system = PLANNER_SYSTEM.replace(
175
+ "{max_research_attempts}", str(self._settings.max_research_attempts)
176
+ )
177
+
178
+ # Annotated, not typed against deepagents' own SubAgent: importing
179
+ # that type here would make this module require the optional
180
+ # dependency at import time. The specs are SubAgent-shaped dicts.
181
+ subagents: list[Any] = [researcher, verifier]
182
+ agent = create_deep_agent(
183
+ model=self._model,
184
+ system_prompt=planner_system,
185
+ subagents=subagents,
186
+ middleware=[*self._middleware, limiter, VerifierEvidenceMiddleware(ledger)],
187
+ )
188
+ result = await agent.ainvoke(
189
+ input_data,
190
+ config={
191
+ "recursion_limit": self._settings.recursion_limit,
192
+ "callbacks": run_callbacks(self._tracer),
193
+ },
194
+ )
195
+ return {**result, "ledger": ledger}
196
+
197
+
198
+ class _SimpleAgent:
199
+ """Fallback agent when deepagents is not installed.
200
+
201
+ Performs a single hybrid search per invocation, then one LLM
202
+ call to synthesize a cited answer from the results -- still no
203
+ agent loop, tool calls, or multi-client composition
204
+ (``build_model_middleware``'s fallback/round-robin strategies
205
+ wrap ``create_deep_agent``'s loop, not a bare model call, and
206
+ this class already only receives ``clients[0]``). There is no
207
+ agent loop, so ``AgentSettings.recursion_limit`` does not apply.
208
+ """
209
+
210
+ def __init__(
211
+ self,
212
+ *,
213
+ model: Any,
214
+ engine: SearchEngine,
215
+ filters: SearchFilters | None = None,
216
+ tracer: Tracer | None = None,
217
+ ) -> None:
218
+ """Construct a simple agent wrapper."""
219
+ self._model = model
220
+ self._engine = engine
221
+ self._filters = filters
222
+ self._tracer = tracer
223
+
224
+ async def ainvoke(self, input_data: dict) -> AgentRunResult:
225
+ """Run the agent with a fresh ledger (simplified path).
226
+
227
+ Creates a new ``Ledger`` and tool set per invocation so
228
+ citation state does not span runs. Runs one search, then one
229
+ LLM call to synthesize a cited answer from the results.
230
+
231
+ Args:
232
+ input_data: Dict with ``messages`` key.
233
+
234
+ Returns:
235
+ Dict with ``messages`` containing the answer and this run's
236
+ ``ledger``.
237
+ """
238
+ span_context = (
239
+ self._tracer.start_as_current_span("agrag.agents.run")
240
+ if self._tracer is not None
241
+ else nullcontext()
242
+ )
243
+ with span_context:
244
+ ledger = Ledger()
245
+ messages = input_data.get("messages", [])
246
+ if not messages:
247
+ return {"messages": [], "ledger": ledger}
248
+
249
+ question = messages[-1].get("content", "")
250
+ from agrag.retrieval.recipes import HYBRID # noqa: PLC0415
251
+
252
+ results = await self._engine.search(question, HYBRID, filters=self._filters)
253
+ evidence = [ledger.render(r) for r in results]
254
+ if not evidence:
255
+ return {
256
+ "messages": [
257
+ {"role": "assistant", "content": "No relevant evidence found."}
258
+ ],
259
+ "ledger": ledger,
260
+ }
261
+
262
+ response = await self._model.ainvoke(
263
+ [
264
+ {"role": "system", "content": SIMPLE_ANSWER_SYSTEM},
265
+ {
266
+ "role": "user",
267
+ "content": f"Question: {question}\n\nEvidence:\n"
268
+ + "\n".join(evidence),
269
+ },
270
+ ],
271
+ config={"callbacks": run_callbacks(self._tracer)},
272
+ )
273
+ return {
274
+ "messages": [{"role": "assistant", "content": response.text}],
275
+ "ledger": ledger,
276
+ }
@@ -0,0 +1,16 @@
1
+ """Errors raised by the agent layer."""
2
+
3
+
4
+ class AgentMissingExtraError(Exception):
5
+ """Agent tracing needs a package extra that is not installed.
6
+
7
+ Attributes:
8
+ extra: The name of the package extra to install.
9
+ """
10
+
11
+ def __init__(self, extra: str) -> None:
12
+ """Bind the missing package extra to the error."""
13
+ super().__init__(
14
+ f"needs the {extra!r} extra: pip install 'agentic-graphrag[{extra}]'"
15
+ )
16
+ self.extra = extra
@@ -0,0 +1,54 @@
1
+ """Process-global DeepAgents harness profile registration.
2
+
3
+ Registers, once per process and per provider, the profile that trims
4
+ DeepAgents' generic tool surface for this project's agent: the execute
5
+ tool is excluded and the general-purpose subagent is disabled. The
6
+ registration is a process-global side effect, so it is guarded against
7
+ re-registration.
8
+ """
9
+
10
+ _HARNESS_PROFILE_REGISTERED: set[str] = set()
11
+ _AGENT_PROVIDER_TO_HARNESS_KEY = {
12
+ "anthropic": "anthropic",
13
+ "openai": "openai",
14
+ "openai-generic": "openai",
15
+ "google-ai": "google_genai",
16
+ }
17
+
18
+
19
+ def model_provider_key(provider: str) -> str:
20
+ """Return the DeepAgents provider key for a configured agent provider.
21
+
22
+ Args:
23
+ provider: The configured agent provider.
24
+
25
+ Returns:
26
+ The provider key used by DeepAgents harness profiles.
27
+ """
28
+ return _AGENT_PROVIDER_TO_HARNESS_KEY[provider]
29
+
30
+
31
+ def ensure_harness_profile(provider: str) -> None:
32
+ """Register the harness profile for provider, once per process.
33
+
34
+ Args:
35
+ provider: The provider key DeepAgents resolves profiles by,
36
+ either a provider string such as ``"anthropic"`` or an
37
+ exact ``"provider:model"`` string.
38
+ """
39
+ if provider in _HARNESS_PROFILE_REGISTERED:
40
+ return
41
+ from deepagents import ( # noqa: PLC0415
42
+ GeneralPurposeSubagentProfile,
43
+ HarnessProfile,
44
+ register_harness_profile,
45
+ )
46
+
47
+ register_harness_profile(
48
+ provider,
49
+ HarnessProfile(
50
+ excluded_tools=frozenset({"execute"}),
51
+ general_purpose_subagent=GeneralPurposeSubagentProfile(enabled=False),
52
+ ),
53
+ )
54
+ _HARNESS_PROFILE_REGISTERED.add(provider)